speed up install and config

main
Tran Xen 2 years ago
parent 17db6ea2b4
commit 054f693815

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
autoflake --in-place --remove-unused-variables -r --remove-all-unused-imports . autoflake --in-place --remove-unused-variables -r --remove-all-unused-imports .
mypy --install-types mypy --non-interactive --install-types
pre-commit run --all-files pre-commit run --all-files

@ -36,6 +36,8 @@ def check_install() -> None:
required_version = parse(package.split(">=")[1]) required_version = parse(package.split(">=")[1])
return installed_version >= required_version return installed_version >= required_version
else: else:
if package_name == "opencv-python":
return launch.is_installed(package_name) or launch.is_installed("cv2")
return launch.is_installed(package_name) return launch.is_installed(package_name)
print("Checking faceswaplab requirements") print("Checking faceswaplab requirements")
@ -59,4 +61,7 @@ def check_install() -> None:
raise e raise e
check_install() import timeit
check_time = timeit.timeit(check_install, number=1)
print(check_time)

@ -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"}]

@ -3,7 +3,6 @@ dill
ifnude ifnude
insightface==0.7.3 insightface==0.7.3
onnx>=1.14.0 onnx>=1.14.0
opencv-python
pandas pandas
pydantic pydantic
safetensors safetensors

@ -1,51 +1,15 @@
import os import os
from tqdm import tqdm from tqdm import tqdm
import traceback
import urllib.request import urllib.request
from scripts.faceswaplab_utils.faceswaplab_logging import logger from scripts.faceswaplab_utils.faceswaplab_logging import logger
from scripts.faceswaplab_globals import * from scripts.faceswaplab_globals import *
from packaging import version from packaging import version
import pkg_resources import pkg_resources
import hashlib from scripts.faceswaplab_utils.models_utils import check_model
ALREADY_DONE = False 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: def check_configuration() -> None:
global ALREADY_DONE global ALREADY_DONE
@ -83,13 +47,7 @@ def check_configuration() -> None:
if not os.path.exists(model_path): if not os.path.exists(model_path):
download(model_url, model_path) download(model_url, model_path)
check_model()
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,
)
gradio_version = pkg_resources.get_distribution("gradio").version gradio_version = pkg_resources.get_distribution("gradio").version

@ -12,7 +12,7 @@ from scripts.faceswaplab_settings import faceswaplab_settings
from scripts.faceswaplab_swapping import swapper from scripts.faceswaplab_swapping import swapper
from scripts.faceswaplab_ui import faceswaplab_tab, faceswaplab_unit_ui from scripts.faceswaplab_ui import faceswaplab_tab, faceswaplab_unit_ui
from scripts.faceswaplab_utils import faceswaplab_logging, imgutils, models_utils 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.typing import *
from scripts.faceswaplab_utils.ui_utils import dataclasses_from_flat_list from scripts.faceswaplab_utils.ui_utils import dataclasses_from_flat_list
from scripts.faceswaplab_utils.faceswaplab_logging import logger, save_img_debug from scripts.faceswaplab_utils.faceswaplab_logging import logger, save_img_debug
@ -99,7 +99,7 @@ class FaceSwapScript(scripts.Script):
return f"faceswaplab" return f"faceswaplab"
def show(self, is_img2img: bool) -> bool: 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]: def ui(self, is_img2img: bool) -> List[gr.components.Component]:
with gr.Accordion(f"FaceSwapLab {VERSION_FLAG}", open=False): with gr.Accordion(f"FaceSwapLab {VERSION_FLAG}", open=False):
@ -147,7 +147,7 @@ class FaceSwapScript(scripts.Script):
(img, None) for img in p.init_images (img, None) for img in p.init_images
] ]
new_inits = swapper.process_images_units( new_inits = swapper.process_images_units(
get_current_model(), get_current_swap_model(),
self.swap_in_source_units, self.swap_in_source_units,
images=init_images, images=init_images,
force_blend=True, force_blend=True,
@ -181,7 +181,7 @@ class FaceSwapScript(scripts.Script):
for i, (img, info) in enumerate(zip(orig_images, orig_infotexts)): for i, (img, info) in enumerate(zip(orig_images, orig_infotexts)):
batch_index = i % p.batch_size batch_index = i % p.batch_size
swapped_images = swapper.process_images_units( swapped_images = swapper.process_images_units(
get_current_model(), get_current_swap_model(),
self.swap_in_generated_units, self.swap_in_generated_units,
images=[(img, info)], images=[(img, info)],
) )
@ -213,8 +213,8 @@ class FaceSwapScript(scripts.Script):
swp_img, swp_img,
p.outpath_samples, p.outpath_samples,
"", "",
p.all_seeds[batch_index], p.all_seeds[batch_index], # type: ignore
p.all_prompts[batch_index], p.all_prompts[batch_index], # type: ignore
opts.samples_format, opts.samples_format,
info=new_info, info=new_info,
p=p, p=p,
@ -231,7 +231,7 @@ class FaceSwapScript(scripts.Script):
text = processed.infotexts[0] text = processed.infotexts[0]
infotexts.insert(0, text) infotexts.insert(0, text)
if opts.enable_pnginfo: if opts.enable_pnginfo:
grid.info["parameters"] = text grid.info["parameters"] = text # type: ignore
images.insert(0, grid) images.insert(0, grid)
if opts.grid_save: if opts.grid_save:
@ -239,8 +239,8 @@ class FaceSwapScript(scripts.Script):
grid, grid,
p.outpath_grids, p.outpath_grids,
"swapped-grid", "swapped-grid",
p.all_seeds[0], p.all_seeds[0], # type: ignore
p.all_prompts[0], p.all_prompts[0], # type: ignore
opts.grid_format, opts.grid_format,
info=text, info=text,
short_filename=not opts.grid_extended_filename, short_filename=not opts.grid_extended_filename,

@ -1,18 +1,27 @@
import os import os
from modules import scripts 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")) 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")) 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")) 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")) 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( REFERENCE_PATH = os.path.join(
scripts.basedir(), "extensions", "sd-webui-faceswaplab", "references" 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") 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. # 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 = 0.7 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" EXPECTED_INSWAPPER_SHA1 = "17a64851eaefd55ea597ee41e5c18409754244c5"

@ -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 from modules import script_callbacks, shared
import gradio as gr import gradio as gr
def on_ui_settings() -> None: def on_ui_settings() -> None:
section = ("faceswaplab", "FaceSwapLab") section = ("faceswaplab", "FaceSwapLab")
models = get_models() models = get_swap_models()
shared.opts.add_option( shared.opts.add_option(
"faceswaplab_model", "faceswaplab_model",
shared.OptionInfo( shared.OptionInfo(

@ -33,7 +33,7 @@ from scripts.faceswaplab_postprocessing.postprocessing import enhance_image
from scripts.faceswaplab_postprocessing.postprocessing_options import ( from scripts.faceswaplab_postprocessing.postprocessing_options import (
PostProcessingOptions, 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_utils.typing import CV2ImgU8, PILImage, Face
from scripts.faceswaplab_inpainting.i2i_pp import img2img_diffusion from scripts.faceswaplab_inpainting.i2i_pp import img2img_diffusion
from modules import shared from modules import shared
@ -51,7 +51,7 @@ def use_gpu() -> bool:
def force_install_gpu_providers() -> None: def force_install_gpu_providers() -> None:
# Ugly Ugly hack due to SDNEXT : # Ugly Ugly hack due to SDNEXT :
try: try:
from scripts.configure import check_install from scripts.faceswaplab_utils.install_utils import check_install
logger.warning("Try to reinstall gpu dependencies") logger.warning("Try to reinstall gpu dependencies")
check_install() check_install()
@ -180,7 +180,7 @@ def batch_process(
current_images = [] current_images = []
swapped_images = process_images_units( 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: if len(swapped_images) > 0:
current_images += [img for img, _ in swapped_images] current_images += [img for img, _ in swapped_images]

@ -17,7 +17,7 @@ from scripts.faceswaplab_ui.faceswaplab_unit_settings import FaceSwapUnitSetting
from scripts.faceswaplab_ui.faceswaplab_unit_ui import faceswap_unit_ui from scripts.faceswaplab_ui.faceswaplab_unit_ui import faceswap_unit_ui
from scripts.faceswaplab_utils import face_checkpoints_utils, imgutils from scripts.faceswaplab_utils import face_checkpoints_utils, imgutils
from scripts.faceswaplab_utils.faceswaplab_logging import logger 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 from scripts.faceswaplab_utils.ui_utils import dataclasses_from_flat_list
@ -232,7 +232,7 @@ def batch_process(
def tools_ui() -> None: def tools_ui() -> None:
models = get_models() models = get_swap_models()
with gr.Tab("Tools"): with gr.Tab("Tools"):
with gr.Tab("Build"): with gr.Tab("Build"):
gr.Markdown( gr.Markdown(

@ -11,7 +11,7 @@ from scripts.faceswaplab_swapping.upcaled_inswapper_options import InswappperOpt
from scripts.faceswaplab_utils.faceswaplab_logging import logger from scripts.faceswaplab_utils.faceswaplab_logging import logger
from scripts.faceswaplab_utils.typing import * from scripts.faceswaplab_utils.typing import *
from scripts.faceswaplab_utils import imgutils 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 traceback
import dill as pickle # will be removed in future versions import dill as pickle # will be removed in future versions
@ -90,7 +90,7 @@ def build_face_checkpoint_and_save(
target_faces=[target_face], target_faces=[target_face],
source_face=blended_face, source_face=blended_face,
target_img=reference_preview_img, target_img=reference_preview_img,
model=get_models()[0], model=get_swap_models()[0],
swapping_options=InswappperOptions(face_restorer_name="Codeformer"), swapping_options=InswappperOptions(face_restorer_name="Codeformer"),
) )
preview_image = result.image preview_image = result.image

@ -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 :( !

@ -3,12 +3,47 @@ import os
from typing import List from typing import List
import modules.scripts as scripts import modules.scripts as scripts
from modules import 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 modules.shared import opts
from scripts.faceswaplab_utils.faceswaplab_logging import logger 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. Retrieve a list of swap model files.
@ -31,13 +66,13 @@ def get_models() -> List[str]:
return models return models
def get_current_model() -> str: def get_current_swap_model() -> str:
model = opts.data.get("faceswaplab_model", None) model = opts.data.get("faceswaplab_model", None) # type: ignore
if model is None: if model is None:
models = get_models() models = get_swap_models()
model = models[0] if len(models) else None model = models[0] if len(models) else None
logger.info("Try to use model : %s", model) 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) logger.error("The model %s cannot be found or loaded", model)
raise FileNotFoundError( raise FileNotFoundError(
"No faceswap model found. Please add it to the faceswaplab directory." "No faceswap model found. Please add it to the faceswaplab directory."

Loading…
Cancel
Save