Path: blob/master/misc/direct/v1.4.1/launch_utils_org.py
3275 views
# this scripts installs necessary requirements and launches main program in webui.py1import subprocess2import os3import sys4import importlib.util5import platform6import json7from functools import lru_cache89from modules import cmd_args, errors10from modules.paths_internal import script_path, extensions_dir1112args, _ = cmd_args.parser.parse_known_args()1314python = sys.executable15git = os.environ.get('GIT', "git")16index_url = os.environ.get('INDEX_URL', "")17dir_repos = "repositories"1819# Whether to default to printing command output20default_command_live = (os.environ.get('WEBUI_LAUNCH_LIVE_OUTPUT') == "1")2122if 'GRADIO_ANALYTICS_ENABLED' not in os.environ:23os.environ['GRADIO_ANALYTICS_ENABLED'] = 'False'242526def check_python_version():27is_windows = platform.system() == "Windows"28major = sys.version_info.major29minor = sys.version_info.minor30micro = sys.version_info.micro3132if is_windows:33supported_minors = [10]34else:35supported_minors = [7, 8, 9, 10, 11]3637if not (major == 3 and minor in supported_minors):38import modules.errors3940modules.errors.print_error_explanation(f"""41INCOMPATIBLE PYTHON VERSION4243This program is tested with 3.10.6 Python, but you have {major}.{minor}.{micro}.44If you encounter an error with "RuntimeError: Couldn't install torch." message,45or any other error regarding unsuccessful package (library) installation,46please downgrade (or upgrade) to the latest version of 3.10 Python47and delete current Python and "venv" folder in WebUI's directory.4849You can download 3.10 Python from here: https://www.python.org/downloads/release/python-3106/5051{"Alternatively, use a binary release of WebUI: https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases" if is_windows else ""}5253Use --skip-python-version-check to suppress this warning.54""")555657@lru_cache()58def commit_hash():59try:60return subprocess.check_output([git, "rev-parse", "HEAD"], shell=False, encoding='utf8').strip()61except Exception:62return "<none>"636465@lru_cache()66def git_tag():67try:68return subprocess.check_output([git, "describe", "--tags"], shell=False, encoding='utf8').strip()69except Exception:70try:71from pathlib import Path72changelog_md = Path(__file__).parent.parent / "CHANGELOG.md"73with changelog_md.open(encoding="utf-8") as file:74return next((line.strip() for line in file if line.strip()), "<none>")75except Exception:76return "<none>"777879def run(command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live) -> str:80if desc is not None:81print(desc)8283run_kwargs = {84"args": command,85"shell": True,86"env": os.environ if custom_env is None else custom_env,87"encoding": 'utf8',88"errors": 'ignore',89}9091if not live:92run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE9394result = subprocess.run(**run_kwargs)9596if result.returncode != 0:97error_bits = [98f"{errdesc or 'Error running command'}.",99f"Command: {command}",100f"Error code: {result.returncode}",101]102if result.stdout:103error_bits.append(f"stdout: {result.stdout}")104if result.stderr:105error_bits.append(f"stderr: {result.stderr}")106raise RuntimeError("\n".join(error_bits))107108return (result.stdout or "")109110111def is_installed(package):112try:113spec = importlib.util.find_spec(package)114except ModuleNotFoundError:115return False116117return spec is not None118119120def repo_dir(name):121return os.path.join(script_path, dir_repos, name)122123124def run_pip(command, desc=None, live=default_command_live):125if args.skip_install:126return127128index_url_line = f' --index-url {index_url}' if index_url != '' else ''129return run(f'"{python}" -m pip {command} --prefer-binary{index_url_line}', desc=f"Installing {desc}", errdesc=f"Couldn't install {desc}", live=live)130131132def check_run_python(code: str) -> bool:133result = subprocess.run([python, "-c", code], capture_output=True, shell=False)134return result.returncode == 0135136137def git_clone(url, dir, name, commithash=None):138# TODO clone into temporary dir and move if successful139140if os.path.exists(dir):141if commithash is None:142return143144current_hash = run(f'"{git}" -C "{dir}" rev-parse HEAD', None, f"Couldn't determine {name}'s hash: {commithash}").strip()145if current_hash == commithash:146return147148run(f'"{git}" -C "{dir}" fetch', f"Fetching updates for {name}...", f"Couldn't fetch {name}")149run(f'"{git}" -C "{dir}" checkout {commithash}', f"Checking out commit for {name} with hash: {commithash}...", f"Couldn't checkout commit {commithash} for {name}")150return151152run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}")153154if commithash is not None:155run(f'"{git}" -C "{dir}" checkout {commithash}', None, "Couldn't checkout {name}'s hash: {commithash}")156157158def git_pull_recursive(dir):159for subdir, _, _ in os.walk(dir):160if os.path.exists(os.path.join(subdir, '.git')):161try:162output = subprocess.check_output([git, '-C', subdir, 'pull', '--autostash'])163print(f"Pulled changes for repository in '{subdir}':\n{output.decode('utf-8').strip()}\n")164except subprocess.CalledProcessError as e:165print(f"Couldn't perform 'git pull' on repository in '{subdir}':\n{e.output.decode('utf-8').strip()}\n")166167168def version_check(commit):169try:170import requests171commits = requests.get('https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master').json()172if commit != "<none>" and commits['commit']['sha'] != commit:173print("--------------------------------------------------------")174print("| You are not up to date with the most recent release. |")175print("| Consider running `git pull` to update. |")176print("--------------------------------------------------------")177elif commits['commit']['sha'] == commit:178print("You are up to date with the most recent release.")179else:180print("Not a git clone, can't perform version check.")181except Exception as e:182print("version check failed", e)183184185def run_extension_installer(extension_dir):186path_installer = os.path.join(extension_dir, "install.py")187if not os.path.isfile(path_installer):188return189190try:191env = os.environ.copy()192env['PYTHONPATH'] = os.path.abspath(".")193194print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))195except Exception as e:196errors.report(str(e))197198199def list_extensions(settings_file):200settings = {}201202try:203if os.path.isfile(settings_file):204with open(settings_file, "r", encoding="utf8") as file:205settings = json.load(file)206except Exception:207errors.report("Could not load settings", exc_info=True)208209disabled_extensions = set(settings.get('disabled_extensions', []))210disable_all_extensions = settings.get('disable_all_extensions', 'none')211212if disable_all_extensions != 'none':213return []214215return [x for x in os.listdir(extensions_dir) if x not in disabled_extensions]216217218def run_extensions_installers(settings_file):219if not os.path.isdir(extensions_dir):220return221222for dirname_extension in list_extensions(settings_file):223run_extension_installer(os.path.join(extensions_dir, dirname_extension))224225226def prepare_environment():227torch_index_url = os.environ.get('TORCH_INDEX_URL', "https://download.pytorch.org/whl/cu118")228torch_command = os.environ.get('TORCH_COMMAND', f"pip install torch==2.0.1 torchvision==0.15.2 --extra-index-url {torch_index_url}")229requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")230231xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.20')232gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "https://github.com/TencentARC/GFPGAN/archive/8d2447a2d918f8eba5a4a01463fd48e45126a379.zip")233clip_package = os.environ.get('CLIP_PACKAGE', "https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip")234openclip_package = os.environ.get('OPENCLIP_PACKAGE', "https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip")235236stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")237k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')238codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')239blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')240241stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf")242k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "c9fe758757e022f05ca5a53fa8fac28889e4f1cf")243codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")244blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")245246try:247# the existance of this file is a signal to webui.sh/bat that webui needs to be restarted when it stops execution248os.remove(os.path.join(script_path, "tmp", "restart"))249os.environ.setdefault('SD_WEBUI_RESTARTING ', '1')250except OSError:251pass252253if not args.skip_python_version_check:254check_python_version()255256commit = commit_hash()257tag = git_tag()258259print(f"Python {sys.version}")260print(f"Version: {tag}")261print(f"Commit hash: {commit}")262263if args.reinstall_torch or not is_installed("torch") or not is_installed("torchvision"):264run(f'"{python}" -m {torch_command}', "Installing torch and torchvision", "Couldn't install torch", live=True)265266if not args.skip_torch_cuda_test and not check_run_python("import torch; assert torch.cuda.is_available()"):267raise RuntimeError(268'Torch is not able to use GPU; '269'add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check'270)271272if not is_installed("gfpgan"):273run_pip(f"install {gfpgan_package}", "gfpgan")274275if not is_installed("clip"):276run_pip(f"install {clip_package}", "clip")277278if not is_installed("open_clip"):279run_pip(f"install {openclip_package}", "open_clip")280281if (not is_installed("xformers") or args.reinstall_xformers) and args.xformers:282if platform.system() == "Windows":283if platform.python_version().startswith("3.10"):284run_pip(f"install -U -I --no-deps {xformers_package}", "xformers", live=True)285else:286print("Installation of xformers is not supported in this version of Python.")287print("You can also check this and build manually: https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers#building-xformers-on-windows-by-duckness")288if not is_installed("xformers"):289exit(0)290elif platform.system() == "Linux":291run_pip(f"install -U -I --no-deps {xformers_package}", "xformers")292293if not is_installed("ngrok") and args.ngrok:294run_pip("install ngrok", "ngrok")295296os.makedirs(os.path.join(script_path, dir_repos), exist_ok=True)297298git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)299git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)300git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)301git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)302303if not is_installed("lpips"):304run_pip(f"install -r \"{os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}\"", "requirements for CodeFormer")305306if not os.path.isfile(requirements_file):307requirements_file = os.path.join(script_path, requirements_file)308run_pip(f"install -r \"{requirements_file}\"", "requirements")309310run_extensions_installers(settings_file=args.ui_settings_file)311312if args.update_check:313version_check(commit)314315if args.update_all_extensions:316git_pull_recursive(extensions_dir)317318if "--exit" in sys.argv:319print("Exiting because of --exit argument")320exit(0)321322323def configure_for_tests():324if "--api" not in sys.argv:325sys.argv.append("--api")326if "--ckpt" not in sys.argv:327sys.argv.append("--ckpt")328sys.argv.append(os.path.join(script_path, "test/test_files/empty.pt"))329if "--skip-torch-cuda-test" not in sys.argv:330sys.argv.append("--skip-torch-cuda-test")331if "--disable-nan-check" not in sys.argv:332sys.argv.append("--disable-nan-check")333334os.environ['COMMANDLINE_ARGS'] = ""335336337def start():338print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")339import webui340if '--nowebui' in sys.argv:341webui.api_only()342else:343webui.webui()344345346