Skip to content

Commit

Permalink
speed up install and config
Browse files Browse the repository at this point in the history
  • Loading branch information
glucauze committed Aug 14, 2023
1 parent 17db6ea commit 054f693
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 74 deletions.
2 changes: 1 addition & 1 deletion check.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
autoflake --in-place --remove-unused-variables -r --remove-all-unused-imports .
mypy --install-types
mypy --non-interactive --install-types
pre-commit run --all-files
7 changes: 6 additions & 1 deletion install.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def is_installed(package: str) -> bool:
required_version = parse(package.split(">=")[1])
return installed_version >= required_version
else:
if package_name == "opencv-python":
return launch.is_installed(package_name) or launch.is_installed("cv2")
return launch.is_installed(package_name)

print("Checking faceswaplab requirements")
Expand All @@ -59,4 +61,7 @@ def is_installed(package: str) -> bool:
raise e


check_install()
import timeit

check_time = timeit.timeit(check_install, number=1)
print(check_time)
1 change: 1 addition & 0 deletions models.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"analyzerName":"intellisense-members-lstm-pylance","languageName":"python","identity":{"modelId":"E61945A9A512ED5E1A3EE3F1A2365B88F8FE","outputId":"E4E9EADA96734F01970E616FAB2FAC19","modifiedTimeUtc":"2020-08-11T14:06:50.811Z"},"filePath":"E61945A9A512ED5E1A3EE3F1A2365B88F8FE_E4E9EADA96734F01970E616FAB2FAC19","lastAccessTimeUtc":"2023-08-14T21:58:14.988Z"}]
1 change: 0 additions & 1 deletion requirements-gpu.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ dill
ifnude
insightface==0.7.3
onnx>=1.14.0
opencv-python
pandas
pydantic
safetensors
Expand Down
46 changes: 2 additions & 44 deletions scripts/configure.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,15 @@
import os
from tqdm import tqdm
import traceback
import urllib.request
from scripts.faceswaplab_utils.faceswaplab_logging import logger
from scripts.faceswaplab_globals import *
from packaging import version
import pkg_resources
import hashlib
from scripts.faceswaplab_utils.models_utils import check_model

ALREADY_DONE = False


def check_install() -> None:
# Very ugly hack :( due to sdnext optimization not calling install.py every time if git log has not changed
import importlib.util
import sys
import os

current_dir = os.path.dirname(os.path.realpath(__file__))
check_install_path = os.path.join(current_dir, "..", "install.py")
spec = importlib.util.spec_from_file_location("check_install", check_install_path)
check_install = importlib.util.module_from_spec(spec)
sys.modules["check_install"] = check_install
spec.loader.exec_module(check_install)
check_install.check_install() # type: ignore
#### End of ugly hack :( !


def is_sha1_matching(file_path: str, expected_sha1: str) -> bool:
sha1_hash = hashlib.sha1(usedforsecurity=False)
try:
with open(file_path, "rb") as file:
for byte_block in iter(lambda: file.read(4096), b""):
sha1_hash.update(byte_block)
if sha1_hash.hexdigest() == expected_sha1:
return True
else:
return False
except Exception as e:
logger.error(
"Failed to check model hash, check the model is valid or has been downloaded adequately : %e",
e,
)
traceback.print_exc()
return False


def check_configuration() -> None:
global ALREADY_DONE

Expand Down Expand Up @@ -83,13 +47,7 @@ def download(url: str, path: str) -> None:

if not os.path.exists(model_path):
download(model_url, model_path)

if not is_sha1_matching(model_path, EXPECTED_INSWAPPER_SHA1):
logger.error(
"Suspicious sha1 for model %s, check the model is valid or has been downloaded adequately. Should be %s",
model_path,
EXPECTED_INSWAPPER_SHA1,
)
check_model()

gradio_version = pkg_resources.get_distribution("gradio").version

Expand Down
18 changes: 9 additions & 9 deletions scripts/faceswaplab.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from scripts.faceswaplab_swapping import swapper
from scripts.faceswaplab_ui import faceswaplab_tab, faceswaplab_unit_ui
from scripts.faceswaplab_utils import faceswaplab_logging, imgutils, models_utils
from scripts.faceswaplab_utils.models_utils import get_current_model
from scripts.faceswaplab_utils.models_utils import get_current_swap_model
from scripts.faceswaplab_utils.typing import *
from scripts.faceswaplab_utils.ui_utils import dataclasses_from_flat_list
from scripts.faceswaplab_utils.faceswaplab_logging import logger, save_img_debug
Expand Down Expand Up @@ -99,7 +99,7 @@ def title(self) -> str:
return f"faceswaplab"

def show(self, is_img2img: bool) -> bool:
return scripts.AlwaysVisible
return scripts.AlwaysVisible # type: ignore

def ui(self, is_img2img: bool) -> List[gr.components.Component]:
with gr.Accordion(f"FaceSwapLab {VERSION_FLAG}", open=False):
Expand Down Expand Up @@ -147,7 +147,7 @@ def process(
(img, None) for img in p.init_images
]
new_inits = swapper.process_images_units(
get_current_model(),
get_current_swap_model(),
self.swap_in_source_units,
images=init_images,
force_blend=True,
Expand Down Expand Up @@ -181,7 +181,7 @@ def postprocess(
for i, (img, info) in enumerate(zip(orig_images, orig_infotexts)):
batch_index = i % p.batch_size
swapped_images = swapper.process_images_units(
get_current_model(),
get_current_swap_model(),
self.swap_in_generated_units,
images=[(img, info)],
)
Expand Down Expand Up @@ -213,8 +213,8 @@ def postprocess(
swp_img,
p.outpath_samples,
"",
p.all_seeds[batch_index],
p.all_prompts[batch_index],
p.all_seeds[batch_index], # type: ignore
p.all_prompts[batch_index], # type: ignore
opts.samples_format,
info=new_info,
p=p,
Expand All @@ -231,16 +231,16 @@ def postprocess(
text = processed.infotexts[0]
infotexts.insert(0, text)
if opts.enable_pnginfo:
grid.info["parameters"] = text
grid.info["parameters"] = text # type: ignore
images.insert(0, grid)

if opts.grid_save:
save_image(
grid,
p.outpath_grids,
"swapped-grid",
p.all_seeds[0],
p.all_prompts[0],
p.all_seeds[0], # type: ignore
p.all_prompts[0], # type: ignore
opts.grid_format,
info=text,
short_filename=not opts.grid_extended_filename,
Expand Down
15 changes: 12 additions & 3 deletions scripts/faceswaplab_globals.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import os
from modules import scripts
from modules.shared import opts

# Defining the absolute path for the 'faceswaplab' directory inside 'models' directory
MODELS_DIR = os.path.abspath(os.path.join("models", "faceswaplab"))
# Defining the absolute path for the 'analysers' directory inside 'MODELS_DIR'
ANALYZER_DIR = os.path.abspath(os.path.join(MODELS_DIR, "analysers"))
# Defining the absolute path for the 'parser' directory inside 'MODELS_DIR'
FACE_PARSER_DIR = os.path.abspath(os.path.join(MODELS_DIR, "parser"))
# Defining the absolute path for the 'faces' directory inside 'MODELS_DIR'
FACES_DIR = os.path.abspath(os.path.join(MODELS_DIR, "faces"))

# Constructing the path for 'references' directory inside the 'extensions' and 'sd-webui-faceswaplab' directories, based on the base directory of scripts
REFERENCE_PATH = os.path.join(
scripts.basedir(), "extensions", "sd-webui-faceswaplab", "references"
)

VERSION_FLAG: str = "v1.2.1"
# Defining the version flag for the application
VERSION_FLAG: str = "v1.2.2"
# Defining the path for 'sd-webui-faceswaplab' inside the 'extensions' directory
EXTENSION_PATH = os.path.join("extensions", "sd-webui-faceswaplab")

# The NSFW score threshold. If any part of the image has a score greater than this threshold, the image will be considered NSFW.
NSFW_SCORE_THRESHOLD: float = 0.7
# Defining the NSFW score threshold. Any image part with a score above this value will be treated as NSFW (Not Safe For Work)
NSFW_SCORE_THRESHOLD: float = opts.data.get("faceswaplab_nsfw_threshold", 0.7) # type: ignore
# Defining the expected SHA1 hash value for 'INSWAPPER'
EXPECTED_INSWAPPER_SHA1 = "17a64851eaefd55ea597ee41e5c18409754244c5"
4 changes: 2 additions & 2 deletions scripts/faceswaplab_settings/faceswaplab_settings.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from scripts.faceswaplab_utils.models_utils import get_models
from scripts.faceswaplab_utils.models_utils import get_swap_models
from modules import script_callbacks, shared
import gradio as gr


def on_ui_settings() -> None:
section = ("faceswaplab", "FaceSwapLab")
models = get_models()
models = get_swap_models()
shared.opts.add_option(
"faceswaplab_model",
shared.OptionInfo(
Expand Down
6 changes: 3 additions & 3 deletions scripts/faceswaplab_swapping/swapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from scripts.faceswaplab_postprocessing.postprocessing_options import (
PostProcessingOptions,
)
from scripts.faceswaplab_utils.models_utils import get_current_model
from scripts.faceswaplab_utils.models_utils import get_current_swap_model
from scripts.faceswaplab_utils.typing import CV2ImgU8, PILImage, Face
from scripts.faceswaplab_inpainting.i2i_pp import img2img_diffusion
from modules import shared
Expand All @@ -51,7 +51,7 @@ def use_gpu() -> bool:
def force_install_gpu_providers() -> None:
# Ugly Ugly hack due to SDNEXT :
try:
from scripts.configure import check_install
from scripts.faceswaplab_utils.install_utils import check_install

logger.warning("Try to reinstall gpu dependencies")
check_install()
Expand Down Expand Up @@ -180,7 +180,7 @@ def batch_process(

current_images = []
swapped_images = process_images_units(
get_current_model(), images=[(src_image, None)], units=units
get_current_swap_model(), images=[(src_image, None)], units=units
)
if len(swapped_images) > 0:
current_images += [img for img, _ in swapped_images]
Expand Down
4 changes: 2 additions & 2 deletions scripts/faceswaplab_ui/faceswaplab_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from scripts.faceswaplab_ui.faceswaplab_unit_ui import faceswap_unit_ui
from scripts.faceswaplab_utils import face_checkpoints_utils, imgutils
from scripts.faceswaplab_utils.faceswaplab_logging import logger
from scripts.faceswaplab_utils.models_utils import get_models
from scripts.faceswaplab_utils.models_utils import get_swap_models
from scripts.faceswaplab_utils.ui_utils import dataclasses_from_flat_list


Expand Down Expand Up @@ -232,7 +232,7 @@ def batch_process(


def tools_ui() -> None:
models = get_models()
models = get_swap_models()
with gr.Tab("Tools"):
with gr.Tab("Build"):
gr.Markdown(
Expand Down
4 changes: 2 additions & 2 deletions scripts/faceswaplab_utils/face_checkpoints_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from scripts.faceswaplab_utils.faceswaplab_logging import logger
from scripts.faceswaplab_utils.typing import *
from scripts.faceswaplab_utils import imgutils
from scripts.faceswaplab_utils.models_utils import get_models
from scripts.faceswaplab_utils.models_utils import get_swap_models
import traceback

import dill as pickle # will be removed in future versions
Expand Down Expand Up @@ -90,7 +90,7 @@ def build_face_checkpoint_and_save(
target_faces=[target_face],
source_face=blended_face,
target_img=reference_preview_img,
model=get_models()[0],
model=get_swap_models()[0],
swapping_options=InswappperOptions(face_restorer_name="Codeformer"),
)
preview_image = result.image
Expand Down
18 changes: 18 additions & 0 deletions scripts/faceswaplab_utils/install_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from types import ModuleType


def check_install() -> None:
# Very ugly hack :( due to sdnext optimization not calling install.py every time if git log has not changed
import importlib.util
import sys
import os

current_dir = os.path.dirname(os.path.realpath(__file__))
check_install_path = os.path.join(current_dir, "..", "..", "install.py")
spec = importlib.util.spec_from_file_location("check_install", check_install_path)
if spec != None:
check_install: ModuleType = importlib.util.module_from_spec(spec)
sys.modules["check_install"] = check_install
spec.loader.exec_module(check_install) # type: ignore
check_install.check_install() # type: ignore
#### End of ugly hack :( !
47 changes: 41 additions & 6 deletions scripts/faceswaplab_utils/models_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,47 @@
from typing import List
import modules.scripts as scripts
from modules import scripts
from scripts.faceswaplab_globals import EXTENSION_PATH
from scripts.faceswaplab_globals import EXPECTED_INSWAPPER_SHA1, EXTENSION_PATH
from modules.shared import opts
from scripts.faceswaplab_utils.faceswaplab_logging import logger
import traceback
import hashlib


def get_models() -> List[str]:
def is_sha1_matching(file_path: str, expected_sha1: str) -> bool:
sha1_hash = hashlib.sha1(usedforsecurity=False)
try:
with open(file_path, "rb") as file:
for byte_block in iter(lambda: file.read(4096), b""):
sha1_hash.update(byte_block)
if sha1_hash.hexdigest() == expected_sha1:
return True
else:
return False
except Exception as e:
logger.error(
"Failed to check model hash, check the model is valid or has been downloaded adequately : %e",
e,
)
traceback.print_exc()
return False


def check_model() -> bool:
model_path = get_current_swap_model()
if not is_sha1_matching(
file_path=model_path, expected_sha1=EXPECTED_INSWAPPER_SHA1
):
logger.error(
"Suspicious sha1 for model %s, check the model is valid or has been downloaded adequately. Should be %s",
model_path,
EXPECTED_INSWAPPER_SHA1,
)
return False
return True


def get_swap_models() -> List[str]:
"""
Retrieve a list of swap model files.
Expand All @@ -31,13 +66,13 @@ def get_models() -> List[str]:
return models


def get_current_model() -> str:
model = opts.data.get("faceswaplab_model", None)
def get_current_swap_model() -> str:
model = opts.data.get("faceswaplab_model", None) # type: ignore
if model is None:
models = get_models()
models = get_swap_models()
model = models[0] if len(models) else None
logger.info("Try to use model : %s", model)
if not os.path.isfile(model):
if not os.path.isfile(model): # type: ignore
logger.error("The model %s cannot be found or loaded", model)
raise FileNotFoundError(
"No faceswap model found. Please add it to the faceswaplab directory."
Expand Down

0 comments on commit 054f693

Please sign in to comment.