diff --git a/.gitignore b/.gitignore index ad70fb55..7c52e4c6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ __pycache__ *.sft .DS_Store .vscode +/.uv-cache /cache /config.json /config_states/ diff --git a/README.md b/README.md index 8e2fd263..3ec42ab3 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ The name "Forge" is inspired by "Minecraft Forge". This project aims to become t
- [X] Rewrite Preset System - - now remembers the checkpoint/module selection and parameters for each preset + - now save the checkpoint/module selection and parameters per each Preset > [!Note] > This overrides the `UI Defaults` for the controlled parameters @@ -101,7 +101,7 @@ The name "Forge" is inspired by "Minecraft Forge". This project aims to become t - adjust in **Settings/System** - [X] Support [uv](https://github.com/astral-sh/uv) package manager - drastically speed up installation - - requires **manually** installing [uv](https://github.com/astral-sh/uv/releases) + - require **manually** installing [uv](https://github.com/astral-sh/uv/releases) - see [Commandline](#by-neo) - [X] Support [SageAttention](https://github.com/thu-ml/SageAttention), [FlashAttention](https://github.com/Dao-AILab/flash-attention), `fp16_accumulation`, `torch._scaled_mm` - see [Commandline](#by-neo) @@ -110,7 +110,7 @@ The name "Forge" is inspired by "Minecraft Forge". This project aims to become t - enable by selecting `int8` in the `Diffusion in Low Bits` - [X] Implement [Radial Attention](https://github.com/mit-han-lab/radial-attention) - speed up `Wan 2.2` - - requires **manually** installing [SpargeAttn](https://github.com/thu-ml/SpargeAttn) + - require **manually** installing [SpargeAttn](https://github.com/thu-ml/SpargeAttn) - [X] Implement fast `state_dict` switching for Refiner - enable in **Settings/Refiner** - [X] Implement RescaleCFG @@ -264,12 +264,17 @@ The name "Forge" is inspired by "Minecraft Forge". This project aims to become t
- `--uv`: Replace the `python -m pip` calls with `uv pip` to massively speed up package installation - - requires **uv** to be installed first *(see [Installation](#installation))* + - requires **uv** to be installed first *(see [Extra Installations](https://github.com/Haoming02/sd-webui-forge-classic/wiki/Extra-Installations))* - `--uv-symlink`: Same as above; but additionally pass `--link-mode symlink` to the commands - significantly reduces installation size (`~7 GB` to `~100 MB`) +- `--uv-local-cache`: Same as above; but additionally set `UV_CACHE_DIR` to a `.uv-cache` folder within WebUI directory + - speed up installation on non-default drive *(**i.e.** not `C:` on Windows)* + - allow clean uninstallation by simply deleting the WebUI directory > [!Important] -> Using `symlink` means it will directly access the packages from the cache folders; refrain from clearing the cache if using this option +> `symlink` means it will directly access the packages from the cache folder instead of copying the packages over ; refrain from clearing the cache when using this option + +
- `--model-ref`: Points to a central `models` folder that contains all your models - said folder should contain subfolders like `Stable-diffusion`, `Lora`, `VAE`, `ESRGAN`, etc. @@ -277,6 +282,8 @@ The name "Forge" is inspired by "Minecraft Forge". This project aims to become t > [!Important] > This simply **replaces** the `models` folder rather than adding on top of it +
+ - `--forge-ref-a1111-home`: Point to an Automatic1111 installation to load its `models` folders - **i.e.** `Stable-diffusion`, `text_encoder`, etc. diff --git a/launch.py b/launch.py index 61a90615..03fce3c4 100644 --- a/launch.py +++ b/launch.py @@ -6,9 +6,10 @@ git = launch_utils.git index_url = launch_utils.index_url dir_repos = launch_utils.dir_repos -if args.uv or args.uv_symlink: +if args.uv or args.uv_symlink or args.uv_local_cache: from modules_forge.uv_hook import patch - patch(args.uv_symlink) + + patch(not args.uv, args.uv_local_cache) git_tag = launch_utils.git_tag diff --git a/modules/cmd_args.py b/modules/cmd_args.py index fa30fe49..f7391a04 100644 --- a/modules/cmd_args.py +++ b/modules/cmd_args.py @@ -101,6 +101,7 @@ parser.add_argument("--adv-samplers", action="store_true", help='show the "sampl pkm = parser.add_mutually_exclusive_group() pkm.add_argument("--uv", action="store_true", help="Use the uv package manager") pkm.add_argument("--uv-symlink", action="store_true", help="Use the uv package manager with symlink") +pkm.add_argument("--uv-local-cache", action="store_true", help="Use the uv package manager with a local cache (.uv-cache) instead of the system-wide cache") parser = _parser paths_internal.parser = parser diff --git a/modules_forge/uv_hook.py b/modules_forge/uv_hook.py index 1a6b65cf..b7eaa796 100644 --- a/modules_forge/uv_hook.py +++ b/modules_forge/uv_hook.py @@ -4,10 +4,42 @@ from copy import copy from functools import wraps -def patch(symlink: bool): +def _pre_check(): + try: + subprocess.run(["uv", "--help"], capture_output=True) + except FileNotFoundError: + print("\n[Error] uv is not installed...") + except Exception: + print("\n[Error] Failed to access uv...") + else: + return + + input("Press Enter to Continue...") + raise SystemExit + + +def _set_cache(): + import os + + webui = os.path.dirname(os.path.dirname(__file__)) + cache = os.path.normpath(os.path.join(webui, ".uv-cache")) + + if not os.path.exists(cache): + print("[uv] Creating .uv-cache folder...") + os.makedirs(cache) + + os.environ.setdefault("UV_CACHE_DIR", cache) + + +def patch(symlink: bool, local: bool): if hasattr(subprocess, "__original_run"): return + _pre_check() + + if local: + _set_cache() + subprocess.__original_run = subprocess.run BAD_FLAGS = ("--prefer-binary", "--ignore-installed", "-I")