UPDATE: CUDA Support

- Full support of ORT-GPU alongside with ORT
- New opton in Settings: Execution Provider selector
- Many different fixes and improvements
VersionUP (0.5.0 alpha2)
This commit is contained in:
Gourieff 2023-11-04 22:37:07 +07:00
parent 4721a4baef
commit b75aa16b11
20 changed files with 230 additions and 172 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ __pycache__/
example
toDo.txt
last_device.txt

View File

@ -1,32 +1,9 @@
<div align="center">
<img src="example/ReActor_logo_red.png" alt="logo" width="180px"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/ReActor_logo_red.png?raw=true" alt="logo" width="180px"/>
![Version](https://img.shields.io/badge/version-0.5.0_alpha1-lightgreen?style=for-the-badge&labelColor=darkgreen)
![Version](https://img.shields.io/badge/version-0.5.0_alpha2-lightgreen?style=for-the-badge&labelColor=darkgreen)
<table>
<tr>
<td width="50%">
<b>
for Any GPU
</b>
<br>
<sup>
NVIDIA / AMD / Intel
</sup>
</td>
<td width="144px">
<a href="https://github.com/Gourieff/sd-webui-reactor-force" target="_blank">
for NVIDIA GPU
<br>
<sup>
8Gb VRAM or more
</sup>
</a>
</td>
</tr>
</table>
<a href='https://ko-fi.com/gourieff' target='_blank'><img height='33' src='https://storage.ko-fi.com/cdn/kofi3.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
<hr>
@ -41,15 +18,9 @@
# ReActor for Stable Diffusion
</div>
### The Fast and Simple FaceSwap Extension with a lot of improvements and without NSFW filter (uncensored, use it on your own [responsibility](#disclaimer))
> Ex "Roop-GE" (GE - Gourieff Edition, aka "NSFW-Roop"), the extension was renamed with the version 0.3.0<br>
> Repository old link: `https://github.com/Gourieff/sd-webui-roop-nsfw`
### The Fast and Simple FaceSwap Extension with a lot of improvements and without NSFW filter (uncensored, use it on your own [responsibility](#disclaimer))
---
<div align="center">
<b>
<a href="#installation">Installation</a> | <a href="#features">Features</a> | <a href="#usage">Usage</a> | <a href="#api">API</a> | <a href="#troubleshooting">Troubleshooting</a> | <a href="#updating">Updating</a> | <a href="#comfyui">ComfyUI</a> | <a href="#disclaimer">Disclaimer</a>
</b>
@ -83,7 +54,7 @@
</tr>
</table>
<img src="example/demo_crop.jpg" alt="example"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/demo_crop.jpg?raw=true" alt="example"/>
## Installation
@ -100,8 +71,8 @@
2. In web-ui, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab and click "Install"
3. Please, wait for several minutes until the installation process will be finished
4. Check the last message in your SD-WebUI Console:
* If you see the message "--- PLEASE, RESTART the Server! ---" - so, do it, stop the Server (CTRL+C or CMD+C) and start it again - or just go to the "Installed" tab (*if you have any other Roop-based extension enabled - disable it, otherwise this extension won't work*), click "Apply and restart UI"
* If you see the message "Done!", just go to the "Installed" tab (*if you have any other Roop-based extension enabled - disable it, otherwise this extension won't work*), click "Apply and restart UI" - or you can just simply reload the UI
* If you see the message "--- PLEASE, RESTART the Server! ---" - so, do it, stop the Server (CTRL+C or CMD+C) and start it again - or just go to the "Installed" tab, click "Apply and restart UI"
* If you see the message "Done!", just reload the UI
5. Enjoy!
<a name="sdnext">If you use [SD.Next](https://github.com/vladmandic/automatic):
@ -113,15 +84,15 @@
5. Run SD.Next, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab and click "Install"
6. Please, wait for several minutes until the installation process will be finished
7. Check the last message in your SD.Next Console:
* If you see the message "--- PLEASE, RESTART the Server! ---" - so, do it, stop the Server (CTRL+C or CMD+C) and start it again - or just go to the "Installed" tab (*if you have any other Roop-based extension enabled - disable it, otherwise this extension won't work*), click "Restart the UI"
8. Stop SD.Next, go to the `automatic\extensions\sd-webui-reactor` directory - if you see there `models\insightface` folder with the file `inswapper_128.onnx`, just move the file to the `automatic\models\insightface` folder
* If you see the message "--- PLEASE, RESTART the Server! ---" - stop the Server (CTRL+C or CMD+C) or just close your console
8. Go to the `automatic\extensions\sd-webui-reactor` directory - if you see there `models\insightface` folder with the file `inswapper_128.onnx`, just move the file to the `automatic\models\insightface` folder
9. Run your SD.Next WebUI and enjoy!
<a name="colab">If you use [Cagliostro Colab UI](https://github.com/Linaqruf/sd-notebook-collection):
1. In active WebUI, go to the "Extensions" tab and use this URL `https://github.com/Gourieff/sd-webui-reactor` in the "Install from URL" tab and click "Install"
2. Please, wait for several minutes until the installation process will be finished
3. When you see the message "--- PLEASE, RESTART the Server! ---" (in your Colab Notebook Start UI section "Start Cagliostro Colab UI") - just go to the "Installed" tab and click "Apply and restart UI" (*if you have any other Roop-based extension enabled - disable it before restart, otherwise this extension won't work*)
3. When you see the message "--- PLEASE, RESTART the Server! ---" (in your Colab Notebook Start UI section "Start Cagliostro Colab UI") - just go to the "Installed" tab and click "Apply and restart UI"
4. Enjoy!
## Features
@ -135,6 +106,7 @@
- Ability to set the **Postprocessing order**
- **100% compatibility** with different **SD WebUIs**: Automatic1111, SD.Next, Cagliostro Colab UI
- **Fast performance** even with CPU, ReActor for SD WebUI is absolutely not picky about how powerful your GPU is
- **CUDA** acceleration support from the version 0.5.0
- **[API](/API.md) support**: both SD WebUI built-in and external (via POST/GET requests)
- **ComfyUI [support](https://github.com/Gourieff/comfyui-reactor-node)**
- **Mac M1/M2 [support](https://github.com/Gourieff/sd-webui-reactor/issues/42)**
@ -149,7 +121,7 @@
2. Turn on the "Enable" checkbox;
3. That's it, now the generated result will have the face you selected.
<img src="example/example.jpg" alt="example" width="808"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/example.jpg?raw=true" alt="example" width="808"/>
### Face Indexes
@ -172,18 +144,18 @@ ReActor will swap a face only if it meets the given condition.
### The result face is blurry
Use the "Restore Face" option. You can also try the "Upscaler" option or for more finer control, use an upscaler from the "Extras" tab.
You can also set the postproduction order (from 0.1.0 version):
<img src="example/pp-order.png" alt="example"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/pp-order.png?raw=true" alt="example"/>
*The old logic was the opposite (Upscale -> then Restore), resulting in worse face quality (and big texture differences) after upscaling.*
### There are multiple faces in result
Select the face numbers you wish to swap using the "Comma separated face number(s)" option for swap-source and result images. You can use different index order.
<img src="example/multiple-faces.png" alt="example"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/multiple-faces.png?raw=true" alt="example"/>
### ~~The result is totally black~~
~~This means NSFW filter detected that your image is NSFW.~~
<img src="example/IamSFW.jpg" alt="IamSFW" width="50%"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/IamSFW.jpg?raw=true" alt="IamSFW" width="50%"/>
### Img2Img
@ -191,21 +163,11 @@ You can choose to activate the swap on the source image or on the generated imag
ReActor works with Inpainting - but only the masked part will be swapped.<br>Please use with the "Only masked" option for "Inpaint area" if you enabled "Upscaler". Otherwise use the upscale option via the Extras tab or via the Script loader (below the screen) with "SD upscale" or "Ultimate SD upscale".
### ReActor + FaceSwapLab inside one enclosure
### Extras Tab
If you have troubles running both extensions together, try the following:
From the version 0.5.0 you can use ReActor via the Extras Tab. It gives a superfast perfomance and ability to swap face2image avoiding SD pipeline that can cause smushing of original image's details
**for NVIDIA GPU with VRAM > 6Gb:**
<br>&nbsp;&nbsp;&nbsp; Just use [ReActor Force](https://github.com/Gourieff/sd-webui-reactor-force)
**for any other GPU**:
1. Delete FaceSwapLab from the extensions folder
2. Delete `onnxruntime` and `onnxruntime-gpu` folders from the site-packages directory (inside VENV Lib)
3. Run SD WebUI and let ReActor to install `onnxruntime`, close SD WebUI
4. `git clone https://github.com/glucauze/sd-webui-faceswaplab` into the SD WebUI extensions folder
5. Edit `sd-webui-faceswaplab/install.py` file:
- Line 9: `use_gpu = True` -> `use_gpu = False`
6. Run SD WebUI, both extensions must work fine after that
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/extras_tab.jpg?raw=true" alt="IamSFW"/>
## API
@ -236,7 +198,7 @@ Please, check the path where "inswapper_128.onnx" model is stored. It must be in
7. Then one-by-one:
- `pip install insightface==0.7.3`
- `pip install onnx`
- `pip install onnxruntime`
- `pip install onnxruntime-gpu>=1.16.1` if you have CUDA, otherwise `pip install onnxruntime`
- `pip install opencv-python`
- `pip install tqdm`
8. Type `deactivate`, you can close your Terminal or Console and start your SD WebUI, ReActor should start OK - if not, welcome to the Issues section.
@ -245,7 +207,7 @@ Please, check the path where "inswapper_128.onnx" model is stored. It must be in
First of all - you need to disable any other Roop-based extensions:
- Go to 'Extensions -> Installed' tab and uncheck any Roop-based extensions except this one
<img src="example/roop-off.png" alt="uncompatible-with-other-roop"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/roop-off.png?raw=true" alt="uncompatible-with-other-roop"/>
- Click 'Apply and restart UI'
Alternative solutions:
@ -254,7 +216,7 @@ Alternative solutions:
### **IV. "AttributeError: 'FaceSwapScript' object has no attribute 'enable'"**
You need to disable the "SD-CN-Animation" extension (or perhaps some another that causes the conflict)
Probably, you need to disable the "SD-CN-Animation" extension (or perhaps some another that causes the conflict)
### **V. "INVALID_PROTOBUF : Load model from <...>\models\insightface\inswapper_128.onnx failed:Protobuf parsing failed" OR "AttributeError: 'NoneType' object has no attribute 'get'" OR "AttributeError: 'FaceSwapScript' object has no attribute 'save_original'"**
@ -270,10 +232,10 @@ and put it to the `stable-diffusion-webui\models\insightface` replacing existing
3. Go to the (Windows)`venv\Scripts` or (MacOS/Linux)`venv/bin` run Terminal or Console (cmd) there and type `activate`
4. Then:
- `python -m pip install -U pip`
- `pip uninstall -y onnx onnxruntime onnxruntime-gpu onnxruntime-silicon onnxruntime-extensions`
- `pip install onnx==1.14.1 onnxruntime`
- `pip uninstall -y onnxruntime onnxruntime-gpu onnxruntime-silicon onnxruntime-extensions`
- `pip install onnxruntime-gpu>=1.16.1` if you have CUDA, otherwise `pip install onnxruntime`
If it didn't help - it seems that you have another extension reinstalling `onnxruntime` when SD WebUI checks requirements. Please see your extensions list. If you find there "WD14 tagger" - try to disable it and then follow the steps above once again. This extension causes reinstalling of `onnxruntime` to `onnxruntime-gpu` or `onnxruntime==1.16.0` every time SD WebUI runs.<br>ORT 1.16.0 has a bug https://github.com/microsoft/onnxruntime/issues/17631 - don't install it!
If it didn't help - it seems that you have another extension reinstalling `onnxruntime` when SD WebUI checks requirements. Please see your extensions list. Some extensions can causes reinstalling of `onnxruntime` or `onnxruntime-gpu` to `onnxruntime<1.16.1` every time SD WebUI runs.<br>ORT 1.16.0 has a bug https://github.com/microsoft/onnxruntime/issues/17631 - don't install it!
### **VII. "ImportError: cannot import name 'builder' from 'google.protobuf.internal'"**

View File

@ -1,32 +1,9 @@
<div align="center">
<img src="example/ReActor_logo_red.png" alt="logo" width="180px"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/ReActor_logo_red.png?raw=true" alt="logo" width="180px"/>
![Version](https://img.shields.io/badge/версия-0.5.0_alpha1-lightgreen?style=for-the-badge&labelColor=darkgreen)
![Version](https://img.shields.io/badge/версия-0.5.0_alpha2-lightgreen?style=for-the-badge&labelColor=darkgreen)
<table>
<tr>
<td width="50%">
<b>
для любых GPU
</b>
<br>
<sup>
NVIDIA / AMD / Intel
</sup>
</td>
<td width="150px">
<a href="https://github.com/Gourieff/sd-webui-reactor-force" target="_blank">
для GPU NVIDIA
<br>
<sup>
б VRAM или более
</sup>
</a>
</td>
</tr>
</table>
<a href='https://ko-fi.com/gourieff' target='_blank'><img height='33' src='https://storage.ko-fi.com/cdn/kofi3.png?v=3' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
<hr>
@ -42,10 +19,7 @@
# ReActor для Stable Diffusion
### Расширение для быстрой и простой замены лиц на любых изображениях. Без фильтра цензуры, 18+, используйте под вашу собственную [ответственность](#disclaimer)
</div>
---
<div align="center">
<b>
<a href="#installation">Установка</a> | <a href="#features">Возможности</a> | <a href="#usage">Использование</a> | <a href="#api">API</a> | <a href="#troubleshooting">Устранение проблем</a> | <a href="#updating">Обновление</a> | <a href="#comfyui">ComfyUI</a> | <a href="#disclaimer">Ответственность</a>
</b>
@ -79,7 +53,7 @@
</tr>
</table>
<img src="example/demo_crop.jpg" alt="example"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/demo_crop.jpg?raw=true" alt="example"/>
<a name="installation">
@ -98,8 +72,8 @@
2. Внутри SD Web-UI перейдите во вкладку "Extensions" и вставьте ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" и нажмите "Install"
3. Пожалуйста, подождите несколько минут, пока процесс установки полностью не завершится
4. Проверьте последнее сообщение в консоли SD-WebUI:
* Если вы видите "--- PLEASE, RESTART the Server! ---" - остановите Сервер (CTRL+C или CMD+C) и запустите его заново - ИЛИ же перейдите во вкладку "Installed" (*если у вас имееются какие-либо другие расширение, основанные на Roop или клонах ReActor - отключите их, иначе данное расширение может не работать*), нажмите "Apply and restart UI"
* Если вы видите "Done!", перейдите во вкладку "Installed" (*если у вас имееются какие-либо другие расширение, основанные на Roop или клонах ReActor - отключите их, иначе данное расширение может не работать*), нажмите "Apply and restart UI" - или же просто перезагрузите UI, нажав на "Reload UI"
* Если вы видите "--- PLEASE, RESTART the Server! ---" - остановите Сервер (CTRL+C или CMD+C) и запустите его заново - ИЛИ же перейдите во вкладку "Installed", нажмите "Apply and restart UI"
* Если вы видите "Done!", просто перезагрузите UI, нажав на "Reload UI"
5. Готово!
<a name="sdnext">Если вы используете [SD.Next](https://github.com/vladmandic/automatic):
@ -111,15 +85,15 @@
5. Запустите SD.Next, перейдите во вкладку "Extensions", вставьте эту ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" и нажмите "Install"
6. Пожалуйста, подождите несколько минут, пока процесс установки полностью не завершится
7. Проверьте последнее сообщение в консоли SD.Next:
* Если вы видите "--- PLEASE, RESTART the Server! ---" - остановите Сервер (CTRL+C или CMD+C) и запустите его заново - ИЛИ же перейдите во вкладку "Installed" (*если у вас имееются какие-либо другие расширение, основанные на Roop или клонах ReActor - отключите их, иначе данное расширение может не работать*), нажмите "Restart the UI"
8. Остановите Сервер SD.Next, перейдите в директорию `automatic\extensions\sd-webui-reactor` - если вы видите там папку `models\insightface` с файлом `inswapper_128.onnx` внутри, переместите его в папку `automatic\models\insightface`
* Если вы видите "--- PLEASE, RESTART the Server! ---" - остановите Сервер (CTRL+C или CMD+C) или просто закройте консоль
8. Перейдите в директорию `automatic\extensions\sd-webui-reactor` - если вы видите там папку `models\insightface` с файлом `inswapper_128.onnx` внутри, переместите его в папку `automatic\models\insightface`
9. Готово, можете запустить SD.Next WebUI!
<a name="colab">Если вы используете [Cagliostro Colab UI](https://github.com/Linaqruf/sd-notebook-collection):
1. В активном WebUI, перейдите во вкладку "Extensions", вставьте ссылку `https://github.com/Gourieff/sd-webui-reactor` в "Install from URL" и нажмите "Install"
2. Пожалуйста, подождите некоторое время, пока процесс установки полностью не завершится
3. Когда вы увидите сообщение "--- PLEASE, RESTART the Server! ---" (в секции "Start UI" вашего ноутбука "Start Cagliostro Colab UI") - перейдите во вкладку "Installed" и нажмите "Apply and restart UI" (*если у вас имееются какие-либо другие расширение, основанные на Roop или клонах ReActor - отключите их, иначе данное расширение может не работать*)
3. Когда вы увидите сообщение "--- PLEASE, RESTART the Server! ---" (в секции "Start UI" вашего ноутбука "Start Cagliostro Colab UI") - перейдите во вкладку "Installed" и нажмите "Apply and restart UI"
4. Готово!
<a name="features">
@ -135,6 +109,7 @@
- Возможность задать **порядок постобработки**
- **100% совместимость** с разными **SD WebUI**: Automatic1111, SD.Next, Cagliostro Colab UI
- **Отличная производительность** даже с использованием ЦПУ, ReActor для SD WebUI абсолютно не требователен к мощности вашей видеокарты
- **Поддержка CUDA**, начиная с версии 0.5.0
- **Поддержка [API](/API.md)**: как встроенного в SD WebUI, так и внешнего (через POST/GET запросы)
- **[Поддержка](https://github.com/Gourieff/comfyui-reactor-node) ComfyUI**
- **[Поддержка](https://github.com/Gourieff/sd-webui-reactor/issues/42) компьютеров Mac M1/M2**
@ -151,7 +126,7 @@
2. Установите флажок "Enable";
3. Готово, теперь результат будет иметь то лицо, которое вы выбрали.
<img src="example/example.jpg" alt="example" width="808"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/example.jpg?raw=true" alt="example" width="808"/>
### Индексы Лиц (Face Indexes)
@ -174,18 +149,18 @@ ReActor заменит только то лицо, которое удовлет
### Если лицо получилось нечётким
Используйте опцию "Restore Face". Также можете попробовать опцию "Upscaler". Для более точного контроля параметров используйте Upscaler во вкладке "Extras".
Также вы можете установить порядок постобработки (начиная с версии 0.1.0):
<img src="example/pp-order.png" alt="example"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/pp-order.png?raw=true" alt="example"/>
*Прежняя логика была противоположенной (Upscale -> затем Restore), что приводило к более худшему качеству изображения лица (а также к значительной разнице текстур) после увеличения.*
### Результат имеет несколько лиц
Выберите номера лиц, которые нужно поменять, используя поля "Comma separated face number(s)" для исходного изображения лица и для результата. Можно устанавливать любой, необходимый вам, порядок лиц.
<img src="example/multiple-faces.png" alt="example"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/multiple-faces.png?raw=true" alt="example"/>
### ~~Результат получился чёрным~~
~~Это значит, что сработал NSFW фильтр.~~
<img src="example/IamSFW.jpg" alt="IamSFW" width="50%"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/IamSFW.jpg?raw=true" alt="IamSFW" width="50%"/>
### Img2Img
@ -193,22 +168,11 @@ ReActor заменит только то лицо, которое удовлет
Inpainting также работает, но замена лица происходит только в области маски.<br>Пожалуйста, используйте с опцией "Only masked" для "Inpaint area", если вы применяете "Upscaler". Иначе, используйте функцию увеличения (апскейла) через вкладку "Extras" или через опциональный загрузчик "Script" (внизу экрана), применив "SD upscale" или "Ultimate SD upscale".
### Использование ReActor + FaceSwapLab внутри одной среды
### Extras
Если вы столкнулись с трудностями запуска одновременно обоих расширений, попробуйте сделать следующее:
Начиная с версии 0.5.0, вы можете использовать ReActor через вкладку Extras, что даёт очень быструю производительность и возможность замены лиц в обход пайплайна SD, что иногда вызывает размытие или искажение деталей оригинального изображения
**для GPU NVIDIA с VRAM > 6Гб:**
<br>&nbsp;&nbsp;&nbsp; Используйте [ReActor Force](https://github.com/Gourieff/sd-webui-reactor-force)
**для любых других GPU**:
1. Удалите FaceSwapLab из папки `extensions`
2. Удалите папки `onnxruntime` и `onnxruntime-gpu` из директории `site-packages` (внутри VENV Lib)
3. Запустите SD WebUI, чтобы ReActor установил библиотеку `onnxruntime`, закройте SD WebUI
4. `git clone https://github.com/glucauze/sd-webui-faceswaplab` в папку `extensions`
5. Отредактируйте файл `sd-webui-faceswaplab/install.py`:
- Строка 9: `use_gpu = True` -> `use_gpu = False`
6. Запустите SD WebUI, оба расширения теперь могут работать внутри одного окружения
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/extras_tab.jpg?raw=true" alt="IamSFW"/>
## API
@ -241,7 +205,7 @@ Inpainting также работает, но замена лица происх
7. Далее:
- `pip install insightface==0.7.3`
- `pip install onnx`
- `pip install onnxruntime`
- `pip install onnxruntime-gpu>=1.16.1` если у весть есть GPU с CUDA, иначе `pip install onnxruntime`
- `pip install opencv-python`
- `pip install tqdm`
8. Выполните `deactivate`, закройте Терминал или Консоль и запустите SD WebUI, ReActor должен запуститься без к-л проблем - если же нет, добро пожаловать в раздел "Issues".
@ -250,7 +214,7 @@ Inpainting также работает, но замена лица происх
Для начала отключите любые другие Roop-подобные расширения:
- Перейдите в 'Extensions -> Installed' и снимите флажок с ненужных:
<img src="example/roop-off.png" alt="uncompatible-with-other-roop"/>
<img src="https://github.com/Gourieff/Assets/raw/main/sd-webui-reactor/roop-off.png?raw=true" alt="uncompatible-with-other-roop"/>
- Нажмите 'Apply and restart UI'
Альтернативные решения:
@ -275,10 +239,10 @@ Inpainting также работает, но замена лица происх
3. Перейдите в (Windows)`venv\Scripts` или (MacOS/Linux)`venv/bin`, откройте Терминал или Консоль (cmd) и выполните `activate`
4. Затем:
- `python -m pip install -U pip`
- `pip uninstall -y onnx onnxruntime onnxruntime-gpu onnxruntime-silicon onnxruntime-extensions`
- `pip install onnx==1.14.1 onnxruntime`
- `pip uninstall -y onnxruntime onnxruntime-gpu onnxruntime-silicon onnxruntime-extensions`
- `pip install onnxruntime-gpu>=1.16.1` если у весть есть GPU с CUDA, иначе `pip install onnxruntime`
Если это не помогло - значит какое-то другое расширение переустанавливает `onnxruntime` всякий раз, когда SD WebUI проверяет требования пакетов. Внимательно посмотрите список активных расширений. Если видите там "WD14 tagger" - попробуйте отключить его и ещё раз выполнить шаги выше. Это расширение вызывает переустановку `onnxruntime` на `onnxruntime-gpu` или `onnxruntime==1.16.0` при каждом запуске SD WebUI.<br>ORT 1.16.0 выкатили с ошибкой https://github.com/microsoft/onnxruntime/issues/17631 - не устанавливайте её!
Если это не помогло - значит какое-то другое расширение переустанавливает `onnxruntime` всякий раз, когда SD WebUI проверяет требования пакетов. Внимательно посмотрите список активных расширений. Некоторые расширения могут вызывать переустановку `onnxruntime` или `onnxruntime-gpu` на версию `onnxruntime<1.16.1` при каждом запуске SD WebUI.<br>ORT 1.16.0 выкатили с ошибкой https://github.com/microsoft/onnxruntime/issues/17631 - не устанавливайте её!
### **VII. "ImportError: cannot import name 'builder' from 'google.protobuf.internal'"**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -42,6 +42,7 @@ args=[
0.8, #17 CodeFormer Weight (0 = maximum effect, 1 = minimum effect), 0.5 - by default
False, #18 Source Image Hash Check, True - by default
False, #19 Target Image Hash Check, False - by default
"CUDA", #20 CPU or CUDA (if you have it), CPU - by default
]
# The args for ReActor can be found by

View File

@ -18,5 +18,6 @@ curl -X POST \
"gender_source": 0,
"gender_target": 0,
"save_to_file": 1,
"result_file_path": ""
"result_file_path": "",
"device": "CUDA"
}'

View File

@ -14,5 +14,6 @@
"gender_source": 0,
"gender_target": 0,
"save_to_file": 1,
"result_file_path": ""
"result_file_path": "",
"device": "CUDA"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,5 +1,6 @@
import subprocess
import os, sys
from typing import Any
import pkg_resources
from tqdm import tqdm
import urllib.request
@ -13,7 +14,10 @@ except:
except:
model_path = os.path.abspath("models")
req_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "requirements.txt")
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
req_file = os.path.join(BASE_PATH, "requirements.txt")
models_dir_old = os.path.join(models_path, "roop")
models_dir = os.path.join(models_path, "insightface")
@ -35,6 +39,10 @@ model_url = "https://github.com/facefusion/facefusion-assets/releases/download/m
model_name = os.path.basename(model_url)
model_path = os.path.join(models_dir, model_name)
def get_sd_option(name: str, default: Any) -> Any:
assert shared.opts.data is not None
return shared.opts.data.get(name, default)
def run_pip(*args):
subprocess.run([sys.executable, "-m", "pip", "install", *args])
@ -68,9 +76,46 @@ if not os.path.exists(models_dir):
if not os.path.exists(model_path):
download(model_url, model_path)
print("Checking ReActor requirements...", end=' ')
print("ReActor preheating...", end=' ')
last_device = None
first_run = False
try:
last_device_log = os.path.join(BASE_PATH, "last_device.txt")
with open(last_device_log) as f:
for el in f:
last_device = el.strip()
except:
last_device = "CPU"
first_run = True
with open(os.path.join(BASE_PATH, "last_device.txt"), "w") as txt:
txt.write(last_device)
with open(req_file) as file:
install_count = 0
try:
import torch.cuda as cuda
if cuda.is_available():
ort = "onnxruntime-gpu"
if first_run:
last_device = "CUDA"
with open(os.path.join(BASE_PATH, "last_device.txt"), "w") as txt:
txt.write(last_device)
else:
ort = "onnxruntime"
if last_device == "CUDA":
last_device = "CPU"
with open("last_device.txt", "w") as txt:
txt.write(last_device)
if not is_installed(ort,"1.16.1",False):
install_count += 1
run_pip(ort)
except Exception as e:
print(e)
print(f"\nERROR: Failed to install {ort} - ReActor won't start")
raise e
print(f"Device: {last_device}")
strict = True
for package in file:
package_version = None
@ -89,6 +134,8 @@ with open(req_file) as file:
print(f"\nERROR: Failed to install {package} - ReActor won't start")
raise e
if install_count > 0:
print(f'\n--- PLEASE, RESTART the Server! ---\n')
else:
print('Ok')
print(f"""
+---------------------------------+
--- PLEASE, RESTART the Server! ---
+---------------------------------+
""")

View File

@ -1,4 +1,3 @@
insightface==0.7.3
onnx>=1.14.0
onnxruntime>=1.15.1
opencv-python>=4.7.0.72

View File

@ -70,7 +70,8 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
gender_source: int = Body(0,title="Gender Detection (Source) (0 - No, 1 - Female Only, 2 - Male Only)"),
gender_target: int = Body(0,title="Gender Detection (Target) (0 - No, 1 - Female Only, 2 - Male Only)"),
save_to_file: int = Body(0,title="Save Result to file, 0 - No, 1 - Yes"),
result_file_path: str = Body("",title="(if 'save_to_file = 1') Result file path")
result_file_path: str = Body("",title="(if 'save_to_file = 1') Result file path"),
device: str = Body("CPU",title="CPU or CUDA (if you have it)")
):
s_image = api.decode_base64_to_image(source_image)
t_image = api.decode_base64_to_image(target_image)
@ -83,7 +84,7 @@ def reactor_api(_: gr.Blocks, app: FastAPI):
use_model = get_full_model(model)
if use_model is None:
Exception("Model not found")
result = swap_face(s_image, t_image, use_model, sf_index, f_index, up_options, gender_s, gender_t)
result = swap_face(s_image, t_image, use_model, sf_index, f_index, up_options, gender_s, gender_t, True, True, device)
if save_to_file == 1:
if result_file_path == "":
result_file_path = default_file_path()

View File

@ -1,6 +1,7 @@
import os, glob
import gradio as gr
from PIL import Image
import torch.cuda as cuda
from typing import List
@ -26,7 +27,8 @@ from scripts.reactor_logger import logger
from scripts.reactor_swapper import EnhancementOptions, swap_face, check_process_halt, reset_messaged
from scripts.reactor_version import version_flag, app_title
from scripts.console_log_patch import apply_logging_patch
from scripts.reactor_helpers import make_grid, get_image_path
from scripts.reactor_helpers import make_grid, get_image_path, set_Device
from scripts.reactor_globals import DEVICE, DEVICE_LIST
MODELS_PATH = None
@ -134,6 +136,26 @@ class FaceSwapScript(scripts.Script):
)
with gr.Tab("Settings"):
models = get_models()
if cuda.is_available():
with gr.Row():
device = gr.Radio(
label="Execution Provider",
choices=DEVICE_LIST,
value=DEVICE,
type="value",
info="If you already run 'Generate' - RESTART is required to apply. Click 'Save', (A1111) Extensions Tab -> 'Apply and restart UI' or (SD.Next) close the Server and start it again",
scale=2,
)
save_device_btn = gr.Button("Save", scale=0)
save = gr.Markdown("")
setattr(device, "do_not_save_to_config", True)
save_device_btn.click(
set_Device,
inputs=[device],
outputs=[save],
)
else:
device = "CPU"
with gr.Row():
if len(models) == 0:
logger.warning(
@ -163,7 +185,7 @@ class FaceSwapScript(scripts.Script):
target_hash_check = gr.Checkbox(
False,
label="Target Image Hash Check",
info="Affects if you use img2img with only 'Swap in source image' option."
info="Affects if you use Extras tab or img2img with only 'Swap in source image' on."
)
return [
@ -187,6 +209,7 @@ class FaceSwapScript(scripts.Script):
codeformer_weight,
source_hash_check,
target_hash_check,
device,
]
@ -239,6 +262,7 @@ class FaceSwapScript(scripts.Script):
codeformer_weight,
source_hash_check,
target_hash_check,
device,
):
self.enable = enable
if self.enable:
@ -254,7 +278,8 @@ class FaceSwapScript(scripts.Script):
self.upscaler_visibility = upscaler_visibility
self.face_restorer_visibility = face_restorer_visibility
self.restore_first = restore_first
self.upscaler_name = upscaler_name
self.upscaler_name = upscaler_name
self.swap_in_source = swap_in_source
self.swap_in_generated = swap_in_generated
self.model = os.path.join(MODELS_PATH,model)
self.console_logging_level = console_logging_level
@ -264,6 +289,7 @@ class FaceSwapScript(scripts.Script):
self.codeformer_weight = codeformer_weight
self.source_hash_check = source_hash_check
self.target_hash_check = target_hash_check
self.device = device
if self.gender_source is None or self.gender_source == "No":
self.gender_source = 0
if self.gender_target is None or self.gender_target == "No":
@ -285,9 +311,11 @@ class FaceSwapScript(scripts.Script):
if self.target_hash_check is None:
self.target_hash_check = False
set_Device(self.device)
if self.source is not None:
apply_logging_patch(console_logging_level)
if isinstance(p, StableDiffusionProcessingImg2Img) and swap_in_source:
if isinstance(p, StableDiffusionProcessingImg2Img) and self.swap_in_source:
logger.status("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
for i in range(len(p.init_images)):
@ -304,6 +332,7 @@ class FaceSwapScript(scripts.Script):
gender_target=self.gender_target,
source_hash_check=self.source_hash_check,
target_hash_check=self.target_hash_check,
device=self.device,
)
p.init_images[i] = result
# result_path = get_image_path(p.init_images[i], p.outpath_samples, "", p.all_seeds[i], p.all_prompts[i], "txt", p=p, suffix="-swapped")
@ -354,6 +383,7 @@ class FaceSwapScript(scripts.Script):
gender_target=self.gender_target,
source_hash_check=self.source_hash_check,
target_hash_check=self.target_hash_check,
device=self.device,
)
if result is not None and swapped > 0:
result_images.append(result)
@ -410,6 +440,7 @@ class FaceSwapScript(scripts.Script):
gender_target=self.gender_target,
source_hash_check=self.source_hash_check,
target_hash_check=self.target_hash_check,
device=self.device,
)
try:
pp = scripts_postprocessing.PostprocessedImage(result)
@ -436,7 +467,6 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
with gr.Column():
img = gr.Image(type="pil")
enable = gr.Checkbox(False, label="Enable", info=f"The Fast and Simple FaceSwap Extension - {version_flag}")
gr.Markdown("<br>")
gr.Markdown("Source Image (above):")
with gr.Row():
source_faces_index = gr.Textbox(
@ -450,7 +480,6 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
label="Gender Detection (Source)",
type="index",
)
gr.Markdown("<br>")
gr.Markdown("Target Image (result):")
with gr.Row():
faces_index = gr.Textbox(
@ -464,7 +493,6 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
label="Gender Detection (Target)",
type="index",
)
gr.Markdown("<br>")
with gr.Row():
face_restorer_name = gr.Radio(
label="Restore Face",
@ -479,7 +507,6 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
codeformer_weight = gr.Slider(
0, 1, 0.5, step=0.1, label="CodeFormer Weight", info="0 = maximum effect, 1 = minimum effect"
)
gr.Markdown("<br>")
with gr.Tab("Upscale"):
restore_first = gr.Checkbox(
@ -493,7 +520,6 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
value="None",
info="Won't scale if you choose -Swap in Source- via img2img, only 1x-postprocessing will affect (texturing, denoising, restyling etc.)"
)
gr.Markdown("<br>")
with gr.Row():
upscaler_scale = gr.Slider(1, 8, 1, step=0.1, label="Scale by")
upscaler_visibility = gr.Slider(
@ -501,6 +527,26 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
)
with gr.Tab("Settings"):
models = get_models()
if cuda.is_available():
with gr.Row():
device = gr.Radio(
label="Execution Provider",
choices=DEVICE_LIST,
value=DEVICE,
type="value",
info="If you already run 'Generate' - RESTART is required to apply. Click 'Save', (A1111) Extensions Tab -> 'Apply and restart UI' or (SD.Next) close the Server and start it again",
scale=2,
)
save_device_btn = gr.Button("Save", scale=0)
save = gr.Markdown("")
setattr(device, "do_not_save_to_config", True)
save_device_btn.click(
set_Device,
inputs=[device],
outputs=[save],
)
else:
device = "CPU"
with gr.Row():
if len(models) == 0:
logger.warning(
@ -520,18 +566,6 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
label="Console Log Level",
type="index",
)
gr.Markdown("<br>")
with gr.Row():
source_hash_check = gr.Checkbox(
True,
label="Source Image Hash Check",
info="Recommended to keep it ON. Processing is faster when Source Image is the same."
)
target_hash_check = gr.Checkbox(
False,
label="Target Image Hash Check",
info="Affects if you use img2img with only 'Swap in source image' option."
)
args = {
'img': img,
@ -549,8 +583,7 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
'gender_source': gender_source,
'gender_target': gender_target,
'codeformer_weight': codeformer_weight,
'source_hash_check': source_hash_check,
'target_hash_check': target_hash_check,
'device': device,
}
return args
@ -599,8 +632,7 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
self.gender_source = args['gender_source']
self.gender_target = args['gender_target']
self.codeformer_weight = args['codeformer_weight']
self.source_hash_check = args['source_hash_check']
self.target_hash_check = args['target_hash_check']
self.device = args['device']
if self.gender_source is None or self.gender_source == "No":
self.gender_source = 0
if self.gender_target is None or self.gender_target == "No":
@ -615,17 +647,16 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
self.source_faces_index = [0]
if len(self.faces_index) == 0:
self.faces_index = [0]
if self.source_hash_check is None:
self.source_hash_check = True
if self.target_hash_check is None:
self.target_hash_check = False
current_job_number = shared.state.job_no + 1
job_count = shared.state.job_count
if current_job_number == job_count:
reset_messaged()
set_Device(self.device)
if self.source is not None:
apply_logging_patch(self.console_logging_level)
logger.status("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index)
image: Image.Image = pp.image
result, output, swapped = swap_face(
@ -637,12 +668,14 @@ class FaceSwapScriptExtras(scripts_postprocessing.ScriptPostprocessing):
enhancement_options=self.enhancement_options,
gender_source=self.gender_source,
gender_target=self.gender_target,
source_hash_check=self.source_hash_check,
target_hash_check=self.target_hash_check,
source_hash_check=True,
target_hash_check=True,
device=self.device,
)
try:
pp.info["ReActor"] = True
pp.image = result
logger.status("---Done!---")
except Exception:
logger.error("Cannot create a result image")
else:

View File

@ -1 +1,18 @@
import os
from pathlib import Path
IS_RUN: bool = False
BASE_PATH = os.path.join(Path(__file__).parents[1])
DEVICE_LIST: list = ["CPU", "CUDA"]
def updateDevice():
try:
LAST_DEVICE_PATH = os.path.join(BASE_PATH, "last_device.txt")
with open(LAST_DEVICE_PATH) as f:
for el in f:
device = el.strip()
except:
device = "CPU"
return device
DEVICE = updateDevice()

View File

@ -8,6 +8,17 @@ import hashlib
from modules.images import FilenameGenerator, get_next_sequence_number
from modules import shared, script_callbacks
from scripts.reactor_globals import DEVICE, BASE_PATH
def set_Device(value):
global DEVICE
DEVICE = value
with open(os.path.join(BASE_PATH, "last_device.txt"), "w") as txt:
txt.write(DEVICE)
def get_Device():
global DEVICE
return DEVICE
def make_grid(image_list: List):

View File

@ -1,7 +1,8 @@
import copy
import os
from dataclasses import dataclass
from typing import List, Union
from typing import List, Union, Tuple
from functools import lru_cache
import cv2
import numpy as np
@ -9,7 +10,7 @@ from PIL import Image
import insightface
from scripts.reactor_helpers import get_image_md5hash
from scripts.reactor_helpers import get_image_md5hash, get_Device
from modules.face_restoration import FaceRestoration
try: # A1111
from modules import codeformer_model
@ -31,7 +32,12 @@ import warnings
np.warnings = warnings
np.warnings.filterwarnings('ignore')
providers = ["CPUExecutionProvider"]
DEVICE = get_Device()
if DEVICE == "CUDA":
PROVIDERS = ["CUDAExecutionProvider"]
else:
PROVIDERS = ["CPUExecutionProvider"]
@dataclass
@ -80,21 +86,32 @@ SOURCE_IMAGE_HASH = None
TARGET_FACES = None
TARGET_IMAGE_HASH = None
def getAnalysisModel():
global ANALYSIS_MODEL
if ANALYSIS_MODEL is None:
ANALYSIS_MODEL = insightface.app.FaceAnalysis(
name="buffalo_l", providers=providers, root=os.path.join(models_path, "insightface") # note: allowed_modules=['detection', 'genderage']
name="buffalo_l", providers=PROVIDERS, root=os.path.join(models_path, "insightface") # note: allowed_modules=['detection', 'genderage']
)
return ANALYSIS_MODEL
@lru_cache(maxsize=3)
def getAnalysisModel_CUDA(det_size: Tuple[int, int] = (640, 640)):
global ANALYSIS_MODEL
if ANALYSIS_MODEL is None:
ANALYSIS_MODEL = insightface.app.FaceAnalysis(
name="buffalo_l", providers=PROVIDERS, root=os.path.join(models_path, "insightface") # note: allowed_modules=['detection', 'genderage']
)
ANALYSIS_MODEL.prepare(ctx_id=0, det_size=det_size)
return ANALYSIS_MODEL
@lru_cache(maxsize=1)
def getFaceSwapModel(model_path: str):
global FS_MODEL
global CURRENT_FS_MODEL_PATH
if CURRENT_FS_MODEL_PATH is None or CURRENT_FS_MODEL_PATH != model_path:
CURRENT_FS_MODEL_PATH = model_path
FS_MODEL = insightface.model_zoo.get_model(model_path, providers=providers)
FS_MODEL = insightface.model_zoo.get_model(model_path, providers=PROVIDERS)
return FS_MODEL
@ -210,17 +227,17 @@ def get_face_age(face, face_index):
return "None"
return face_age
# def reget_face_single(img_data: np.ndarray, face, det_size, face_index, gender_source, gender_target):
# det_size_half = (det_size[0] // 2, det_size[1] // 2)
# return get_face_single(img_data, face, face_index=face_index, det_size=det_size_half, gender_source=gender_source, gender_target=gender_target)
def half_det_size(det_size):
logger.status("Trying to halve 'det_size' parameter")
return (det_size[0] // 2, det_size[1] // 2)
def analyze_faces(img_data: np.ndarray, det_size=(640, 640)):
face_analyser = copy.deepcopy(getAnalysisModel())
face_analyser.prepare(ctx_id=0, det_size=det_size)
logger.info("Applied Execution Provider: %s", PROVIDERS[0])
if DEVICE == "CUDA":
face_analyser = getAnalysisModel_CUDA(det_size)
else:
face_analyser = copy.deepcopy(getAnalysisModel())
face_analyser.prepare(ctx_id=0, det_size=det_size)
return face_analyser.get(img_data)
def get_face_single(img_data: np.ndarray, face, face_index=0, det_size=(640, 640), gender_source=0, gender_target=0):
@ -278,9 +295,12 @@ def swap_face(
gender_target: int = 0,
source_hash_check: bool = True,
target_hash_check: bool = False,
device: str = "CPU",
):
global SOURCE_FACES, SOURCE_IMAGE_HASH, TARGET_FACES, TARGET_IMAGE_HASH
global SOURCE_FACES, SOURCE_IMAGE_HASH, TARGET_FACES, TARGET_IMAGE_HASH, PROVIDERS
result_image = target_img
PROVIDERS = ["CUDAExecutionProvider"] if device == "CUDA" else ["CPUExecutionProvider"]
if check_process_halt():
return result_image, [], 0

View File

@ -1,5 +1,5 @@
app_title = "ReActor"
version_flag = "v0.5.0-a1"
version_flag = "v0.5.0-a2"
from scripts.reactor_logger import logger, get_Run, set_Run