NN commited on
Commit
b0b44df
·
1 Parent(s): f5aa56d

Upload 144 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. stable-diffusion-webui-master/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  2. stable-diffusion-webui-master/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. stable-diffusion-webui-master/.github/ISSUE_TEMPLATE/feature_request.yml +40 -0
  4. stable-diffusion-webui-master/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +28 -0
  5. stable-diffusion-webui-master/.github/workflows/on_pull_request.yaml +42 -0
  6. stable-diffusion-webui-master/.github/workflows/run_tests.yaml +31 -0
  7. stable-diffusion-webui-master/.gitignore +34 -0
  8. stable-diffusion-webui-master/.pylintrc +3 -0
  9. stable-diffusion-webui-master/CODEOWNERS +12 -0
  10. stable-diffusion-webui-master/README.md +150 -0
  11. stable-diffusion-webui-master/artists.csv +0 -0
  12. stable-diffusion-webui-master/embeddings/Place Textual Inversion embeddings here.txt +0 -0
  13. stable-diffusion-webui-master/environment-wsl2.yaml +11 -0
  14. stable-diffusion-webui-master/extensions/put extensions here.txt +0 -0
  15. stable-diffusion-webui-master/javascript/aspectRatioOverlay.js +108 -0
  16. stable-diffusion-webui-master/javascript/contextMenus.js +177 -0
  17. stable-diffusion-webui-master/javascript/dragdrop.js +89 -0
  18. stable-diffusion-webui-master/javascript/edit-attention.js +75 -0
  19. stable-diffusion-webui-master/javascript/extensions.js +35 -0
  20. stable-diffusion-webui-master/javascript/generationParams.js +33 -0
  21. stable-diffusion-webui-master/javascript/hints.js +129 -0
  22. stable-diffusion-webui-master/javascript/imageMaskFix.js +45 -0
  23. stable-diffusion-webui-master/javascript/imageParams.js +19 -0
  24. stable-diffusion-webui-master/javascript/imageviewer.js +276 -0
  25. stable-diffusion-webui-master/javascript/localization.js +167 -0
  26. stable-diffusion-webui-master/javascript/notification.js +49 -0
  27. stable-diffusion-webui-master/javascript/progressbar.js +137 -0
  28. stable-diffusion-webui-master/javascript/textualInversion.js +8 -0
  29. stable-diffusion-webui-master/javascript/ui.js +213 -0
  30. stable-diffusion-webui-master/launch.py +294 -0
  31. stable-diffusion-webui-master/localizations/Put localization files here.txt +0 -0
  32. stable-diffusion-webui-master/models/Stable-diffusion/Put Stable Diffusion checkpoints here.txt +0 -0
  33. stable-diffusion-webui-master/models/VAE/Put VAE here.txt +0 -0
  34. stable-diffusion-webui-master/models/deepbooru/Put your deepbooru release project folder here.txt +0 -0
  35. stable-diffusion-webui-master/modules/api/api.py +329 -0
  36. stable-diffusion-webui-master/modules/api/models.py +242 -0
  37. stable-diffusion-webui-master/modules/artists.py +25 -0
  38. stable-diffusion-webui-master/modules/call_queue.py +98 -0
  39. stable-diffusion-webui-master/modules/codeformer/codeformer_arch.py +278 -0
  40. stable-diffusion-webui-master/modules/codeformer/vqgan_arch.py +437 -0
  41. stable-diffusion-webui-master/modules/codeformer_model.py +143 -0
  42. stable-diffusion-webui-master/modules/deepbooru.py +97 -0
  43. stable-diffusion-webui-master/modules/deepbooru_model.py +676 -0
  44. stable-diffusion-webui-master/modules/devices.py +124 -0
  45. stable-diffusion-webui-master/modules/errors.py +10 -0
  46. stable-diffusion-webui-master/modules/esrgan_model.py +233 -0
  47. stable-diffusion-webui-master/modules/esrgan_model_arch.py +463 -0
  48. stable-diffusion-webui-master/modules/extensions.py +89 -0
  49. stable-diffusion-webui-master/modules/extras.py +313 -0
  50. stable-diffusion-webui-master/modules/face_restoration.py +19 -0
stable-diffusion-webui-master/.github/ISSUE_TEMPLATE/bug_report.yml ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Bug Report
2
+ description: You think somethings is broken in the UI
3
+ title: "[Bug]: "
4
+ labels: ["bug-report"]
5
+
6
+ body:
7
+ - type: checkboxes
8
+ attributes:
9
+ label: Is there an existing issue for this?
10
+ description: Please search to see if an issue already exists for the bug you encountered, and that it hasn't been fixed in a recent build/commit.
11
+ options:
12
+ - label: I have searched the existing issues and checked the recent builds/commits
13
+ required: true
14
+ - type: markdown
15
+ attributes:
16
+ value: |
17
+ *Please fill this form with as much information as possible, don't forget to fill "What OS..." and "What browsers" and *provide screenshots if possible**
18
+ - type: textarea
19
+ id: what-did
20
+ attributes:
21
+ label: What happened?
22
+ description: Tell us what happened in a very clear and simple way
23
+ validations:
24
+ required: true
25
+ - type: textarea
26
+ id: steps
27
+ attributes:
28
+ label: Steps to reproduce the problem
29
+ description: Please provide us with precise step by step information on how to reproduce the bug
30
+ value: |
31
+ 1. Go to ....
32
+ 2. Press ....
33
+ 3. ...
34
+ validations:
35
+ required: true
36
+ - type: textarea
37
+ id: what-should
38
+ attributes:
39
+ label: What should have happened?
40
+ description: tell what you think the normal behavior should be
41
+ validations:
42
+ required: true
43
+ - type: input
44
+ id: commit
45
+ attributes:
46
+ label: Commit where the problem happens
47
+ description: Which commit are you running ? (Do not write *Latest version/repo/commit*, as this means nothing and will have changed by the time we read your issue. Rather, copy the **Commit hash** shown in the cmd/terminal when you launch the UI)
48
+ validations:
49
+ required: true
50
+ - type: dropdown
51
+ id: platforms
52
+ attributes:
53
+ label: What platforms do you use to access UI ?
54
+ multiple: true
55
+ options:
56
+ - Windows
57
+ - Linux
58
+ - MacOS
59
+ - iOS
60
+ - Android
61
+ - Other/Cloud
62
+ - type: dropdown
63
+ id: browsers
64
+ attributes:
65
+ label: What browsers do you use to access the UI ?
66
+ multiple: true
67
+ options:
68
+ - Mozilla Firefox
69
+ - Google Chrome
70
+ - Brave
71
+ - Apple Safari
72
+ - Microsoft Edge
73
+ - type: textarea
74
+ id: cmdargs
75
+ attributes:
76
+ label: Command Line Arguments
77
+ description: Are you using any launching parameters/command line arguments (modified webui-user.py) ? If yes, please write them below
78
+ render: Shell
79
+ - type: textarea
80
+ id: misc
81
+ attributes:
82
+ label: Additional information, context and logs
83
+ description: Please provide us with any relevant additional info, context or log output.
stable-diffusion-webui-master/.github/ISSUE_TEMPLATE/config.yml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: WebUI Community Support
4
+ url: https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions
5
+ about: Please ask and answer questions here.
stable-diffusion-webui-master/.github/ISSUE_TEMPLATE/feature_request.yml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Feature request
2
+ description: Suggest an idea for this project
3
+ title: "[Feature Request]: "
4
+ labels: ["suggestion"]
5
+
6
+ body:
7
+ - type: checkboxes
8
+ attributes:
9
+ label: Is there an existing issue for this?
10
+ description: Please search to see if an issue already exists for the feature you want, and that it's not implemented in a recent build/commit.
11
+ options:
12
+ - label: I have searched the existing issues and checked the recent builds/commits
13
+ required: true
14
+ - type: markdown
15
+ attributes:
16
+ value: |
17
+ *Please fill this form with as much information as possible, provide screenshots and/or illustrations of the feature if possible*
18
+ - type: textarea
19
+ id: feature
20
+ attributes:
21
+ label: What would your feature do ?
22
+ description: Tell us about your feature in a very clear and simple way, and what problem it would solve
23
+ validations:
24
+ required: true
25
+ - type: textarea
26
+ id: workflow
27
+ attributes:
28
+ label: Proposed workflow
29
+ description: Please provide us with step by step information on how you'd like the feature to be accessed and used
30
+ value: |
31
+ 1. Go to ....
32
+ 2. Press ....
33
+ 3. ...
34
+ validations:
35
+ required: true
36
+ - type: textarea
37
+ id: misc
38
+ attributes:
39
+ label: Additional information
40
+ description: Add any other context or screenshots about the feature request here.
stable-diffusion-webui-master/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Please read the [contributing wiki page](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Contributing) before submitting a pull request!
2
+
3
+ If you have a large change, pay special attention to this paragraph:
4
+
5
+ > Before making changes, if you think that your feature will result in more than 100 lines changing, find me and talk to me about the feature you are proposing. It pains me to reject the hard work someone else did, but I won't add everything to the repo, and it's better if the rejection happens before you have to waste time working on the feature.
6
+
7
+ Otherwise, after making sure you're following the rules described in wiki page, remove this section and continue on.
8
+
9
+ **Describe what this pull request is trying to achieve.**
10
+
11
+ A clear and concise description of what you're trying to accomplish with this, so your intent doesn't have to be extracted from your code.
12
+
13
+ **Additional notes and description of your changes**
14
+
15
+ More technical discussion about your changes go here, plus anything that a maintainer might have to specifically take a look at, or be wary of.
16
+
17
+ **Environment this was tested in**
18
+
19
+ List the environment you have developed / tested this on. As per the contributing page, changes should be able to work on Windows out of the box.
20
+ - OS: [e.g. Windows, Linux]
21
+ - Browser [e.g. chrome, safari]
22
+ - Graphics card [e.g. NVIDIA RTX 2080 8GB, AMD RX 6600 8GB]
23
+
24
+ **Screenshots or videos of your changes**
25
+
26
+ If applicable, screenshots or a video showing off your changes. If it edits an existing UI, it should ideally contain a comparison of what used to be there, before your changes were made.
27
+
28
+ This is **required** for anything that touches the user interface.
stable-diffusion-webui-master/.github/workflows/on_pull_request.yaml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://github.com/actions/starter-workflows/blob/1067f16ad8a1eac328834e4b0ae24f7d206f810d/ci/pylint.yml for original reference file
2
+ name: Run Linting/Formatting on Pull Requests
3
+
4
+ on:
5
+ - push
6
+ - pull_request
7
+ # See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpull_requestpull_request_targetbranchesbranches-ignore for syntax docs
8
+ # if you want to filter out branches, delete the `- pull_request` and uncomment these lines :
9
+ # pull_request:
10
+ # branches:
11
+ # - master
12
+ # branches-ignore:
13
+ # - development
14
+
15
+ jobs:
16
+ lint:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - name: Checkout Code
20
+ uses: actions/checkout@v3
21
+ - name: Set up Python 3.10
22
+ uses: actions/setup-python@v3
23
+ with:
24
+ python-version: 3.10.6
25
+ - uses: actions/cache@v2
26
+ with:
27
+ path: ~/.cache/pip
28
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
29
+ restore-keys: |
30
+ ${{ runner.os }}-pip-
31
+ - name: Install PyLint
32
+ run: |
33
+ python -m pip install --upgrade pip
34
+ pip install pylint
35
+ # This lets PyLint check to see if it can resolve imports
36
+ - name: Install dependencies
37
+ run : |
38
+ export COMMANDLINE_ARGS="--skip-torch-cuda-test --exit"
39
+ python launch.py
40
+ - name: Analysing the code with pylint
41
+ run: |
42
+ pylint $(git ls-files '*.py')
stable-diffusion-webui-master/.github/workflows/run_tests.yaml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Run basic features tests on CPU with empty SD model
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Checkout Code
12
+ uses: actions/checkout@v3
13
+ - name: Set up Python 3.10
14
+ uses: actions/setup-python@v4
15
+ with:
16
+ python-version: 3.10.6
17
+ - uses: actions/cache@v3
18
+ with:
19
+ path: ~/.cache/pip
20
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
21
+ restore-keys: ${{ runner.os }}-pip-
22
+ - name: Run tests
23
+ run: python launch.py --tests basic_features --no-half --disable-opt-split-attention --use-cpu all --skip-torch-cuda-test
24
+ - name: Upload main app stdout-stderr
25
+ uses: actions/upload-artifact@v3
26
+ if: always()
27
+ with:
28
+ name: stdout-stderr
29
+ path: |
30
+ test/stdout.txt
31
+ test/stderr.txt
stable-diffusion-webui-master/.gitignore ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__
2
+ *.ckpt
3
+ *.safetensors
4
+ *.pth
5
+ /ESRGAN/*
6
+ /SwinIR/*
7
+ /repositories
8
+ /venv
9
+ /tmp
10
+ /model.ckpt
11
+ /models/**/*
12
+ /GFPGANv1.3.pth
13
+ /gfpgan/weights/*.pth
14
+ /ui-config.json
15
+ /outputs
16
+ /config.json
17
+ /log
18
+ /webui.settings.bat
19
+ /embeddings
20
+ /styles.csv
21
+ /params.txt
22
+ /styles.csv.bak
23
+ /webui-user.bat
24
+ /webui-user.sh
25
+ /interrogate
26
+ /user.css
27
+ /.idea
28
+ notification.mp3
29
+ /SwinIR
30
+ /textual_inversion
31
+ .vscode
32
+ /extensions
33
+ /test/stdout.txt
34
+ /test/stderr.txt
stable-diffusion-webui-master/.pylintrc ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # See https://pylint.pycqa.org/en/latest/user_guide/messages/message_control.html
2
+ [MESSAGES CONTROL]
3
+ disable=C,R,W,E,I
stable-diffusion-webui-master/CODEOWNERS ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * @AUTOMATIC1111
2
+
3
+ # if you were managing a localization and were removed from this file, this is because
4
+ # the intended way to do localizations now is via extensions. See:
5
+ # https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Developing-extensions
6
+ # Make a repo with your localization and since you are still listed as a collaborator
7
+ # you can add it to the wiki page yourself. This change is because some people complained
8
+ # the git commit log is cluttered with things unrelated to almost everyone and
9
+ # because I believe this is the best overall for the project to handle localizations almost
10
+ # entirely without my oversight.
11
+
12
+
stable-diffusion-webui-master/README.md ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stable Diffusion web UI
2
+ A browser interface based on Gradio library for Stable Diffusion.
3
+
4
+ ![](txt2img_Screenshot.png)
5
+
6
+ Check the [custom scripts](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Custom-Scripts) wiki page for extra scripts developed by users.
7
+
8
+ ## Features
9
+ [Detailed feature showcase with images](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features):
10
+ - Original txt2img and img2img modes
11
+ - One click install and run script (but you still must install python and git)
12
+ - Outpainting
13
+ - Inpainting
14
+ - Color Sketch
15
+ - Prompt Matrix
16
+ - Stable Diffusion Upscale
17
+ - Attention, specify parts of text that the model should pay more attention to
18
+ - a man in a ((tuxedo)) - will pay more attention to tuxedo
19
+ - a man in a (tuxedo:1.21) - alternative syntax
20
+ - select text and press ctrl+up or ctrl+down to automatically adjust attention to selected text (code contributed by anonymous user)
21
+ - Loopback, run img2img processing multiple times
22
+ - X/Y plot, a way to draw a 2 dimensional plot of images with different parameters
23
+ - Textual Inversion
24
+ - have as many embeddings as you want and use any names you like for them
25
+ - use multiple embeddings with different numbers of vectors per token
26
+ - works with half precision floating point numbers
27
+ - train embeddings on 8GB (also reports of 6GB working)
28
+ - Extras tab with:
29
+ - GFPGAN, neural network that fixes faces
30
+ - CodeFormer, face restoration tool as an alternative to GFPGAN
31
+ - RealESRGAN, neural network upscaler
32
+ - ESRGAN, neural network upscaler with a lot of third party models
33
+ - SwinIR and Swin2SR([see here](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/2092)), neural network upscalers
34
+ - LDSR, Latent diffusion super resolution upscaling
35
+ - Resizing aspect ratio options
36
+ - Sampling method selection
37
+ - Adjust sampler eta values (noise multiplier)
38
+ - More advanced noise setting options
39
+ - Interrupt processing at any time
40
+ - 4GB video card support (also reports of 2GB working)
41
+ - Correct seeds for batches
42
+ - Live prompt token length validation
43
+ - Generation parameters
44
+ - parameters you used to generate images are saved with that image
45
+ - in PNG chunks for PNG, in EXIF for JPEG
46
+ - can drag the image to PNG info tab to restore generation parameters and automatically copy them into UI
47
+ - can be disabled in settings
48
+ - drag and drop an image/text-parameters to promptbox
49
+ - Read Generation Parameters Button, loads parameters in promptbox to UI
50
+ - Settings page
51
+ - Running arbitrary python code from UI (must run with --allow-code to enable)
52
+ - Mouseover hints for most UI elements
53
+ - Possible to change defaults/mix/max/step values for UI elements via text config
54
+ - Random artist button
55
+ - Tiling support, a checkbox to create images that can be tiled like textures
56
+ - Progress bar and live image generation preview
57
+ - Negative prompt, an extra text field that allows you to list what you don't want to see in generated image
58
+ - Styles, a way to save part of prompt and easily apply them via dropdown later
59
+ - Variations, a way to generate same image but with tiny differences
60
+ - Seed resizing, a way to generate same image but at slightly different resolution
61
+ - CLIP interrogator, a button that tries to guess prompt from an image
62
+ - Prompt Editing, a way to change prompt mid-generation, say to start making a watermelon and switch to anime girl midway
63
+ - Batch Processing, process a group of files using img2img
64
+ - Img2img Alternative, reverse Euler method of cross attention control
65
+ - Highres Fix, a convenience option to produce high resolution pictures in one click without usual distortions
66
+ - Reloading checkpoints on the fly
67
+ - Checkpoint Merger, a tab that allows you to merge up to 3 checkpoints into one
68
+ - [Custom scripts](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Custom-Scripts) with many extensions from community
69
+ - [Composable-Diffusion](https://energy-based-model.github.io/Compositional-Visual-Generation-with-Composable-Diffusion-Models/), a way to use multiple prompts at once
70
+ - separate prompts using uppercase `AND`
71
+ - also supports weights for prompts: `a cat :1.2 AND a dog AND a penguin :2.2`
72
+ - No token limit for prompts (original stable diffusion lets you use up to 75 tokens)
73
+ - DeepDanbooru integration, creates danbooru style tags for anime prompts
74
+ - [xformers](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers), major speed increase for select cards: (add --xformers to commandline args)
75
+ - via extension: [History tab](https://github.com/yfszzx/stable-diffusion-webui-images-browser): view, direct and delete images conveniently within the UI
76
+ - Generate forever option
77
+ - Training tab
78
+ - hypernetworks and embeddings options
79
+ - Preprocessing images: cropping, mirroring, autotagging using BLIP or deepdanbooru (for anime)
80
+ - Clip skip
81
+ - Use Hypernetworks
82
+ - Use VAEs
83
+ - Estimated completion time in progress bar
84
+ - API
85
+ - Support for dedicated [inpainting model](https://github.com/runwayml/stable-diffusion#inpainting-with-stable-diffusion) by RunwayML.
86
+ - 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))
87
+ - [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
88
+
89
+ ## Installation and Running
90
+ 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.
91
+
92
+ Alternatively, use online services (like Google Colab):
93
+
94
+ - [List of Online Services](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Online-Services)
95
+
96
+ ### Automatic Installation on Windows
97
+ 1. Install [Python 3.10.6](https://www.python.org/downloads/windows/), checking "Add Python to PATH"
98
+ 2. Install [git](https://git-scm.com/download/win).
99
+ 3. Download the stable-diffusion-webui repository, for example by running `git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git`.
100
+ 4. Place `model.ckpt` in the `models` directory (see [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) for where to get it).
101
+ 5. _*(Optional)*_ Place `GFPGANv1.4.pth` in the base directory, alongside `webui.py` (see [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) for where to get it).
102
+ 6. Run `webui-user.bat` from Windows Explorer as normal, non-administrator, user.
103
+
104
+ ### Automatic Installation on Linux
105
+ 1. Install the dependencies:
106
+ ```bash
107
+ # Debian-based:
108
+ sudo apt install wget git python3 python3-venv
109
+ # Red Hat-based:
110
+ sudo dnf install wget git python3
111
+ # Arch-based:
112
+ sudo pacman -S wget git python3
113
+ ```
114
+ 2. To install in `/home/$(whoami)/stable-diffusion-webui/`, run:
115
+ ```bash
116
+ bash <(wget -qO- https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh)
117
+ ```
118
+
119
+ ### Installation on Apple Silicon
120
+
121
+ Find the instructions [here](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Installation-on-Apple-Silicon).
122
+
123
+ ## Contributing
124
+ Here's how to add code to this repo: [Contributing](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Contributing)
125
+
126
+ ## Documentation
127
+ The documentation was moved from this README over to the project's [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki).
128
+
129
+ ## Credits
130
+ - Stable Diffusion - https://github.com/CompVis/stable-diffusion, https://github.com/CompVis/taming-transformers
131
+ - k-diffusion - https://github.com/crowsonkb/k-diffusion.git
132
+ - GFPGAN - https://github.com/TencentARC/GFPGAN.git
133
+ - CodeFormer - https://github.com/sczhou/CodeFormer
134
+ - ESRGAN - https://github.com/xinntao/ESRGAN
135
+ - SwinIR - https://github.com/JingyunLiang/SwinIR
136
+ - Swin2SR - https://github.com/mv-lab/swin2sr
137
+ - LDSR - https://github.com/Hafiidz/latent-diffusion
138
+ - Ideas for optimizations - https://github.com/basujindal/stable-diffusion
139
+ - Cross Attention layer optimization - Doggettx - https://github.com/Doggettx/stable-diffusion, original idea for prompt editing.
140
+ - Cross Attention layer optimization - InvokeAI, lstein - https://github.com/invoke-ai/InvokeAI (originally http://github.com/lstein/stable-diffusion)
141
+ - Textual Inversion - Rinon Gal - https://github.com/rinongal/textual_inversion (we're not using his code, but we are using his ideas).
142
+ - Idea for SD upscale - https://github.com/jquesnelle/txt2imghd
143
+ - Noise generation for outpainting mk2 - https://github.com/parlance-zz/g-diffuser-bot
144
+ - CLIP interrogator idea and borrowing some code - https://github.com/pharmapsychotic/clip-interrogator
145
+ - Idea for Composable Diffusion - https://github.com/energy-based-model/Compositional-Visual-Generation-with-Composable-Diffusion-Models-PyTorch
146
+ - xformers - https://github.com/facebookresearch/xformers
147
+ - DeepDanbooru - interrogator for anime diffusers https://github.com/KichangKim/DeepDanbooru
148
+ - Security advice - RyotaK
149
+ - Initial Gradio script - posted on 4chan by an Anonymous user. Thank you Anonymous user.
150
+ - (You)
stable-diffusion-webui-master/artists.csv ADDED
The diff for this file is too large to render. See raw diff
 
stable-diffusion-webui-master/embeddings/Place Textual Inversion embeddings here.txt ADDED
File without changes
stable-diffusion-webui-master/environment-wsl2.yaml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: automatic
2
+ channels:
3
+ - pytorch
4
+ - defaults
5
+ dependencies:
6
+ - python=3.10
7
+ - pip=22.2.2
8
+ - cudatoolkit=11.3
9
+ - pytorch=1.12.1
10
+ - torchvision=0.13.1
11
+ - numpy=1.23.1
stable-diffusion-webui-master/extensions/put extensions here.txt ADDED
File without changes
stable-diffusion-webui-master/javascript/aspectRatioOverlay.js ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ let currentWidth = null;
3
+ let currentHeight = null;
4
+ let arFrameTimeout = setTimeout(function(){},0);
5
+
6
+ function dimensionChange(e, is_width, is_height){
7
+
8
+ if(is_width){
9
+ currentWidth = e.target.value*1.0
10
+ }
11
+ if(is_height){
12
+ currentHeight = e.target.value*1.0
13
+ }
14
+
15
+ var inImg2img = Boolean(gradioApp().querySelector("button.rounded-t-lg.border-gray-200"))
16
+
17
+ if(!inImg2img){
18
+ return;
19
+ }
20
+
21
+ var targetElement = null;
22
+
23
+ var tabIndex = get_tab_index('mode_img2img')
24
+ if(tabIndex == 0){
25
+ targetElement = gradioApp().querySelector('div[data-testid=image] img');
26
+ } else if(tabIndex == 1){
27
+ targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img');
28
+ }
29
+
30
+ if(targetElement){
31
+
32
+ var arPreviewRect = gradioApp().querySelector('#imageARPreview');
33
+ if(!arPreviewRect){
34
+ arPreviewRect = document.createElement('div')
35
+ arPreviewRect.id = "imageARPreview";
36
+ gradioApp().getRootNode().appendChild(arPreviewRect)
37
+ }
38
+
39
+
40
+
41
+ var viewportOffset = targetElement.getBoundingClientRect();
42
+
43
+ viewportscale = Math.min( targetElement.clientWidth/targetElement.naturalWidth, targetElement.clientHeight/targetElement.naturalHeight )
44
+
45
+ scaledx = targetElement.naturalWidth*viewportscale
46
+ scaledy = targetElement.naturalHeight*viewportscale
47
+
48
+ cleintRectTop = (viewportOffset.top+window.scrollY)
49
+ cleintRectLeft = (viewportOffset.left+window.scrollX)
50
+ cleintRectCentreY = cleintRectTop + (targetElement.clientHeight/2)
51
+ cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth/2)
52
+
53
+ viewRectTop = cleintRectCentreY-(scaledy/2)
54
+ viewRectLeft = cleintRectCentreX-(scaledx/2)
55
+ arRectWidth = scaledx
56
+ arRectHeight = scaledy
57
+
58
+ arscale = Math.min( arRectWidth/currentWidth, arRectHeight/currentHeight )
59
+ arscaledx = currentWidth*arscale
60
+ arscaledy = currentHeight*arscale
61
+
62
+ arRectTop = cleintRectCentreY-(arscaledy/2)
63
+ arRectLeft = cleintRectCentreX-(arscaledx/2)
64
+ arRectWidth = arscaledx
65
+ arRectHeight = arscaledy
66
+
67
+ arPreviewRect.style.top = arRectTop+'px';
68
+ arPreviewRect.style.left = arRectLeft+'px';
69
+ arPreviewRect.style.width = arRectWidth+'px';
70
+ arPreviewRect.style.height = arRectHeight+'px';
71
+
72
+ clearTimeout(arFrameTimeout);
73
+ arFrameTimeout = setTimeout(function(){
74
+ arPreviewRect.style.display = 'none';
75
+ },2000);
76
+
77
+ arPreviewRect.style.display = 'block';
78
+
79
+ }
80
+
81
+ }
82
+
83
+
84
+ onUiUpdate(function(){
85
+ var arPreviewRect = gradioApp().querySelector('#imageARPreview');
86
+ if(arPreviewRect){
87
+ arPreviewRect.style.display = 'none';
88
+ }
89
+ var inImg2img = Boolean(gradioApp().querySelector("button.rounded-t-lg.border-gray-200"))
90
+ if(inImg2img){
91
+ let inputs = gradioApp().querySelectorAll('input');
92
+ inputs.forEach(function(e){
93
+ var is_width = e.parentElement.id == "img2img_width"
94
+ var is_height = e.parentElement.id == "img2img_height"
95
+
96
+ if((is_width || is_height) && !e.classList.contains('scrollwatch')){
97
+ e.addEventListener('input', function(e){dimensionChange(e, is_width, is_height)} )
98
+ e.classList.add('scrollwatch')
99
+ }
100
+ if(is_width){
101
+ currentWidth = e.value*1.0
102
+ }
103
+ if(is_height){
104
+ currentHeight = e.value*1.0
105
+ }
106
+ })
107
+ }
108
+ });
stable-diffusion-webui-master/javascript/contextMenus.js ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ contextMenuInit = function(){
3
+ let eventListenerApplied=false;
4
+ let menuSpecs = new Map();
5
+
6
+ const uid = function(){
7
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
8
+ }
9
+
10
+ function showContextMenu(event,element,menuEntries){
11
+ let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
12
+ let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
13
+
14
+ let oldMenu = gradioApp().querySelector('#context-menu')
15
+ if(oldMenu){
16
+ oldMenu.remove()
17
+ }
18
+
19
+ let tabButton = uiCurrentTab
20
+ let baseStyle = window.getComputedStyle(tabButton)
21
+
22
+ const contextMenu = document.createElement('nav')
23
+ contextMenu.id = "context-menu"
24
+ contextMenu.style.background = baseStyle.background
25
+ contextMenu.style.color = baseStyle.color
26
+ contextMenu.style.fontFamily = baseStyle.fontFamily
27
+ contextMenu.style.top = posy+'px'
28
+ contextMenu.style.left = posx+'px'
29
+
30
+
31
+
32
+ const contextMenuList = document.createElement('ul')
33
+ contextMenuList.className = 'context-menu-items';
34
+ contextMenu.append(contextMenuList);
35
+
36
+ menuEntries.forEach(function(entry){
37
+ let contextMenuEntry = document.createElement('a')
38
+ contextMenuEntry.innerHTML = entry['name']
39
+ contextMenuEntry.addEventListener("click", function(e) {
40
+ entry['func']();
41
+ })
42
+ contextMenuList.append(contextMenuEntry);
43
+
44
+ })
45
+
46
+ gradioApp().getRootNode().appendChild(contextMenu)
47
+
48
+ let menuWidth = contextMenu.offsetWidth + 4;
49
+ let menuHeight = contextMenu.offsetHeight + 4;
50
+
51
+ let windowWidth = window.innerWidth;
52
+ let windowHeight = window.innerHeight;
53
+
54
+ if ( (windowWidth - posx) < menuWidth ) {
55
+ contextMenu.style.left = windowWidth - menuWidth + "px";
56
+ }
57
+
58
+ if ( (windowHeight - posy) < menuHeight ) {
59
+ contextMenu.style.top = windowHeight - menuHeight + "px";
60
+ }
61
+
62
+ }
63
+
64
+ function appendContextMenuOption(targetEmementSelector,entryName,entryFunction){
65
+
66
+ currentItems = menuSpecs.get(targetEmementSelector)
67
+
68
+ if(!currentItems){
69
+ currentItems = []
70
+ menuSpecs.set(targetEmementSelector,currentItems);
71
+ }
72
+ let newItem = {'id':targetEmementSelector+'_'+uid(),
73
+ 'name':entryName,
74
+ 'func':entryFunction,
75
+ 'isNew':true}
76
+
77
+ currentItems.push(newItem)
78
+ return newItem['id']
79
+ }
80
+
81
+ function removeContextMenuOption(uid){
82
+ menuSpecs.forEach(function(v,k) {
83
+ let index = -1
84
+ v.forEach(function(e,ei){if(e['id']==uid){index=ei}})
85
+ if(index>=0){
86
+ v.splice(index, 1);
87
+ }
88
+ })
89
+ }
90
+
91
+ function addContextMenuEventListener(){
92
+ if(eventListenerApplied){
93
+ return;
94
+ }
95
+ gradioApp().addEventListener("click", function(e) {
96
+ let source = e.composedPath()[0]
97
+ if(source.id && source.id.indexOf('check_progress')>-1){
98
+ return
99
+ }
100
+
101
+ let oldMenu = gradioApp().querySelector('#context-menu')
102
+ if(oldMenu){
103
+ oldMenu.remove()
104
+ }
105
+ });
106
+ gradioApp().addEventListener("contextmenu", function(e) {
107
+ let oldMenu = gradioApp().querySelector('#context-menu')
108
+ if(oldMenu){
109
+ oldMenu.remove()
110
+ }
111
+ menuSpecs.forEach(function(v,k) {
112
+ if(e.composedPath()[0].matches(k)){
113
+ showContextMenu(e,e.composedPath()[0],v)
114
+ e.preventDefault()
115
+ return
116
+ }
117
+ })
118
+ });
119
+ eventListenerApplied=true
120
+
121
+ }
122
+
123
+ return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener]
124
+ }
125
+
126
+ initResponse = contextMenuInit();
127
+ appendContextMenuOption = initResponse[0];
128
+ removeContextMenuOption = initResponse[1];
129
+ addContextMenuEventListener = initResponse[2];
130
+
131
+ (function(){
132
+ //Start example Context Menu Items
133
+ let generateOnRepeat = function(genbuttonid,interruptbuttonid){
134
+ let genbutton = gradioApp().querySelector(genbuttonid);
135
+ let interruptbutton = gradioApp().querySelector(interruptbuttonid);
136
+ if(!interruptbutton.offsetParent){
137
+ genbutton.click();
138
+ }
139
+ clearInterval(window.generateOnRepeatInterval)
140
+ window.generateOnRepeatInterval = setInterval(function(){
141
+ if(!interruptbutton.offsetParent){
142
+ genbutton.click();
143
+ }
144
+ },
145
+ 500)
146
+ }
147
+
148
+ appendContextMenuOption('#txt2img_generate','Generate forever',function(){
149
+ generateOnRepeat('#txt2img_generate','#txt2img_interrupt');
150
+ })
151
+ appendContextMenuOption('#img2img_generate','Generate forever',function(){
152
+ generateOnRepeat('#img2img_generate','#img2img_interrupt');
153
+ })
154
+
155
+ let cancelGenerateForever = function(){
156
+ clearInterval(window.generateOnRepeatInterval)
157
+ }
158
+
159
+ appendContextMenuOption('#txt2img_interrupt','Cancel generate forever',cancelGenerateForever)
160
+ appendContextMenuOption('#txt2img_generate', 'Cancel generate forever',cancelGenerateForever)
161
+ appendContextMenuOption('#img2img_interrupt','Cancel generate forever',cancelGenerateForever)
162
+ appendContextMenuOption('#img2img_generate', 'Cancel generate forever',cancelGenerateForever)
163
+
164
+ appendContextMenuOption('#roll','Roll three',
165
+ function(){
166
+ let rollbutton = get_uiCurrentTabContent().querySelector('#roll');
167
+ setTimeout(function(){rollbutton.click()},100)
168
+ setTimeout(function(){rollbutton.click()},200)
169
+ setTimeout(function(){rollbutton.click()},300)
170
+ }
171
+ )
172
+ })();
173
+ //End example Context Menu Items
174
+
175
+ onUiUpdate(function(){
176
+ addContextMenuEventListener()
177
+ });
stable-diffusion-webui-master/javascript/dragdrop.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // allows drag-dropping files into gradio image elements, and also pasting images from clipboard
2
+
3
+ function isValidImageList( files ) {
4
+ return files && files?.length === 1 && ['image/png', 'image/gif', 'image/jpeg'].includes(files[0].type);
5
+ }
6
+
7
+ function dropReplaceImage( imgWrap, files ) {
8
+ if ( ! isValidImageList( files ) ) {
9
+ return;
10
+ }
11
+
12
+ imgWrap.querySelector('.modify-upload button + button, .touch-none + div button + button')?.click();
13
+ const callback = () => {
14
+ const fileInput = imgWrap.querySelector('input[type="file"]');
15
+ if ( fileInput ) {
16
+ fileInput.files = files;
17
+ fileInput.dispatchEvent(new Event('change'));
18
+ }
19
+ };
20
+
21
+ if ( imgWrap.closest('#pnginfo_image') ) {
22
+ // special treatment for PNG Info tab, wait for fetch request to finish
23
+ const oldFetch = window.fetch;
24
+ window.fetch = async (input, options) => {
25
+ const response = await oldFetch(input, options);
26
+ if ( 'api/predict/' === input ) {
27
+ const content = await response.text();
28
+ window.fetch = oldFetch;
29
+ window.requestAnimationFrame( () => callback() );
30
+ return new Response(content, {
31
+ status: response.status,
32
+ statusText: response.statusText,
33
+ headers: response.headers
34
+ })
35
+ }
36
+ return response;
37
+ };
38
+ } else {
39
+ window.requestAnimationFrame( () => callback() );
40
+ }
41
+ }
42
+
43
+ window.document.addEventListener('dragover', e => {
44
+ const target = e.composedPath()[0];
45
+ const imgWrap = target.closest('[data-testid="image"]');
46
+ if ( !imgWrap && target.placeholder && target.placeholder.indexOf("Prompt") == -1) {
47
+ return;
48
+ }
49
+ e.stopPropagation();
50
+ e.preventDefault();
51
+ e.dataTransfer.dropEffect = 'copy';
52
+ });
53
+
54
+ window.document.addEventListener('drop', e => {
55
+ const target = e.composedPath()[0];
56
+ if (target.placeholder.indexOf("Prompt") == -1) {
57
+ return;
58
+ }
59
+ const imgWrap = target.closest('[data-testid="image"]');
60
+ if ( !imgWrap ) {
61
+ return;
62
+ }
63
+ e.stopPropagation();
64
+ e.preventDefault();
65
+ const files = e.dataTransfer.files;
66
+ dropReplaceImage( imgWrap, files );
67
+ });
68
+
69
+ window.addEventListener('paste', e => {
70
+ const files = e.clipboardData.files;
71
+ if ( ! isValidImageList( files ) ) {
72
+ return;
73
+ }
74
+
75
+ const visibleImageFields = [...gradioApp().querySelectorAll('[data-testid="image"]')]
76
+ .filter(el => uiElementIsVisible(el));
77
+ if ( ! visibleImageFields.length ) {
78
+ return;
79
+ }
80
+
81
+ const firstFreeImageField = visibleImageFields
82
+ .filter(el => el.querySelector('input[type=file]'))?.[0];
83
+
84
+ dropReplaceImage(
85
+ firstFreeImageField ?
86
+ firstFreeImageField :
87
+ visibleImageFields[visibleImageFields.length - 1]
88
+ , files );
89
+ });
stable-diffusion-webui-master/javascript/edit-attention.js ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ addEventListener('keydown', (event) => {
2
+ let target = event.originalTarget || event.composedPath()[0];
3
+ if (!target.matches("#toprow textarea.gr-text-input[placeholder]")) return;
4
+ if (! (event.metaKey || event.ctrlKey)) return;
5
+
6
+
7
+ let plus = "ArrowUp"
8
+ let minus = "ArrowDown"
9
+ if (event.key != plus && event.key != minus) return;
10
+
11
+ let selectionStart = target.selectionStart;
12
+ let selectionEnd = target.selectionEnd;
13
+ // If the user hasn't selected anything, let's select their current parenthesis block
14
+ if (selectionStart === selectionEnd) {
15
+ // Find opening parenthesis around current cursor
16
+ const before = target.value.substring(0, selectionStart);
17
+ let beforeParen = before.lastIndexOf("(");
18
+ if (beforeParen == -1) return;
19
+ let beforeParenClose = before.lastIndexOf(")");
20
+ while (beforeParenClose !== -1 && beforeParenClose > beforeParen) {
21
+ beforeParen = before.lastIndexOf("(", beforeParen - 1);
22
+ beforeParenClose = before.lastIndexOf(")", beforeParenClose - 1);
23
+ }
24
+
25
+ // Find closing parenthesis around current cursor
26
+ const after = target.value.substring(selectionStart);
27
+ let afterParen = after.indexOf(")");
28
+ if (afterParen == -1) return;
29
+ let afterParenOpen = after.indexOf("(");
30
+ while (afterParenOpen !== -1 && afterParen > afterParenOpen) {
31
+ afterParen = after.indexOf(")", afterParen + 1);
32
+ afterParenOpen = after.indexOf("(", afterParenOpen + 1);
33
+ }
34
+ if (beforeParen === -1 || afterParen === -1) return;
35
+
36
+ // Set the selection to the text between the parenthesis
37
+ const parenContent = target.value.substring(beforeParen + 1, selectionStart + afterParen);
38
+ const lastColon = parenContent.lastIndexOf(":");
39
+ selectionStart = beforeParen + 1;
40
+ selectionEnd = selectionStart + lastColon;
41
+ target.setSelectionRange(selectionStart, selectionEnd);
42
+ }
43
+
44
+ event.preventDefault();
45
+
46
+ if (selectionStart == 0 || target.value[selectionStart - 1] != "(") {
47
+ target.value = target.value.slice(0, selectionStart) +
48
+ "(" + target.value.slice(selectionStart, selectionEnd) + ":1.0)" +
49
+ target.value.slice(selectionEnd);
50
+
51
+ target.focus();
52
+ target.selectionStart = selectionStart + 1;
53
+ target.selectionEnd = selectionEnd + 1;
54
+
55
+ } else {
56
+ end = target.value.slice(selectionEnd + 1).indexOf(")") + 1;
57
+ weight = parseFloat(target.value.slice(selectionEnd + 1, selectionEnd + 1 + end));
58
+ if (isNaN(weight)) return;
59
+ if (event.key == minus) weight -= 0.1;
60
+ if (event.key == plus) weight += 0.1;
61
+
62
+ weight = parseFloat(weight.toPrecision(12));
63
+
64
+ target.value = target.value.slice(0, selectionEnd + 1) +
65
+ weight +
66
+ target.value.slice(selectionEnd + 1 + end - 1);
67
+
68
+ target.focus();
69
+ target.selectionStart = selectionStart;
70
+ target.selectionEnd = selectionEnd;
71
+ }
72
+ // Since we've modified a Gradio Textbox component manually, we need to simulate an `input` DOM event to ensure its
73
+ // internal Svelte data binding remains in sync.
74
+ target.dispatchEvent(new Event("input", { bubbles: true }));
75
+ });
stable-diffusion-webui-master/javascript/extensions.js ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function extensions_apply(_, _){
3
+ disable = []
4
+ update = []
5
+ gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x){
6
+ if(x.name.startsWith("enable_") && ! x.checked)
7
+ disable.push(x.name.substr(7))
8
+
9
+ if(x.name.startsWith("update_") && x.checked)
10
+ update.push(x.name.substr(7))
11
+ })
12
+
13
+ restart_reload()
14
+
15
+ return [JSON.stringify(disable), JSON.stringify(update)]
16
+ }
17
+
18
+ function extensions_check(){
19
+ gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x){
20
+ x.innerHTML = "Loading..."
21
+ })
22
+
23
+ return []
24
+ }
25
+
26
+ function install_extension_from_index(button, url){
27
+ button.disabled = "disabled"
28
+ button.value = "Installing..."
29
+
30
+ textarea = gradioApp().querySelector('#extension_to_install textarea')
31
+ textarea.value = url
32
+ textarea.dispatchEvent(new Event("input", { bubbles: true }))
33
+
34
+ gradioApp().querySelector('#install_extension_button').click()
35
+ }
stable-diffusion-webui-master/javascript/generationParams.js ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes
2
+
3
+ let txt2img_gallery, img2img_gallery, modal = undefined;
4
+ onUiUpdate(function(){
5
+ if (!txt2img_gallery) {
6
+ txt2img_gallery = attachGalleryListeners("txt2img")
7
+ }
8
+ if (!img2img_gallery) {
9
+ img2img_gallery = attachGalleryListeners("img2img")
10
+ }
11
+ if (!modal) {
12
+ modal = gradioApp().getElementById('lightboxModal')
13
+ modalObserver.observe(modal, { attributes : true, attributeFilter : ['style'] });
14
+ }
15
+ });
16
+
17
+ let modalObserver = new MutationObserver(function(mutations) {
18
+ mutations.forEach(function(mutationRecord) {
19
+ let selectedTab = gradioApp().querySelector('#tabs div button.bg-white')?.innerText
20
+ if (mutationRecord.target.style.display === 'none' && selectedTab === 'txt2img' || selectedTab === 'img2img')
21
+ gradioApp().getElementById(selectedTab+"_generation_info_button").click()
22
+ });
23
+ });
24
+
25
+ function attachGalleryListeners(tab_name) {
26
+ gallery = gradioApp().querySelector('#'+tab_name+'_gallery')
27
+ gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name+"_generation_info_button").click());
28
+ gallery?.addEventListener('keydown', (e) => {
29
+ if (e.keyCode == 37 || e.keyCode == 39) // left or right arrow
30
+ gradioApp().getElementById(tab_name+"_generation_info_button").click()
31
+ });
32
+ return gallery;
33
+ }
stable-diffusion-webui-master/javascript/hints.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // mouseover tooltips for various UI elements
2
+
3
+ titles = {
4
+ "Sampling steps": "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results",
5
+ "Sampling method": "Which algorithm to use to produce the image",
6
+ "GFPGAN": "Restore low quality faces using GFPGAN neural network",
7
+ "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",
8
+ "DDIM": "Denoising Diffusion Implicit Models - best at inpainting",
9
+
10
+ "Batch count": "How many batches of images to create",
11
+ "Batch size": "How many image to create in a single batch",
12
+ "CFG Scale": "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results",
13
+ "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",
14
+ "\u{1f3b2}\ufe0f": "Set seed to -1, which will cause a new random number to be used every time",
15
+ "\u267b\ufe0f": "Reuse seed from last generation, mostly useful if it was randomed",
16
+ "\u{1f3a8}": "Add a random artist to the prompt.",
17
+ "\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.",
18
+ "\u{1f4c2}": "Open images output directory",
19
+ "\u{1f4be}": "Save style",
20
+ "\u{1f4cb}": "Apply selected styles to current prompt",
21
+
22
+ "Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt",
23
+ "SD upscale": "Upscale image normally, split result into tiles, improve each tile using img2img, merge whole image back",
24
+
25
+ "Just resize": "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.",
26
+ "Crop and resize": "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.",
27
+ "Resize and fill": "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.",
28
+
29
+ "Mask blur": "How much to blur the mask before processing, in pixels.",
30
+ "Masked content": "What to put inside the masked area before processing it with Stable Diffusion.",
31
+ "fill": "fill it with colors of the image",
32
+ "original": "keep whatever was there originally",
33
+ "latent noise": "fill it with latent space noise",
34
+ "latent nothing": "fill it with latent space zeroes",
35
+ "Inpaint at full resolution": "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image",
36
+
37
+ "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.",
38
+ "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.",
39
+
40
+ "Skip": "Stop processing current image and continue processing.",
41
+ "Interrupt": "Stop processing images and return any results accumulated so far.",
42
+ "Save": "Write image to a directory (default - log/images) and generation parameters into csv file.",
43
+
44
+ "X values": "Separate values for X axis using commas.",
45
+ "Y values": "Separate values for Y axis using commas.",
46
+
47
+ "None": "Do not do anything special",
48
+ "Prompt matrix": "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)",
49
+ "X/Y plot": "Create a grid where images will have different parameters. Use inputs below to specify which parameters will be shared by columns and rows",
50
+ "Custom code": "Run Python code. Advanced user only. Must run program with --allow-code for this to work",
51
+
52
+ "Prompt S/R": "Separate a list of words with commas, and the first word will be used as a keyword: script will search for this word in the prompt, and replace it with others",
53
+ "Prompt order": "Separate a list of words with commas, and the script will make a variation of prompt with those words for their every possible order",
54
+
55
+ "Tiling": "Produce an image that can be tiled.",
56
+ "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.",
57
+
58
+ "Variation seed": "Seed of a different picture to be mixed into the generation.",
59
+ "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).",
60
+ "Resize seed from height": "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution",
61
+ "Resize seed from width": "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution",
62
+
63
+ "Interrogate": "Reconstruct prompt from existing image and put it into the prompt field.",
64
+
65
+ "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.",
66
+ "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.",
67
+ "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",
68
+
69
+ "Loopback": "Process an image, use it as an input, repeat.",
70
+ "Loops": "How many times to repeat processing an image and using it as input for the next iteration",
71
+
72
+ "Style 1": "Style to apply; styles have components for both positive and negative prompts and apply to both",
73
+ "Style 2": "Style to apply; styles have components for both positive and negative prompts and apply to both",
74
+ "Apply style": "Insert selected styles into prompt fields",
75
+ "Create style": "Save current prompts as a style. If you add the token {prompt} to the text, the style use that as placeholder for your prompt when you use the style in the future.",
76
+
77
+ "Checkpoint name": "Loads weights from checkpoint before making images. You can either use hash or a part of filename (as seen in settings) for checkpoint name. Recommended to use with Y axis for less switching.",
78
+ "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.",
79
+
80
+ "vram": "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%).",
81
+
82
+ "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",
83
+ "Scale latent": "Uscale the image in latent space. Alternative is to produce the full image from latent representation, upscale that, and then move it back to latent space.",
84
+
85
+ "Eta noise seed delta": "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.",
86
+ "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.",
87
+
88
+ "Filename word 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.",
89
+ "Filename join string": "This string will be used to join split words into a single line if the option above is enabled.",
90
+
91
+ "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.",
92
+
93
+ "Weighted sum": "Result = A * (1 - M) + B * M",
94
+ "Add difference": "Result = A + (B - C) * M",
95
+
96
+ "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.",
97
+ }
98
+
99
+
100
+ onUiUpdate(function(){
101
+ gradioApp().querySelectorAll('span, button, select, p').forEach(function(span){
102
+ tooltip = titles[span.textContent];
103
+
104
+ if(!tooltip){
105
+ tooltip = titles[span.value];
106
+ }
107
+
108
+ if(!tooltip){
109
+ for (const c of span.classList) {
110
+ if (c in titles) {
111
+ tooltip = titles[c];
112
+ break;
113
+ }
114
+ }
115
+ }
116
+
117
+ if(tooltip){
118
+ span.title = tooltip;
119
+ }
120
+ })
121
+
122
+ gradioApp().querySelectorAll('select').forEach(function(select){
123
+ if (select.onchange != null) return;
124
+
125
+ select.onchange = function(){
126
+ select.title = titles[select.value] || "";
127
+ }
128
+ })
129
+ })
stable-diffusion-webui-master/javascript/imageMaskFix.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * temporary fix for https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/668
3
+ * @see https://github.com/gradio-app/gradio/issues/1721
4
+ */
5
+ window.addEventListener( 'resize', () => imageMaskResize());
6
+ function imageMaskResize() {
7
+ const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas');
8
+ if ( ! canvases.length ) {
9
+ canvases_fixed = false;
10
+ window.removeEventListener( 'resize', imageMaskResize );
11
+ return;
12
+ }
13
+
14
+ const wrapper = canvases[0].closest('.touch-none');
15
+ const previewImage = wrapper.previousElementSibling;
16
+
17
+ if ( ! previewImage.complete ) {
18
+ previewImage.addEventListener( 'load', () => imageMaskResize());
19
+ return;
20
+ }
21
+
22
+ const w = previewImage.width;
23
+ const h = previewImage.height;
24
+ const nw = previewImage.naturalWidth;
25
+ const nh = previewImage.naturalHeight;
26
+ const portrait = nh > nw;
27
+ const factor = portrait;
28
+
29
+ const wW = Math.min(w, portrait ? h/nh*nw : w/nw*nw);
30
+ const wH = Math.min(h, portrait ? h/nh*nh : w/nw*nh);
31
+
32
+ wrapper.style.width = `${wW}px`;
33
+ wrapper.style.height = `${wH}px`;
34
+ wrapper.style.left = `0px`;
35
+ wrapper.style.top = `0px`;
36
+
37
+ canvases.forEach( c => {
38
+ c.style.width = c.style.height = '';
39
+ c.style.maxWidth = '100%';
40
+ c.style.maxHeight = '100%';
41
+ c.style.objectFit = 'contain';
42
+ });
43
+ }
44
+
45
+ onUiUpdate(() => imageMaskResize());
stable-diffusion-webui-master/javascript/imageParams.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ window.onload = (function(){
2
+ window.addEventListener('drop', e => {
3
+ const target = e.composedPath()[0];
4
+ const idx = selected_gallery_index();
5
+ if (target.placeholder.indexOf("Prompt") == -1) return;
6
+
7
+ let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image";
8
+
9
+ e.stopPropagation();
10
+ e.preventDefault();
11
+ const imgParent = gradioApp().getElementById(prompt_target);
12
+ const files = e.dataTransfer.files;
13
+ const fileInput = imgParent.querySelector('input[type="file"]');
14
+ if ( fileInput ) {
15
+ fileInput.files = files;
16
+ fileInput.dispatchEvent(new Event('change'));
17
+ }
18
+ });
19
+ });
stable-diffusion-webui-master/javascript/imageviewer.js ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // A full size 'lightbox' preview modal shown when left clicking on gallery previews
2
+ function closeModal() {
3
+ gradioApp().getElementById("lightboxModal").style.display = "none";
4
+ }
5
+
6
+ function showModal(event) {
7
+ const source = event.target || event.srcElement;
8
+ const modalImage = gradioApp().getElementById("modalImage")
9
+ const lb = gradioApp().getElementById("lightboxModal")
10
+ modalImage.src = source.src
11
+ if (modalImage.style.display === 'none') {
12
+ lb.style.setProperty('background-image', 'url(' + source.src + ')');
13
+ }
14
+ lb.style.display = "block";
15
+ lb.focus()
16
+
17
+ const tabTxt2Img = gradioApp().getElementById("tab_txt2img")
18
+ const tabImg2Img = gradioApp().getElementById("tab_img2img")
19
+ // show the save button in modal only on txt2img or img2img tabs
20
+ if (tabTxt2Img.style.display != "none" || tabImg2Img.style.display != "none") {
21
+ gradioApp().getElementById("modal_save").style.display = "inline"
22
+ } else {
23
+ gradioApp().getElementById("modal_save").style.display = "none"
24
+ }
25
+ event.stopPropagation()
26
+ }
27
+
28
+ function negmod(n, m) {
29
+ return ((n % m) + m) % m;
30
+ }
31
+
32
+ function updateOnBackgroundChange() {
33
+ const modalImage = gradioApp().getElementById("modalImage")
34
+ if (modalImage && modalImage.offsetParent) {
35
+ let allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2")
36
+ let currentButton = null
37
+ allcurrentButtons.forEach(function(elem) {
38
+ if (elem.parentElement.offsetParent) {
39
+ currentButton = elem;
40
+ }
41
+ })
42
+
43
+ if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
44
+ modalImage.src = currentButton.children[0].src;
45
+ if (modalImage.style.display === 'none') {
46
+ modal.style.setProperty('background-image', `url(${modalImage.src})`)
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ function modalImageSwitch(offset) {
53
+ var allgalleryButtons = gradioApp().querySelectorAll(".gallery-item.transition-all")
54
+ var galleryButtons = []
55
+ allgalleryButtons.forEach(function(elem) {
56
+ if (elem.parentElement.offsetParent) {
57
+ galleryButtons.push(elem);
58
+ }
59
+ })
60
+
61
+ if (galleryButtons.length > 1) {
62
+ var allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2")
63
+ var currentButton = null
64
+ allcurrentButtons.forEach(function(elem) {
65
+ if (elem.parentElement.offsetParent) {
66
+ currentButton = elem;
67
+ }
68
+ })
69
+
70
+ var result = -1
71
+ galleryButtons.forEach(function(v, i) {
72
+ if (v == currentButton) {
73
+ result = i
74
+ }
75
+ })
76
+
77
+ if (result != -1) {
78
+ nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)]
79
+ nextButton.click()
80
+ const modalImage = gradioApp().getElementById("modalImage");
81
+ const modal = gradioApp().getElementById("lightboxModal");
82
+ modalImage.src = nextButton.children[0].src;
83
+ if (modalImage.style.display === 'none') {
84
+ modal.style.setProperty('background-image', `url(${modalImage.src})`)
85
+ }
86
+ setTimeout(function() {
87
+ modal.focus()
88
+ }, 10)
89
+ }
90
+ }
91
+ }
92
+
93
+ function saveImage(){
94
+ const tabTxt2Img = gradioApp().getElementById("tab_txt2img")
95
+ const tabImg2Img = gradioApp().getElementById("tab_img2img")
96
+ const saveTxt2Img = "save_txt2img"
97
+ const saveImg2Img = "save_img2img"
98
+ if (tabTxt2Img.style.display != "none") {
99
+ gradioApp().getElementById(saveTxt2Img).click()
100
+ } else if (tabImg2Img.style.display != "none") {
101
+ gradioApp().getElementById(saveImg2Img).click()
102
+ } else {
103
+ console.error("missing implementation for saving modal of this type")
104
+ }
105
+ }
106
+
107
+ function modalSaveImage(event) {
108
+ saveImage()
109
+ event.stopPropagation()
110
+ }
111
+
112
+ function modalNextImage(event) {
113
+ modalImageSwitch(1)
114
+ event.stopPropagation()
115
+ }
116
+
117
+ function modalPrevImage(event) {
118
+ modalImageSwitch(-1)
119
+ event.stopPropagation()
120
+ }
121
+
122
+ function modalKeyHandler(event) {
123
+ switch (event.key) {
124
+ case "s":
125
+ saveImage()
126
+ break;
127
+ case "ArrowLeft":
128
+ modalPrevImage(event)
129
+ break;
130
+ case "ArrowRight":
131
+ modalNextImage(event)
132
+ break;
133
+ case "Escape":
134
+ closeModal();
135
+ break;
136
+ }
137
+ }
138
+
139
+ function showGalleryImage() {
140
+ setTimeout(function() {
141
+ fullImg_preview = gradioApp().querySelectorAll('img.w-full.object-contain')
142
+
143
+ if (fullImg_preview != null) {
144
+ fullImg_preview.forEach(function function_name(e) {
145
+ if (e.dataset.modded)
146
+ return;
147
+ e.dataset.modded = true;
148
+ if(e && e.parentElement.tagName == 'DIV'){
149
+ e.style.cursor='pointer'
150
+ e.style.userSelect='none'
151
+ e.addEventListener('click', function (evt) {
152
+ if(!opts.js_modal_lightbox) return;
153
+ modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
154
+ showModal(evt)
155
+ }, true);
156
+ }
157
+ });
158
+ }
159
+
160
+ }, 100);
161
+ }
162
+
163
+ function modalZoomSet(modalImage, enable) {
164
+ if (enable) {
165
+ modalImage.classList.add('modalImageFullscreen');
166
+ } else {
167
+ modalImage.classList.remove('modalImageFullscreen');
168
+ }
169
+ }
170
+
171
+ function modalZoomToggle(event) {
172
+ modalImage = gradioApp().getElementById("modalImage");
173
+ modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen'))
174
+ event.stopPropagation()
175
+ }
176
+
177
+ function modalTileImageToggle(event) {
178
+ const modalImage = gradioApp().getElementById("modalImage");
179
+ const modal = gradioApp().getElementById("lightboxModal");
180
+ const isTiling = modalImage.style.display === 'none';
181
+ if (isTiling) {
182
+ modalImage.style.display = 'block';
183
+ modal.style.setProperty('background-image', 'none')
184
+ } else {
185
+ modalImage.style.display = 'none';
186
+ modal.style.setProperty('background-image', `url(${modalImage.src})`)
187
+ }
188
+
189
+ event.stopPropagation()
190
+ }
191
+
192
+ function galleryImageHandler(e) {
193
+ if (e && e.parentElement.tagName == 'BUTTON') {
194
+ e.onclick = showGalleryImage;
195
+ }
196
+ }
197
+
198
+ onUiUpdate(function() {
199
+ fullImg_preview = gradioApp().querySelectorAll('img.w-full')
200
+ if (fullImg_preview != null) {
201
+ fullImg_preview.forEach(galleryImageHandler);
202
+ }
203
+ updateOnBackgroundChange();
204
+ })
205
+
206
+ document.addEventListener("DOMContentLoaded", function() {
207
+ const modalFragment = document.createDocumentFragment();
208
+ const modal = document.createElement('div')
209
+ modal.onclick = closeModal;
210
+ modal.id = "lightboxModal";
211
+ modal.tabIndex = 0
212
+ modal.addEventListener('keydown', modalKeyHandler, true)
213
+
214
+ const modalControls = document.createElement('div')
215
+ modalControls.className = 'modalControls gradio-container';
216
+ modal.append(modalControls);
217
+
218
+ const modalZoom = document.createElement('span')
219
+ modalZoom.className = 'modalZoom cursor';
220
+ modalZoom.innerHTML = '&#10529;'
221
+ modalZoom.addEventListener('click', modalZoomToggle, true)
222
+ modalZoom.title = "Toggle zoomed view";
223
+ modalControls.appendChild(modalZoom)
224
+
225
+ const modalTileImage = document.createElement('span')
226
+ modalTileImage.className = 'modalTileImage cursor';
227
+ modalTileImage.innerHTML = '&#8862;'
228
+ modalTileImage.addEventListener('click', modalTileImageToggle, true)
229
+ modalTileImage.title = "Preview tiling";
230
+ modalControls.appendChild(modalTileImage)
231
+
232
+ const modalSave = document.createElement("span")
233
+ modalSave.className = "modalSave cursor"
234
+ modalSave.id = "modal_save"
235
+ modalSave.innerHTML = "&#x1F5AB;"
236
+ modalSave.addEventListener("click", modalSaveImage, true)
237
+ modalSave.title = "Save Image(s)"
238
+ modalControls.appendChild(modalSave)
239
+
240
+ const modalClose = document.createElement('span')
241
+ modalClose.className = 'modalClose cursor';
242
+ modalClose.innerHTML = '&times;'
243
+ modalClose.onclick = closeModal;
244
+ modalClose.title = "Close image viewer";
245
+ modalControls.appendChild(modalClose)
246
+
247
+ const modalImage = document.createElement('img')
248
+ modalImage.id = 'modalImage';
249
+ modalImage.onclick = closeModal;
250
+ modalImage.tabIndex = 0
251
+ modalImage.addEventListener('keydown', modalKeyHandler, true)
252
+ modal.appendChild(modalImage)
253
+
254
+ const modalPrev = document.createElement('a')
255
+ modalPrev.className = 'modalPrev';
256
+ modalPrev.innerHTML = '&#10094;'
257
+ modalPrev.tabIndex = 0
258
+ modalPrev.addEventListener('click', modalPrevImage, true);
259
+ modalPrev.addEventListener('keydown', modalKeyHandler, true)
260
+ modal.appendChild(modalPrev)
261
+
262
+ const modalNext = document.createElement('a')
263
+ modalNext.className = 'modalNext';
264
+ modalNext.innerHTML = '&#10095;'
265
+ modalNext.tabIndex = 0
266
+ modalNext.addEventListener('click', modalNextImage, true);
267
+ modalNext.addEventListener('keydown', modalKeyHandler, true)
268
+
269
+ modal.appendChild(modalNext)
270
+
271
+
272
+ gradioApp().getRootNode().appendChild(modal)
273
+
274
+ document.body.appendChild(modalFragment);
275
+
276
+ });
stable-diffusion-webui-master/javascript/localization.js ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // localization = {} -- the dict with translations is created by the backend
3
+
4
+ ignore_ids_for_localization={
5
+ setting_sd_hypernetwork: 'OPTION',
6
+ setting_sd_model_checkpoint: 'OPTION',
7
+ setting_realesrgan_enabled_models: 'OPTION',
8
+ modelmerger_primary_model_name: 'OPTION',
9
+ modelmerger_secondary_model_name: 'OPTION',
10
+ modelmerger_tertiary_model_name: 'OPTION',
11
+ train_embedding: 'OPTION',
12
+ train_hypernetwork: 'OPTION',
13
+ txt2img_style_index: 'OPTION',
14
+ txt2img_style2_index: 'OPTION',
15
+ img2img_style_index: 'OPTION',
16
+ img2img_style2_index: 'OPTION',
17
+ setting_random_artist_categories: 'SPAN',
18
+ setting_face_restoration_model: 'SPAN',
19
+ setting_realesrgan_enabled_models: 'SPAN',
20
+ extras_upscaler_1: 'SPAN',
21
+ extras_upscaler_2: 'SPAN',
22
+ }
23
+
24
+ re_num = /^[\.\d]+$/
25
+ re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u
26
+
27
+ original_lines = {}
28
+ translated_lines = {}
29
+
30
+ function textNodesUnder(el){
31
+ var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false);
32
+ while(n=walk.nextNode()) a.push(n);
33
+ return a;
34
+ }
35
+
36
+ function canBeTranslated(node, text){
37
+ if(! text) return false;
38
+ if(! node.parentElement) return false;
39
+
40
+ parentType = node.parentElement.nodeName
41
+ if(parentType=='SCRIPT' || parentType=='STYLE' || parentType=='TEXTAREA') return false;
42
+
43
+ if (parentType=='OPTION' || parentType=='SPAN'){
44
+ pnode = node
45
+ for(var level=0; level<4; level++){
46
+ pnode = pnode.parentElement
47
+ if(! pnode) break;
48
+
49
+ if(ignore_ids_for_localization[pnode.id] == parentType) return false;
50
+ }
51
+ }
52
+
53
+ if(re_num.test(text)) return false;
54
+ if(re_emoji.test(text)) return false;
55
+ return true
56
+ }
57
+
58
+ function getTranslation(text){
59
+ if(! text) return undefined
60
+
61
+ if(translated_lines[text] === undefined){
62
+ original_lines[text] = 1
63
+ }
64
+
65
+ tl = localization[text]
66
+ if(tl !== undefined){
67
+ translated_lines[tl] = 1
68
+ }
69
+
70
+ return tl
71
+ }
72
+
73
+ function processTextNode(node){
74
+ text = node.textContent.trim()
75
+
76
+ if(! canBeTranslated(node, text)) return
77
+
78
+ tl = getTranslation(text)
79
+ if(tl !== undefined){
80
+ node.textContent = tl
81
+ }
82
+ }
83
+
84
+ function processNode(node){
85
+ if(node.nodeType == 3){
86
+ processTextNode(node)
87
+ return
88
+ }
89
+
90
+ if(node.title){
91
+ tl = getTranslation(node.title)
92
+ if(tl !== undefined){
93
+ node.title = tl
94
+ }
95
+ }
96
+
97
+ if(node.placeholder){
98
+ tl = getTranslation(node.placeholder)
99
+ if(tl !== undefined){
100
+ node.placeholder = tl
101
+ }
102
+ }
103
+
104
+ textNodesUnder(node).forEach(function(node){
105
+ processTextNode(node)
106
+ })
107
+ }
108
+
109
+ function dumpTranslations(){
110
+ dumped = {}
111
+ if (localization.rtl) {
112
+ dumped.rtl = true
113
+ }
114
+
115
+ Object.keys(original_lines).forEach(function(text){
116
+ if(dumped[text] !== undefined) return
117
+
118
+ dumped[text] = localization[text] || text
119
+ })
120
+
121
+ return dumped
122
+ }
123
+
124
+ onUiUpdate(function(m){
125
+ m.forEach(function(mutation){
126
+ mutation.addedNodes.forEach(function(node){
127
+ processNode(node)
128
+ })
129
+ });
130
+ })
131
+
132
+
133
+ document.addEventListener("DOMContentLoaded", function() {
134
+ processNode(gradioApp())
135
+
136
+ if (localization.rtl) { // if the language is from right to left,
137
+ (new MutationObserver((mutations, observer) => { // wait for the style to load
138
+ mutations.forEach(mutation => {
139
+ mutation.addedNodes.forEach(node => {
140
+ if (node.tagName === 'STYLE') {
141
+ observer.disconnect();
142
+
143
+ for (const x of node.sheet.rules) { // find all rtl media rules
144
+ if (Array.from(x.media || []).includes('rtl')) {
145
+ x.media.appendMedium('all'); // enable them
146
+ }
147
+ }
148
+ }
149
+ })
150
+ });
151
+ })).observe(gradioApp(), { childList: true });
152
+ }
153
+ })
154
+
155
+ function download_localization() {
156
+ text = JSON.stringify(dumpTranslations(), null, 4)
157
+
158
+ var element = document.createElement('a');
159
+ element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
160
+ element.setAttribute('download', "localization.json");
161
+ element.style.display = 'none';
162
+ document.body.appendChild(element);
163
+
164
+ element.click();
165
+
166
+ document.body.removeChild(element);
167
+ }
stable-diffusion-webui-master/javascript/notification.js ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Monitors the gallery and sends a browser notification when the leading image is new.
2
+
3
+ let lastHeadImg = null;
4
+
5
+ notificationButton = null
6
+
7
+ onUiUpdate(function(){
8
+ if(notificationButton == null){
9
+ notificationButton = gradioApp().getElementById('request_notifications')
10
+
11
+ if(notificationButton != null){
12
+ notificationButton.addEventListener('click', function (evt) {
13
+ Notification.requestPermission();
14
+ },true);
15
+ }
16
+ }
17
+
18
+ const galleryPreviews = gradioApp().querySelectorAll('img.h-full.w-full.overflow-hidden');
19
+
20
+ if (galleryPreviews == null) return;
21
+
22
+ const headImg = galleryPreviews[0]?.src;
23
+
24
+ if (headImg == null || headImg == lastHeadImg) return;
25
+
26
+ lastHeadImg = headImg;
27
+
28
+ // play notification sound if available
29
+ gradioApp().querySelector('#audio_notification audio')?.play();
30
+
31
+ if (document.hasFocus()) return;
32
+
33
+ // Multiple copies of the images are in the DOM when one is selected. Dedup with a Set to get the real number generated.
34
+ const imgs = new Set(Array.from(galleryPreviews).map(img => img.src));
35
+
36
+ const notification = new Notification(
37
+ 'Stable Diffusion',
38
+ {
39
+ body: `Generated ${imgs.size > 1 ? imgs.size - opts.return_grid : 1} image${imgs.size > 1 ? 's' : ''}`,
40
+ icon: headImg,
41
+ image: headImg,
42
+ }
43
+ );
44
+
45
+ notification.onclick = function(_){
46
+ parent.focus();
47
+ this.close();
48
+ };
49
+ });
stable-diffusion-webui-master/javascript/progressbar.js ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // code related to showing and updating progressbar shown as the image is being made
2
+ global_progressbars = {}
3
+ galleries = {}
4
+ galleryObservers = {}
5
+
6
+ // this tracks laumnches of window.setTimeout for progressbar to prevent starting a new timeout when the previous is still running
7
+ timeoutIds = {}
8
+
9
+ function check_progressbar(id_part, id_progressbar, id_progressbar_span, id_skip, id_interrupt, id_preview, id_gallery){
10
+ // gradio 3.8's enlightened approach allows them to create two nested div elements inside each other with same id
11
+ // every time you use gr.HTML(elem_id='xxx'), so we handle this here
12
+ var progressbar = gradioApp().querySelector("#"+id_progressbar+" #"+id_progressbar)
13
+ var progressbarParent
14
+ if(progressbar){
15
+ progressbarParent = gradioApp().querySelector("#"+id_progressbar)
16
+ } else{
17
+ progressbar = gradioApp().getElementById(id_progressbar)
18
+ progressbarParent = null
19
+ }
20
+
21
+ var skip = id_skip ? gradioApp().getElementById(id_skip) : null
22
+ var interrupt = gradioApp().getElementById(id_interrupt)
23
+
24
+ if(opts.show_progress_in_title && progressbar && progressbar.offsetParent){
25
+ if(progressbar.innerText){
26
+ let newtitle = '[' + progressbar.innerText.trim() + '] Stable Diffusion';
27
+ if(document.title != newtitle){
28
+ document.title = newtitle;
29
+ }
30
+ }else{
31
+ let newtitle = 'Stable Diffusion'
32
+ if(document.title != newtitle){
33
+ document.title = newtitle;
34
+ }
35
+ }
36
+ }
37
+
38
+ if(progressbar!= null && progressbar != global_progressbars[id_progressbar]){
39
+ global_progressbars[id_progressbar] = progressbar
40
+
41
+ var mutationObserver = new MutationObserver(function(m){
42
+ if(timeoutIds[id_part]) return;
43
+
44
+ preview = gradioApp().getElementById(id_preview)
45
+ gallery = gradioApp().getElementById(id_gallery)
46
+
47
+ if(preview != null && gallery != null){
48
+ preview.style.width = gallery.clientWidth + "px"
49
+ preview.style.height = gallery.clientHeight + "px"
50
+ if(progressbarParent) progressbar.style.width = progressbarParent.clientWidth + "px"
51
+
52
+ //only watch gallery if there is a generation process going on
53
+ check_gallery(id_gallery);
54
+
55
+ var progressDiv = gradioApp().querySelectorAll('#' + id_progressbar_span).length > 0;
56
+ if(progressDiv){
57
+ timeoutIds[id_part] = window.setTimeout(function() {
58
+ timeoutIds[id_part] = null
59
+ requestMoreProgress(id_part, id_progressbar_span, id_skip, id_interrupt)
60
+ }, 500)
61
+ } else{
62
+ if (skip) {
63
+ skip.style.display = "none"
64
+ }
65
+ interrupt.style.display = "none"
66
+
67
+ //disconnect observer once generation finished, so user can close selected image if they want
68
+ if (galleryObservers[id_gallery]) {
69
+ galleryObservers[id_gallery].disconnect();
70
+ galleries[id_gallery] = null;
71
+ }
72
+ }
73
+ }
74
+
75
+ });
76
+ mutationObserver.observe( progressbar, { childList:true, subtree:true })
77
+ }
78
+ }
79
+
80
+ function check_gallery(id_gallery){
81
+ let gallery = gradioApp().getElementById(id_gallery)
82
+ // if gallery has no change, no need to setting up observer again.
83
+ if (gallery && galleries[id_gallery] !== gallery){
84
+ galleries[id_gallery] = gallery;
85
+ if(galleryObservers[id_gallery]){
86
+ galleryObservers[id_gallery].disconnect();
87
+ }
88
+ let prevSelectedIndex = selected_gallery_index();
89
+ galleryObservers[id_gallery] = new MutationObserver(function (){
90
+ let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
91
+ let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
92
+ if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
93
+ // automatically re-open previously selected index (if exists)
94
+ activeElement = gradioApp().activeElement;
95
+
96
+ galleryButtons[prevSelectedIndex].click();
97
+ showGalleryImage();
98
+
99
+ if(activeElement){
100
+ // i fought this for about an hour; i don't know why the focus is lost or why this helps recover it
101
+ // if somenoe has a better solution please by all means
102
+ setTimeout(function() { activeElement.focus() }, 1);
103
+ }
104
+ }
105
+ })
106
+ galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })
107
+ }
108
+ }
109
+
110
+ onUiUpdate(function(){
111
+ check_progressbar('txt2img', 'txt2img_progressbar', 'txt2img_progress_span', 'txt2img_skip', 'txt2img_interrupt', 'txt2img_preview', 'txt2img_gallery')
112
+ check_progressbar('img2img', 'img2img_progressbar', 'img2img_progress_span', 'img2img_skip', 'img2img_interrupt', 'img2img_preview', 'img2img_gallery')
113
+ check_progressbar('ti', 'ti_progressbar', 'ti_progress_span', '', 'ti_interrupt', 'ti_preview', 'ti_gallery')
114
+ })
115
+
116
+ function requestMoreProgress(id_part, id_progressbar_span, id_skip, id_interrupt){
117
+ btn = gradioApp().getElementById(id_part+"_check_progress");
118
+ if(btn==null) return;
119
+
120
+ btn.click();
121
+ var progressDiv = gradioApp().querySelectorAll('#' + id_progressbar_span).length > 0;
122
+ var skip = id_skip ? gradioApp().getElementById(id_skip) : null
123
+ var interrupt = gradioApp().getElementById(id_interrupt)
124
+ if(progressDiv && interrupt){
125
+ if (skip) {
126
+ skip.style.display = "block"
127
+ }
128
+ interrupt.style.display = "block"
129
+ }
130
+ }
131
+
132
+ function requestProgress(id_part){
133
+ btn = gradioApp().getElementById(id_part+"_check_progress_initial");
134
+ if(btn==null) return;
135
+
136
+ btn.click();
137
+ }
stable-diffusion-webui-master/javascript/textualInversion.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ function start_training_textual_inversion(){
4
+ requestProgress('ti')
5
+ gradioApp().querySelector('#ti_error').innerHTML=''
6
+
7
+ return args_to_array(arguments)
8
+ }
stable-diffusion-webui-master/javascript/ui.js ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // various functions for interation with ui.py not large enough to warrant putting them in separate files
2
+
3
+ function set_theme(theme){
4
+ gradioURL = window.location.href
5
+ if (!gradioURL.includes('?__theme=')) {
6
+ window.location.replace(gradioURL + '?__theme=' + theme);
7
+ }
8
+ }
9
+
10
+ function selected_gallery_index(){
11
+ var buttons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item')
12
+ var button = gradioApp().querySelector('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item.\\!ring-2')
13
+
14
+ var result = -1
15
+ buttons.forEach(function(v, i){ if(v==button) { result = i } })
16
+
17
+ return result
18
+ }
19
+
20
+ function extract_image_from_gallery(gallery){
21
+ if(gallery.length == 1){
22
+ return gallery[0]
23
+ }
24
+
25
+ index = selected_gallery_index()
26
+
27
+ if (index < 0 || index >= gallery.length){
28
+ return [null]
29
+ }
30
+
31
+ return gallery[index];
32
+ }
33
+
34
+ function args_to_array(args){
35
+ res = []
36
+ for(var i=0;i<args.length;i++){
37
+ res.push(args[i])
38
+ }
39
+ return res
40
+ }
41
+
42
+ function switch_to_txt2img(){
43
+ gradioApp().querySelector('#tabs').querySelectorAll('button')[0].click();
44
+
45
+ return args_to_array(arguments);
46
+ }
47
+
48
+ function switch_to_img2img(){
49
+ gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click();
50
+ gradioApp().getElementById('mode_img2img').querySelectorAll('button')[0].click();
51
+
52
+ return args_to_array(arguments);
53
+ }
54
+
55
+ function switch_to_inpaint(){
56
+ gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click();
57
+ gradioApp().getElementById('mode_img2img').querySelectorAll('button')[1].click();
58
+
59
+ return args_to_array(arguments);
60
+ }
61
+
62
+ function switch_to_extras(){
63
+ gradioApp().querySelector('#tabs').querySelectorAll('button')[2].click();
64
+
65
+ return args_to_array(arguments);
66
+ }
67
+
68
+ function get_tab_index(tabId){
69
+ var res = 0
70
+
71
+ gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button').forEach(function(button, i){
72
+ if(button.className.indexOf('bg-white') != -1)
73
+ res = i
74
+ })
75
+
76
+ return res
77
+ }
78
+
79
+ function create_tab_index_args(tabId, args){
80
+ var res = []
81
+ for(var i=0; i<args.length; i++){
82
+ res.push(args[i])
83
+ }
84
+
85
+ res[0] = get_tab_index(tabId)
86
+
87
+ return res
88
+ }
89
+
90
+ function get_extras_tab_index(){
91
+ const [,,...args] = [...arguments]
92
+ return [get_tab_index('mode_extras'), get_tab_index('extras_resize_mode'), ...args]
93
+ }
94
+
95
+ function create_submit_args(args){
96
+ res = []
97
+ for(var i=0;i<args.length;i++){
98
+ res.push(args[i])
99
+ }
100
+
101
+ // 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.
102
+ // This can lead to uploading a huge gallery of previously generated images, which leads to an unnecessary delay between submitting and beginning to generate.
103
+ // 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.
104
+ // If gradio at some point stops sending outputs, this may break something
105
+ if(Array.isArray(res[res.length - 3])){
106
+ res[res.length - 3] = null
107
+ }
108
+
109
+ return res
110
+ }
111
+
112
+ function submit(){
113
+ requestProgress('txt2img')
114
+
115
+ return create_submit_args(arguments)
116
+ }
117
+
118
+ function submit_img2img(){
119
+ requestProgress('img2img')
120
+
121
+ res = create_submit_args(arguments)
122
+
123
+ res[0] = get_tab_index('mode_img2img')
124
+
125
+ return res
126
+ }
127
+
128
+
129
+ function ask_for_style_name(_, prompt_text, negative_prompt_text) {
130
+ name_ = prompt('Style name:')
131
+ return [name_, prompt_text, negative_prompt_text]
132
+ }
133
+
134
+
135
+
136
+ opts = {}
137
+ function apply_settings(jsdata){
138
+ console.log(jsdata)
139
+
140
+ opts = JSON.parse(jsdata)
141
+
142
+ return jsdata
143
+ }
144
+
145
+ onUiUpdate(function(){
146
+ if(Object.keys(opts).length != 0) return;
147
+
148
+ json_elem = gradioApp().getElementById('settings_json')
149
+ if(json_elem == null) return;
150
+
151
+ textarea = json_elem.querySelector('textarea')
152
+ jsdata = textarea.value
153
+ opts = JSON.parse(jsdata)
154
+
155
+
156
+ Object.defineProperty(textarea, 'value', {
157
+ set: function(newValue) {
158
+ var valueProp = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value');
159
+ var oldValue = valueProp.get.call(textarea);
160
+ valueProp.set.call(textarea, newValue);
161
+
162
+ if (oldValue != newValue) {
163
+ opts = JSON.parse(textarea.value)
164
+ }
165
+ },
166
+ get: function() {
167
+ var valueProp = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value');
168
+ return valueProp.get.call(textarea);
169
+ }
170
+ });
171
+
172
+ json_elem.parentElement.style.display="none"
173
+
174
+ if (!txt2img_textarea) {
175
+ txt2img_textarea = gradioApp().querySelector("#txt2img_prompt > label > textarea");
176
+ txt2img_textarea?.addEventListener("input", () => update_token_counter("txt2img_token_button"));
177
+ }
178
+ if (!img2img_textarea) {
179
+ img2img_textarea = gradioApp().querySelector("#img2img_prompt > label > textarea");
180
+ img2img_textarea?.addEventListener("input", () => update_token_counter("img2img_token_button"));
181
+ }
182
+ })
183
+
184
+ let txt2img_textarea, img2img_textarea = undefined;
185
+ let wait_time = 800
186
+ let token_timeout;
187
+
188
+ function update_txt2img_tokens(...args) {
189
+ update_token_counter("txt2img_token_button")
190
+ if (args.length == 2)
191
+ return args[0]
192
+ return args;
193
+ }
194
+
195
+ function update_img2img_tokens(...args) {
196
+ update_token_counter("img2img_token_button")
197
+ if (args.length == 2)
198
+ return args[0]
199
+ return args;
200
+ }
201
+
202
+ function update_token_counter(button_id) {
203
+ if (token_timeout)
204
+ clearTimeout(token_timeout);
205
+ token_timeout = setTimeout(() => gradioApp().getElementById(button_id)?.click(), wait_time);
206
+ }
207
+
208
+ function restart_reload(){
209
+ document.body.innerHTML='<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
210
+ setTimeout(function(){location.reload()},2000)
211
+
212
+ return []
213
+ }
stable-diffusion-webui-master/launch.py ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this scripts installs necessary requirements and launches main program in webui.py
2
+ import subprocess
3
+ import os
4
+ import sys
5
+ import importlib.util
6
+ import shlex
7
+ import platform
8
+ import argparse
9
+ import json
10
+
11
+ dir_repos = "repositories"
12
+ dir_extensions = "extensions"
13
+ python = sys.executable
14
+ git = os.environ.get('GIT', "git")
15
+ index_url = os.environ.get('INDEX_URL', "")
16
+
17
+
18
+ def extract_arg(args, name):
19
+ return [x for x in args if x != name], name in args
20
+
21
+
22
+ def extract_opt(args, name):
23
+ opt = None
24
+ is_present = False
25
+ if name in args:
26
+ is_present = True
27
+ idx = args.index(name)
28
+ del args[idx]
29
+ if idx < len(args) and args[idx][0] != "-":
30
+ opt = args[idx]
31
+ del args[idx]
32
+ return args, is_present, opt
33
+
34
+
35
+ def run(command, desc=None, errdesc=None, custom_env=None):
36
+ if desc is not None:
37
+ print(desc)
38
+
39
+ result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, env=os.environ if custom_env is None else custom_env)
40
+
41
+ if result.returncode != 0:
42
+
43
+ message = f"""{errdesc or 'Error running command'}.
44
+ Command: {command}
45
+ Error code: {result.returncode}
46
+ stdout: {result.stdout.decode(encoding="utf8", errors="ignore") if len(result.stdout)>0 else '<empty>'}
47
+ stderr: {result.stderr.decode(encoding="utf8", errors="ignore") if len(result.stderr)>0 else '<empty>'}
48
+ """
49
+ raise RuntimeError(message)
50
+
51
+ return result.stdout.decode(encoding="utf8", errors="ignore")
52
+
53
+
54
+ def check_run(command):
55
+ result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
56
+ return result.returncode == 0
57
+
58
+
59
+ def is_installed(package):
60
+ try:
61
+ spec = importlib.util.find_spec(package)
62
+ except ModuleNotFoundError:
63
+ return False
64
+
65
+ return spec is not None
66
+
67
+
68
+ def repo_dir(name):
69
+ return os.path.join(dir_repos, name)
70
+
71
+
72
+ def run_python(code, desc=None, errdesc=None):
73
+ return run(f'"{python}" -c "{code}"', desc, errdesc)
74
+
75
+
76
+ def run_pip(args, desc=None):
77
+ index_url_line = f' --index-url {index_url}' if index_url != '' else ''
78
+ return run(f'"{python}" -m pip {args} --prefer-binary{index_url_line}', desc=f"Installing {desc}", errdesc=f"Couldn't install {desc}")
79
+
80
+
81
+ def check_run_python(code):
82
+ return check_run(f'"{python}" -c "{code}"')
83
+
84
+
85
+ def git_clone(url, dir, name, commithash=None):
86
+ # TODO clone into temporary dir and move if successful
87
+
88
+ if os.path.exists(dir):
89
+ if commithash is None:
90
+ return
91
+
92
+ current_hash = run(f'"{git}" -C {dir} rev-parse HEAD', None, f"Couldn't determine {name}'s hash: {commithash}").strip()
93
+ if current_hash == commithash:
94
+ return
95
+
96
+ run(f'"{git}" -C {dir} fetch', f"Fetching updates for {name}...", f"Couldn't fetch {name}")
97
+ run(f'"{git}" -C {dir} checkout {commithash}', f"Checking out commit for {name} with hash: {commithash}...", f"Couldn't checkout commit {commithash} for {name}")
98
+ return
99
+
100
+ run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}")
101
+
102
+ if commithash is not None:
103
+ run(f'"{git}" -C {dir} checkout {commithash}', None, "Couldn't checkout {name}'s hash: {commithash}")
104
+
105
+
106
+ def version_check(commit):
107
+ try:
108
+ import requests
109
+ commits = requests.get('https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master').json()
110
+ if commit != "<none>" and commits['commit']['sha'] != commit:
111
+ print("--------------------------------------------------------")
112
+ print("| You are not up to date with the most recent release. |")
113
+ print("| Consider running `git pull` to update. |")
114
+ print("--------------------------------------------------------")
115
+ elif commits['commit']['sha'] == commit:
116
+ print("You are up to date with the most recent release.")
117
+ else:
118
+ print("Not a git clone, can't perform version check.")
119
+ except Exception as e:
120
+ print("version check failed", e)
121
+
122
+
123
+ def run_extension_installer(extension_dir):
124
+ path_installer = os.path.join(extension_dir, "install.py")
125
+ if not os.path.isfile(path_installer):
126
+ return
127
+
128
+ try:
129
+ env = os.environ.copy()
130
+ env['PYTHONPATH'] = os.path.abspath(".")
131
+
132
+ print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))
133
+ except Exception as e:
134
+ print(e, file=sys.stderr)
135
+
136
+
137
+ def list_extensions(settings_file):
138
+ settings = {}
139
+
140
+ try:
141
+ if os.path.isfile(settings_file):
142
+ with open(settings_file, "r", encoding="utf8") as file:
143
+ settings = json.load(file)
144
+ except Exception as e:
145
+ print(e, file=sys.stderr)
146
+
147
+ disabled_extensions = set(settings.get('disabled_extensions', []))
148
+
149
+ return [x for x in os.listdir(dir_extensions) if x not in disabled_extensions]
150
+
151
+
152
+ def run_extensions_installers(settings_file):
153
+ if not os.path.isdir(dir_extensions):
154
+ return
155
+
156
+ for dirname_extension in list_extensions(settings_file):
157
+ run_extension_installer(os.path.join(dir_extensions, dirname_extension))
158
+
159
+
160
+ def prepare_enviroment():
161
+ 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")
162
+ requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
163
+ commandline_args = os.environ.get('COMMANDLINE_ARGS', "")
164
+
165
+ gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379")
166
+ clip_package = os.environ.get('CLIP_PACKAGE', "git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1")
167
+ openclip_package = os.environ.get('OPENCLIP_PACKAGE', "git+https://github.com/mlfoundations/open_clip.git@bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b")
168
+
169
+ 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')
170
+
171
+ stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")
172
+ taming_transformers_repo = os.environ.get('TAMING_TRANSFORMERS_REPO', "https://github.com/CompVis/taming-transformers.git")
173
+ k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
174
+ codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')
175
+ blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
176
+
177
+ stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "47b6b607fdd31875c9279cd2f4f16b92e4ea958e")
178
+ taming_transformers_commit_hash = os.environ.get('TAMING_TRANSFORMERS_COMMIT_HASH', "24268930bf1dce879235a7fddd0b2355b84d7ea6")
179
+ k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "5b3af030dd83e0297272d861c19477735d0317ec")
180
+ codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")
181
+ blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")
182
+
183
+ sys.argv += shlex.split(commandline_args)
184
+
185
+ parser = argparse.ArgumentParser()
186
+ parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui settings", default='config.json')
187
+ args, _ = parser.parse_known_args(sys.argv)
188
+
189
+ sys.argv, skip_torch_cuda_test = extract_arg(sys.argv, '--skip-torch-cuda-test')
190
+ sys.argv, reinstall_xformers = extract_arg(sys.argv, '--reinstall-xformers')
191
+ sys.argv, update_check = extract_arg(sys.argv, '--update-check')
192
+ sys.argv, run_tests, test_dir = extract_opt(sys.argv, '--tests')
193
+ xformers = '--xformers' in sys.argv
194
+ ngrok = '--ngrok' in sys.argv
195
+
196
+ try:
197
+ commit = run(f"{git} rev-parse HEAD").strip()
198
+ except Exception:
199
+ commit = "<none>"
200
+
201
+ print(f"Python {sys.version}")
202
+ print(f"Commit hash: {commit}")
203
+
204
+ if not is_installed("torch") or not is_installed("torchvision"):
205
+ run(f'"{python}" -m {torch_command}', "Installing torch and torchvision", "Couldn't install torch")
206
+
207
+ if not skip_torch_cuda_test:
208
+ run_python("import torch; assert torch.cuda.is_available(), 'Torch is not able to use GPU; add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check'")
209
+
210
+ if not is_installed("gfpgan"):
211
+ run_pip(f"install {gfpgan_package}", "gfpgan")
212
+
213
+ if not is_installed("clip"):
214
+ run_pip(f"install {clip_package}", "clip")
215
+
216
+ if not is_installed("open_clip"):
217
+ run_pip(f"install {openclip_package}", "open_clip")
218
+
219
+ if (not is_installed("xformers") or reinstall_xformers) and xformers:
220
+ if platform.system() == "Windows":
221
+ if platform.python_version().startswith("3.10"):
222
+ run_pip(f"install -U -I --no-deps {xformers_windows_package}", "xformers")
223
+ else:
224
+ print("Installation of xformers is not supported in this version of Python.")
225
+ print("You can also check this and build manually: https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers#building-xformers-on-windows-by-duckness")
226
+ if not is_installed("xformers"):
227
+ exit(0)
228
+ elif platform.system() == "Linux":
229
+ run_pip("install xformers", "xformers")
230
+
231
+ if not is_installed("pyngrok") and ngrok:
232
+ run_pip("install pyngrok", "ngrok")
233
+
234
+ os.makedirs(dir_repos, exist_ok=True)
235
+
236
+ git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)
237
+ git_clone(taming_transformers_repo, repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash)
238
+ git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
239
+ git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
240
+ git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)
241
+
242
+ if not is_installed("lpips"):
243
+ run_pip(f"install -r {os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}", "requirements for CodeFormer")
244
+
245
+ run_pip(f"install -r {requirements_file}", "requirements for Web UI")
246
+
247
+ run_extensions_installers(settings_file=args.ui_settings_file)
248
+
249
+ if update_check:
250
+ version_check(commit)
251
+
252
+ if "--exit" in sys.argv:
253
+ print("Exiting because of --exit argument")
254
+ exit(0)
255
+
256
+ if run_tests:
257
+ exitcode = tests(test_dir)
258
+ exit(exitcode)
259
+
260
+
261
+ def tests(test_dir):
262
+ if "--api" not in sys.argv:
263
+ sys.argv.append("--api")
264
+ if "--ckpt" not in sys.argv:
265
+ sys.argv.append("--ckpt")
266
+ sys.argv.append("./test/test_files/empty.pt")
267
+ if "--skip-torch-cuda-test" not in sys.argv:
268
+ sys.argv.append("--skip-torch-cuda-test")
269
+
270
+ print(f"Launching Web UI in another process for testing with arguments: {' '.join(sys.argv[1:])}")
271
+
272
+ with open('test/stdout.txt', "w", encoding="utf8") as stdout, open('test/stderr.txt', "w", encoding="utf8") as stderr:
273
+ proc = subprocess.Popen([sys.executable, *sys.argv], stdout=stdout, stderr=stderr)
274
+
275
+ import test.server_poll
276
+ exitcode = test.server_poll.run_tests(proc, test_dir)
277
+
278
+ print(f"Stopping Web UI process with id {proc.pid}")
279
+ proc.kill()
280
+ return exitcode
281
+
282
+
283
+ def start():
284
+ print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
285
+ import webui
286
+ if '--nowebui' in sys.argv:
287
+ webui.api_only()
288
+ else:
289
+ webui.webui()
290
+
291
+
292
+ if __name__ == "__main__":
293
+ prepare_enviroment()
294
+ start()
stable-diffusion-webui-master/localizations/Put localization files here.txt ADDED
File without changes
stable-diffusion-webui-master/models/Stable-diffusion/Put Stable Diffusion checkpoints here.txt ADDED
File without changes
stable-diffusion-webui-master/models/VAE/Put VAE here.txt ADDED
File without changes
stable-diffusion-webui-master/models/deepbooru/Put your deepbooru release project folder here.txt ADDED
File without changes
stable-diffusion-webui-master/modules/api/api.py ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import io
3
+ import time
4
+ import uvicorn
5
+ from threading import Lock
6
+ from io import BytesIO
7
+ from gradio.processing_utils import decode_base64_to_file
8
+ from fastapi import APIRouter, Depends, FastAPI, HTTPException
9
+ from fastapi.security import HTTPBasic, HTTPBasicCredentials
10
+ from secrets import compare_digest
11
+
12
+ import modules.shared as shared
13
+ from modules import sd_samplers, deepbooru
14
+ from modules.api.models import *
15
+ from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
16
+ from modules.extras import run_extras, run_pnginfo
17
+ from PIL import PngImagePlugin,Image
18
+ from modules.sd_models import checkpoints_list
19
+ from modules.realesrgan_model import get_realesrgan_models
20
+ from typing import List
21
+
22
+ def upscaler_to_index(name: str):
23
+ try:
24
+ return [x.name.lower() for x in shared.sd_upscalers].index(name.lower())
25
+ except:
26
+ raise HTTPException(status_code=400, detail=f"Invalid upscaler, needs to be on of these: {' , '.join([x.name for x in sd_upscalers])}")
27
+
28
+
29
+ def validate_sampler_name(name):
30
+ config = sd_samplers.all_samplers_map.get(name, None)
31
+ if config is None:
32
+ raise HTTPException(status_code=404, detail="Sampler not found")
33
+
34
+ return name
35
+
36
+ def setUpscalers(req: dict):
37
+ reqDict = vars(req)
38
+ reqDict['extras_upscaler_1'] = upscaler_to_index(req.upscaler_1)
39
+ reqDict['extras_upscaler_2'] = upscaler_to_index(req.upscaler_2)
40
+ reqDict.pop('upscaler_1')
41
+ reqDict.pop('upscaler_2')
42
+ return reqDict
43
+
44
+ def decode_base64_to_image(encoding):
45
+ if encoding.startswith("data:image/"):
46
+ encoding = encoding.split(";")[1].split(",")[1]
47
+ return Image.open(BytesIO(base64.b64decode(encoding)))
48
+
49
+ def encode_pil_to_base64(image):
50
+ with io.BytesIO() as output_bytes:
51
+
52
+ # Copy any text-only metadata
53
+ use_metadata = False
54
+ metadata = PngImagePlugin.PngInfo()
55
+ for key, value in image.info.items():
56
+ if isinstance(key, str) and isinstance(value, str):
57
+ metadata.add_text(key, value)
58
+ use_metadata = True
59
+
60
+ image.save(
61
+ output_bytes, "PNG", pnginfo=(metadata if use_metadata else None)
62
+ )
63
+ bytes_data = output_bytes.getvalue()
64
+ return base64.b64encode(bytes_data)
65
+
66
+
67
+ class Api:
68
+ def __init__(self, app: FastAPI, queue_lock: Lock):
69
+ if shared.cmd_opts.api_auth:
70
+ self.credenticals = dict()
71
+ for auth in shared.cmd_opts.api_auth.split(","):
72
+ user, password = auth.split(":")
73
+ self.credenticals[user] = password
74
+
75
+ self.router = APIRouter()
76
+ self.app = app
77
+ self.queue_lock = queue_lock
78
+ self.add_api_route("/sdapi/v1/txt2img", self.text2imgapi, methods=["POST"], response_model=TextToImageResponse)
79
+ self.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=ImageToImageResponse)
80
+ self.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=ExtrasSingleImageResponse)
81
+ self.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=ExtrasBatchImagesResponse)
82
+ self.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=PNGInfoResponse)
83
+ self.add_api_route("/sdapi/v1/progress", self.progressapi, methods=["GET"], response_model=ProgressResponse)
84
+ self.add_api_route("/sdapi/v1/interrogate", self.interrogateapi, methods=["POST"])
85
+ self.add_api_route("/sdapi/v1/interrupt", self.interruptapi, methods=["POST"])
86
+ self.add_api_route("/sdapi/v1/skip", self.skip, methods=["POST"])
87
+ self.add_api_route("/sdapi/v1/options", self.get_config, methods=["GET"], response_model=OptionsModel)
88
+ self.add_api_route("/sdapi/v1/options", self.set_config, methods=["POST"])
89
+ self.add_api_route("/sdapi/v1/cmd-flags", self.get_cmd_flags, methods=["GET"], response_model=FlagsModel)
90
+ self.add_api_route("/sdapi/v1/samplers", self.get_samplers, methods=["GET"], response_model=List[SamplerItem])
91
+ self.add_api_route("/sdapi/v1/upscalers", self.get_upscalers, methods=["GET"], response_model=List[UpscalerItem])
92
+ self.add_api_route("/sdapi/v1/sd-models", self.get_sd_models, methods=["GET"], response_model=List[SDModelItem])
93
+ self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=List[HypernetworkItem])
94
+ self.add_api_route("/sdapi/v1/face-restorers", self.get_face_restorers, methods=["GET"], response_model=List[FaceRestorerItem])
95
+ self.add_api_route("/sdapi/v1/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=List[RealesrganItem])
96
+ self.add_api_route("/sdapi/v1/prompt-styles", self.get_promp_styles, methods=["GET"], response_model=List[PromptStyleItem])
97
+ self.add_api_route("/sdapi/v1/artist-categories", self.get_artists_categories, methods=["GET"], response_model=List[str])
98
+ self.add_api_route("/sdapi/v1/artists", self.get_artists, methods=["GET"], response_model=List[ArtistItem])
99
+
100
+ def add_api_route(self, path: str, endpoint, **kwargs):
101
+ if shared.cmd_opts.api_auth:
102
+ return self.app.add_api_route(path, endpoint, dependencies=[Depends(self.auth)], **kwargs)
103
+ return self.app.add_api_route(path, endpoint, **kwargs)
104
+
105
+ def auth(self, credenticals: HTTPBasicCredentials = Depends(HTTPBasic())):
106
+ if credenticals.username in self.credenticals:
107
+ if compare_digest(credenticals.password, self.credenticals[credenticals.username]):
108
+ return True
109
+
110
+ raise HTTPException(status_code=401, detail="Incorrect username or password", headers={"WWW-Authenticate": "Basic"})
111
+
112
+ def text2imgapi(self, txt2imgreq: StableDiffusionTxt2ImgProcessingAPI):
113
+ populate = txt2imgreq.copy(update={ # Override __init__ params
114
+ "sd_model": shared.sd_model,
115
+ "sampler_name": validate_sampler_name(txt2imgreq.sampler_name or txt2imgreq.sampler_index),
116
+ "do_not_save_samples": True,
117
+ "do_not_save_grid": True
118
+ }
119
+ )
120
+ if populate.sampler_name:
121
+ populate.sampler_index = None # prevent a warning later on
122
+ p = StableDiffusionProcessingTxt2Img(**vars(populate))
123
+ # Override object param
124
+
125
+ shared.state.begin()
126
+
127
+ with self.queue_lock:
128
+ processed = process_images(p)
129
+
130
+ shared.state.end()
131
+
132
+ b64images = list(map(encode_pil_to_base64, processed.images))
133
+
134
+ return TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js())
135
+
136
+ def img2imgapi(self, img2imgreq: StableDiffusionImg2ImgProcessingAPI):
137
+ init_images = img2imgreq.init_images
138
+ if init_images is None:
139
+ raise HTTPException(status_code=404, detail="Init image not found")
140
+
141
+ mask = img2imgreq.mask
142
+ if mask:
143
+ mask = decode_base64_to_image(mask)
144
+
145
+ populate = img2imgreq.copy(update={ # Override __init__ params
146
+ "sd_model": shared.sd_model,
147
+ "sampler_name": validate_sampler_name(img2imgreq.sampler_name or img2imgreq.sampler_index),
148
+ "do_not_save_samples": True,
149
+ "do_not_save_grid": True,
150
+ "mask": mask
151
+ }
152
+ )
153
+ if populate.sampler_name:
154
+ populate.sampler_index = None # prevent a warning later on
155
+ p = StableDiffusionProcessingImg2Img(**vars(populate))
156
+
157
+ imgs = []
158
+ for img in init_images:
159
+ img = decode_base64_to_image(img)
160
+ imgs = [img] * p.batch_size
161
+
162
+ p.init_images = imgs
163
+
164
+ shared.state.begin()
165
+
166
+ with self.queue_lock:
167
+ processed = process_images(p)
168
+
169
+ shared.state.end()
170
+
171
+ b64images = list(map(encode_pil_to_base64, processed.images))
172
+
173
+ if (not img2imgreq.include_init_images):
174
+ img2imgreq.init_images = None
175
+ img2imgreq.mask = None
176
+
177
+ return ImageToImageResponse(images=b64images, parameters=vars(img2imgreq), info=processed.js())
178
+
179
+ def extras_single_image_api(self, req: ExtrasSingleImageRequest):
180
+ reqDict = setUpscalers(req)
181
+
182
+ reqDict['image'] = decode_base64_to_image(reqDict['image'])
183
+
184
+ with self.queue_lock:
185
+ result = run_extras(extras_mode=0, image_folder="", input_dir="", output_dir="", **reqDict)
186
+
187
+ return ExtrasSingleImageResponse(image=encode_pil_to_base64(result[0][0]), html_info=result[1])
188
+
189
+ def extras_batch_images_api(self, req: ExtrasBatchImagesRequest):
190
+ reqDict = setUpscalers(req)
191
+
192
+ def prepareFiles(file):
193
+ file = decode_base64_to_file(file.data, file_path=file.name)
194
+ file.orig_name = file.name
195
+ return file
196
+
197
+ reqDict['image_folder'] = list(map(prepareFiles, reqDict['imageList']))
198
+ reqDict.pop('imageList')
199
+
200
+ with self.queue_lock:
201
+ result = run_extras(extras_mode=1, image="", input_dir="", output_dir="", **reqDict)
202
+
203
+ return ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
204
+
205
+ def pnginfoapi(self, req: PNGInfoRequest):
206
+ if(not req.image.strip()):
207
+ return PNGInfoResponse(info="")
208
+
209
+ result = run_pnginfo(decode_base64_to_image(req.image.strip()))
210
+
211
+ return PNGInfoResponse(info=result[1])
212
+
213
+ def progressapi(self, req: ProgressRequest = Depends()):
214
+ # copy from check_progress_call of ui.py
215
+
216
+ if shared.state.job_count == 0:
217
+ return ProgressResponse(progress=0, eta_relative=0, state=shared.state.dict())
218
+
219
+ # avoid dividing zero
220
+ progress = 0.01
221
+
222
+ if shared.state.job_count > 0:
223
+ progress += shared.state.job_no / shared.state.job_count
224
+ if shared.state.sampling_steps > 0:
225
+ progress += 1 / shared.state.job_count * shared.state.sampling_step / shared.state.sampling_steps
226
+
227
+ time_since_start = time.time() - shared.state.time_start
228
+ eta = (time_since_start/progress)
229
+ eta_relative = eta-time_since_start
230
+
231
+ progress = min(progress, 1)
232
+
233
+ shared.state.set_current_image()
234
+
235
+ current_image = None
236
+ if shared.state.current_image and not req.skip_current_image:
237
+ current_image = encode_pil_to_base64(shared.state.current_image)
238
+
239
+ return ProgressResponse(progress=progress, eta_relative=eta_relative, state=shared.state.dict(), current_image=current_image)
240
+
241
+ def interrogateapi(self, interrogatereq: InterrogateRequest):
242
+ image_b64 = interrogatereq.image
243
+ if image_b64 is None:
244
+ raise HTTPException(status_code=404, detail="Image not found")
245
+
246
+ img = decode_base64_to_image(image_b64)
247
+ img = img.convert('RGB')
248
+
249
+ # Override object param
250
+ with self.queue_lock:
251
+ if interrogatereq.model == "clip":
252
+ processed = shared.interrogator.interrogate(img)
253
+ elif interrogatereq.model == "deepdanbooru":
254
+ processed = deepbooru.model.tag(img)
255
+ else:
256
+ raise HTTPException(status_code=404, detail="Model not found")
257
+
258
+ return InterrogateResponse(caption=processed)
259
+
260
+ def interruptapi(self):
261
+ shared.state.interrupt()
262
+
263
+ return {}
264
+
265
+ def skip(self):
266
+ shared.state.skip()
267
+
268
+ def get_config(self):
269
+ options = {}
270
+ for key in shared.opts.data.keys():
271
+ metadata = shared.opts.data_labels.get(key)
272
+ if(metadata is not None):
273
+ options.update({key: shared.opts.data.get(key, shared.opts.data_labels.get(key).default)})
274
+ else:
275
+ options.update({key: shared.opts.data.get(key, None)})
276
+
277
+ return options
278
+
279
+ def set_config(self, req: Dict[str, Any]):
280
+ for k, v in req.items():
281
+ shared.opts.set(k, v)
282
+
283
+ shared.opts.save(shared.config_filename)
284
+ return
285
+
286
+ def get_cmd_flags(self):
287
+ return vars(shared.cmd_opts)
288
+
289
+ def get_samplers(self):
290
+ return [{"name": sampler[0], "aliases":sampler[2], "options":sampler[3]} for sampler in sd_samplers.all_samplers]
291
+
292
+ def get_upscalers(self):
293
+ upscalers = []
294
+
295
+ for upscaler in shared.sd_upscalers:
296
+ u = upscaler.scaler
297
+ upscalers.append({"name":u.name, "model_name":u.model_name, "model_path":u.model_path, "model_url":u.model_url})
298
+
299
+ return upscalers
300
+
301
+ def get_sd_models(self):
302
+ return [{"title":x.title, "model_name":x.model_name, "hash":x.hash, "filename": x.filename, "config": x.config} for x in checkpoints_list.values()]
303
+
304
+ def get_hypernetworks(self):
305
+ return [{"name": name, "path": shared.hypernetworks[name]} for name in shared.hypernetworks]
306
+
307
+ def get_face_restorers(self):
308
+ return [{"name":x.name(), "cmd_dir": getattr(x, "cmd_dir", None)} for x in shared.face_restorers]
309
+
310
+ def get_realesrgan_models(self):
311
+ return [{"name":x.name,"path":x.data_path, "scale":x.scale} for x in get_realesrgan_models(None)]
312
+
313
+ def get_promp_styles(self):
314
+ styleList = []
315
+ for k in shared.prompt_styles.styles:
316
+ style = shared.prompt_styles.styles[k]
317
+ styleList.append({"name":style[0], "prompt": style[1], "negative_prompt": style[2]})
318
+
319
+ return styleList
320
+
321
+ def get_artists_categories(self):
322
+ return shared.artist_db.cats
323
+
324
+ def get_artists(self):
325
+ return [{"name":x[0], "score":x[1], "category":x[2]} for x in shared.artist_db.artists]
326
+
327
+ def launch(self, server_name, port):
328
+ self.app.include_router(self.router)
329
+ uvicorn.run(self.app, host=server_name, port=port)
stable-diffusion-webui-master/modules/api/models.py ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import inspect
2
+ from pydantic import BaseModel, Field, create_model
3
+ from typing import Any, Optional
4
+ from typing_extensions import Literal
5
+ from inflection import underscore
6
+ from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img
7
+ from modules.shared import sd_upscalers, opts, parser
8
+ from typing import Dict, List
9
+
10
+ API_NOT_ALLOWED = [
11
+ "self",
12
+ "kwargs",
13
+ "sd_model",
14
+ "outpath_samples",
15
+ "outpath_grids",
16
+ "sampler_index",
17
+ "do_not_save_samples",
18
+ "do_not_save_grid",
19
+ "extra_generation_params",
20
+ "overlay_images",
21
+ "do_not_reload_embeddings",
22
+ "seed_enable_extras",
23
+ "prompt_for_display",
24
+ "sampler_noise_scheduler_override",
25
+ "ddim_discretize"
26
+ ]
27
+
28
+ class ModelDef(BaseModel):
29
+ """Assistance Class for Pydantic Dynamic Model Generation"""
30
+
31
+ field: str
32
+ field_alias: str
33
+ field_type: Any
34
+ field_value: Any
35
+ field_exclude: bool = False
36
+
37
+
38
+ class PydanticModelGenerator:
39
+ """
40
+ Takes in created classes and stubs them out in a way FastAPI/Pydantic is happy about:
41
+ source_data is a snapshot of the default values produced by the class
42
+ params are the names of the actual keys required by __init__
43
+ """
44
+
45
+ def __init__(
46
+ self,
47
+ model_name: str = None,
48
+ class_instance = None,
49
+ additional_fields = None,
50
+ ):
51
+ def field_type_generator(k, v):
52
+ # field_type = str if not overrides.get(k) else overrides[k]["type"]
53
+ # print(k, v.annotation, v.default)
54
+ field_type = v.annotation
55
+
56
+ return Optional[field_type]
57
+
58
+ def merge_class_params(class_):
59
+ all_classes = list(filter(lambda x: x is not object, inspect.getmro(class_)))
60
+ parameters = {}
61
+ for classes in all_classes:
62
+ parameters = {**parameters, **inspect.signature(classes.__init__).parameters}
63
+ return parameters
64
+
65
+
66
+ self._model_name = model_name
67
+ self._class_data = merge_class_params(class_instance)
68
+
69
+ self._model_def = [
70
+ ModelDef(
71
+ field=underscore(k),
72
+ field_alias=k,
73
+ field_type=field_type_generator(k, v),
74
+ field_value=v.default
75
+ )
76
+ for (k,v) in self._class_data.items() if k not in API_NOT_ALLOWED
77
+ ]
78
+
79
+ for fields in additional_fields:
80
+ self._model_def.append(ModelDef(
81
+ field=underscore(fields["key"]),
82
+ field_alias=fields["key"],
83
+ field_type=fields["type"],
84
+ field_value=fields["default"],
85
+ field_exclude=fields["exclude"] if "exclude" in fields else False))
86
+
87
+ def generate_model(self):
88
+ """
89
+ Creates a pydantic BaseModel
90
+ from the json and overrides provided at initialization
91
+ """
92
+ fields = {
93
+ d.field: (d.field_type, Field(default=d.field_value, alias=d.field_alias, exclude=d.field_exclude)) for d in self._model_def
94
+ }
95
+ DynamicModel = create_model(self._model_name, **fields)
96
+ DynamicModel.__config__.allow_population_by_field_name = True
97
+ DynamicModel.__config__.allow_mutation = True
98
+ return DynamicModel
99
+
100
+ StableDiffusionTxt2ImgProcessingAPI = PydanticModelGenerator(
101
+ "StableDiffusionProcessingTxt2Img",
102
+ StableDiffusionProcessingTxt2Img,
103
+ [{"key": "sampler_index", "type": str, "default": "Euler"}]
104
+ ).generate_model()
105
+
106
+ StableDiffusionImg2ImgProcessingAPI = PydanticModelGenerator(
107
+ "StableDiffusionProcessingImg2Img",
108
+ StableDiffusionProcessingImg2Img,
109
+ [{"key": "sampler_index", "type": str, "default": "Euler"}, {"key": "init_images", "type": list, "default": None}, {"key": "denoising_strength", "type": float, "default": 0.75}, {"key": "mask", "type": str, "default": None}, {"key": "include_init_images", "type": bool, "default": False, "exclude" : True}]
110
+ ).generate_model()
111
+
112
+ class TextToImageResponse(BaseModel):
113
+ images: List[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
114
+ parameters: dict
115
+ info: str
116
+
117
+ class ImageToImageResponse(BaseModel):
118
+ images: List[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
119
+ parameters: dict
120
+ info: str
121
+
122
+ class ExtrasBaseRequest(BaseModel):
123
+ resize_mode: Literal[0, 1] = Field(default=0, title="Resize Mode", description="Sets the resize mode: 0 to upscale by upscaling_resize amount, 1 to upscale up to upscaling_resize_h x upscaling_resize_w.")
124
+ show_extras_results: bool = Field(default=True, title="Show results", description="Should the backend return the generated image?")
125
+ gfpgan_visibility: float = Field(default=0, title="GFPGAN Visibility", ge=0, le=1, allow_inf_nan=False, description="Sets the visibility of GFPGAN, values should be between 0 and 1.")
126
+ codeformer_visibility: float = Field(default=0, title="CodeFormer Visibility", ge=0, le=1, allow_inf_nan=False, description="Sets the visibility of CodeFormer, values should be between 0 and 1.")
127
+ codeformer_weight: float = Field(default=0, title="CodeFormer Weight", ge=0, le=1, allow_inf_nan=False, description="Sets the weight of CodeFormer, values should be between 0 and 1.")
128
+ 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.")
129
+ 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.")
130
+ 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.")
131
+ upscaling_crop: bool = Field(default=True, title="Crop to fit", description="Should the upscaler crop the image to fit in the choosen size?")
132
+ 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])}")
133
+ 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])}")
134
+ 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.")
135
+ upscale_first: bool = Field(default=False, title="Upscale first", description="Should the upscaler run before restoring faces?")
136
+
137
+ class ExtraBaseResponse(BaseModel):
138
+ html_info: str = Field(title="HTML info", description="A series of HTML tags containing the process info.")
139
+
140
+ class ExtrasSingleImageRequest(ExtrasBaseRequest):
141
+ image: str = Field(default="", title="Image", description="Image to work on, must be a Base64 string containing the image's data.")
142
+
143
+ class ExtrasSingleImageResponse(ExtraBaseResponse):
144
+ image: str = Field(default=None, title="Image", description="The generated image in base64 format.")
145
+
146
+ class FileData(BaseModel):
147
+ data: str = Field(title="File data", description="Base64 representation of the file")
148
+ name: str = Field(title="File name")
149
+
150
+ class ExtrasBatchImagesRequest(ExtrasBaseRequest):
151
+ imageList: List[FileData] = Field(title="Images", description="List of images to work on. Must be Base64 strings")
152
+
153
+ class ExtrasBatchImagesResponse(ExtraBaseResponse):
154
+ images: List[str] = Field(title="Images", description="The generated images in base64 format.")
155
+
156
+ class PNGInfoRequest(BaseModel):
157
+ image: str = Field(title="Image", description="The base64 encoded PNG image")
158
+
159
+ class PNGInfoResponse(BaseModel):
160
+ info: str = Field(title="Image info", description="A string with all the info the image had")
161
+
162
+ class ProgressRequest(BaseModel):
163
+ skip_current_image: bool = Field(default=False, title="Skip current image", description="Skip current image serialization")
164
+
165
+ class ProgressResponse(BaseModel):
166
+ progress: float = Field(title="Progress", description="The progress with a range of 0 to 1")
167
+ eta_relative: float = Field(title="ETA in secs")
168
+ state: dict = Field(title="State", description="The current state snapshot")
169
+ 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.")
170
+
171
+ class InterrogateRequest(BaseModel):
172
+ image: str = Field(default="", title="Image", description="Image to work on, must be a Base64 string containing the image's data.")
173
+ model: str = Field(default="clip", title="Model", description="The interrogate model used.")
174
+
175
+ class InterrogateResponse(BaseModel):
176
+ caption: str = Field(default=None, title="Caption", description="The generated caption for the image.")
177
+
178
+ fields = {}
179
+ for key, metadata in opts.data_labels.items():
180
+ value = opts.data.get(key)
181
+ optType = opts.typemap.get(type(metadata.default), type(value))
182
+
183
+ if (metadata is not None):
184
+ fields.update({key: (Optional[optType], Field(
185
+ default=metadata.default ,description=metadata.label))})
186
+ else:
187
+ fields.update({key: (Optional[optType], Field())})
188
+
189
+ OptionsModel = create_model("Options", **fields)
190
+
191
+ flags = {}
192
+ _options = vars(parser)['_option_string_actions']
193
+ for key in _options:
194
+ if(_options[key].dest != 'help'):
195
+ flag = _options[key]
196
+ _type = str
197
+ if _options[key].default is not None: _type = type(_options[key].default)
198
+ flags.update({flag.dest: (_type,Field(default=flag.default, description=flag.help))})
199
+
200
+ FlagsModel = create_model("Flags", **flags)
201
+
202
+ class SamplerItem(BaseModel):
203
+ name: str = Field(title="Name")
204
+ aliases: List[str] = Field(title="Aliases")
205
+ options: Dict[str, str] = Field(title="Options")
206
+
207
+ class UpscalerItem(BaseModel):
208
+ name: str = Field(title="Name")
209
+ model_name: Optional[str] = Field(title="Model Name")
210
+ model_path: Optional[str] = Field(title="Path")
211
+ model_url: Optional[str] = Field(title="URL")
212
+
213
+ class SDModelItem(BaseModel):
214
+ title: str = Field(title="Title")
215
+ model_name: str = Field(title="Model Name")
216
+ hash: str = Field(title="Hash")
217
+ filename: str = Field(title="Filename")
218
+ config: str = Field(title="Config file")
219
+
220
+ class HypernetworkItem(BaseModel):
221
+ name: str = Field(title="Name")
222
+ path: Optional[str] = Field(title="Path")
223
+
224
+ class FaceRestorerItem(BaseModel):
225
+ name: str = Field(title="Name")
226
+ cmd_dir: Optional[str] = Field(title="Path")
227
+
228
+ class RealesrganItem(BaseModel):
229
+ name: str = Field(title="Name")
230
+ path: Optional[str] = Field(title="Path")
231
+ scale: Optional[int] = Field(title="Scale")
232
+
233
+ class PromptStyleItem(BaseModel):
234
+ name: str = Field(title="Name")
235
+ prompt: Optional[str] = Field(title="Prompt")
236
+ negative_prompt: Optional[str] = Field(title="Negative Prompt")
237
+
238
+ class ArtistItem(BaseModel):
239
+ name: str = Field(title="Name")
240
+ score: float = Field(title="Score")
241
+ category: str = Field(title="Category")
242
+
stable-diffusion-webui-master/modules/artists.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path
2
+ import csv
3
+ from collections import namedtuple
4
+
5
+ Artist = namedtuple("Artist", ['name', 'weight', 'category'])
6
+
7
+
8
+ class ArtistsDatabase:
9
+ def __init__(self, filename):
10
+ self.cats = set()
11
+ self.artists = []
12
+
13
+ if not os.path.exists(filename):
14
+ return
15
+
16
+ with open(filename, "r", newline='', encoding="utf8") as file:
17
+ reader = csv.DictReader(file)
18
+
19
+ for row in reader:
20
+ artist = Artist(row["artist"], float(row["score"]), row["category"])
21
+ self.artists.append(artist)
22
+ self.cats.add(artist.category)
23
+
24
+ def categories(self):
25
+ return sorted(self.cats)
stable-diffusion-webui-master/modules/call_queue.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import html
2
+ import sys
3
+ import threading
4
+ import traceback
5
+ import time
6
+
7
+ from modules import shared
8
+
9
+ queue_lock = threading.Lock()
10
+
11
+
12
+ def wrap_queued_call(func):
13
+ def f(*args, **kwargs):
14
+ with queue_lock:
15
+ res = func(*args, **kwargs)
16
+
17
+ return res
18
+
19
+ return f
20
+
21
+
22
+ def wrap_gradio_gpu_call(func, extra_outputs=None):
23
+ def f(*args, **kwargs):
24
+
25
+ shared.state.begin()
26
+
27
+ with queue_lock:
28
+ res = func(*args, **kwargs)
29
+
30
+ shared.state.end()
31
+
32
+ return res
33
+
34
+ return wrap_gradio_call(f, extra_outputs=extra_outputs, add_stats=True)
35
+
36
+
37
+ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
38
+ def f(*args, extra_outputs_array=extra_outputs, **kwargs):
39
+ run_memmon = shared.opts.memmon_poll_rate > 0 and not shared.mem_mon.disabled and add_stats
40
+ if run_memmon:
41
+ shared.mem_mon.monitor()
42
+ t = time.perf_counter()
43
+
44
+ try:
45
+ res = list(func(*args, **kwargs))
46
+ except Exception as e:
47
+ # When printing out our debug argument list, do not print out more than a MB of text
48
+ max_debug_str_len = 131072 # (1024*1024)/8
49
+
50
+ print("Error completing request", file=sys.stderr)
51
+ argStr = f"Arguments: {str(args)} {str(kwargs)}"
52
+ print(argStr[:max_debug_str_len], file=sys.stderr)
53
+ if len(argStr) > max_debug_str_len:
54
+ print(f"(Argument list truncated at {max_debug_str_len}/{len(argStr)} characters)", file=sys.stderr)
55
+
56
+ print(traceback.format_exc(), file=sys.stderr)
57
+
58
+ shared.state.job = ""
59
+ shared.state.job_count = 0
60
+
61
+ if extra_outputs_array is None:
62
+ extra_outputs_array = [None, '']
63
+
64
+ res = extra_outputs_array + [f"<div class='error'>{html.escape(type(e).__name__+': '+str(e))}</div>"]
65
+
66
+ shared.state.skipped = False
67
+ shared.state.interrupted = False
68
+ shared.state.job_count = 0
69
+
70
+ if not add_stats:
71
+ return tuple(res)
72
+
73
+ elapsed = time.perf_counter() - t
74
+ elapsed_m = int(elapsed // 60)
75
+ elapsed_s = elapsed % 60
76
+ elapsed_text = f"{elapsed_s:.2f}s"
77
+ if elapsed_m > 0:
78
+ elapsed_text = f"{elapsed_m}m "+elapsed_text
79
+
80
+ if run_memmon:
81
+ mem_stats = {k: -(v//-(1024*1024)) for k, v in shared.mem_mon.stop().items()}
82
+ active_peak = mem_stats['active_peak']
83
+ reserved_peak = mem_stats['reserved_peak']
84
+ sys_peak = mem_stats['system_peak']
85
+ sys_total = mem_stats['total']
86
+ sys_pct = round(sys_peak/max(sys_total, 1) * 100, 2)
87
+
88
+ 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>"
89
+ else:
90
+ vram_html = ''
91
+
92
+ # last item is always HTML
93
+ res[-1] += f"<div class='performance'><p class='time'>Time taken: <wbr>{elapsed_text}</p>{vram_html}</div>"
94
+
95
+ return tuple(res)
96
+
97
+ return f
98
+
stable-diffusion-webui-master/modules/codeformer/codeformer_arch.py ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this file is copied from CodeFormer repository. Please see comment in modules/codeformer_model.py
2
+
3
+ import math
4
+ import numpy as np
5
+ import torch
6
+ from torch import nn, Tensor
7
+ import torch.nn.functional as F
8
+ from typing import Optional, List
9
+
10
+ from modules.codeformer.vqgan_arch import *
11
+ from basicsr.utils import get_root_logger
12
+ from basicsr.utils.registry import ARCH_REGISTRY
13
+
14
+ def calc_mean_std(feat, eps=1e-5):
15
+ """Calculate mean and std for adaptive_instance_normalization.
16
+
17
+ Args:
18
+ feat (Tensor): 4D tensor.
19
+ eps (float): A small value added to the variance to avoid
20
+ divide-by-zero. Default: 1e-5.
21
+ """
22
+ size = feat.size()
23
+ assert len(size) == 4, 'The input feature should be 4D tensor.'
24
+ b, c = size[:2]
25
+ feat_var = feat.view(b, c, -1).var(dim=2) + eps
26
+ feat_std = feat_var.sqrt().view(b, c, 1, 1)
27
+ feat_mean = feat.view(b, c, -1).mean(dim=2).view(b, c, 1, 1)
28
+ return feat_mean, feat_std
29
+
30
+
31
+ def adaptive_instance_normalization(content_feat, style_feat):
32
+ """Adaptive instance normalization.
33
+
34
+ Adjust the reference features to have the similar color and illuminations
35
+ as those in the degradate features.
36
+
37
+ Args:
38
+ content_feat (Tensor): The reference feature.
39
+ style_feat (Tensor): The degradate features.
40
+ """
41
+ size = content_feat.size()
42
+ style_mean, style_std = calc_mean_std(style_feat)
43
+ content_mean, content_std = calc_mean_std(content_feat)
44
+ normalized_feat = (content_feat - content_mean.expand(size)) / content_std.expand(size)
45
+ return normalized_feat * style_std.expand(size) + style_mean.expand(size)
46
+
47
+
48
+ class PositionEmbeddingSine(nn.Module):
49
+ """
50
+ This is a more standard version of the position embedding, very similar to the one
51
+ used by the Attention is all you need paper, generalized to work on images.
52
+ """
53
+
54
+ def __init__(self, num_pos_feats=64, temperature=10000, normalize=False, scale=None):
55
+ super().__init__()
56
+ self.num_pos_feats = num_pos_feats
57
+ self.temperature = temperature
58
+ self.normalize = normalize
59
+ if scale is not None and normalize is False:
60
+ raise ValueError("normalize should be True if scale is passed")
61
+ if scale is None:
62
+ scale = 2 * math.pi
63
+ self.scale = scale
64
+
65
+ def forward(self, x, mask=None):
66
+ if mask is None:
67
+ mask = torch.zeros((x.size(0), x.size(2), x.size(3)), device=x.device, dtype=torch.bool)
68
+ not_mask = ~mask
69
+ y_embed = not_mask.cumsum(1, dtype=torch.float32)
70
+ x_embed = not_mask.cumsum(2, dtype=torch.float32)
71
+ if self.normalize:
72
+ eps = 1e-6
73
+ y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale
74
+ x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale
75
+
76
+ dim_t = torch.arange(self.num_pos_feats, dtype=torch.float32, device=x.device)
77
+ dim_t = self.temperature ** (2 * (dim_t // 2) / self.num_pos_feats)
78
+
79
+ pos_x = x_embed[:, :, :, None] / dim_t
80
+ pos_y = y_embed[:, :, :, None] / dim_t
81
+ pos_x = torch.stack(
82
+ (pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4
83
+ ).flatten(3)
84
+ pos_y = torch.stack(
85
+ (pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4
86
+ ).flatten(3)
87
+ pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2)
88
+ return pos
89
+
90
+ def _get_activation_fn(activation):
91
+ """Return an activation function given a string"""
92
+ if activation == "relu":
93
+ return F.relu
94
+ if activation == "gelu":
95
+ return F.gelu
96
+ if activation == "glu":
97
+ return F.glu
98
+ raise RuntimeError(F"activation should be relu/gelu, not {activation}.")
99
+
100
+
101
+ class TransformerSALayer(nn.Module):
102
+ def __init__(self, embed_dim, nhead=8, dim_mlp=2048, dropout=0.0, activation="gelu"):
103
+ super().__init__()
104
+ self.self_attn = nn.MultiheadAttention(embed_dim, nhead, dropout=dropout)
105
+ # Implementation of Feedforward model - MLP
106
+ self.linear1 = nn.Linear(embed_dim, dim_mlp)
107
+ self.dropout = nn.Dropout(dropout)
108
+ self.linear2 = nn.Linear(dim_mlp, embed_dim)
109
+
110
+ self.norm1 = nn.LayerNorm(embed_dim)
111
+ self.norm2 = nn.LayerNorm(embed_dim)
112
+ self.dropout1 = nn.Dropout(dropout)
113
+ self.dropout2 = nn.Dropout(dropout)
114
+
115
+ self.activation = _get_activation_fn(activation)
116
+
117
+ def with_pos_embed(self, tensor, pos: Optional[Tensor]):
118
+ return tensor if pos is None else tensor + pos
119
+
120
+ def forward(self, tgt,
121
+ tgt_mask: Optional[Tensor] = None,
122
+ tgt_key_padding_mask: Optional[Tensor] = None,
123
+ query_pos: Optional[Tensor] = None):
124
+
125
+ # self attention
126
+ tgt2 = self.norm1(tgt)
127
+ q = k = self.with_pos_embed(tgt2, query_pos)
128
+ tgt2 = self.self_attn(q, k, value=tgt2, attn_mask=tgt_mask,
129
+ key_padding_mask=tgt_key_padding_mask)[0]
130
+ tgt = tgt + self.dropout1(tgt2)
131
+
132
+ # ffn
133
+ tgt2 = self.norm2(tgt)
134
+ tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2))))
135
+ tgt = tgt + self.dropout2(tgt2)
136
+ return tgt
137
+
138
+ class Fuse_sft_block(nn.Module):
139
+ def __init__(self, in_ch, out_ch):
140
+ super().__init__()
141
+ self.encode_enc = ResBlock(2*in_ch, out_ch)
142
+
143
+ self.scale = nn.Sequential(
144
+ nn.Conv2d(in_ch, out_ch, kernel_size=3, padding=1),
145
+ nn.LeakyReLU(0.2, True),
146
+ nn.Conv2d(out_ch, out_ch, kernel_size=3, padding=1))
147
+
148
+ self.shift = nn.Sequential(
149
+ nn.Conv2d(in_ch, out_ch, kernel_size=3, padding=1),
150
+ nn.LeakyReLU(0.2, True),
151
+ nn.Conv2d(out_ch, out_ch, kernel_size=3, padding=1))
152
+
153
+ def forward(self, enc_feat, dec_feat, w=1):
154
+ enc_feat = self.encode_enc(torch.cat([enc_feat, dec_feat], dim=1))
155
+ scale = self.scale(enc_feat)
156
+ shift = self.shift(enc_feat)
157
+ residual = w * (dec_feat * scale + shift)
158
+ out = dec_feat + residual
159
+ return out
160
+
161
+
162
+ @ARCH_REGISTRY.register()
163
+ class CodeFormer(VQAutoEncoder):
164
+ def __init__(self, dim_embd=512, n_head=8, n_layers=9,
165
+ codebook_size=1024, latent_size=256,
166
+ connect_list=['32', '64', '128', '256'],
167
+ fix_modules=['quantize','generator']):
168
+ super(CodeFormer, self).__init__(512, 64, [1, 2, 2, 4, 4, 8], 'nearest',2, [16], codebook_size)
169
+
170
+ if fix_modules is not None:
171
+ for module in fix_modules:
172
+ for param in getattr(self, module).parameters():
173
+ param.requires_grad = False
174
+
175
+ self.connect_list = connect_list
176
+ self.n_layers = n_layers
177
+ self.dim_embd = dim_embd
178
+ self.dim_mlp = dim_embd*2
179
+
180
+ self.position_emb = nn.Parameter(torch.zeros(latent_size, self.dim_embd))
181
+ self.feat_emb = nn.Linear(256, self.dim_embd)
182
+
183
+ # transformer
184
+ self.ft_layers = nn.Sequential(*[TransformerSALayer(embed_dim=dim_embd, nhead=n_head, dim_mlp=self.dim_mlp, dropout=0.0)
185
+ for _ in range(self.n_layers)])
186
+
187
+ # logits_predict head
188
+ self.idx_pred_layer = nn.Sequential(
189
+ nn.LayerNorm(dim_embd),
190
+ nn.Linear(dim_embd, codebook_size, bias=False))
191
+
192
+ self.channels = {
193
+ '16': 512,
194
+ '32': 256,
195
+ '64': 256,
196
+ '128': 128,
197
+ '256': 128,
198
+ '512': 64,
199
+ }
200
+
201
+ # after second residual block for > 16, before attn layer for ==16
202
+ self.fuse_encoder_block = {'512':2, '256':5, '128':8, '64':11, '32':14, '16':18}
203
+ # after first residual block for > 16, before attn layer for ==16
204
+ self.fuse_generator_block = {'16':6, '32': 9, '64':12, '128':15, '256':18, '512':21}
205
+
206
+ # fuse_convs_dict
207
+ self.fuse_convs_dict = nn.ModuleDict()
208
+ for f_size in self.connect_list:
209
+ in_ch = self.channels[f_size]
210
+ self.fuse_convs_dict[f_size] = Fuse_sft_block(in_ch, in_ch)
211
+
212
+ def _init_weights(self, module):
213
+ if isinstance(module, (nn.Linear, nn.Embedding)):
214
+ module.weight.data.normal_(mean=0.0, std=0.02)
215
+ if isinstance(module, nn.Linear) and module.bias is not None:
216
+ module.bias.data.zero_()
217
+ elif isinstance(module, nn.LayerNorm):
218
+ module.bias.data.zero_()
219
+ module.weight.data.fill_(1.0)
220
+
221
+ def forward(self, x, w=0, detach_16=True, code_only=False, adain=False):
222
+ # ################### Encoder #####################
223
+ enc_feat_dict = {}
224
+ out_list = [self.fuse_encoder_block[f_size] for f_size in self.connect_list]
225
+ for i, block in enumerate(self.encoder.blocks):
226
+ x = block(x)
227
+ if i in out_list:
228
+ enc_feat_dict[str(x.shape[-1])] = x.clone()
229
+
230
+ lq_feat = x
231
+ # ################# Transformer ###################
232
+ # quant_feat, codebook_loss, quant_stats = self.quantize(lq_feat)
233
+ pos_emb = self.position_emb.unsqueeze(1).repeat(1,x.shape[0],1)
234
+ # BCHW -> BC(HW) -> (HW)BC
235
+ feat_emb = self.feat_emb(lq_feat.flatten(2).permute(2,0,1))
236
+ query_emb = feat_emb
237
+ # Transformer encoder
238
+ for layer in self.ft_layers:
239
+ query_emb = layer(query_emb, query_pos=pos_emb)
240
+
241
+ # output logits
242
+ logits = self.idx_pred_layer(query_emb) # (hw)bn
243
+ logits = logits.permute(1,0,2) # (hw)bn -> b(hw)n
244
+
245
+ if code_only: # for training stage II
246
+ # logits doesn't need softmax before cross_entropy loss
247
+ return logits, lq_feat
248
+
249
+ # ################# Quantization ###################
250
+ # if self.training:
251
+ # quant_feat = torch.einsum('btn,nc->btc', [soft_one_hot, self.quantize.embedding.weight])
252
+ # # b(hw)c -> bc(hw) -> bchw
253
+ # quant_feat = quant_feat.permute(0,2,1).view(lq_feat.shape)
254
+ # ------------
255
+ soft_one_hot = F.softmax(logits, dim=2)
256
+ _, top_idx = torch.topk(soft_one_hot, 1, dim=2)
257
+ quant_feat = self.quantize.get_codebook_feat(top_idx, shape=[x.shape[0],16,16,256])
258
+ # preserve gradients
259
+ # quant_feat = lq_feat + (quant_feat - lq_feat).detach()
260
+
261
+ if detach_16:
262
+ quant_feat = quant_feat.detach() # for training stage III
263
+ if adain:
264
+ quant_feat = adaptive_instance_normalization(quant_feat, lq_feat)
265
+
266
+ # ################## Generator ####################
267
+ x = quant_feat
268
+ fuse_list = [self.fuse_generator_block[f_size] for f_size in self.connect_list]
269
+
270
+ for i, block in enumerate(self.generator.blocks):
271
+ x = block(x)
272
+ if i in fuse_list: # fuse after i-th block
273
+ f_size = str(x.shape[-1])
274
+ if w>0:
275
+ x = self.fuse_convs_dict[f_size](enc_feat_dict[f_size].detach(), x, w)
276
+ out = x
277
+ # logits doesn't need softmax before cross_entropy loss
278
+ return out, logits, lq_feat
stable-diffusion-webui-master/modules/codeformer/vqgan_arch.py ADDED
@@ -0,0 +1,437 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this file is copied from CodeFormer repository. Please see comment in modules/codeformer_model.py
2
+
3
+ '''
4
+ VQGAN code, adapted from the original created by the Unleashing Transformers authors:
5
+ https://github.com/samb-t/unleashing-transformers/blob/master/models/vqgan.py
6
+
7
+ '''
8
+ import numpy as np
9
+ import torch
10
+ import torch.nn as nn
11
+ import torch.nn.functional as F
12
+ import copy
13
+ from basicsr.utils import get_root_logger
14
+ from basicsr.utils.registry import ARCH_REGISTRY
15
+
16
+ def normalize(in_channels):
17
+ return torch.nn.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True)
18
+
19
+
20
+ @torch.jit.script
21
+ def swish(x):
22
+ return x*torch.sigmoid(x)
23
+
24
+
25
+ # Define VQVAE classes
26
+ class VectorQuantizer(nn.Module):
27
+ def __init__(self, codebook_size, emb_dim, beta):
28
+ super(VectorQuantizer, self).__init__()
29
+ self.codebook_size = codebook_size # number of embeddings
30
+ self.emb_dim = emb_dim # dimension of embedding
31
+ self.beta = beta # commitment cost used in loss term, beta * ||z_e(x)-sg[e]||^2
32
+ self.embedding = nn.Embedding(self.codebook_size, self.emb_dim)
33
+ self.embedding.weight.data.uniform_(-1.0 / self.codebook_size, 1.0 / self.codebook_size)
34
+
35
+ def forward(self, z):
36
+ # reshape z -> (batch, height, width, channel) and flatten
37
+ z = z.permute(0, 2, 3, 1).contiguous()
38
+ z_flattened = z.view(-1, self.emb_dim)
39
+
40
+ # distances from z to embeddings e_j (z - e)^2 = z^2 + e^2 - 2 e * z
41
+ d = (z_flattened ** 2).sum(dim=1, keepdim=True) + (self.embedding.weight**2).sum(1) - \
42
+ 2 * torch.matmul(z_flattened, self.embedding.weight.t())
43
+
44
+ mean_distance = torch.mean(d)
45
+ # find closest encodings
46
+ # min_encoding_indices = torch.argmin(d, dim=1).unsqueeze(1)
47
+ min_encoding_scores, min_encoding_indices = torch.topk(d, 1, dim=1, largest=False)
48
+ # [0-1], higher score, higher confidence
49
+ min_encoding_scores = torch.exp(-min_encoding_scores/10)
50
+
51
+ min_encodings = torch.zeros(min_encoding_indices.shape[0], self.codebook_size).to(z)
52
+ min_encodings.scatter_(1, min_encoding_indices, 1)
53
+
54
+ # get quantized latent vectors
55
+ z_q = torch.matmul(min_encodings, self.embedding.weight).view(z.shape)
56
+ # compute loss for embedding
57
+ loss = torch.mean((z_q.detach()-z)**2) + self.beta * torch.mean((z_q - z.detach()) ** 2)
58
+ # preserve gradients
59
+ z_q = z + (z_q - z).detach()
60
+
61
+ # perplexity
62
+ e_mean = torch.mean(min_encodings, dim=0)
63
+ perplexity = torch.exp(-torch.sum(e_mean * torch.log(e_mean + 1e-10)))
64
+ # reshape back to match original input shape
65
+ z_q = z_q.permute(0, 3, 1, 2).contiguous()
66
+
67
+ return z_q, loss, {
68
+ "perplexity": perplexity,
69
+ "min_encodings": min_encodings,
70
+ "min_encoding_indices": min_encoding_indices,
71
+ "min_encoding_scores": min_encoding_scores,
72
+ "mean_distance": mean_distance
73
+ }
74
+
75
+ def get_codebook_feat(self, indices, shape):
76
+ # input indices: batch*token_num -> (batch*token_num)*1
77
+ # shape: batch, height, width, channel
78
+ indices = indices.view(-1,1)
79
+ min_encodings = torch.zeros(indices.shape[0], self.codebook_size).to(indices)
80
+ min_encodings.scatter_(1, indices, 1)
81
+ # get quantized latent vectors
82
+ z_q = torch.matmul(min_encodings.float(), self.embedding.weight)
83
+
84
+ if shape is not None: # reshape back to match original input shape
85
+ z_q = z_q.view(shape).permute(0, 3, 1, 2).contiguous()
86
+
87
+ return z_q
88
+
89
+
90
+ class GumbelQuantizer(nn.Module):
91
+ def __init__(self, codebook_size, emb_dim, num_hiddens, straight_through=False, kl_weight=5e-4, temp_init=1.0):
92
+ super().__init__()
93
+ self.codebook_size = codebook_size # number of embeddings
94
+ self.emb_dim = emb_dim # dimension of embedding
95
+ self.straight_through = straight_through
96
+ self.temperature = temp_init
97
+ self.kl_weight = kl_weight
98
+ self.proj = nn.Conv2d(num_hiddens, codebook_size, 1) # projects last encoder layer to quantized logits
99
+ self.embed = nn.Embedding(codebook_size, emb_dim)
100
+
101
+ def forward(self, z):
102
+ hard = self.straight_through if self.training else True
103
+
104
+ logits = self.proj(z)
105
+
106
+ soft_one_hot = F.gumbel_softmax(logits, tau=self.temperature, dim=1, hard=hard)
107
+
108
+ z_q = torch.einsum("b n h w, n d -> b d h w", soft_one_hot, self.embed.weight)
109
+
110
+ # + kl divergence to the prior loss
111
+ qy = F.softmax(logits, dim=1)
112
+ diff = self.kl_weight * torch.sum(qy * torch.log(qy * self.codebook_size + 1e-10), dim=1).mean()
113
+ min_encoding_indices = soft_one_hot.argmax(dim=1)
114
+
115
+ return z_q, diff, {
116
+ "min_encoding_indices": min_encoding_indices
117
+ }
118
+
119
+
120
+ class Downsample(nn.Module):
121
+ def __init__(self, in_channels):
122
+ super().__init__()
123
+ self.conv = torch.nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=2, padding=0)
124
+
125
+ def forward(self, x):
126
+ pad = (0, 1, 0, 1)
127
+ x = torch.nn.functional.pad(x, pad, mode="constant", value=0)
128
+ x = self.conv(x)
129
+ return x
130
+
131
+
132
+ class Upsample(nn.Module):
133
+ def __init__(self, in_channels):
134
+ super().__init__()
135
+ self.conv = nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1)
136
+
137
+ def forward(self, x):
138
+ x = F.interpolate(x, scale_factor=2.0, mode="nearest")
139
+ x = self.conv(x)
140
+
141
+ return x
142
+
143
+
144
+ class ResBlock(nn.Module):
145
+ def __init__(self, in_channels, out_channels=None):
146
+ super(ResBlock, self).__init__()
147
+ self.in_channels = in_channels
148
+ self.out_channels = in_channels if out_channels is None else out_channels
149
+ self.norm1 = normalize(in_channels)
150
+ self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1)
151
+ self.norm2 = normalize(out_channels)
152
+ self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)
153
+ if self.in_channels != self.out_channels:
154
+ self.conv_out = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0)
155
+
156
+ def forward(self, x_in):
157
+ x = x_in
158
+ x = self.norm1(x)
159
+ x = swish(x)
160
+ x = self.conv1(x)
161
+ x = self.norm2(x)
162
+ x = swish(x)
163
+ x = self.conv2(x)
164
+ if self.in_channels != self.out_channels:
165
+ x_in = self.conv_out(x_in)
166
+
167
+ return x + x_in
168
+
169
+
170
+ class AttnBlock(nn.Module):
171
+ def __init__(self, in_channels):
172
+ super().__init__()
173
+ self.in_channels = in_channels
174
+
175
+ self.norm = normalize(in_channels)
176
+ self.q = torch.nn.Conv2d(
177
+ in_channels,
178
+ in_channels,
179
+ kernel_size=1,
180
+ stride=1,
181
+ padding=0
182
+ )
183
+ self.k = torch.nn.Conv2d(
184
+ in_channels,
185
+ in_channels,
186
+ kernel_size=1,
187
+ stride=1,
188
+ padding=0
189
+ )
190
+ self.v = torch.nn.Conv2d(
191
+ in_channels,
192
+ in_channels,
193
+ kernel_size=1,
194
+ stride=1,
195
+ padding=0
196
+ )
197
+ self.proj_out = torch.nn.Conv2d(
198
+ in_channels,
199
+ in_channels,
200
+ kernel_size=1,
201
+ stride=1,
202
+ padding=0
203
+ )
204
+
205
+ def forward(self, x):
206
+ h_ = x
207
+ h_ = self.norm(h_)
208
+ q = self.q(h_)
209
+ k = self.k(h_)
210
+ v = self.v(h_)
211
+
212
+ # compute attention
213
+ b, c, h, w = q.shape
214
+ q = q.reshape(b, c, h*w)
215
+ q = q.permute(0, 2, 1)
216
+ k = k.reshape(b, c, h*w)
217
+ w_ = torch.bmm(q, k)
218
+ w_ = w_ * (int(c)**(-0.5))
219
+ w_ = F.softmax(w_, dim=2)
220
+
221
+ # attend to values
222
+ v = v.reshape(b, c, h*w)
223
+ w_ = w_.permute(0, 2, 1)
224
+ h_ = torch.bmm(v, w_)
225
+ h_ = h_.reshape(b, c, h, w)
226
+
227
+ h_ = self.proj_out(h_)
228
+
229
+ return x+h_
230
+
231
+
232
+ class Encoder(nn.Module):
233
+ def __init__(self, in_channels, nf, emb_dim, ch_mult, num_res_blocks, resolution, attn_resolutions):
234
+ super().__init__()
235
+ self.nf = nf
236
+ self.num_resolutions = len(ch_mult)
237
+ self.num_res_blocks = num_res_blocks
238
+ self.resolution = resolution
239
+ self.attn_resolutions = attn_resolutions
240
+
241
+ curr_res = self.resolution
242
+ in_ch_mult = (1,)+tuple(ch_mult)
243
+
244
+ blocks = []
245
+ # initial convultion
246
+ blocks.append(nn.Conv2d(in_channels, nf, kernel_size=3, stride=1, padding=1))
247
+
248
+ # residual and downsampling blocks, with attention on smaller res (16x16)
249
+ for i in range(self.num_resolutions):
250
+ block_in_ch = nf * in_ch_mult[i]
251
+ block_out_ch = nf * ch_mult[i]
252
+ for _ in range(self.num_res_blocks):
253
+ blocks.append(ResBlock(block_in_ch, block_out_ch))
254
+ block_in_ch = block_out_ch
255
+ if curr_res in attn_resolutions:
256
+ blocks.append(AttnBlock(block_in_ch))
257
+
258
+ if i != self.num_resolutions - 1:
259
+ blocks.append(Downsample(block_in_ch))
260
+ curr_res = curr_res // 2
261
+
262
+ # non-local attention block
263
+ blocks.append(ResBlock(block_in_ch, block_in_ch))
264
+ blocks.append(AttnBlock(block_in_ch))
265
+ blocks.append(ResBlock(block_in_ch, block_in_ch))
266
+
267
+ # normalise and convert to latent size
268
+ blocks.append(normalize(block_in_ch))
269
+ blocks.append(nn.Conv2d(block_in_ch, emb_dim, kernel_size=3, stride=1, padding=1))
270
+ self.blocks = nn.ModuleList(blocks)
271
+
272
+ def forward(self, x):
273
+ for block in self.blocks:
274
+ x = block(x)
275
+
276
+ return x
277
+
278
+
279
+ class Generator(nn.Module):
280
+ def __init__(self, nf, emb_dim, ch_mult, res_blocks, img_size, attn_resolutions):
281
+ super().__init__()
282
+ self.nf = nf
283
+ self.ch_mult = ch_mult
284
+ self.num_resolutions = len(self.ch_mult)
285
+ self.num_res_blocks = res_blocks
286
+ self.resolution = img_size
287
+ self.attn_resolutions = attn_resolutions
288
+ self.in_channels = emb_dim
289
+ self.out_channels = 3
290
+ block_in_ch = self.nf * self.ch_mult[-1]
291
+ curr_res = self.resolution // 2 ** (self.num_resolutions-1)
292
+
293
+ blocks = []
294
+ # initial conv
295
+ blocks.append(nn.Conv2d(self.in_channels, block_in_ch, kernel_size=3, stride=1, padding=1))
296
+
297
+ # non-local attention block
298
+ blocks.append(ResBlock(block_in_ch, block_in_ch))
299
+ blocks.append(AttnBlock(block_in_ch))
300
+ blocks.append(ResBlock(block_in_ch, block_in_ch))
301
+
302
+ for i in reversed(range(self.num_resolutions)):
303
+ block_out_ch = self.nf * self.ch_mult[i]
304
+
305
+ for _ in range(self.num_res_blocks):
306
+ blocks.append(ResBlock(block_in_ch, block_out_ch))
307
+ block_in_ch = block_out_ch
308
+
309
+ if curr_res in self.attn_resolutions:
310
+ blocks.append(AttnBlock(block_in_ch))
311
+
312
+ if i != 0:
313
+ blocks.append(Upsample(block_in_ch))
314
+ curr_res = curr_res * 2
315
+
316
+ blocks.append(normalize(block_in_ch))
317
+ blocks.append(nn.Conv2d(block_in_ch, self.out_channels, kernel_size=3, stride=1, padding=1))
318
+
319
+ self.blocks = nn.ModuleList(blocks)
320
+
321
+
322
+ def forward(self, x):
323
+ for block in self.blocks:
324
+ x = block(x)
325
+
326
+ return x
327
+
328
+
329
+ @ARCH_REGISTRY.register()
330
+ class VQAutoEncoder(nn.Module):
331
+ def __init__(self, img_size, nf, ch_mult, quantizer="nearest", res_blocks=2, attn_resolutions=[16], codebook_size=1024, emb_dim=256,
332
+ beta=0.25, gumbel_straight_through=False, gumbel_kl_weight=1e-8, model_path=None):
333
+ super().__init__()
334
+ logger = get_root_logger()
335
+ self.in_channels = 3
336
+ self.nf = nf
337
+ self.n_blocks = res_blocks
338
+ self.codebook_size = codebook_size
339
+ self.embed_dim = emb_dim
340
+ self.ch_mult = ch_mult
341
+ self.resolution = img_size
342
+ self.attn_resolutions = attn_resolutions
343
+ self.quantizer_type = quantizer
344
+ self.encoder = Encoder(
345
+ self.in_channels,
346
+ self.nf,
347
+ self.embed_dim,
348
+ self.ch_mult,
349
+ self.n_blocks,
350
+ self.resolution,
351
+ self.attn_resolutions
352
+ )
353
+ if self.quantizer_type == "nearest":
354
+ self.beta = beta #0.25
355
+ self.quantize = VectorQuantizer(self.codebook_size, self.embed_dim, self.beta)
356
+ elif self.quantizer_type == "gumbel":
357
+ self.gumbel_num_hiddens = emb_dim
358
+ self.straight_through = gumbel_straight_through
359
+ self.kl_weight = gumbel_kl_weight
360
+ self.quantize = GumbelQuantizer(
361
+ self.codebook_size,
362
+ self.embed_dim,
363
+ self.gumbel_num_hiddens,
364
+ self.straight_through,
365
+ self.kl_weight
366
+ )
367
+ self.generator = Generator(
368
+ self.nf,
369
+ self.embed_dim,
370
+ self.ch_mult,
371
+ self.n_blocks,
372
+ self.resolution,
373
+ self.attn_resolutions
374
+ )
375
+
376
+ if model_path is not None:
377
+ chkpt = torch.load(model_path, map_location='cpu')
378
+ if 'params_ema' in chkpt:
379
+ self.load_state_dict(torch.load(model_path, map_location='cpu')['params_ema'])
380
+ logger.info(f'vqgan is loaded from: {model_path} [params_ema]')
381
+ elif 'params' in chkpt:
382
+ self.load_state_dict(torch.load(model_path, map_location='cpu')['params'])
383
+ logger.info(f'vqgan is loaded from: {model_path} [params]')
384
+ else:
385
+ raise ValueError(f'Wrong params!')
386
+
387
+
388
+ def forward(self, x):
389
+ x = self.encoder(x)
390
+ quant, codebook_loss, quant_stats = self.quantize(x)
391
+ x = self.generator(quant)
392
+ return x, codebook_loss, quant_stats
393
+
394
+
395
+
396
+ # patch based discriminator
397
+ @ARCH_REGISTRY.register()
398
+ class VQGANDiscriminator(nn.Module):
399
+ def __init__(self, nc=3, ndf=64, n_layers=4, model_path=None):
400
+ super().__init__()
401
+
402
+ layers = [nn.Conv2d(nc, ndf, kernel_size=4, stride=2, padding=1), nn.LeakyReLU(0.2, True)]
403
+ ndf_mult = 1
404
+ ndf_mult_prev = 1
405
+ for n in range(1, n_layers): # gradually increase the number of filters
406
+ ndf_mult_prev = ndf_mult
407
+ ndf_mult = min(2 ** n, 8)
408
+ layers += [
409
+ nn.Conv2d(ndf * ndf_mult_prev, ndf * ndf_mult, kernel_size=4, stride=2, padding=1, bias=False),
410
+ nn.BatchNorm2d(ndf * ndf_mult),
411
+ nn.LeakyReLU(0.2, True)
412
+ ]
413
+
414
+ ndf_mult_prev = ndf_mult
415
+ ndf_mult = min(2 ** n_layers, 8)
416
+
417
+ layers += [
418
+ nn.Conv2d(ndf * ndf_mult_prev, ndf * ndf_mult, kernel_size=4, stride=1, padding=1, bias=False),
419
+ nn.BatchNorm2d(ndf * ndf_mult),
420
+ nn.LeakyReLU(0.2, True)
421
+ ]
422
+
423
+ layers += [
424
+ nn.Conv2d(ndf * ndf_mult, 1, kernel_size=4, stride=1, padding=1)] # output 1 channel prediction map
425
+ self.main = nn.Sequential(*layers)
426
+
427
+ if model_path is not None:
428
+ chkpt = torch.load(model_path, map_location='cpu')
429
+ if 'params_d' in chkpt:
430
+ self.load_state_dict(torch.load(model_path, map_location='cpu')['params_d'])
431
+ elif 'params' in chkpt:
432
+ self.load_state_dict(torch.load(model_path, map_location='cpu')['params'])
433
+ else:
434
+ raise ValueError(f'Wrong params!')
435
+
436
+ def forward(self, x):
437
+ return self.main(x)
stable-diffusion-webui-master/modules/codeformer_model.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import traceback
4
+
5
+ import cv2
6
+ import torch
7
+
8
+ import modules.face_restoration
9
+ import modules.shared
10
+ from modules import shared, devices, modelloader
11
+ from modules.paths import script_path, models_path
12
+
13
+ # codeformer people made a choice to include modified basicsr library to their project which makes
14
+ # it utterly impossible to use it alongside with other libraries that also use basicsr, like GFPGAN.
15
+ # I am making a choice to include some files from codeformer to work around this issue.
16
+ model_dir = "Codeformer"
17
+ model_path = os.path.join(models_path, model_dir)
18
+ model_url = 'https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/codeformer.pth'
19
+
20
+ have_codeformer = False
21
+ codeformer = None
22
+
23
+
24
+ def setup_model(dirname):
25
+ global model_path
26
+ if not os.path.exists(model_path):
27
+ os.makedirs(model_path)
28
+
29
+ path = modules.paths.paths.get("CodeFormer", None)
30
+ if path is None:
31
+ return
32
+
33
+ try:
34
+ from torchvision.transforms.functional import normalize
35
+ from modules.codeformer.codeformer_arch import CodeFormer
36
+ from basicsr.utils.download_util import load_file_from_url
37
+ from basicsr.utils import imwrite, img2tensor, tensor2img
38
+ from facelib.utils.face_restoration_helper import FaceRestoreHelper
39
+ from facelib.detection.retinaface import retinaface
40
+ from modules.shared import cmd_opts
41
+
42
+ net_class = CodeFormer
43
+
44
+ class FaceRestorerCodeFormer(modules.face_restoration.FaceRestoration):
45
+ def name(self):
46
+ return "CodeFormer"
47
+
48
+ def __init__(self, dirname):
49
+ self.net = None
50
+ self.face_helper = None
51
+ self.cmd_dir = dirname
52
+
53
+ def create_models(self):
54
+
55
+ if self.net is not None and self.face_helper is not None:
56
+ self.net.to(devices.device_codeformer)
57
+ return self.net, self.face_helper
58
+ model_paths = modelloader.load_models(model_path, model_url, self.cmd_dir, download_name='codeformer-v0.1.0.pth')
59
+ if len(model_paths) != 0:
60
+ ckpt_path = model_paths[0]
61
+ else:
62
+ print("Unable to load codeformer model.")
63
+ return None, None
64
+ net = net_class(dim_embd=512, codebook_size=1024, n_head=8, n_layers=9, connect_list=['32', '64', '128', '256']).to(devices.device_codeformer)
65
+ checkpoint = torch.load(ckpt_path)['params_ema']
66
+ net.load_state_dict(checkpoint)
67
+ net.eval()
68
+
69
+ if hasattr(retinaface, 'device'):
70
+ retinaface.device = devices.device_codeformer
71
+ 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)
72
+
73
+ self.net = net
74
+ self.face_helper = face_helper
75
+
76
+ return net, face_helper
77
+
78
+ def send_model_to(self, device):
79
+ self.net.to(device)
80
+ self.face_helper.face_det.to(device)
81
+ self.face_helper.face_parse.to(device)
82
+
83
+ def restore(self, np_image, w=None):
84
+ np_image = np_image[:, :, ::-1]
85
+
86
+ original_resolution = np_image.shape[0:2]
87
+
88
+ self.create_models()
89
+ if self.net is None or self.face_helper is None:
90
+ return np_image
91
+
92
+ self.send_model_to(devices.device_codeformer)
93
+
94
+ self.face_helper.clean_all()
95
+ self.face_helper.read_image(np_image)
96
+ self.face_helper.get_face_landmarks_5(only_center_face=False, resize=640, eye_dist_threshold=5)
97
+ self.face_helper.align_warp_face()
98
+
99
+ for idx, cropped_face in enumerate(self.face_helper.cropped_faces):
100
+ cropped_face_t = img2tensor(cropped_face / 255., bgr2rgb=True, float32=True)
101
+ normalize(cropped_face_t, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
102
+ cropped_face_t = cropped_face_t.unsqueeze(0).to(devices.device_codeformer)
103
+
104
+ try:
105
+ with torch.no_grad():
106
+ output = self.net(cropped_face_t, w=w if w is not None else shared.opts.code_former_weight, adain=True)[0]
107
+ restored_face = tensor2img(output, rgb2bgr=True, min_max=(-1, 1))
108
+ del output
109
+ torch.cuda.empty_cache()
110
+ except Exception as error:
111
+ print(f'\tFailed inference for CodeFormer: {error}', file=sys.stderr)
112
+ restored_face = tensor2img(cropped_face_t, rgb2bgr=True, min_max=(-1, 1))
113
+
114
+ restored_face = restored_face.astype('uint8')
115
+ self.face_helper.add_restored_face(restored_face)
116
+
117
+ self.face_helper.get_inverse_affine(None)
118
+
119
+ restored_img = self.face_helper.paste_faces_to_input_image()
120
+ restored_img = restored_img[:, :, ::-1]
121
+
122
+ if original_resolution != restored_img.shape[0:2]:
123
+ restored_img = cv2.resize(restored_img, (0, 0), fx=original_resolution[1]/restored_img.shape[1], fy=original_resolution[0]/restored_img.shape[0], interpolation=cv2.INTER_LINEAR)
124
+
125
+ self.face_helper.clean_all()
126
+
127
+ if shared.opts.face_restoration_unload:
128
+ self.send_model_to(devices.cpu)
129
+
130
+ return restored_img
131
+
132
+ global have_codeformer
133
+ have_codeformer = True
134
+
135
+ global codeformer
136
+ codeformer = FaceRestorerCodeFormer(dirname)
137
+ shared.face_restorers.append(codeformer)
138
+
139
+ except Exception:
140
+ print("Error setting up CodeFormer:", file=sys.stderr)
141
+ print(traceback.format_exc(), file=sys.stderr)
142
+
143
+ # sys.path = stored_sys_path
stable-diffusion-webui-master/modules/deepbooru.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+
4
+ import torch
5
+ from PIL import Image
6
+ import numpy as np
7
+
8
+ from modules import modelloader, paths, deepbooru_model, devices, images, shared
9
+
10
+ re_special = re.compile(r'([\\()])')
11
+
12
+
13
+ class DeepDanbooru:
14
+ def __init__(self):
15
+ self.model = None
16
+
17
+ def load(self):
18
+ if self.model is not None:
19
+ return
20
+
21
+ files = modelloader.load_models(
22
+ model_path=os.path.join(paths.models_path, "torch_deepdanbooru"),
23
+ model_url='https://github.com/AUTOMATIC1111/TorchDeepDanbooru/releases/download/v1/model-resnet_custom_v3.pt',
24
+ ext_filter=".pt",
25
+ download_name='model-resnet_custom_v3.pt',
26
+ )
27
+
28
+ self.model = deepbooru_model.DeepDanbooruModel()
29
+ self.model.load_state_dict(torch.load(files[0], map_location="cpu"))
30
+
31
+ self.model.eval()
32
+ self.model.to(devices.cpu, devices.dtype)
33
+
34
+ def start(self):
35
+ self.load()
36
+ self.model.to(devices.device)
37
+
38
+ def stop(self):
39
+ if not shared.opts.interrogate_keep_models_in_memory:
40
+ self.model.to(devices.cpu)
41
+ devices.torch_gc()
42
+
43
+ def tag(self, pil_image):
44
+ self.start()
45
+ res = self.tag_multi(pil_image)
46
+ self.stop()
47
+
48
+ return res
49
+
50
+ def tag_multi(self, pil_image, force_disable_ranks=False):
51
+ threshold = shared.opts.interrogate_deepbooru_score_threshold
52
+ use_spaces = shared.opts.deepbooru_use_spaces
53
+ use_escape = shared.opts.deepbooru_escape
54
+ alpha_sort = shared.opts.deepbooru_sort_alpha
55
+ include_ranks = shared.opts.interrogate_return_ranks and not force_disable_ranks
56
+
57
+ pic = images.resize_image(2, pil_image.convert("RGB"), 512, 512)
58
+ a = np.expand_dims(np.array(pic, dtype=np.float32), 0) / 255
59
+
60
+ with torch.no_grad(), devices.autocast():
61
+ x = torch.from_numpy(a).to(devices.device)
62
+ y = self.model(x)[0].detach().cpu().numpy()
63
+
64
+ probability_dict = {}
65
+
66
+ for tag, probability in zip(self.model.tags, y):
67
+ if probability < threshold:
68
+ continue
69
+
70
+ if tag.startswith("rating:"):
71
+ continue
72
+
73
+ probability_dict[tag] = probability
74
+
75
+ if alpha_sort:
76
+ tags = sorted(probability_dict)
77
+ else:
78
+ tags = [tag for tag, _ in sorted(probability_dict.items(), key=lambda x: -x[1])]
79
+
80
+ res = []
81
+
82
+ for tag in tags:
83
+ probability = probability_dict[tag]
84
+ tag_outformat = tag
85
+ if use_spaces:
86
+ tag_outformat = tag_outformat.replace('_', ' ')
87
+ if use_escape:
88
+ tag_outformat = re.sub(re_special, r'\\\1', tag_outformat)
89
+ if include_ranks:
90
+ tag_outformat = f"({tag_outformat}:{probability:.3f})"
91
+
92
+ res.append(tag_outformat)
93
+
94
+ return ", ".join(res)
95
+
96
+
97
+ model = DeepDanbooru()
stable-diffusion-webui-master/modules/deepbooru_model.py ADDED
@@ -0,0 +1,676 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+
5
+ # see https://github.com/AUTOMATIC1111/TorchDeepDanbooru for more
6
+
7
+
8
+ class DeepDanbooruModel(nn.Module):
9
+ def __init__(self):
10
+ super(DeepDanbooruModel, self).__init__()
11
+
12
+ self.tags = []
13
+
14
+ self.n_Conv_0 = nn.Conv2d(kernel_size=(7, 7), in_channels=3, out_channels=64, stride=(2, 2))
15
+ self.n_MaxPool_0 = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2))
16
+ self.n_Conv_1 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
17
+ self.n_Conv_2 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=64)
18
+ self.n_Conv_3 = nn.Conv2d(kernel_size=(3, 3), in_channels=64, out_channels=64)
19
+ self.n_Conv_4 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
20
+ self.n_Conv_5 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=64)
21
+ self.n_Conv_6 = nn.Conv2d(kernel_size=(3, 3), in_channels=64, out_channels=64)
22
+ self.n_Conv_7 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
23
+ self.n_Conv_8 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=64)
24
+ self.n_Conv_9 = nn.Conv2d(kernel_size=(3, 3), in_channels=64, out_channels=64)
25
+ self.n_Conv_10 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
26
+ self.n_Conv_11 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=512, stride=(2, 2))
27
+ self.n_Conv_12 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=128)
28
+ self.n_Conv_13 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128, stride=(2, 2))
29
+ self.n_Conv_14 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
30
+ self.n_Conv_15 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
31
+ self.n_Conv_16 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
32
+ self.n_Conv_17 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
33
+ self.n_Conv_18 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
34
+ self.n_Conv_19 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
35
+ self.n_Conv_20 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
36
+ self.n_Conv_21 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
37
+ self.n_Conv_22 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
38
+ self.n_Conv_23 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
39
+ self.n_Conv_24 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
40
+ self.n_Conv_25 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
41
+ self.n_Conv_26 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
42
+ self.n_Conv_27 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
43
+ self.n_Conv_28 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
44
+ self.n_Conv_29 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
45
+ self.n_Conv_30 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
46
+ self.n_Conv_31 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
47
+ self.n_Conv_32 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
48
+ self.n_Conv_33 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
49
+ self.n_Conv_34 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
50
+ self.n_Conv_35 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
51
+ self.n_Conv_36 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=1024, stride=(2, 2))
52
+ self.n_Conv_37 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=256)
53
+ self.n_Conv_38 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256, stride=(2, 2))
54
+ self.n_Conv_39 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
55
+ self.n_Conv_40 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
56
+ self.n_Conv_41 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
57
+ self.n_Conv_42 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
58
+ self.n_Conv_43 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
59
+ self.n_Conv_44 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
60
+ self.n_Conv_45 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
61
+ self.n_Conv_46 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
62
+ self.n_Conv_47 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
63
+ self.n_Conv_48 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
64
+ self.n_Conv_49 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
65
+ self.n_Conv_50 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
66
+ self.n_Conv_51 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
67
+ self.n_Conv_52 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
68
+ self.n_Conv_53 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
69
+ self.n_Conv_54 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
70
+ self.n_Conv_55 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
71
+ self.n_Conv_56 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
72
+ self.n_Conv_57 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
73
+ self.n_Conv_58 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
74
+ self.n_Conv_59 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
75
+ self.n_Conv_60 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
76
+ self.n_Conv_61 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
77
+ self.n_Conv_62 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
78
+ self.n_Conv_63 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
79
+ self.n_Conv_64 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
80
+ self.n_Conv_65 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
81
+ self.n_Conv_66 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
82
+ self.n_Conv_67 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
83
+ self.n_Conv_68 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
84
+ self.n_Conv_69 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
85
+ self.n_Conv_70 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
86
+ self.n_Conv_71 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
87
+ self.n_Conv_72 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
88
+ self.n_Conv_73 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
89
+ self.n_Conv_74 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
90
+ self.n_Conv_75 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
91
+ self.n_Conv_76 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
92
+ self.n_Conv_77 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
93
+ self.n_Conv_78 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
94
+ self.n_Conv_79 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
95
+ self.n_Conv_80 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
96
+ self.n_Conv_81 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
97
+ self.n_Conv_82 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
98
+ self.n_Conv_83 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
99
+ self.n_Conv_84 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
100
+ self.n_Conv_85 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
101
+ self.n_Conv_86 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
102
+ self.n_Conv_87 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
103
+ self.n_Conv_88 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
104
+ self.n_Conv_89 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
105
+ self.n_Conv_90 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
106
+ self.n_Conv_91 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
107
+ self.n_Conv_92 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
108
+ self.n_Conv_93 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
109
+ self.n_Conv_94 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
110
+ self.n_Conv_95 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
111
+ self.n_Conv_96 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
112
+ self.n_Conv_97 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
113
+ self.n_Conv_98 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256, stride=(2, 2))
114
+ self.n_Conv_99 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
115
+ self.n_Conv_100 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=1024, stride=(2, 2))
116
+ self.n_Conv_101 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
117
+ self.n_Conv_102 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
118
+ self.n_Conv_103 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
119
+ self.n_Conv_104 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
120
+ self.n_Conv_105 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
121
+ self.n_Conv_106 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
122
+ self.n_Conv_107 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
123
+ self.n_Conv_108 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
124
+ self.n_Conv_109 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
125
+ self.n_Conv_110 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
126
+ self.n_Conv_111 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
127
+ self.n_Conv_112 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
128
+ self.n_Conv_113 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
129
+ self.n_Conv_114 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
130
+ self.n_Conv_115 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
131
+ self.n_Conv_116 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
132
+ self.n_Conv_117 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
133
+ self.n_Conv_118 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
134
+ self.n_Conv_119 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
135
+ self.n_Conv_120 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
136
+ self.n_Conv_121 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
137
+ self.n_Conv_122 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
138
+ self.n_Conv_123 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
139
+ self.n_Conv_124 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
140
+ self.n_Conv_125 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
141
+ self.n_Conv_126 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
142
+ self.n_Conv_127 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
143
+ self.n_Conv_128 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
144
+ self.n_Conv_129 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
145
+ self.n_Conv_130 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
146
+ self.n_Conv_131 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
147
+ self.n_Conv_132 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
148
+ self.n_Conv_133 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
149
+ self.n_Conv_134 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
150
+ self.n_Conv_135 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
151
+ self.n_Conv_136 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
152
+ self.n_Conv_137 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
153
+ self.n_Conv_138 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
154
+ self.n_Conv_139 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
155
+ self.n_Conv_140 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
156
+ self.n_Conv_141 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
157
+ self.n_Conv_142 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
158
+ self.n_Conv_143 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
159
+ self.n_Conv_144 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
160
+ self.n_Conv_145 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
161
+ self.n_Conv_146 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
162
+ self.n_Conv_147 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
163
+ self.n_Conv_148 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
164
+ self.n_Conv_149 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
165
+ self.n_Conv_150 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
166
+ self.n_Conv_151 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
167
+ self.n_Conv_152 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
168
+ self.n_Conv_153 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
169
+ self.n_Conv_154 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
170
+ self.n_Conv_155 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
171
+ self.n_Conv_156 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
172
+ self.n_Conv_157 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
173
+ self.n_Conv_158 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=2048, stride=(2, 2))
174
+ self.n_Conv_159 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=512)
175
+ self.n_Conv_160 = nn.Conv2d(kernel_size=(3, 3), in_channels=512, out_channels=512, stride=(2, 2))
176
+ self.n_Conv_161 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=2048)
177
+ self.n_Conv_162 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=512)
178
+ self.n_Conv_163 = nn.Conv2d(kernel_size=(3, 3), in_channels=512, out_channels=512)
179
+ self.n_Conv_164 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=2048)
180
+ self.n_Conv_165 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=512)
181
+ self.n_Conv_166 = nn.Conv2d(kernel_size=(3, 3), in_channels=512, out_channels=512)
182
+ self.n_Conv_167 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=2048)
183
+ self.n_Conv_168 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=4096, stride=(2, 2))
184
+ self.n_Conv_169 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=1024)
185
+ self.n_Conv_170 = nn.Conv2d(kernel_size=(3, 3), in_channels=1024, out_channels=1024, stride=(2, 2))
186
+ self.n_Conv_171 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=4096)
187
+ self.n_Conv_172 = nn.Conv2d(kernel_size=(1, 1), in_channels=4096, out_channels=1024)
188
+ self.n_Conv_173 = nn.Conv2d(kernel_size=(3, 3), in_channels=1024, out_channels=1024)
189
+ self.n_Conv_174 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=4096)
190
+ self.n_Conv_175 = nn.Conv2d(kernel_size=(1, 1), in_channels=4096, out_channels=1024)
191
+ self.n_Conv_176 = nn.Conv2d(kernel_size=(3, 3), in_channels=1024, out_channels=1024)
192
+ self.n_Conv_177 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=4096)
193
+ self.n_Conv_178 = nn.Conv2d(kernel_size=(1, 1), in_channels=4096, out_channels=9176, bias=False)
194
+
195
+ def forward(self, *inputs):
196
+ t_358, = inputs
197
+ t_359 = t_358.permute(*[0, 3, 1, 2])
198
+ t_359_padded = F.pad(t_359, [2, 3, 2, 3], value=0)
199
+ t_360 = self.n_Conv_0(t_359_padded)
200
+ t_361 = F.relu(t_360)
201
+ t_361 = F.pad(t_361, [0, 1, 0, 1], value=float('-inf'))
202
+ t_362 = self.n_MaxPool_0(t_361)
203
+ t_363 = self.n_Conv_1(t_362)
204
+ t_364 = self.n_Conv_2(t_362)
205
+ t_365 = F.relu(t_364)
206
+ t_365_padded = F.pad(t_365, [1, 1, 1, 1], value=0)
207
+ t_366 = self.n_Conv_3(t_365_padded)
208
+ t_367 = F.relu(t_366)
209
+ t_368 = self.n_Conv_4(t_367)
210
+ t_369 = torch.add(t_368, t_363)
211
+ t_370 = F.relu(t_369)
212
+ t_371 = self.n_Conv_5(t_370)
213
+ t_372 = F.relu(t_371)
214
+ t_372_padded = F.pad(t_372, [1, 1, 1, 1], value=0)
215
+ t_373 = self.n_Conv_6(t_372_padded)
216
+ t_374 = F.relu(t_373)
217
+ t_375 = self.n_Conv_7(t_374)
218
+ t_376 = torch.add(t_375, t_370)
219
+ t_377 = F.relu(t_376)
220
+ t_378 = self.n_Conv_8(t_377)
221
+ t_379 = F.relu(t_378)
222
+ t_379_padded = F.pad(t_379, [1, 1, 1, 1], value=0)
223
+ t_380 = self.n_Conv_9(t_379_padded)
224
+ t_381 = F.relu(t_380)
225
+ t_382 = self.n_Conv_10(t_381)
226
+ t_383 = torch.add(t_382, t_377)
227
+ t_384 = F.relu(t_383)
228
+ t_385 = self.n_Conv_11(t_384)
229
+ t_386 = self.n_Conv_12(t_384)
230
+ t_387 = F.relu(t_386)
231
+ t_387_padded = F.pad(t_387, [0, 1, 0, 1], value=0)
232
+ t_388 = self.n_Conv_13(t_387_padded)
233
+ t_389 = F.relu(t_388)
234
+ t_390 = self.n_Conv_14(t_389)
235
+ t_391 = torch.add(t_390, t_385)
236
+ t_392 = F.relu(t_391)
237
+ t_393 = self.n_Conv_15(t_392)
238
+ t_394 = F.relu(t_393)
239
+ t_394_padded = F.pad(t_394, [1, 1, 1, 1], value=0)
240
+ t_395 = self.n_Conv_16(t_394_padded)
241
+ t_396 = F.relu(t_395)
242
+ t_397 = self.n_Conv_17(t_396)
243
+ t_398 = torch.add(t_397, t_392)
244
+ t_399 = F.relu(t_398)
245
+ t_400 = self.n_Conv_18(t_399)
246
+ t_401 = F.relu(t_400)
247
+ t_401_padded = F.pad(t_401, [1, 1, 1, 1], value=0)
248
+ t_402 = self.n_Conv_19(t_401_padded)
249
+ t_403 = F.relu(t_402)
250
+ t_404 = self.n_Conv_20(t_403)
251
+ t_405 = torch.add(t_404, t_399)
252
+ t_406 = F.relu(t_405)
253
+ t_407 = self.n_Conv_21(t_406)
254
+ t_408 = F.relu(t_407)
255
+ t_408_padded = F.pad(t_408, [1, 1, 1, 1], value=0)
256
+ t_409 = self.n_Conv_22(t_408_padded)
257
+ t_410 = F.relu(t_409)
258
+ t_411 = self.n_Conv_23(t_410)
259
+ t_412 = torch.add(t_411, t_406)
260
+ t_413 = F.relu(t_412)
261
+ t_414 = self.n_Conv_24(t_413)
262
+ t_415 = F.relu(t_414)
263
+ t_415_padded = F.pad(t_415, [1, 1, 1, 1], value=0)
264
+ t_416 = self.n_Conv_25(t_415_padded)
265
+ t_417 = F.relu(t_416)
266
+ t_418 = self.n_Conv_26(t_417)
267
+ t_419 = torch.add(t_418, t_413)
268
+ t_420 = F.relu(t_419)
269
+ t_421 = self.n_Conv_27(t_420)
270
+ t_422 = F.relu(t_421)
271
+ t_422_padded = F.pad(t_422, [1, 1, 1, 1], value=0)
272
+ t_423 = self.n_Conv_28(t_422_padded)
273
+ t_424 = F.relu(t_423)
274
+ t_425 = self.n_Conv_29(t_424)
275
+ t_426 = torch.add(t_425, t_420)
276
+ t_427 = F.relu(t_426)
277
+ t_428 = self.n_Conv_30(t_427)
278
+ t_429 = F.relu(t_428)
279
+ t_429_padded = F.pad(t_429, [1, 1, 1, 1], value=0)
280
+ t_430 = self.n_Conv_31(t_429_padded)
281
+ t_431 = F.relu(t_430)
282
+ t_432 = self.n_Conv_32(t_431)
283
+ t_433 = torch.add(t_432, t_427)
284
+ t_434 = F.relu(t_433)
285
+ t_435 = self.n_Conv_33(t_434)
286
+ t_436 = F.relu(t_435)
287
+ t_436_padded = F.pad(t_436, [1, 1, 1, 1], value=0)
288
+ t_437 = self.n_Conv_34(t_436_padded)
289
+ t_438 = F.relu(t_437)
290
+ t_439 = self.n_Conv_35(t_438)
291
+ t_440 = torch.add(t_439, t_434)
292
+ t_441 = F.relu(t_440)
293
+ t_442 = self.n_Conv_36(t_441)
294
+ t_443 = self.n_Conv_37(t_441)
295
+ t_444 = F.relu(t_443)
296
+ t_444_padded = F.pad(t_444, [0, 1, 0, 1], value=0)
297
+ t_445 = self.n_Conv_38(t_444_padded)
298
+ t_446 = F.relu(t_445)
299
+ t_447 = self.n_Conv_39(t_446)
300
+ t_448 = torch.add(t_447, t_442)
301
+ t_449 = F.relu(t_448)
302
+ t_450 = self.n_Conv_40(t_449)
303
+ t_451 = F.relu(t_450)
304
+ t_451_padded = F.pad(t_451, [1, 1, 1, 1], value=0)
305
+ t_452 = self.n_Conv_41(t_451_padded)
306
+ t_453 = F.relu(t_452)
307
+ t_454 = self.n_Conv_42(t_453)
308
+ t_455 = torch.add(t_454, t_449)
309
+ t_456 = F.relu(t_455)
310
+ t_457 = self.n_Conv_43(t_456)
311
+ t_458 = F.relu(t_457)
312
+ t_458_padded = F.pad(t_458, [1, 1, 1, 1], value=0)
313
+ t_459 = self.n_Conv_44(t_458_padded)
314
+ t_460 = F.relu(t_459)
315
+ t_461 = self.n_Conv_45(t_460)
316
+ t_462 = torch.add(t_461, t_456)
317
+ t_463 = F.relu(t_462)
318
+ t_464 = self.n_Conv_46(t_463)
319
+ t_465 = F.relu(t_464)
320
+ t_465_padded = F.pad(t_465, [1, 1, 1, 1], value=0)
321
+ t_466 = self.n_Conv_47(t_465_padded)
322
+ t_467 = F.relu(t_466)
323
+ t_468 = self.n_Conv_48(t_467)
324
+ t_469 = torch.add(t_468, t_463)
325
+ t_470 = F.relu(t_469)
326
+ t_471 = self.n_Conv_49(t_470)
327
+ t_472 = F.relu(t_471)
328
+ t_472_padded = F.pad(t_472, [1, 1, 1, 1], value=0)
329
+ t_473 = self.n_Conv_50(t_472_padded)
330
+ t_474 = F.relu(t_473)
331
+ t_475 = self.n_Conv_51(t_474)
332
+ t_476 = torch.add(t_475, t_470)
333
+ t_477 = F.relu(t_476)
334
+ t_478 = self.n_Conv_52(t_477)
335
+ t_479 = F.relu(t_478)
336
+ t_479_padded = F.pad(t_479, [1, 1, 1, 1], value=0)
337
+ t_480 = self.n_Conv_53(t_479_padded)
338
+ t_481 = F.relu(t_480)
339
+ t_482 = self.n_Conv_54(t_481)
340
+ t_483 = torch.add(t_482, t_477)
341
+ t_484 = F.relu(t_483)
342
+ t_485 = self.n_Conv_55(t_484)
343
+ t_486 = F.relu(t_485)
344
+ t_486_padded = F.pad(t_486, [1, 1, 1, 1], value=0)
345
+ t_487 = self.n_Conv_56(t_486_padded)
346
+ t_488 = F.relu(t_487)
347
+ t_489 = self.n_Conv_57(t_488)
348
+ t_490 = torch.add(t_489, t_484)
349
+ t_491 = F.relu(t_490)
350
+ t_492 = self.n_Conv_58(t_491)
351
+ t_493 = F.relu(t_492)
352
+ t_493_padded = F.pad(t_493, [1, 1, 1, 1], value=0)
353
+ t_494 = self.n_Conv_59(t_493_padded)
354
+ t_495 = F.relu(t_494)
355
+ t_496 = self.n_Conv_60(t_495)
356
+ t_497 = torch.add(t_496, t_491)
357
+ t_498 = F.relu(t_497)
358
+ t_499 = self.n_Conv_61(t_498)
359
+ t_500 = F.relu(t_499)
360
+ t_500_padded = F.pad(t_500, [1, 1, 1, 1], value=0)
361
+ t_501 = self.n_Conv_62(t_500_padded)
362
+ t_502 = F.relu(t_501)
363
+ t_503 = self.n_Conv_63(t_502)
364
+ t_504 = torch.add(t_503, t_498)
365
+ t_505 = F.relu(t_504)
366
+ t_506 = self.n_Conv_64(t_505)
367
+ t_507 = F.relu(t_506)
368
+ t_507_padded = F.pad(t_507, [1, 1, 1, 1], value=0)
369
+ t_508 = self.n_Conv_65(t_507_padded)
370
+ t_509 = F.relu(t_508)
371
+ t_510 = self.n_Conv_66(t_509)
372
+ t_511 = torch.add(t_510, t_505)
373
+ t_512 = F.relu(t_511)
374
+ t_513 = self.n_Conv_67(t_512)
375
+ t_514 = F.relu(t_513)
376
+ t_514_padded = F.pad(t_514, [1, 1, 1, 1], value=0)
377
+ t_515 = self.n_Conv_68(t_514_padded)
378
+ t_516 = F.relu(t_515)
379
+ t_517 = self.n_Conv_69(t_516)
380
+ t_518 = torch.add(t_517, t_512)
381
+ t_519 = F.relu(t_518)
382
+ t_520 = self.n_Conv_70(t_519)
383
+ t_521 = F.relu(t_520)
384
+ t_521_padded = F.pad(t_521, [1, 1, 1, 1], value=0)
385
+ t_522 = self.n_Conv_71(t_521_padded)
386
+ t_523 = F.relu(t_522)
387
+ t_524 = self.n_Conv_72(t_523)
388
+ t_525 = torch.add(t_524, t_519)
389
+ t_526 = F.relu(t_525)
390
+ t_527 = self.n_Conv_73(t_526)
391
+ t_528 = F.relu(t_527)
392
+ t_528_padded = F.pad(t_528, [1, 1, 1, 1], value=0)
393
+ t_529 = self.n_Conv_74(t_528_padded)
394
+ t_530 = F.relu(t_529)
395
+ t_531 = self.n_Conv_75(t_530)
396
+ t_532 = torch.add(t_531, t_526)
397
+ t_533 = F.relu(t_532)
398
+ t_534 = self.n_Conv_76(t_533)
399
+ t_535 = F.relu(t_534)
400
+ t_535_padded = F.pad(t_535, [1, 1, 1, 1], value=0)
401
+ t_536 = self.n_Conv_77(t_535_padded)
402
+ t_537 = F.relu(t_536)
403
+ t_538 = self.n_Conv_78(t_537)
404
+ t_539 = torch.add(t_538, t_533)
405
+ t_540 = F.relu(t_539)
406
+ t_541 = self.n_Conv_79(t_540)
407
+ t_542 = F.relu(t_541)
408
+ t_542_padded = F.pad(t_542, [1, 1, 1, 1], value=0)
409
+ t_543 = self.n_Conv_80(t_542_padded)
410
+ t_544 = F.relu(t_543)
411
+ t_545 = self.n_Conv_81(t_544)
412
+ t_546 = torch.add(t_545, t_540)
413
+ t_547 = F.relu(t_546)
414
+ t_548 = self.n_Conv_82(t_547)
415
+ t_549 = F.relu(t_548)
416
+ t_549_padded = F.pad(t_549, [1, 1, 1, 1], value=0)
417
+ t_550 = self.n_Conv_83(t_549_padded)
418
+ t_551 = F.relu(t_550)
419
+ t_552 = self.n_Conv_84(t_551)
420
+ t_553 = torch.add(t_552, t_547)
421
+ t_554 = F.relu(t_553)
422
+ t_555 = self.n_Conv_85(t_554)
423
+ t_556 = F.relu(t_555)
424
+ t_556_padded = F.pad(t_556, [1, 1, 1, 1], value=0)
425
+ t_557 = self.n_Conv_86(t_556_padded)
426
+ t_558 = F.relu(t_557)
427
+ t_559 = self.n_Conv_87(t_558)
428
+ t_560 = torch.add(t_559, t_554)
429
+ t_561 = F.relu(t_560)
430
+ t_562 = self.n_Conv_88(t_561)
431
+ t_563 = F.relu(t_562)
432
+ t_563_padded = F.pad(t_563, [1, 1, 1, 1], value=0)
433
+ t_564 = self.n_Conv_89(t_563_padded)
434
+ t_565 = F.relu(t_564)
435
+ t_566 = self.n_Conv_90(t_565)
436
+ t_567 = torch.add(t_566, t_561)
437
+ t_568 = F.relu(t_567)
438
+ t_569 = self.n_Conv_91(t_568)
439
+ t_570 = F.relu(t_569)
440
+ t_570_padded = F.pad(t_570, [1, 1, 1, 1], value=0)
441
+ t_571 = self.n_Conv_92(t_570_padded)
442
+ t_572 = F.relu(t_571)
443
+ t_573 = self.n_Conv_93(t_572)
444
+ t_574 = torch.add(t_573, t_568)
445
+ t_575 = F.relu(t_574)
446
+ t_576 = self.n_Conv_94(t_575)
447
+ t_577 = F.relu(t_576)
448
+ t_577_padded = F.pad(t_577, [1, 1, 1, 1], value=0)
449
+ t_578 = self.n_Conv_95(t_577_padded)
450
+ t_579 = F.relu(t_578)
451
+ t_580 = self.n_Conv_96(t_579)
452
+ t_581 = torch.add(t_580, t_575)
453
+ t_582 = F.relu(t_581)
454
+ t_583 = self.n_Conv_97(t_582)
455
+ t_584 = F.relu(t_583)
456
+ t_584_padded = F.pad(t_584, [0, 1, 0, 1], value=0)
457
+ t_585 = self.n_Conv_98(t_584_padded)
458
+ t_586 = F.relu(t_585)
459
+ t_587 = self.n_Conv_99(t_586)
460
+ t_588 = self.n_Conv_100(t_582)
461
+ t_589 = torch.add(t_587, t_588)
462
+ t_590 = F.relu(t_589)
463
+ t_591 = self.n_Conv_101(t_590)
464
+ t_592 = F.relu(t_591)
465
+ t_592_padded = F.pad(t_592, [1, 1, 1, 1], value=0)
466
+ t_593 = self.n_Conv_102(t_592_padded)
467
+ t_594 = F.relu(t_593)
468
+ t_595 = self.n_Conv_103(t_594)
469
+ t_596 = torch.add(t_595, t_590)
470
+ t_597 = F.relu(t_596)
471
+ t_598 = self.n_Conv_104(t_597)
472
+ t_599 = F.relu(t_598)
473
+ t_599_padded = F.pad(t_599, [1, 1, 1, 1], value=0)
474
+ t_600 = self.n_Conv_105(t_599_padded)
475
+ t_601 = F.relu(t_600)
476
+ t_602 = self.n_Conv_106(t_601)
477
+ t_603 = torch.add(t_602, t_597)
478
+ t_604 = F.relu(t_603)
479
+ t_605 = self.n_Conv_107(t_604)
480
+ t_606 = F.relu(t_605)
481
+ t_606_padded = F.pad(t_606, [1, 1, 1, 1], value=0)
482
+ t_607 = self.n_Conv_108(t_606_padded)
483
+ t_608 = F.relu(t_607)
484
+ t_609 = self.n_Conv_109(t_608)
485
+ t_610 = torch.add(t_609, t_604)
486
+ t_611 = F.relu(t_610)
487
+ t_612 = self.n_Conv_110(t_611)
488
+ t_613 = F.relu(t_612)
489
+ t_613_padded = F.pad(t_613, [1, 1, 1, 1], value=0)
490
+ t_614 = self.n_Conv_111(t_613_padded)
491
+ t_615 = F.relu(t_614)
492
+ t_616 = self.n_Conv_112(t_615)
493
+ t_617 = torch.add(t_616, t_611)
494
+ t_618 = F.relu(t_617)
495
+ t_619 = self.n_Conv_113(t_618)
496
+ t_620 = F.relu(t_619)
497
+ t_620_padded = F.pad(t_620, [1, 1, 1, 1], value=0)
498
+ t_621 = self.n_Conv_114(t_620_padded)
499
+ t_622 = F.relu(t_621)
500
+ t_623 = self.n_Conv_115(t_622)
501
+ t_624 = torch.add(t_623, t_618)
502
+ t_625 = F.relu(t_624)
503
+ t_626 = self.n_Conv_116(t_625)
504
+ t_627 = F.relu(t_626)
505
+ t_627_padded = F.pad(t_627, [1, 1, 1, 1], value=0)
506
+ t_628 = self.n_Conv_117(t_627_padded)
507
+ t_629 = F.relu(t_628)
508
+ t_630 = self.n_Conv_118(t_629)
509
+ t_631 = torch.add(t_630, t_625)
510
+ t_632 = F.relu(t_631)
511
+ t_633 = self.n_Conv_119(t_632)
512
+ t_634 = F.relu(t_633)
513
+ t_634_padded = F.pad(t_634, [1, 1, 1, 1], value=0)
514
+ t_635 = self.n_Conv_120(t_634_padded)
515
+ t_636 = F.relu(t_635)
516
+ t_637 = self.n_Conv_121(t_636)
517
+ t_638 = torch.add(t_637, t_632)
518
+ t_639 = F.relu(t_638)
519
+ t_640 = self.n_Conv_122(t_639)
520
+ t_641 = F.relu(t_640)
521
+ t_641_padded = F.pad(t_641, [1, 1, 1, 1], value=0)
522
+ t_642 = self.n_Conv_123(t_641_padded)
523
+ t_643 = F.relu(t_642)
524
+ t_644 = self.n_Conv_124(t_643)
525
+ t_645 = torch.add(t_644, t_639)
526
+ t_646 = F.relu(t_645)
527
+ t_647 = self.n_Conv_125(t_646)
528
+ t_648 = F.relu(t_647)
529
+ t_648_padded = F.pad(t_648, [1, 1, 1, 1], value=0)
530
+ t_649 = self.n_Conv_126(t_648_padded)
531
+ t_650 = F.relu(t_649)
532
+ t_651 = self.n_Conv_127(t_650)
533
+ t_652 = torch.add(t_651, t_646)
534
+ t_653 = F.relu(t_652)
535
+ t_654 = self.n_Conv_128(t_653)
536
+ t_655 = F.relu(t_654)
537
+ t_655_padded = F.pad(t_655, [1, 1, 1, 1], value=0)
538
+ t_656 = self.n_Conv_129(t_655_padded)
539
+ t_657 = F.relu(t_656)
540
+ t_658 = self.n_Conv_130(t_657)
541
+ t_659 = torch.add(t_658, t_653)
542
+ t_660 = F.relu(t_659)
543
+ t_661 = self.n_Conv_131(t_660)
544
+ t_662 = F.relu(t_661)
545
+ t_662_padded = F.pad(t_662, [1, 1, 1, 1], value=0)
546
+ t_663 = self.n_Conv_132(t_662_padded)
547
+ t_664 = F.relu(t_663)
548
+ t_665 = self.n_Conv_133(t_664)
549
+ t_666 = torch.add(t_665, t_660)
550
+ t_667 = F.relu(t_666)
551
+ t_668 = self.n_Conv_134(t_667)
552
+ t_669 = F.relu(t_668)
553
+ t_669_padded = F.pad(t_669, [1, 1, 1, 1], value=0)
554
+ t_670 = self.n_Conv_135(t_669_padded)
555
+ t_671 = F.relu(t_670)
556
+ t_672 = self.n_Conv_136(t_671)
557
+ t_673 = torch.add(t_672, t_667)
558
+ t_674 = F.relu(t_673)
559
+ t_675 = self.n_Conv_137(t_674)
560
+ t_676 = F.relu(t_675)
561
+ t_676_padded = F.pad(t_676, [1, 1, 1, 1], value=0)
562
+ t_677 = self.n_Conv_138(t_676_padded)
563
+ t_678 = F.relu(t_677)
564
+ t_679 = self.n_Conv_139(t_678)
565
+ t_680 = torch.add(t_679, t_674)
566
+ t_681 = F.relu(t_680)
567
+ t_682 = self.n_Conv_140(t_681)
568
+ t_683 = F.relu(t_682)
569
+ t_683_padded = F.pad(t_683, [1, 1, 1, 1], value=0)
570
+ t_684 = self.n_Conv_141(t_683_padded)
571
+ t_685 = F.relu(t_684)
572
+ t_686 = self.n_Conv_142(t_685)
573
+ t_687 = torch.add(t_686, t_681)
574
+ t_688 = F.relu(t_687)
575
+ t_689 = self.n_Conv_143(t_688)
576
+ t_690 = F.relu(t_689)
577
+ t_690_padded = F.pad(t_690, [1, 1, 1, 1], value=0)
578
+ t_691 = self.n_Conv_144(t_690_padded)
579
+ t_692 = F.relu(t_691)
580
+ t_693 = self.n_Conv_145(t_692)
581
+ t_694 = torch.add(t_693, t_688)
582
+ t_695 = F.relu(t_694)
583
+ t_696 = self.n_Conv_146(t_695)
584
+ t_697 = F.relu(t_696)
585
+ t_697_padded = F.pad(t_697, [1, 1, 1, 1], value=0)
586
+ t_698 = self.n_Conv_147(t_697_padded)
587
+ t_699 = F.relu(t_698)
588
+ t_700 = self.n_Conv_148(t_699)
589
+ t_701 = torch.add(t_700, t_695)
590
+ t_702 = F.relu(t_701)
591
+ t_703 = self.n_Conv_149(t_702)
592
+ t_704 = F.relu(t_703)
593
+ t_704_padded = F.pad(t_704, [1, 1, 1, 1], value=0)
594
+ t_705 = self.n_Conv_150(t_704_padded)
595
+ t_706 = F.relu(t_705)
596
+ t_707 = self.n_Conv_151(t_706)
597
+ t_708 = torch.add(t_707, t_702)
598
+ t_709 = F.relu(t_708)
599
+ t_710 = self.n_Conv_152(t_709)
600
+ t_711 = F.relu(t_710)
601
+ t_711_padded = F.pad(t_711, [1, 1, 1, 1], value=0)
602
+ t_712 = self.n_Conv_153(t_711_padded)
603
+ t_713 = F.relu(t_712)
604
+ t_714 = self.n_Conv_154(t_713)
605
+ t_715 = torch.add(t_714, t_709)
606
+ t_716 = F.relu(t_715)
607
+ t_717 = self.n_Conv_155(t_716)
608
+ t_718 = F.relu(t_717)
609
+ t_718_padded = F.pad(t_718, [1, 1, 1, 1], value=0)
610
+ t_719 = self.n_Conv_156(t_718_padded)
611
+ t_720 = F.relu(t_719)
612
+ t_721 = self.n_Conv_157(t_720)
613
+ t_722 = torch.add(t_721, t_716)
614
+ t_723 = F.relu(t_722)
615
+ t_724 = self.n_Conv_158(t_723)
616
+ t_725 = self.n_Conv_159(t_723)
617
+ t_726 = F.relu(t_725)
618
+ t_726_padded = F.pad(t_726, [0, 1, 0, 1], value=0)
619
+ t_727 = self.n_Conv_160(t_726_padded)
620
+ t_728 = F.relu(t_727)
621
+ t_729 = self.n_Conv_161(t_728)
622
+ t_730 = torch.add(t_729, t_724)
623
+ t_731 = F.relu(t_730)
624
+ t_732 = self.n_Conv_162(t_731)
625
+ t_733 = F.relu(t_732)
626
+ t_733_padded = F.pad(t_733, [1, 1, 1, 1], value=0)
627
+ t_734 = self.n_Conv_163(t_733_padded)
628
+ t_735 = F.relu(t_734)
629
+ t_736 = self.n_Conv_164(t_735)
630
+ t_737 = torch.add(t_736, t_731)
631
+ t_738 = F.relu(t_737)
632
+ t_739 = self.n_Conv_165(t_738)
633
+ t_740 = F.relu(t_739)
634
+ t_740_padded = F.pad(t_740, [1, 1, 1, 1], value=0)
635
+ t_741 = self.n_Conv_166(t_740_padded)
636
+ t_742 = F.relu(t_741)
637
+ t_743 = self.n_Conv_167(t_742)
638
+ t_744 = torch.add(t_743, t_738)
639
+ t_745 = F.relu(t_744)
640
+ t_746 = self.n_Conv_168(t_745)
641
+ t_747 = self.n_Conv_169(t_745)
642
+ t_748 = F.relu(t_747)
643
+ t_748_padded = F.pad(t_748, [0, 1, 0, 1], value=0)
644
+ t_749 = self.n_Conv_170(t_748_padded)
645
+ t_750 = F.relu(t_749)
646
+ t_751 = self.n_Conv_171(t_750)
647
+ t_752 = torch.add(t_751, t_746)
648
+ t_753 = F.relu(t_752)
649
+ t_754 = self.n_Conv_172(t_753)
650
+ t_755 = F.relu(t_754)
651
+ t_755_padded = F.pad(t_755, [1, 1, 1, 1], value=0)
652
+ t_756 = self.n_Conv_173(t_755_padded)
653
+ t_757 = F.relu(t_756)
654
+ t_758 = self.n_Conv_174(t_757)
655
+ t_759 = torch.add(t_758, t_753)
656
+ t_760 = F.relu(t_759)
657
+ t_761 = self.n_Conv_175(t_760)
658
+ t_762 = F.relu(t_761)
659
+ t_762_padded = F.pad(t_762, [1, 1, 1, 1], value=0)
660
+ t_763 = self.n_Conv_176(t_762_padded)
661
+ t_764 = F.relu(t_763)
662
+ t_765 = self.n_Conv_177(t_764)
663
+ t_766 = torch.add(t_765, t_760)
664
+ t_767 = F.relu(t_766)
665
+ t_768 = self.n_Conv_178(t_767)
666
+ t_769 = F.avg_pool2d(t_768, kernel_size=t_768.shape[-2:])
667
+ t_770 = torch.squeeze(t_769, 3)
668
+ t_770 = torch.squeeze(t_770, 2)
669
+ t_771 = torch.sigmoid(t_770)
670
+ return t_771
671
+
672
+ def load_state_dict(self, state_dict, **kwargs):
673
+ self.tags = state_dict.get('tags', [])
674
+
675
+ super(DeepDanbooruModel, self).load_state_dict({k: v for k, v in state_dict.items() if k != 'tags'})
676
+
stable-diffusion-webui-master/modules/devices.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys, os, shlex
2
+ import contextlib
3
+ import torch
4
+ from modules import errors
5
+ from packaging import version
6
+
7
+
8
+ # has_mps is only available in nightly pytorch (for now) and macOS 12.3+.
9
+ # check `getattr` and try it for compatibility
10
+ def has_mps() -> bool:
11
+ if not getattr(torch, 'has_mps', False):
12
+ return False
13
+ try:
14
+ torch.zeros(1).to(torch.device("mps"))
15
+ return True
16
+ except Exception:
17
+ return False
18
+
19
+
20
+ def extract_device_id(args, name):
21
+ for x in range(len(args)):
22
+ if name in args[x]:
23
+ return args[x + 1]
24
+
25
+ return None
26
+
27
+
28
+ def get_cuda_device_string():
29
+ from modules import shared
30
+
31
+ if shared.cmd_opts.device_id is not None:
32
+ return f"cuda:{shared.cmd_opts.device_id}"
33
+
34
+ return "cuda"
35
+
36
+
37
+ def get_optimal_device():
38
+ if torch.cuda.is_available():
39
+ return torch.device(get_cuda_device_string())
40
+
41
+ if has_mps():
42
+ return torch.device("mps")
43
+
44
+ return cpu
45
+
46
+
47
+ def torch_gc():
48
+ if torch.cuda.is_available():
49
+ with torch.cuda.device(get_cuda_device_string()):
50
+ torch.cuda.empty_cache()
51
+ torch.cuda.ipc_collect()
52
+
53
+
54
+ def enable_tf32():
55
+ if torch.cuda.is_available():
56
+ torch.backends.cuda.matmul.allow_tf32 = True
57
+ torch.backends.cudnn.allow_tf32 = True
58
+
59
+
60
+ errors.run(enable_tf32, "Enabling TF32")
61
+
62
+ cpu = torch.device("cpu")
63
+ device = device_interrogate = device_gfpgan = device_swinir = device_esrgan = device_scunet = device_codeformer = None
64
+ dtype = torch.float16
65
+ dtype_vae = torch.float16
66
+
67
+
68
+ def randn(seed, shape):
69
+ # Pytorch currently doesn't handle setting randomness correctly when the metal backend is used.
70
+ if device.type == 'mps':
71
+ generator = torch.Generator(device=cpu)
72
+ generator.manual_seed(seed)
73
+ noise = torch.randn(shape, generator=generator, device=cpu).to(device)
74
+ return noise
75
+
76
+ torch.manual_seed(seed)
77
+ return torch.randn(shape, device=device)
78
+
79
+
80
+ def randn_without_seed(shape):
81
+ # Pytorch currently doesn't handle setting randomness correctly when the metal backend is used.
82
+ if device.type == 'mps':
83
+ generator = torch.Generator(device=cpu)
84
+ noise = torch.randn(shape, generator=generator, device=cpu).to(device)
85
+ return noise
86
+
87
+ return torch.randn(shape, device=device)
88
+
89
+
90
+ def autocast(disable=False):
91
+ from modules import shared
92
+
93
+ if disable:
94
+ return contextlib.nullcontext()
95
+
96
+ if dtype == torch.float32 or shared.cmd_opts.precision == "full":
97
+ return contextlib.nullcontext()
98
+
99
+ return torch.autocast("cuda")
100
+
101
+
102
+ # MPS workaround for https://github.com/pytorch/pytorch/issues/79383
103
+ orig_tensor_to = torch.Tensor.to
104
+ def tensor_to_fix(self, *args, **kwargs):
105
+ if self.device.type != 'mps' and \
106
+ ((len(args) > 0 and isinstance(args[0], torch.device) and args[0].type == 'mps') or \
107
+ (isinstance(kwargs.get('device'), torch.device) and kwargs['device'].type == 'mps')):
108
+ self = self.contiguous()
109
+ return orig_tensor_to(self, *args, **kwargs)
110
+
111
+
112
+ # MPS workaround for https://github.com/pytorch/pytorch/issues/80800
113
+ orig_layer_norm = torch.nn.functional.layer_norm
114
+ def layer_norm_fix(*args, **kwargs):
115
+ if len(args) > 0 and isinstance(args[0], torch.Tensor) and args[0].device.type == 'mps':
116
+ args = list(args)
117
+ args[0] = args[0].contiguous()
118
+ return orig_layer_norm(*args, **kwargs)
119
+
120
+
121
+ # PyTorch 1.13 doesn't need these fixes but unfortunately is slower and has regressions that prevent training from working
122
+ if has_mps() and version.parse(torch.__version__) < version.parse("1.13"):
123
+ torch.Tensor.to = tensor_to_fix
124
+ torch.nn.functional.layer_norm = layer_norm_fix
stable-diffusion-webui-master/modules/errors.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import traceback
3
+
4
+
5
+ def run(code, task):
6
+ try:
7
+ code()
8
+ except Exception as e:
9
+ print(f"{task}: {type(e).__name__}", file=sys.stderr)
10
+ print(traceback.format_exc(), file=sys.stderr)
stable-diffusion-webui-master/modules/esrgan_model.py ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import numpy as np
4
+ import torch
5
+ from PIL import Image
6
+ from basicsr.utils.download_util import load_file_from_url
7
+
8
+ import modules.esrgan_model_arch as arch
9
+ from modules import shared, modelloader, images, devices
10
+ from modules.upscaler import Upscaler, UpscalerData
11
+ from modules.shared import opts
12
+
13
+
14
+
15
+ def mod2normal(state_dict):
16
+ # this code is copied from https://github.com/victorca25/iNNfer
17
+ if 'conv_first.weight' in state_dict:
18
+ crt_net = {}
19
+ items = []
20
+ for k, v in state_dict.items():
21
+ items.append(k)
22
+
23
+ crt_net['model.0.weight'] = state_dict['conv_first.weight']
24
+ crt_net['model.0.bias'] = state_dict['conv_first.bias']
25
+
26
+ for k in items.copy():
27
+ if 'RDB' in k:
28
+ ori_k = k.replace('RRDB_trunk.', 'model.1.sub.')
29
+ if '.weight' in k:
30
+ ori_k = ori_k.replace('.weight', '.0.weight')
31
+ elif '.bias' in k:
32
+ ori_k = ori_k.replace('.bias', '.0.bias')
33
+ crt_net[ori_k] = state_dict[k]
34
+ items.remove(k)
35
+
36
+ crt_net['model.1.sub.23.weight'] = state_dict['trunk_conv.weight']
37
+ crt_net['model.1.sub.23.bias'] = state_dict['trunk_conv.bias']
38
+ crt_net['model.3.weight'] = state_dict['upconv1.weight']
39
+ crt_net['model.3.bias'] = state_dict['upconv1.bias']
40
+ crt_net['model.6.weight'] = state_dict['upconv2.weight']
41
+ crt_net['model.6.bias'] = state_dict['upconv2.bias']
42
+ crt_net['model.8.weight'] = state_dict['HRconv.weight']
43
+ crt_net['model.8.bias'] = state_dict['HRconv.bias']
44
+ crt_net['model.10.weight'] = state_dict['conv_last.weight']
45
+ crt_net['model.10.bias'] = state_dict['conv_last.bias']
46
+ state_dict = crt_net
47
+ return state_dict
48
+
49
+
50
+ def resrgan2normal(state_dict, nb=23):
51
+ # this code is copied from https://github.com/victorca25/iNNfer
52
+ if "conv_first.weight" in state_dict and "body.0.rdb1.conv1.weight" in state_dict:
53
+ re8x = 0
54
+ crt_net = {}
55
+ items = []
56
+ for k, v in state_dict.items():
57
+ items.append(k)
58
+
59
+ crt_net['model.0.weight'] = state_dict['conv_first.weight']
60
+ crt_net['model.0.bias'] = state_dict['conv_first.bias']
61
+
62
+ for k in items.copy():
63
+ if "rdb" in k:
64
+ ori_k = k.replace('body.', 'model.1.sub.')
65
+ ori_k = ori_k.replace('.rdb', '.RDB')
66
+ if '.weight' in k:
67
+ ori_k = ori_k.replace('.weight', '.0.weight')
68
+ elif '.bias' in k:
69
+ ori_k = ori_k.replace('.bias', '.0.bias')
70
+ crt_net[ori_k] = state_dict[k]
71
+ items.remove(k)
72
+
73
+ crt_net[f'model.1.sub.{nb}.weight'] = state_dict['conv_body.weight']
74
+ crt_net[f'model.1.sub.{nb}.bias'] = state_dict['conv_body.bias']
75
+ crt_net['model.3.weight'] = state_dict['conv_up1.weight']
76
+ crt_net['model.3.bias'] = state_dict['conv_up1.bias']
77
+ crt_net['model.6.weight'] = state_dict['conv_up2.weight']
78
+ crt_net['model.6.bias'] = state_dict['conv_up2.bias']
79
+
80
+ if 'conv_up3.weight' in state_dict:
81
+ # modification supporting: https://github.com/ai-forever/Real-ESRGAN/blob/main/RealESRGAN/rrdbnet_arch.py
82
+ re8x = 3
83
+ crt_net['model.9.weight'] = state_dict['conv_up3.weight']
84
+ crt_net['model.9.bias'] = state_dict['conv_up3.bias']
85
+
86
+ crt_net[f'model.{8+re8x}.weight'] = state_dict['conv_hr.weight']
87
+ crt_net[f'model.{8+re8x}.bias'] = state_dict['conv_hr.bias']
88
+ crt_net[f'model.{10+re8x}.weight'] = state_dict['conv_last.weight']
89
+ crt_net[f'model.{10+re8x}.bias'] = state_dict['conv_last.bias']
90
+
91
+ state_dict = crt_net
92
+ return state_dict
93
+
94
+
95
+ def infer_params(state_dict):
96
+ # this code is copied from https://github.com/victorca25/iNNfer
97
+ scale2x = 0
98
+ scalemin = 6
99
+ n_uplayer = 0
100
+ plus = False
101
+
102
+ for block in list(state_dict):
103
+ parts = block.split(".")
104
+ n_parts = len(parts)
105
+ if n_parts == 5 and parts[2] == "sub":
106
+ nb = int(parts[3])
107
+ elif n_parts == 3:
108
+ part_num = int(parts[1])
109
+ if (part_num > scalemin
110
+ and parts[0] == "model"
111
+ and parts[2] == "weight"):
112
+ scale2x += 1
113
+ if part_num > n_uplayer:
114
+ n_uplayer = part_num
115
+ out_nc = state_dict[block].shape[0]
116
+ if not plus and "conv1x1" in block:
117
+ plus = True
118
+
119
+ nf = state_dict["model.0.weight"].shape[0]
120
+ in_nc = state_dict["model.0.weight"].shape[1]
121
+ out_nc = out_nc
122
+ scale = 2 ** scale2x
123
+
124
+ return in_nc, out_nc, nf, nb, plus, scale
125
+
126
+
127
+ class UpscalerESRGAN(Upscaler):
128
+ def __init__(self, dirname):
129
+ self.name = "ESRGAN"
130
+ self.model_url = "https://github.com/cszn/KAIR/releases/download/v1.0/ESRGAN.pth"
131
+ self.model_name = "ESRGAN_4x"
132
+ self.scalers = []
133
+ self.user_path = dirname
134
+ super().__init__()
135
+ model_paths = self.find_models(ext_filter=[".pt", ".pth"])
136
+ scalers = []
137
+ if len(model_paths) == 0:
138
+ scaler_data = UpscalerData(self.model_name, self.model_url, self, 4)
139
+ scalers.append(scaler_data)
140
+ for file in model_paths:
141
+ if "http" in file:
142
+ name = self.model_name
143
+ else:
144
+ name = modelloader.friendly_name(file)
145
+
146
+ scaler_data = UpscalerData(name, file, self, 4)
147
+ self.scalers.append(scaler_data)
148
+
149
+ def do_upscale(self, img, selected_model):
150
+ model = self.load_model(selected_model)
151
+ if model is None:
152
+ return img
153
+ model.to(devices.device_esrgan)
154
+ img = esrgan_upscale(model, img)
155
+ return img
156
+
157
+ def load_model(self, path: str):
158
+ if "http" in path:
159
+ filename = load_file_from_url(url=self.model_url, model_dir=self.model_path,
160
+ file_name="%s.pth" % self.model_name,
161
+ progress=True)
162
+ else:
163
+ filename = path
164
+ if not os.path.exists(filename) or filename is None:
165
+ print("Unable to load %s from %s" % (self.model_path, filename))
166
+ return None
167
+
168
+ state_dict = torch.load(filename, map_location='cpu' if devices.device_esrgan.type == 'mps' else None)
169
+
170
+ if "params_ema" in state_dict:
171
+ state_dict = state_dict["params_ema"]
172
+ elif "params" in state_dict:
173
+ state_dict = state_dict["params"]
174
+ num_conv = 16 if "realesr-animevideov3" in filename else 32
175
+ model = arch.SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=num_conv, upscale=4, act_type='prelu')
176
+ model.load_state_dict(state_dict)
177
+ model.eval()
178
+ return model
179
+
180
+ if "body.0.rdb1.conv1.weight" in state_dict and "conv_first.weight" in state_dict:
181
+ nb = 6 if "RealESRGAN_x4plus_anime_6B" in filename else 23
182
+ state_dict = resrgan2normal(state_dict, nb)
183
+ elif "conv_first.weight" in state_dict:
184
+ state_dict = mod2normal(state_dict)
185
+ elif "model.0.weight" not in state_dict:
186
+ raise Exception("The file is not a recognized ESRGAN model.")
187
+
188
+ in_nc, out_nc, nf, nb, plus, mscale = infer_params(state_dict)
189
+
190
+ model = arch.RRDBNet(in_nc=in_nc, out_nc=out_nc, nf=nf, nb=nb, upscale=mscale, plus=plus)
191
+ model.load_state_dict(state_dict)
192
+ model.eval()
193
+
194
+ return model
195
+
196
+
197
+ def upscale_without_tiling(model, img):
198
+ img = np.array(img)
199
+ img = img[:, :, ::-1]
200
+ img = np.ascontiguousarray(np.transpose(img, (2, 0, 1))) / 255
201
+ img = torch.from_numpy(img).float()
202
+ img = img.unsqueeze(0).to(devices.device_esrgan)
203
+ with torch.no_grad():
204
+ output = model(img)
205
+ output = output.squeeze().float().cpu().clamp_(0, 1).numpy()
206
+ output = 255. * np.moveaxis(output, 0, 2)
207
+ output = output.astype(np.uint8)
208
+ output = output[:, :, ::-1]
209
+ return Image.fromarray(output, 'RGB')
210
+
211
+
212
+ def esrgan_upscale(model, img):
213
+ if opts.ESRGAN_tile == 0:
214
+ return upscale_without_tiling(model, img)
215
+
216
+ grid = images.split_grid(img, opts.ESRGAN_tile, opts.ESRGAN_tile, opts.ESRGAN_tile_overlap)
217
+ newtiles = []
218
+ scale_factor = 1
219
+
220
+ for y, h, row in grid.tiles:
221
+ newrow = []
222
+ for tiledata in row:
223
+ x, w, tile = tiledata
224
+
225
+ output = upscale_without_tiling(model, tile)
226
+ scale_factor = output.width // tile.width
227
+
228
+ newrow.append([x * scale_factor, w * scale_factor, output])
229
+ newtiles.append([y * scale_factor, h * scale_factor, newrow])
230
+
231
+ newgrid = images.Grid(newtiles, grid.tile_w * scale_factor, grid.tile_h * scale_factor, grid.image_w * scale_factor, grid.image_h * scale_factor, grid.overlap * scale_factor)
232
+ output = images.combine_grid(newgrid)
233
+ return output
stable-diffusion-webui-master/modules/esrgan_model_arch.py ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this file is adapted from https://github.com/victorca25/iNNfer
2
+
3
+ import math
4
+ import functools
5
+ import torch
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+
9
+
10
+ ####################
11
+ # RRDBNet Generator
12
+ ####################
13
+
14
+ class RRDBNet(nn.Module):
15
+ def __init__(self, in_nc, out_nc, nf, nb, nr=3, gc=32, upscale=4, norm_type=None,
16
+ act_type='leakyrelu', mode='CNA', upsample_mode='upconv', convtype='Conv2D',
17
+ finalact=None, gaussian_noise=False, plus=False):
18
+ super(RRDBNet, self).__init__()
19
+ n_upscale = int(math.log(upscale, 2))
20
+ if upscale == 3:
21
+ n_upscale = 1
22
+
23
+ self.resrgan_scale = 0
24
+ if in_nc % 16 == 0:
25
+ self.resrgan_scale = 1
26
+ elif in_nc != 4 and in_nc % 4 == 0:
27
+ self.resrgan_scale = 2
28
+
29
+ fea_conv = conv_block(in_nc, nf, kernel_size=3, norm_type=None, act_type=None, convtype=convtype)
30
+ rb_blocks = [RRDB(nf, nr, kernel_size=3, gc=32, stride=1, bias=1, pad_type='zero',
31
+ norm_type=norm_type, act_type=act_type, mode='CNA', convtype=convtype,
32
+ gaussian_noise=gaussian_noise, plus=plus) for _ in range(nb)]
33
+ LR_conv = conv_block(nf, nf, kernel_size=3, norm_type=norm_type, act_type=None, mode=mode, convtype=convtype)
34
+
35
+ if upsample_mode == 'upconv':
36
+ upsample_block = upconv_block
37
+ elif upsample_mode == 'pixelshuffle':
38
+ upsample_block = pixelshuffle_block
39
+ else:
40
+ raise NotImplementedError('upsample mode [{:s}] is not found'.format(upsample_mode))
41
+ if upscale == 3:
42
+ upsampler = upsample_block(nf, nf, 3, act_type=act_type, convtype=convtype)
43
+ else:
44
+ upsampler = [upsample_block(nf, nf, act_type=act_type, convtype=convtype) for _ in range(n_upscale)]
45
+ HR_conv0 = conv_block(nf, nf, kernel_size=3, norm_type=None, act_type=act_type, convtype=convtype)
46
+ HR_conv1 = conv_block(nf, out_nc, kernel_size=3, norm_type=None, act_type=None, convtype=convtype)
47
+
48
+ outact = act(finalact) if finalact else None
49
+
50
+ self.model = sequential(fea_conv, ShortcutBlock(sequential(*rb_blocks, LR_conv)),
51
+ *upsampler, HR_conv0, HR_conv1, outact)
52
+
53
+ def forward(self, x, outm=None):
54
+ if self.resrgan_scale == 1:
55
+ feat = pixel_unshuffle(x, scale=4)
56
+ elif self.resrgan_scale == 2:
57
+ feat = pixel_unshuffle(x, scale=2)
58
+ else:
59
+ feat = x
60
+
61
+ return self.model(feat)
62
+
63
+
64
+ class RRDB(nn.Module):
65
+ """
66
+ Residual in Residual Dense Block
67
+ (ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks)
68
+ """
69
+
70
+ def __init__(self, nf, nr=3, kernel_size=3, gc=32, stride=1, bias=1, pad_type='zero',
71
+ norm_type=None, act_type='leakyrelu', mode='CNA', convtype='Conv2D',
72
+ spectral_norm=False, gaussian_noise=False, plus=False):
73
+ super(RRDB, self).__init__()
74
+ # This is for backwards compatibility with existing models
75
+ if nr == 3:
76
+ self.RDB1 = ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
77
+ norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
78
+ gaussian_noise=gaussian_noise, plus=plus)
79
+ self.RDB2 = ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
80
+ norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
81
+ gaussian_noise=gaussian_noise, plus=plus)
82
+ self.RDB3 = ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
83
+ norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
84
+ gaussian_noise=gaussian_noise, plus=plus)
85
+ else:
86
+ RDB_list = [ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
87
+ norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
88
+ gaussian_noise=gaussian_noise, plus=plus) for _ in range(nr)]
89
+ self.RDBs = nn.Sequential(*RDB_list)
90
+
91
+ def forward(self, x):
92
+ if hasattr(self, 'RDB1'):
93
+ out = self.RDB1(x)
94
+ out = self.RDB2(out)
95
+ out = self.RDB3(out)
96
+ else:
97
+ out = self.RDBs(x)
98
+ return out * 0.2 + x
99
+
100
+
101
+ class ResidualDenseBlock_5C(nn.Module):
102
+ """
103
+ Residual Dense Block
104
+ The core module of paper: (Residual Dense Network for Image Super-Resolution, CVPR 18)
105
+ Modified options that can be used:
106
+ - "Partial Convolution based Padding" arXiv:1811.11718
107
+ - "Spectral normalization" arXiv:1802.05957
108
+ - "ICASSP 2020 - ESRGAN+ : Further Improving ESRGAN" N. C.
109
+ {Rakotonirina} and A. {Rasoanaivo}
110
+ """
111
+
112
+ def __init__(self, nf=64, kernel_size=3, gc=32, stride=1, bias=1, pad_type='zero',
113
+ norm_type=None, act_type='leakyrelu', mode='CNA', convtype='Conv2D',
114
+ spectral_norm=False, gaussian_noise=False, plus=False):
115
+ super(ResidualDenseBlock_5C, self).__init__()
116
+
117
+ self.noise = GaussianNoise() if gaussian_noise else None
118
+ self.conv1x1 = conv1x1(nf, gc) if plus else None
119
+
120
+ self.conv1 = conv_block(nf, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
121
+ norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
122
+ spectral_norm=spectral_norm)
123
+ self.conv2 = conv_block(nf+gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
124
+ norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
125
+ spectral_norm=spectral_norm)
126
+ self.conv3 = conv_block(nf+2*gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
127
+ norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
128
+ spectral_norm=spectral_norm)
129
+ self.conv4 = conv_block(nf+3*gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
130
+ norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
131
+ spectral_norm=spectral_norm)
132
+ if mode == 'CNA':
133
+ last_act = None
134
+ else:
135
+ last_act = act_type
136
+ self.conv5 = conv_block(nf+4*gc, nf, 3, stride, bias=bias, pad_type=pad_type,
137
+ norm_type=norm_type, act_type=last_act, mode=mode, convtype=convtype,
138
+ spectral_norm=spectral_norm)
139
+
140
+ def forward(self, x):
141
+ x1 = self.conv1(x)
142
+ x2 = self.conv2(torch.cat((x, x1), 1))
143
+ if self.conv1x1:
144
+ x2 = x2 + self.conv1x1(x)
145
+ x3 = self.conv3(torch.cat((x, x1, x2), 1))
146
+ x4 = self.conv4(torch.cat((x, x1, x2, x3), 1))
147
+ if self.conv1x1:
148
+ x4 = x4 + x2
149
+ x5 = self.conv5(torch.cat((x, x1, x2, x3, x4), 1))
150
+ if self.noise:
151
+ return self.noise(x5.mul(0.2) + x)
152
+ else:
153
+ return x5 * 0.2 + x
154
+
155
+
156
+ ####################
157
+ # ESRGANplus
158
+ ####################
159
+
160
+ class GaussianNoise(nn.Module):
161
+ def __init__(self, sigma=0.1, is_relative_detach=False):
162
+ super().__init__()
163
+ self.sigma = sigma
164
+ self.is_relative_detach = is_relative_detach
165
+ self.noise = torch.tensor(0, dtype=torch.float)
166
+
167
+ def forward(self, x):
168
+ if self.training and self.sigma != 0:
169
+ self.noise = self.noise.to(x.device)
170
+ scale = self.sigma * x.detach() if self.is_relative_detach else self.sigma * x
171
+ sampled_noise = self.noise.repeat(*x.size()).normal_() * scale
172
+ x = x + sampled_noise
173
+ return x
174
+
175
+ def conv1x1(in_planes, out_planes, stride=1):
176
+ return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
177
+
178
+
179
+ ####################
180
+ # SRVGGNetCompact
181
+ ####################
182
+
183
+ class SRVGGNetCompact(nn.Module):
184
+ """A compact VGG-style network structure for super-resolution.
185
+ This class is copied from https://github.com/xinntao/Real-ESRGAN
186
+ """
187
+
188
+ def __init__(self, num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=16, upscale=4, act_type='prelu'):
189
+ super(SRVGGNetCompact, self).__init__()
190
+ self.num_in_ch = num_in_ch
191
+ self.num_out_ch = num_out_ch
192
+ self.num_feat = num_feat
193
+ self.num_conv = num_conv
194
+ self.upscale = upscale
195
+ self.act_type = act_type
196
+
197
+ self.body = nn.ModuleList()
198
+ # the first conv
199
+ self.body.append(nn.Conv2d(num_in_ch, num_feat, 3, 1, 1))
200
+ # the first activation
201
+ if act_type == 'relu':
202
+ activation = nn.ReLU(inplace=True)
203
+ elif act_type == 'prelu':
204
+ activation = nn.PReLU(num_parameters=num_feat)
205
+ elif act_type == 'leakyrelu':
206
+ activation = nn.LeakyReLU(negative_slope=0.1, inplace=True)
207
+ self.body.append(activation)
208
+
209
+ # the body structure
210
+ for _ in range(num_conv):
211
+ self.body.append(nn.Conv2d(num_feat, num_feat, 3, 1, 1))
212
+ # activation
213
+ if act_type == 'relu':
214
+ activation = nn.ReLU(inplace=True)
215
+ elif act_type == 'prelu':
216
+ activation = nn.PReLU(num_parameters=num_feat)
217
+ elif act_type == 'leakyrelu':
218
+ activation = nn.LeakyReLU(negative_slope=0.1, inplace=True)
219
+ self.body.append(activation)
220
+
221
+ # the last conv
222
+ self.body.append(nn.Conv2d(num_feat, num_out_ch * upscale * upscale, 3, 1, 1))
223
+ # upsample
224
+ self.upsampler = nn.PixelShuffle(upscale)
225
+
226
+ def forward(self, x):
227
+ out = x
228
+ for i in range(0, len(self.body)):
229
+ out = self.body[i](out)
230
+
231
+ out = self.upsampler(out)
232
+ # add the nearest upsampled image, so that the network learns the residual
233
+ base = F.interpolate(x, scale_factor=self.upscale, mode='nearest')
234
+ out += base
235
+ return out
236
+
237
+
238
+ ####################
239
+ # Upsampler
240
+ ####################
241
+
242
+ class Upsample(nn.Module):
243
+ r"""Upsamples a given multi-channel 1D (temporal), 2D (spatial) or 3D (volumetric) data.
244
+ The input data is assumed to be of the form
245
+ `minibatch x channels x [optional depth] x [optional height] x width`.
246
+ """
247
+
248
+ def __init__(self, size=None, scale_factor=None, mode="nearest", align_corners=None):
249
+ super(Upsample, self).__init__()
250
+ if isinstance(scale_factor, tuple):
251
+ self.scale_factor = tuple(float(factor) for factor in scale_factor)
252
+ else:
253
+ self.scale_factor = float(scale_factor) if scale_factor else None
254
+ self.mode = mode
255
+ self.size = size
256
+ self.align_corners = align_corners
257
+
258
+ def forward(self, x):
259
+ return nn.functional.interpolate(x, size=self.size, scale_factor=self.scale_factor, mode=self.mode, align_corners=self.align_corners)
260
+
261
+ def extra_repr(self):
262
+ if self.scale_factor is not None:
263
+ info = 'scale_factor=' + str(self.scale_factor)
264
+ else:
265
+ info = 'size=' + str(self.size)
266
+ info += ', mode=' + self.mode
267
+ return info
268
+
269
+
270
+ def pixel_unshuffle(x, scale):
271
+ """ Pixel unshuffle.
272
+ Args:
273
+ x (Tensor): Input feature with shape (b, c, hh, hw).
274
+ scale (int): Downsample ratio.
275
+ Returns:
276
+ Tensor: the pixel unshuffled feature.
277
+ """
278
+ b, c, hh, hw = x.size()
279
+ out_channel = c * (scale**2)
280
+ assert hh % scale == 0 and hw % scale == 0
281
+ h = hh // scale
282
+ w = hw // scale
283
+ x_view = x.view(b, c, h, scale, w, scale)
284
+ return x_view.permute(0, 1, 3, 5, 2, 4).reshape(b, out_channel, h, w)
285
+
286
+
287
+ def pixelshuffle_block(in_nc, out_nc, upscale_factor=2, kernel_size=3, stride=1, bias=True,
288
+ pad_type='zero', norm_type=None, act_type='relu', convtype='Conv2D'):
289
+ """
290
+ Pixel shuffle layer
291
+ (Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional
292
+ Neural Network, CVPR17)
293
+ """
294
+ conv = conv_block(in_nc, out_nc * (upscale_factor ** 2), kernel_size, stride, bias=bias,
295
+ pad_type=pad_type, norm_type=None, act_type=None, convtype=convtype)
296
+ pixel_shuffle = nn.PixelShuffle(upscale_factor)
297
+
298
+ n = norm(norm_type, out_nc) if norm_type else None
299
+ a = act(act_type) if act_type else None
300
+ return sequential(conv, pixel_shuffle, n, a)
301
+
302
+
303
+ def upconv_block(in_nc, out_nc, upscale_factor=2, kernel_size=3, stride=1, bias=True,
304
+ pad_type='zero', norm_type=None, act_type='relu', mode='nearest', convtype='Conv2D'):
305
+ """ Upconv layer """
306
+ upscale_factor = (1, upscale_factor, upscale_factor) if convtype == 'Conv3D' else upscale_factor
307
+ upsample = Upsample(scale_factor=upscale_factor, mode=mode)
308
+ conv = conv_block(in_nc, out_nc, kernel_size, stride, bias=bias,
309
+ pad_type=pad_type, norm_type=norm_type, act_type=act_type, convtype=convtype)
310
+ return sequential(upsample, conv)
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+ ####################
320
+ # Basic blocks
321
+ ####################
322
+
323
+
324
+ def make_layer(basic_block, num_basic_block, **kwarg):
325
+ """Make layers by stacking the same blocks.
326
+ Args:
327
+ basic_block (nn.module): nn.module class for basic block. (block)
328
+ num_basic_block (int): number of blocks. (n_layers)
329
+ Returns:
330
+ nn.Sequential: Stacked blocks in nn.Sequential.
331
+ """
332
+ layers = []
333
+ for _ in range(num_basic_block):
334
+ layers.append(basic_block(**kwarg))
335
+ return nn.Sequential(*layers)
336
+
337
+
338
+ def act(act_type, inplace=True, neg_slope=0.2, n_prelu=1, beta=1.0):
339
+ """ activation helper """
340
+ act_type = act_type.lower()
341
+ if act_type == 'relu':
342
+ layer = nn.ReLU(inplace)
343
+ elif act_type in ('leakyrelu', 'lrelu'):
344
+ layer = nn.LeakyReLU(neg_slope, inplace)
345
+ elif act_type == 'prelu':
346
+ layer = nn.PReLU(num_parameters=n_prelu, init=neg_slope)
347
+ elif act_type == 'tanh': # [-1, 1] range output
348
+ layer = nn.Tanh()
349
+ elif act_type == 'sigmoid': # [0, 1] range output
350
+ layer = nn.Sigmoid()
351
+ else:
352
+ raise NotImplementedError('activation layer [{:s}] is not found'.format(act_type))
353
+ return layer
354
+
355
+
356
+ class Identity(nn.Module):
357
+ def __init__(self, *kwargs):
358
+ super(Identity, self).__init__()
359
+
360
+ def forward(self, x, *kwargs):
361
+ return x
362
+
363
+
364
+ def norm(norm_type, nc):
365
+ """ Return a normalization layer """
366
+ norm_type = norm_type.lower()
367
+ if norm_type == 'batch':
368
+ layer = nn.BatchNorm2d(nc, affine=True)
369
+ elif norm_type == 'instance':
370
+ layer = nn.InstanceNorm2d(nc, affine=False)
371
+ elif norm_type == 'none':
372
+ def norm_layer(x): return Identity()
373
+ else:
374
+ raise NotImplementedError('normalization layer [{:s}] is not found'.format(norm_type))
375
+ return layer
376
+
377
+
378
+ def pad(pad_type, padding):
379
+ """ padding layer helper """
380
+ pad_type = pad_type.lower()
381
+ if padding == 0:
382
+ return None
383
+ if pad_type == 'reflect':
384
+ layer = nn.ReflectionPad2d(padding)
385
+ elif pad_type == 'replicate':
386
+ layer = nn.ReplicationPad2d(padding)
387
+ elif pad_type == 'zero':
388
+ layer = nn.ZeroPad2d(padding)
389
+ else:
390
+ raise NotImplementedError('padding layer [{:s}] is not implemented'.format(pad_type))
391
+ return layer
392
+
393
+
394
+ def get_valid_padding(kernel_size, dilation):
395
+ kernel_size = kernel_size + (kernel_size - 1) * (dilation - 1)
396
+ padding = (kernel_size - 1) // 2
397
+ return padding
398
+
399
+
400
+ class ShortcutBlock(nn.Module):
401
+ """ Elementwise sum the output of a submodule to its input """
402
+ def __init__(self, submodule):
403
+ super(ShortcutBlock, self).__init__()
404
+ self.sub = submodule
405
+
406
+ def forward(self, x):
407
+ output = x + self.sub(x)
408
+ return output
409
+
410
+ def __repr__(self):
411
+ return 'Identity + \n|' + self.sub.__repr__().replace('\n', '\n|')
412
+
413
+
414
+ def sequential(*args):
415
+ """ Flatten Sequential. It unwraps nn.Sequential. """
416
+ if len(args) == 1:
417
+ if isinstance(args[0], OrderedDict):
418
+ raise NotImplementedError('sequential does not support OrderedDict input.')
419
+ return args[0] # No sequential is needed.
420
+ modules = []
421
+ for module in args:
422
+ if isinstance(module, nn.Sequential):
423
+ for submodule in module.children():
424
+ modules.append(submodule)
425
+ elif isinstance(module, nn.Module):
426
+ modules.append(module)
427
+ return nn.Sequential(*modules)
428
+
429
+
430
+ def conv_block(in_nc, out_nc, kernel_size, stride=1, dilation=1, groups=1, bias=True,
431
+ pad_type='zero', norm_type=None, act_type='relu', mode='CNA', convtype='Conv2D',
432
+ spectral_norm=False):
433
+ """ Conv layer with padding, normalization, activation """
434
+ assert mode in ['CNA', 'NAC', 'CNAC'], 'Wrong conv mode [{:s}]'.format(mode)
435
+ padding = get_valid_padding(kernel_size, dilation)
436
+ p = pad(pad_type, padding) if pad_type and pad_type != 'zero' else None
437
+ padding = padding if pad_type == 'zero' else 0
438
+
439
+ if convtype=='PartialConv2D':
440
+ c = PartialConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
441
+ dilation=dilation, bias=bias, groups=groups)
442
+ elif convtype=='DeformConv2D':
443
+ c = DeformConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
444
+ dilation=dilation, bias=bias, groups=groups)
445
+ elif convtype=='Conv3D':
446
+ c = nn.Conv3d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
447
+ dilation=dilation, bias=bias, groups=groups)
448
+ else:
449
+ c = nn.Conv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
450
+ dilation=dilation, bias=bias, groups=groups)
451
+
452
+ if spectral_norm:
453
+ c = nn.utils.spectral_norm(c)
454
+
455
+ a = act(act_type) if act_type else None
456
+ if 'CNA' in mode:
457
+ n = norm(norm_type, out_nc) if norm_type else None
458
+ return sequential(p, c, n, a)
459
+ elif mode == 'NAC':
460
+ if norm_type is None and act_type is not None:
461
+ a = act(act_type, inplace=False)
462
+ n = norm(norm_type, in_nc) if norm_type else None
463
+ return sequential(n, a, p, c)
stable-diffusion-webui-master/modules/extensions.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import traceback
4
+
5
+ import git
6
+
7
+ from modules import paths, shared
8
+
9
+ extensions = []
10
+ extensions_dir = os.path.join(paths.script_path, "extensions")
11
+
12
+
13
+ def active():
14
+ return [x for x in extensions if x.enabled]
15
+
16
+
17
+ class Extension:
18
+ def __init__(self, name, path, enabled=True):
19
+ self.name = name
20
+ self.path = path
21
+ self.enabled = enabled
22
+ self.status = ''
23
+ self.can_update = False
24
+
25
+ repo = None
26
+ try:
27
+ if os.path.exists(os.path.join(path, ".git")):
28
+ repo = git.Repo(path)
29
+ except Exception:
30
+ print(f"Error reading github repository info from {path}:", file=sys.stderr)
31
+ print(traceback.format_exc(), file=sys.stderr)
32
+
33
+ if repo is None or repo.bare:
34
+ self.remote = None
35
+ else:
36
+ try:
37
+ self.remote = next(repo.remote().urls, None)
38
+ self.status = 'unknown'
39
+ except Exception:
40
+ self.remote = None
41
+
42
+ def list_files(self, subdir, extension):
43
+ from modules import scripts
44
+
45
+ dirpath = os.path.join(self.path, subdir)
46
+ if not os.path.isdir(dirpath):
47
+ return []
48
+
49
+ res = []
50
+ for filename in sorted(os.listdir(dirpath)):
51
+ res.append(scripts.ScriptFile(self.path, filename, os.path.join(dirpath, filename)))
52
+
53
+ res = [x for x in res if os.path.splitext(x.path)[1].lower() == extension and os.path.isfile(x.path)]
54
+
55
+ return res
56
+
57
+ def check_updates(self):
58
+ repo = git.Repo(self.path)
59
+ for fetch in repo.remote().fetch("--dry-run"):
60
+ if fetch.flags != fetch.HEAD_UPTODATE:
61
+ self.can_update = True
62
+ self.status = "behind"
63
+ return
64
+
65
+ self.can_update = False
66
+ self.status = "latest"
67
+
68
+ def fetch_and_reset_hard(self):
69
+ repo = git.Repo(self.path)
70
+ # Fix: `error: Your local changes to the following files would be overwritten by merge`,
71
+ # because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
72
+ repo.git.fetch('--all')
73
+ repo.git.reset('--hard', 'origin')
74
+
75
+
76
+ def list_extensions():
77
+ extensions.clear()
78
+
79
+ if not os.path.isdir(extensions_dir):
80
+ return
81
+
82
+ for dirname in sorted(os.listdir(extensions_dir)):
83
+ path = os.path.join(extensions_dir, dirname)
84
+ if not os.path.isdir(path):
85
+ continue
86
+
87
+ extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions)
88
+ extensions.append(extension)
89
+
stable-diffusion-webui-master/modules/extras.py ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ import math
3
+ import os
4
+ import sys
5
+ import traceback
6
+
7
+ import numpy as np
8
+ from PIL import Image
9
+
10
+ import torch
11
+ import tqdm
12
+
13
+ from typing import Callable, List, OrderedDict, Tuple
14
+ from functools import partial
15
+ from dataclasses import dataclass
16
+
17
+ from modules import processing, shared, images, devices, sd_models, sd_samplers
18
+ from modules.shared import opts
19
+ import modules.gfpgan_model
20
+ from modules.ui import plaintext_to_html
21
+ import modules.codeformer_model
22
+ import piexif
23
+ import piexif.helper
24
+ import gradio as gr
25
+ import safetensors.torch
26
+
27
+ class LruCache(OrderedDict):
28
+ @dataclass(frozen=True)
29
+ class Key:
30
+ image_hash: int
31
+ info_hash: int
32
+ args_hash: int
33
+
34
+ @dataclass
35
+ class Value:
36
+ image: Image.Image
37
+ info: str
38
+
39
+ def __init__(self, max_size: int = 5, *args, **kwargs):
40
+ super().__init__(*args, **kwargs)
41
+ self._max_size = max_size
42
+
43
+ def get(self, key: LruCache.Key) -> LruCache.Value:
44
+ ret = super().get(key)
45
+ if ret is not None:
46
+ self.move_to_end(key) # Move to end of eviction list
47
+ return ret
48
+
49
+ def put(self, key: LruCache.Key, value: LruCache.Value) -> None:
50
+ self[key] = value
51
+ while len(self) > self._max_size:
52
+ self.popitem(last=False)
53
+
54
+
55
+ cached_images: LruCache = LruCache(max_size=5)
56
+
57
+
58
+ 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):
59
+ devices.torch_gc()
60
+
61
+ imageArr = []
62
+ # Also keep track of original file names
63
+ imageNameArr = []
64
+ outputs = []
65
+
66
+ if extras_mode == 1:
67
+ #convert file to pillow image
68
+ for img in image_folder:
69
+ image = Image.open(img)
70
+ imageArr.append(image)
71
+ imageNameArr.append(os.path.splitext(img.orig_name)[0])
72
+ elif extras_mode == 2:
73
+ assert not shared.cmd_opts.hide_ui_dir_config, '--hide-ui-dir-config option must be disabled'
74
+
75
+ if input_dir == '':
76
+ return outputs, "Please select an input directory.", ''
77
+ image_list = shared.listfiles(input_dir)
78
+ for img in image_list:
79
+ try:
80
+ image = Image.open(img)
81
+ except Exception:
82
+ continue
83
+ imageArr.append(image)
84
+ imageNameArr.append(img)
85
+ else:
86
+ imageArr.append(image)
87
+ imageNameArr.append(None)
88
+
89
+ if extras_mode == 2 and output_dir != '':
90
+ outpath = output_dir
91
+ else:
92
+ outpath = opts.outdir_samples or opts.outdir_extras_samples
93
+
94
+ # Extra operation definitions
95
+
96
+ def run_gfpgan(image: Image.Image, info: str) -> Tuple[Image.Image, str]:
97
+ restored_img = modules.gfpgan_model.gfpgan_fix_faces(np.array(image, dtype=np.uint8))
98
+ res = Image.fromarray(restored_img)
99
+
100
+ if gfpgan_visibility < 1.0:
101
+ res = Image.blend(image, res, gfpgan_visibility)
102
+
103
+ info += f"GFPGAN visibility:{round(gfpgan_visibility, 2)}\n"
104
+ return (res, info)
105
+
106
+ def run_codeformer(image: Image.Image, info: str) -> Tuple[Image.Image, str]:
107
+ restored_img = modules.codeformer_model.codeformer.restore(np.array(image, dtype=np.uint8), w=codeformer_weight)
108
+ res = Image.fromarray(restored_img)
109
+
110
+ if codeformer_visibility < 1.0:
111
+ res = Image.blend(image, res, codeformer_visibility)
112
+
113
+ info += f"CodeFormer w: {round(codeformer_weight, 2)}, CodeFormer visibility:{round(codeformer_visibility, 2)}\n"
114
+ return (res, info)
115
+
116
+ def upscale(image, scaler_index, resize, mode, resize_w, resize_h, crop):
117
+ upscaler = shared.sd_upscalers[scaler_index]
118
+ res = upscaler.scaler.upscale(image, resize, upscaler.data_path)
119
+ if mode == 1 and crop:
120
+ cropped = Image.new("RGB", (resize_w, resize_h))
121
+ cropped.paste(res, box=(resize_w // 2 - res.width // 2, resize_h // 2 - res.height // 2))
122
+ res = cropped
123
+ return res
124
+
125
+ def run_prepare_crop(image: Image.Image, info: str) -> Tuple[Image.Image, str]:
126
+ # Actual crop happens in run_upscalers_blend, this just sets upscaling_resize and adds info text
127
+ nonlocal upscaling_resize
128
+ if resize_mode == 1:
129
+ upscaling_resize = max(upscaling_resize_w/image.width, upscaling_resize_h/image.height)
130
+ crop_info = " (crop)" if upscaling_crop else ""
131
+ info += f"Resize to: {upscaling_resize_w:g}x{upscaling_resize_h:g}{crop_info}\n"
132
+ return (image, info)
133
+
134
+ @dataclass
135
+ class UpscaleParams:
136
+ upscaler_idx: int
137
+ blend_alpha: float
138
+
139
+ def run_upscalers_blend(params: List[UpscaleParams], image: Image.Image, info: str) -> Tuple[Image.Image, str]:
140
+ blended_result: Image.Image = None
141
+ image_hash: str = hash(np.array(image.getdata()).tobytes())
142
+ for upscaler in params:
143
+ upscale_args = (upscaler.upscaler_idx, upscaling_resize, resize_mode,
144
+ upscaling_resize_w, upscaling_resize_h, upscaling_crop)
145
+ cache_key = LruCache.Key(image_hash=image_hash,
146
+ info_hash=hash(info),
147
+ args_hash=hash(upscale_args))
148
+ cached_entry = cached_images.get(cache_key)
149
+ if cached_entry is None:
150
+ res = upscale(image, *upscale_args)
151
+ info += f"Upscale: {round(upscaling_resize, 3)}, visibility: {upscaler.blend_alpha}, model:{shared.sd_upscalers[upscaler.upscaler_idx].name}\n"
152
+ cached_images.put(cache_key, LruCache.Value(image=res, info=info))
153
+ else:
154
+ res, info = cached_entry.image, cached_entry.info
155
+
156
+ if blended_result is None:
157
+ blended_result = res
158
+ else:
159
+ blended_result = Image.blend(blended_result, res, upscaler.blend_alpha)
160
+ return (blended_result, info)
161
+
162
+ # Build a list of operations to run
163
+ facefix_ops: List[Callable] = []
164
+ facefix_ops += [run_gfpgan] if gfpgan_visibility > 0 else []
165
+ facefix_ops += [run_codeformer] if codeformer_visibility > 0 else []
166
+
167
+ upscale_ops: List[Callable] = []
168
+ upscale_ops += [run_prepare_crop] if resize_mode == 1 else []
169
+
170
+ if upscaling_resize != 0:
171
+ step_params: List[UpscaleParams] = []
172
+ step_params.append(UpscaleParams(upscaler_idx=extras_upscaler_1, blend_alpha=1.0))
173
+ if extras_upscaler_2 != 0 and extras_upscaler_2_visibility > 0:
174
+ step_params.append(UpscaleParams(upscaler_idx=extras_upscaler_2, blend_alpha=extras_upscaler_2_visibility))
175
+
176
+ upscale_ops.append(partial(run_upscalers_blend, step_params))
177
+
178
+ extras_ops: List[Callable] = (upscale_ops + facefix_ops) if upscale_first else (facefix_ops + upscale_ops)
179
+
180
+ for image, image_name in zip(imageArr, imageNameArr):
181
+ if image is None:
182
+ return outputs, "Please select an input image.", ''
183
+ existing_pnginfo = image.info or {}
184
+
185
+ image = image.convert("RGB")
186
+ info = ""
187
+ # Run each operation on each image
188
+ for op in extras_ops:
189
+ image, info = op(image, info)
190
+
191
+ if opts.use_original_name_batch and image_name != None:
192
+ basename = os.path.splitext(os.path.basename(image_name))[0]
193
+ else:
194
+ basename = ''
195
+
196
+ images.save_image(image, path=outpath, basename=basename, seed=None, prompt=None, extension=opts.samples_format, info=info, short_filename=True,
197
+ no_prompt=True, grid=False, pnginfo_section_name="extras", existing_info=existing_pnginfo, forced_filename=None)
198
+
199
+ if opts.enable_pnginfo:
200
+ image.info = existing_pnginfo
201
+ image.info["extras"] = info
202
+
203
+ if extras_mode != 2 or show_extras_results :
204
+ outputs.append(image)
205
+
206
+ devices.torch_gc()
207
+
208
+ return outputs, plaintext_to_html(info), ''
209
+
210
+ def clear_cache():
211
+ cached_images.clear()
212
+
213
+
214
+ def run_pnginfo(image):
215
+ if image is None:
216
+ return '', '', ''
217
+
218
+ geninfo, items = images.read_info_from_image(image)
219
+ items = {**{'parameters': geninfo}, **items}
220
+
221
+ info = ''
222
+ for key, text in items.items():
223
+ info += f"""
224
+ <div>
225
+ <p><b>{plaintext_to_html(str(key))}</b></p>
226
+ <p>{plaintext_to_html(str(text))}</p>
227
+ </div>
228
+ """.strip()+"\n"
229
+
230
+ if len(info) == 0:
231
+ message = "Nothing found in the image."
232
+ info = f"<div><p>{message}<p></div>"
233
+
234
+ return '', geninfo, info
235
+
236
+
237
+ def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_name, interp_method, multiplier, save_as_half, custom_name, checkpoint_format):
238
+ def weighted_sum(theta0, theta1, alpha):
239
+ return ((1 - alpha) * theta0) + (alpha * theta1)
240
+
241
+ def get_difference(theta1, theta2):
242
+ return theta1 - theta2
243
+
244
+ def add_difference(theta0, theta1_2_diff, alpha):
245
+ return theta0 + (alpha * theta1_2_diff)
246
+
247
+ primary_model_info = sd_models.checkpoints_list[primary_model_name]
248
+ secondary_model_info = sd_models.checkpoints_list[secondary_model_name]
249
+ teritary_model_info = sd_models.checkpoints_list.get(teritary_model_name, None)
250
+
251
+ print(f"Loading {primary_model_info.filename}...")
252
+ theta_0 = sd_models.read_state_dict(primary_model_info.filename, map_location='cpu')
253
+
254
+ print(f"Loading {secondary_model_info.filename}...")
255
+ theta_1 = sd_models.read_state_dict(secondary_model_info.filename, map_location='cpu')
256
+
257
+ if teritary_model_info is not None:
258
+ print(f"Loading {teritary_model_info.filename}...")
259
+ theta_2 = sd_models.read_state_dict(teritary_model_info.filename, map_location='cpu')
260
+ else:
261
+ theta_2 = None
262
+
263
+ theta_funcs = {
264
+ "Weighted sum": (None, weighted_sum),
265
+ "Add difference": (get_difference, add_difference),
266
+ }
267
+ theta_func1, theta_func2 = theta_funcs[interp_method]
268
+
269
+ print(f"Merging...")
270
+
271
+ if theta_func1:
272
+ for key in tqdm.tqdm(theta_1.keys()):
273
+ if 'model' in key:
274
+ if key in theta_2:
275
+ t2 = theta_2.get(key, torch.zeros_like(theta_1[key]))
276
+ theta_1[key] = theta_func1(theta_1[key], t2)
277
+ else:
278
+ theta_1[key] = torch.zeros_like(theta_1[key])
279
+ del theta_2
280
+
281
+ for key in tqdm.tqdm(theta_0.keys()):
282
+ if 'model' in key and key in theta_1:
283
+
284
+ theta_0[key] = theta_func2(theta_0[key], theta_1[key], multiplier)
285
+
286
+ if save_as_half:
287
+ theta_0[key] = theta_0[key].half()
288
+
289
+ # I believe this part should be discarded, but I'll leave it for now until I am sure
290
+ for key in theta_1.keys():
291
+ if 'model' in key and key not in theta_0:
292
+ theta_0[key] = theta_1[key]
293
+ if save_as_half:
294
+ theta_0[key] = theta_0[key].half()
295
+
296
+ ckpt_dir = shared.cmd_opts.ckpt_dir or sd_models.model_path
297
+
298
+ filename = primary_model_info.model_name + '_' + str(round(1-multiplier, 2)) + '-' + secondary_model_info.model_name + '_' + str(round(multiplier, 2)) + '-' + interp_method.replace(" ", "_") + '-merged.' + checkpoint_format
299
+ filename = filename if custom_name == '' else (custom_name + '.' + checkpoint_format)
300
+ output_modelname = os.path.join(ckpt_dir, filename)
301
+
302
+ print(f"Saving to {output_modelname}...")
303
+
304
+ _, extension = os.path.splitext(output_modelname)
305
+ if extension.lower() == ".safetensors":
306
+ safetensors.torch.save_file(theta_0, output_modelname, metadata={"format": "pt"})
307
+ else:
308
+ torch.save(theta_0, output_modelname)
309
+
310
+ sd_models.list_models()
311
+
312
+ print(f"Checkpoint saved.")
313
+ return ["Checkpoint saved to " + output_modelname] + [gr.Dropdown.update(choices=sd_models.checkpoint_tiles()) for _ in range(4)]
stable-diffusion-webui-master/modules/face_restoration.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules import shared
2
+
3
+
4
+ class FaceRestoration:
5
+ def name(self):
6
+ return "None"
7
+
8
+ def restore(self, np_image):
9
+ return np_image
10
+
11
+
12
+ def restore_faces(np_image):
13
+ face_restorers = [x for x in shared.face_restorers if x.name() == shared.opts.face_restoration_model or shared.opts.face_restoration_model is None]
14
+ if len(face_restorers) == 0:
15
+ return np_image
16
+
17
+ face_restorer = face_restorers[0]
18
+
19
+ return face_restorer.restore(np_image)