mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-08 13:20:50 +08:00
887 lines
61 KiB
Python
887 lines
61 KiB
Python
from __future__ import annotations
|
|
|
|
import collections
|
|
import logging
|
|
import operator
|
|
import os
|
|
import shutil
|
|
import sys
|
|
from collections.abc import Sequence, MutableSequence
|
|
from functools import reduce
|
|
from itertools import chain
|
|
from os.path import join
|
|
from pathlib import Path
|
|
from typing import List, Optional, Final, Set
|
|
|
|
import requests
|
|
import requests_cache
|
|
import tqdm
|
|
from huggingface_hub import dump_environment_info, hf_hub_download, scan_cache_dir, snapshot_download, HfFileSystem, CacheNotFound
|
|
from huggingface_hub.utils import GatedRepoError, LocalEntryNotFoundError
|
|
from requests import Session
|
|
from safetensors import safe_open
|
|
from safetensors.torch import save_file
|
|
|
|
from .cli_args import args
|
|
from .cmd import folder_paths
|
|
from .cmd.folder_paths import add_model_folder_path, supported_pt_extensions # pylint: disable=import-error
|
|
from .component_model.deprecation import _deprecate_method
|
|
from .component_model.files import canonicalize_path
|
|
from .interruption import InterruptProcessingException
|
|
from .model_downloader_types import CivitFile, HuggingFile, CivitModelsGetResponse, CivitFile_, Downloadable, UrlFile, DownloadableFileList
|
|
from .utils import ProgressBar, comfy_tqdm
|
|
|
|
_session = Session()
|
|
_hf_fs = HfFileSystem()
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_filename_list(folder_name: str) -> Sequence[str]:
|
|
return get_filename_list_with_downloadable(folder_name)
|
|
|
|
|
|
def get_folder_paths(*args, **kwargs):
|
|
return folder_paths.get_folder_paths(*args, **kwargs)
|
|
|
|
|
|
def get_filename_list_with_downloadable(folder_name: str, known_files: Optional[List[Downloadable] | KnownDownloadables] = None) -> DownloadableFileList | list[str]:
|
|
if known_files is None:
|
|
known_files = _get_known_models_for_folder_name(folder_name)
|
|
|
|
# workaround for lora loading issue, still needs to be investigated
|
|
if sys.platform == "nt":
|
|
existing = frozenset(folder_paths.get_filename_list(folder_name))
|
|
downloadable = frozenset() if args.disable_known_models else frozenset(str(f) for f in known_files)
|
|
return list(map(canonicalize_path, sorted(list(existing | downloadable))))
|
|
else:
|
|
existing = folder_paths.get_filename_list(folder_name)
|
|
|
|
downloadable_files = []
|
|
if not args.disable_known_models:
|
|
downloadable_files = known_files
|
|
|
|
return DownloadableFileList(existing, downloadable_files)
|
|
|
|
|
|
def get_full_path_or_raise(folder_name: str, filename: str, known_files: Optional[List[Downloadable] | KnownDownloadables] = None) -> str:
|
|
res = get_or_download(folder_name, filename, known_files=known_files)
|
|
if res is None:
|
|
raise FileNotFoundError(f"{folder_name} does not contain {filename}")
|
|
return res
|
|
|
|
|
|
def get_full_path(folder_name: str, filename: str) -> Optional[str]:
|
|
return get_or_download(folder_name, filename)
|
|
|
|
|
|
def get_or_download(folder_name: str, filename: str, known_files: Optional[List[Downloadable] | KnownDownloadables] = None) -> Optional[str]:
|
|
if known_files is None:
|
|
known_files = _get_known_models_for_folder_name(folder_name)
|
|
|
|
filename = canonicalize_path(filename)
|
|
path = folder_paths.get_full_path(folder_name, filename)
|
|
|
|
candidate_str_match = False
|
|
candidate_filename_match = False
|
|
candidate_alternate_filenames_match = False
|
|
candidate_save_filename_match = False
|
|
if path is None and not args.disable_known_models:
|
|
try:
|
|
# todo: should this be the first or last path?
|
|
this_model_directory = folder_paths.get_folder_paths(folder_name)[0]
|
|
known_file: Optional[HuggingFile | CivitFile] = None
|
|
for candidate in known_files:
|
|
candidate_str_match = canonicalize_path(str(candidate)) == filename
|
|
candidate_filename_match = canonicalize_path(candidate.filename) == filename
|
|
candidate_alternate_filenames_match = filename in list(map(canonicalize_path, candidate.alternate_filenames))
|
|
candidate_save_filename_match = filename == canonicalize_path(candidate.save_with_filename)
|
|
if (candidate_str_match
|
|
or candidate_filename_match
|
|
or candidate_alternate_filenames_match
|
|
or candidate_save_filename_match):
|
|
known_file = candidate
|
|
break
|
|
if known_file is None:
|
|
logger.debug(f"get_or_download could not find {filename} in {folder_name}, known_files={known_files}")
|
|
return path
|
|
with comfy_tqdm() as watcher:
|
|
if isinstance(known_file, HuggingFile):
|
|
if known_file.save_with_filename is not None:
|
|
linked_filename = known_file.save_with_filename
|
|
elif not known_file.force_save_in_repo_id and os.path.basename(known_file.filename) != known_file.filename:
|
|
linked_filename = os.path.basename(known_file.filename)
|
|
else:
|
|
linked_filename = known_file.filename
|
|
|
|
if known_file.force_save_in_repo_id or linked_filename is not None and os.path.dirname(known_file.filename) == "":
|
|
# if the known file has an overridden linked name, save it into a repo_id sub directory
|
|
# this deals with situations like
|
|
# jschoormans/controlnet-densepose-sdxl repo having diffusion_pytorch_model.safetensors
|
|
# it should be saved to controlnet-densepose-sdxl.safetensors
|
|
# since there are a bajillion diffusion_pytorch_model.safetensors, it should be downloaded by hf into jschoormans/controlnet-densepose-sdxl/diffusion_pytorch_model.safetensors
|
|
# then linked to the local folder to controlnet-densepose-sdxl.safetensors or some other canonical name
|
|
hf_destination_dir = os.path.join(this_model_directory, known_file.repo_id)
|
|
else:
|
|
hf_destination_dir = this_model_directory
|
|
|
|
# converted 16 bit files should be skipped
|
|
# todo: the file size should be replaced with a file hash
|
|
path = os.path.join(hf_destination_dir, known_file.filename)
|
|
try:
|
|
file_size = os.stat(path, follow_symlinks=True).st_size if os.path.isfile(path) else None
|
|
except:
|
|
file_size = None
|
|
if os.path.isfile(path) and file_size == known_file.size:
|
|
return path
|
|
# at this point, the file was not found with its candidate name
|
|
path = None
|
|
|
|
cache_hit = False
|
|
hf_hub_download_kwargs = dict(repo_id=known_file.repo_id,
|
|
filename=known_file.filename,
|
|
repo_type=known_file.repo_type,
|
|
revision=known_file.revision,
|
|
local_files_only=True,
|
|
local_dir=hf_destination_dir if args.force_hf_local_dir_mode else None,
|
|
token=True,
|
|
)
|
|
|
|
with requests_cache.disabled():
|
|
try:
|
|
# always retrieve this from the cache if it already exists there
|
|
path = hf_hub_download(**hf_hub_download_kwargs)
|
|
logger.debug(f"hf_hub_download cache hit for {known_file.repo_id}/{known_file.filename}")
|
|
cache_hit = True
|
|
except LocalEntryNotFoundError:
|
|
try:
|
|
logger.debug(f"{folder_name}/{filename} is being downloaded from {known_file.repo_id}/{known_file.filename} candidate_str_match={candidate_str_match} candidate_filename_match={candidate_filename_match} candidate_alternate_filenames_match={candidate_alternate_filenames_match} candidate_save_filename_match={candidate_save_filename_match}")
|
|
hf_hub_download_kwargs.pop("local_files_only")
|
|
path = hf_hub_download(**hf_hub_download_kwargs)
|
|
except requests.exceptions.HTTPError as exc_info:
|
|
if exc_info.response.status_code == 401:
|
|
raise GatedRepoError(f"{known_file.repo_id}/{known_file.filename}", response=exc_info.response)
|
|
except IOError as exc_info:
|
|
logger.error(f"cannot reach huggingface {known_file.repo_id}/{known_file.filename}", exc_info=exc_info)
|
|
except Exception as exc_info:
|
|
logger.error(f"an exception occurred while downloading {known_file.repo_id}/{known_file.filename}. hf_hub_download kwargs={hf_hub_download_kwargs}", exc_info=exc_info)
|
|
dump_environment_info()
|
|
for key, value in os.environ.items():
|
|
if key.startswith("HF_"):
|
|
if key == "HF_TOKEN":
|
|
value = "*****"
|
|
print(f"{key}={value}", file=sys.stderr)
|
|
|
|
if path is not None and known_file.convert_to_16_bit and file_size is not None and file_size != 0:
|
|
tensors = {}
|
|
with safe_open(path, framework="pt") as f:
|
|
with tqdm.tqdm(total=len(f.keys())) as pb:
|
|
for k in f.keys():
|
|
x = f.get_tensor(k)
|
|
tensors[k] = x.half()
|
|
del x
|
|
pb.update()
|
|
|
|
# always save converted files to the destination so that the huggingface cache is not corrupted
|
|
save_file(tensors, os.path.join(hf_destination_dir, known_file.filename))
|
|
|
|
for _, v in tensors.items():
|
|
del v
|
|
logger.info(f"Converted {path} to 16 bit, size is {os.stat(path, follow_symlinks=True).st_size}")
|
|
|
|
link_successful = True
|
|
exc_info_link = {}
|
|
if path is not None:
|
|
if Path(linked_filename).is_absolute():
|
|
raise ValueError(f"{known_file.repo_id}/{known_file.filename} surprisingly was trying to link to an absolute path {linked_filename}, failing")
|
|
|
|
destination_link = Path(this_model_directory) / linked_filename
|
|
if destination_link.is_file():
|
|
logger.warning(f"{known_file.repo_id}/{known_file.filename} could not link to {destination_link} because the path already exists, which is unexpected")
|
|
else:
|
|
try:
|
|
# sometimes, linked filename has a path in it, on purpose, such as with controlnet_aux nodes
|
|
Path(destination_link).parent.mkdir(parents=True, exist_ok=True)
|
|
os.symlink(path, destination_link)
|
|
except FileExistsError:
|
|
# the download was resumed
|
|
pass
|
|
except Exception as exc_info:
|
|
exc_info_link = exc_info
|
|
logger.error("error while symbolic linking", exc_info=exc_info)
|
|
try:
|
|
os.link(path, destination_link)
|
|
except Exception as hard_link_exc:
|
|
logger.error("error while hard linking", exc_info=hard_link_exc)
|
|
if cache_hit:
|
|
shutil.copyfile(path, destination_link)
|
|
link_successful = False
|
|
exc_info_link = (exc_info, hard_link_exc)
|
|
|
|
if not link_successful:
|
|
logger.error(f"Failed to link file with alternative download save name in a way that is compatible with Hugging Face caching {repr(known_file)}. If cache_hit={cache_hit} is True, the file was copied into the destination. exc_info={exc_info_link}")
|
|
else:
|
|
url: Optional[str] = None
|
|
save_filename = known_file.save_with_filename or known_file.filename
|
|
|
|
if isinstance(known_file, CivitFile):
|
|
model_info_res = _session.get(
|
|
f"https://civitai.com/api/v1/models/{known_file.model_id}?modelVersionId={known_file.model_version_id}")
|
|
model_info: CivitModelsGetResponse = model_info_res.json()
|
|
|
|
civit_file: CivitFile_
|
|
for civit_file in chain.from_iterable(version['files'] for version in model_info['modelVersions']):
|
|
if canonicalize_path(civit_file['name']) == filename:
|
|
url = civit_file['downloadUrl']
|
|
break
|
|
elif isinstance(known_file, UrlFile):
|
|
url = known_file.url
|
|
else:
|
|
raise RuntimeError("Unknown file type")
|
|
|
|
if url is None:
|
|
logger.warning(f"Could not retrieve file {str(known_file)}")
|
|
else:
|
|
destination_with_filename = join(this_model_directory, save_filename)
|
|
os.makedirs(os.path.dirname(destination_with_filename), exist_ok=True)
|
|
try:
|
|
|
|
with _session.get(url, stream=True, allow_redirects=True) as response:
|
|
total_size = int(response.headers.get("content-length", 0))
|
|
progress_bar = ProgressBar(total=total_size)
|
|
with open(destination_with_filename, "wb") as file:
|
|
for chunk in response.iter_content(chunk_size=512 * 1024):
|
|
progress_bar.update(len(chunk))
|
|
file.write(chunk)
|
|
except InterruptProcessingException:
|
|
os.remove(destination_with_filename)
|
|
|
|
path = folder_paths.get_full_path(folder_name, filename)
|
|
assert path is not None
|
|
except StopIteration:
|
|
pass
|
|
except GatedRepoError as exc_info:
|
|
exc_info.append_to_message(f"""
|
|
Visit the repository, accept the terms, and then do one of the following:
|
|
|
|
- Set the HF_TOKEN environment variable to your Hugging Face token; or,
|
|
- Login to Hugging Face in your terminal using `huggingface-cli login`
|
|
""")
|
|
raise exc_info
|
|
return path
|
|
|
|
|
|
class KnownDownloadables(collections.UserList[Downloadable]):
|
|
# we're not invoking the constructor because we want a reference to the passed list
|
|
# noinspection PyMissingConstructor
|
|
def __init__(self, data, folder_name: Optional[str | Sequence[str]] = None, folder_names: Optional[Sequence[str]] = None):
|
|
# this should be a view
|
|
self.data = data
|
|
folder_names = folder_names or []
|
|
if isinstance(folder_name, str):
|
|
folder_names.append(folder_name)
|
|
elif folder_name is not None and hasattr(folder_name, "__getitem__") and len(folder_name[0]) > 1:
|
|
folder_names += folder_name
|
|
self._folder_names = folder_names
|
|
|
|
@property
|
|
def folder_names(self) -> list[str]:
|
|
return self._folder_names
|
|
|
|
@folder_names.setter
|
|
def folder_names(self, value: list[str]):
|
|
self._folder_names = value
|
|
|
|
def __contains__(self, item):
|
|
if isinstance(item, str):
|
|
return item in self._folder_names
|
|
else:
|
|
return item in self.data
|
|
|
|
|
|
KNOWN_CHECKPOINTS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("stabilityai/stable-diffusion-xl-base-1.0", "sd_xl_base_1.0.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-xl-refiner-1.0", "sd_xl_refiner_1.0.safetensors"),
|
|
HuggingFile("stabilityai/sdxl-turbo", "sd_xl_turbo_1.0_fp16.safetensors"),
|
|
HuggingFile("stabilityai/sdxl-turbo", "sd_xl_turbo_1.0.safetensors", show_in_ui=False),
|
|
HuggingFile("stabilityai/stable-cascade", "comfyui_checkpoints/stable_cascade_stage_b.safetensors"),
|
|
HuggingFile("stabilityai/stable-cascade", "comfyui_checkpoints/stable_cascade_stage_c.safetensors"),
|
|
HuggingFile("stabilityai/stable-cascade", "comfyui_checkpoints/stage_a.safetensors", show_in_ui=False),
|
|
HuggingFile("Comfy-Org/stable-diffusion-v1-5-archive", "v1-5-pruned-emaonly.safetensors"),
|
|
HuggingFile("Comfy-Org/stable-diffusion-v1-5-archive", "v1-5-pruned-emaonly-fp16.safetensors"),
|
|
# from https://github.com/comfyanonymous/ComfyUI_examples/tree/master/2_pass_txt2img
|
|
HuggingFile("stabilityai/stable-diffusion-2-1", "v2-1_768-ema-pruned.ckpt", show_in_ui=False),
|
|
HuggingFile("waifu-diffusion/wd-1-5-beta3", "wd-illusion-fp16.safetensors", show_in_ui=False),
|
|
HuggingFile("jomcs/NeverEnding_Dream-Feb19-2023", "CarDos Anime/cardosAnime_v10.safetensors", show_in_ui=False),
|
|
# from https://github.com/comfyanonymous/ComfyUI_examples/blob/master/area_composition/README.md
|
|
HuggingFile("ckpt/anything-v3.0", "Anything-V3.0.ckpt", show_in_ui=False),
|
|
HuggingFile("stabilityai/cosxl", "cosxl.safetensors"),
|
|
HuggingFile("stabilityai/cosxl", "cosxl_edit.safetensors"),
|
|
# latest, popular civitai models
|
|
CivitFile(133005, 357609, filename="juggernautXL_v9Rundiffusionphoto2.safetensors"),
|
|
CivitFile(112902, 351306, filename="dreamshaperXL_v21TurboDPMSDE.safetensors"),
|
|
CivitFile(139562, 344487, filename="realvisxlV40_v40Bakedvae.safetensors"),
|
|
HuggingFile("SG161222/Realistic_Vision_V6.0_B1_noVAE", "Realistic_Vision_V6.0_NV_B1_fp16.safetensors"),
|
|
HuggingFile("SG161222/Realistic_Vision_V5.1_noVAE", "Realistic_Vision_V5.1_fp16-no-ema.safetensors"),
|
|
HuggingFile("Lykon/DreamShaper", "DreamShaper_8_pruned.safetensors", save_with_filename="dreamshaper_8.safetensors", alternate_filenames=("DreamShaper_8_pruned.safetensors",)),
|
|
CivitFile(7371, 425083, filename="revAnimated_v2Rebirth.safetensors"),
|
|
CivitFile(4468, 57618, filename="counterfeitV30_v30.safetensors"),
|
|
CivitFile(241415, 272376, filename="picxReal_10.safetensors"),
|
|
CivitFile(23900, 95489, filename="anyloraCheckpoint_bakedvaeBlessedFp16.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3-medium", "sd3_medium.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3-medium", "sd3_medium_incl_clips.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3-medium", "sd3_medium_incl_clips_t5xxlfp8.safetensors"),
|
|
HuggingFile("fal/AuraFlow", "aura_flow_0.1.safetensors"),
|
|
# stable audio, # uses names from https://comfyanonymous.github.io/ComfyUI_examples/audio/
|
|
HuggingFile("Comfy-Org/stable-audio-open-1.0_repackaged", "stable-audio-open-1.0.safetensors", alternate_filenames=("stable_audio_open_1.0.safetensors",)),
|
|
# hunyuandit
|
|
HuggingFile("comfyanonymous/hunyuan_dit_comfyui", "hunyuan_dit_1.0.safetensors"),
|
|
HuggingFile("comfyanonymous/hunyuan_dit_comfyui", "hunyuan_dit_1.1.safetensors"),
|
|
HuggingFile("comfyanonymous/hunyuan_dit_comfyui", "hunyuan_dit_1.2.safetensors"),
|
|
HuggingFile("lllyasviel/flux1-dev-bnb-nf4", "flux1-dev-bnb-nf4.safetensors"),
|
|
HuggingFile("lllyasviel/flux1-dev-bnb-nf4", "flux1-dev-bnb-nf4-v2.safetensors"),
|
|
HuggingFile("silveroxides/flux1-nf4-weights", "flux1-schnell-bnb-nf4.safetensors"),
|
|
HuggingFile("Lightricks/LTX-Video", "ltx-video-2b-v0.9.safetensors"),
|
|
HuggingFile("Lightricks/LTX-Video", "ltx-video-2b-v0.9.1.safetensors"),
|
|
HuggingFile("Comfy-Org/Lumina_Image_2.0_Repackaged", "all_in_one/lumina_2.safetensors"),
|
|
HuggingFile("Comfy-Org/flux1-schnell", "flux1-schnell-fp8.safetensors"),
|
|
HuggingFile("Comfy-Org/flux1-dev", "flux1-dev-fp8.safetensors"),
|
|
HuggingFile("stabilityai/stable-video-diffusion-img2vid", "svd.safetensors"),
|
|
HuggingFile("stabilityai/stable-video-diffusion-img2vid-xt", "svd_xt.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-2-inpainting", "v2-inpainting-pruned-ema.safetensors"),
|
|
HuggingFile("runwayml/stable-diffusion-inpainting", "sd-v1-5-inpainting.ckpt", show_in_ui=False),
|
|
HuggingFile("stabilityai/stable-diffusion-3.5-large", "sd3.5_large.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3.5-medium", "sd3.5_medium.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3.5-large-turbo", "sd3.5_large_turbo.safetensors"),
|
|
HuggingFile("Comfy-Org/stable-diffusion-3.5-fp8", "sd3.5_large_fp8_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/stable-diffusion-3.5-fp8", "sd3.5_medium_incl_clips_t5xxlfp8scaled.safetensors"),
|
|
HuggingFile("fal/AuraFlow-v0.2", "aura_flow_0.2.safetensors"),
|
|
HuggingFile("lodestones/Chroma", "Chroma_v1.0.safetensors"),
|
|
HuggingFile("Comfy-Org/mochi_preview_repackaged", "all_in_one/mochi_preview_fp8_scaled.safetensors"),
|
|
HuggingFile("Lightricks/LTX-Video", "ltx-video-2b-v0.9.5.safetensors"),
|
|
HuggingFile("Comfy-Org/ACE-Step_ComfyUI_repackaged", "all_in_one/ace_step_v1_3.5b.safetensors"),
|
|
CivitFile(8714, 13359, filename="AOM2-Hard.safetensors"),
|
|
CivitFile(4291, 132454, filename="AOM3A3.safetensors"),
|
|
CivitFile(140737, 357037, filename="albedobaseXL_v21.safetensors"),
|
|
], folder_name="checkpoints")
|
|
|
|
KNOWN_UNCLIP_CHECKPOINTS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("stabilityai/stable-cascade", "comfyui_checkpoints/stable_cascade_stage_c.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-2-1-unclip", "sd21-unclip-h.ckpt"),
|
|
HuggingFile("stabilityai/stable-diffusion-2-1-unclip", "sd21-unclip-l.ckpt"),
|
|
HuggingFile("comfyanonymous/wd-1.5-beta2_unCLIP", "wd-1-5-beta2-aesthetic-unclip-h.safetensors"),
|
|
HuggingFile("comfyanonymous/illuminatiDiffusionV1_v11_unCLIP", "illuminatiDiffusionV1_v11-unclip-h.safetensors"),
|
|
], folder_name="checkpoints")
|
|
|
|
KNOWN_IMAGE_ONLY_CHECKPOINTS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("stabilityai/stable-zero123", "stable_zero123.ckpt")
|
|
], folder_name="checkpoints")
|
|
|
|
KNOWN_UPSCALERS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("lllyasviel/Annotators", "RealESRGAN_x4plus.pth")
|
|
], folder_name="upscale_models")
|
|
|
|
KNOWN_GLIGEN_MODELS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("comfyanonymous/GLIGEN_pruned_safetensors", "gligen_sd14_textbox_pruned.safetensors", show_in_ui=False),
|
|
HuggingFile("comfyanonymous/GLIGEN_pruned_safetensors", "gligen_sd14_textbox_pruned_fp16.safetensors"),
|
|
], folder_name="gligen")
|
|
|
|
KNOWN_CLIP_VISION_MODELS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("comfyanonymous/clip_vision_g", "clip_vision_g.safetensors"),
|
|
HuggingFile("Comfy-Org/sigclip_vision_384", "sigclip_vision_patch14_384.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanVideo_repackaged", "split_files/clip_vision/llava_llama3_vision.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/clip_vision/clip_vision_h.safetensors"),
|
|
], folder_name="clip_vision")
|
|
|
|
KNOWN_LORAS: Final[KnownDownloadables] = KnownDownloadables([
|
|
CivitFile(model_id=211577, model_version_id=238349, filename="openxl_handsfix.safetensors"),
|
|
CivitFile(model_id=324815, model_version_id=364137, filename="blur_control_xl_v1.safetensors"),
|
|
CivitFile(model_id=47085, model_version_id=55199, filename="GoodHands-beta2.safetensors"),
|
|
HuggingFile("artificialguybr/pixelartredmond-1-5v-pixel-art-loras-for-sd-1-5", "PixelArtRedmond15V-PixelArt-PIXARFK.safetensors"),
|
|
HuggingFile("ByteDance/Hyper-SD", "Hyper-SDXL-12steps-CFG-lora.safetensors"),
|
|
HuggingFile("ByteDance/Hyper-SD", "Hyper-SD15-12steps-CFG-lora.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-Canny-dev-lora", "flux1-canny-dev-lora.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-Depth-dev-lora", "flux1-depth-dev-lora.safetensors"),
|
|
HuggingFile("latent-consistency/lcm-lora-sdxl", "pytorch_lora_weights.safetensors", save_with_filename="lcm_lora_sdxl.safetensors"),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-4steps-V1.0.safetensors", show_in_ui=False),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-4steps-V1.0-bf16.safetensors", show_in_ui=False),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-4steps-V2.0.safetensors"),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-4steps-V2.0-bf16.safetensors", show_in_ui=False),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-8steps-V1.0.safetensors", show_in_ui=False),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-8steps-V1.1.safetensors", show_in_ui=False),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-8steps-V1.1-bf16.safetensors", show_in_ui=False),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-8steps-V2.0.safetensors"),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Lightning-8steps-V2.0-bf16.safetensors"),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Edit-Lightning-4steps-V1.0.safetensors"),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Edit-Lightning-4steps-V1.0-bf16.safetensors", show_in_ui=False),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Edit-Lightning-8steps-V1.0.safetensors"),
|
|
HuggingFile("lightx2v/Qwen-Image-Lightning", "Qwen-Image-Edit-Lightning-8steps-V1.0-bf16.safetensors", show_in_ui=False),
|
|
], folder_name="loras")
|
|
|
|
KNOWN_CONTROLNETS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("thibaud/controlnet-openpose-sdxl-1.0", "OpenPoseXL2.safetensors", convert_to_16_bit=True, size=2502139104),
|
|
HuggingFile("thibaud/controlnet-openpose-sdxl-1.0", "control-lora-openposeXL2-rank256.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11e_sd15_ip2p_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11e_sd15_shuffle_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11f1e_sd15_tile_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11f1p_sd15_depth_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_canny_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_inpaint_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_lineart_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_mlsd_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_normalbae_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_openpose_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_scribble_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_seg_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15_softedge_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_lora_rank128_v11p_sd15s2_lineart_anime_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11e_sd15_ip2p_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11e_sd15_shuffle_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11f1e_sd15_tile_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11f1p_sd15_depth_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_canny_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_inpaint_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_lineart_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_mlsd_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_normalbae_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_openpose_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_scribble_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_seg_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15_softedge_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11p_sd15s2_lineart_anime_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/ControlNet-v1-1_fp16_safetensors", "control_v11u_sd15_tile_fp16.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "diffusers_xl_canny_full.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "diffusers_xl_canny_mid.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "diffusers_xl_canny_small.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "diffusers_xl_depth_full.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "diffusers_xl_depth_mid.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "diffusers_xl_depth_small.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "ioclab_sd15_recolor.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_blur.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_blur_anime.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_blur_anime_beta.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_canny.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_canny_anime.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_depth.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_depth_anime.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_openpose_anime.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_openpose_anime_v2.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "kohya_controllllite_xl_scribble_anime.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_canny_128lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_canny_256lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_depth_128lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_depth_256lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_recolor_128lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_recolor_256lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_sketch_128lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sai_xl_sketch_256lora.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sargezt_xl_depth.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sargezt_xl_depth_faid_vidit.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sargezt_xl_depth_zeed.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "sargezt_xl_softedge.safetensors"),
|
|
HuggingFile("SargeZT/controlnet-sd-xl-1.0-depth-16bit-zoe", "depth-zoe-xl-v1.0-controlnet.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_diffusers_xl_canny.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_diffusers_xl_depth_midas.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_diffusers_xl_depth_zoe.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_diffusers_xl_lineart.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_diffusers_xl_openpose.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_diffusers_xl_sketch.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_xl_canny.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_xl_openpose.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "t2i-adapter_xl_sketch.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "thibaud_xl_openpose.safetensors"),
|
|
HuggingFile("lllyasviel/sd_control_collection", "thibaud_xl_openpose_256lora.safetensors"),
|
|
HuggingFile("jschoormans/controlnet-densepose-sdxl", "diffusion_pytorch_model.safetensors", save_with_filename="controlnet-densepose-sdxl.safetensors", convert_to_16_bit=True, size=2502139104),
|
|
HuggingFile("stabilityai/stable-cascade", "controlnet/canny.safetensors", save_with_filename="stable_cascade_canny.safetensors"),
|
|
HuggingFile("stabilityai/stable-cascade", "controlnet/inpainting.safetensors", save_with_filename="stable_cascade_inpainting.safetensors"),
|
|
HuggingFile("stabilityai/stable-cascade", "controlnet/super_resolution.safetensors", save_with_filename="stable_cascade_super_resolution.safetensors"),
|
|
HuggingFile("limingcv/ControlNet-Plus-Plus", "checkpoints/canny/controlnet/diffusion_pytorch_model.safetensors", save_with_filename="ControlNet-Plus-Plus_sd15_canny.safetensors", repo_type="space"),
|
|
HuggingFile("limingcv/ControlNet-Plus-Plus", "checkpoints/depth/controlnet/diffusion_pytorch_model.safetensors", save_with_filename="ControlNet-Plus-Plus_sd15_grayscale_depth.safetensors", repo_type="space"),
|
|
HuggingFile("limingcv/ControlNet-Plus-Plus", "checkpoints/hed/controlnet/diffusion_pytorch_model.bin", save_with_filename="ControlNet-Plus-Plus_sd15_hed.bin", repo_type="space"),
|
|
HuggingFile("limingcv/ControlNet-Plus-Plus", "checkpoints/lineart/controlnet/diffusion_pytorch_model.bin", save_with_filename="ControlNet-Plus-Plus_sd15_lineart.bin", repo_type="space"),
|
|
HuggingFile("limingcv/ControlNet-Plus-Plus", "checkpoints/seg/controlnet/diffusion_pytorch_model.safetensors", save_with_filename="ControlNet-Plus-Plus_sd15_ade20k_seg.safetensors", repo_type="space"),
|
|
HuggingFile("xinsir/controlnet-scribble-sdxl-1.0", "diffusion_pytorch_model.safetensors", save_with_filename="xinsir-controlnet-scribble-sdxl-1.0.safetensors"),
|
|
HuggingFile("xinsir/controlnet-canny-sdxl-1.0", "diffusion_pytorch_model.safetensors", save_with_filename="xinsir-controlnet-canny-sdxl-1.0.safetensors"),
|
|
HuggingFile("xinsir/controlnet-canny-sdxl-1.0", "diffusion_pytorch_model_V2.safetensors", save_with_filename="xinsir-controlnet-canny-sdxl-1.0_V2.safetensors"),
|
|
HuggingFile("xinsir/controlnet-openpose-sdxl-1.0", "diffusion_pytorch_model.safetensors", save_with_filename="xinsir-controlnet-openpose-sdxl-1.0.safetensors"),
|
|
HuggingFile("xinsir/anime-painter", "diffusion_pytorch_model.safetensors", save_with_filename="xinsir-anime-painter-scribble-sdxl-1.0.safetensors"),
|
|
HuggingFile("TheMistoAI/MistoLine", "mistoLine_rank256.safetensors"),
|
|
HuggingFile("xinsir/controlnet-union-sdxl-1.0", "diffusion_pytorch_model_promax.safetensors", save_with_filename="xinsir-controlnet-union-sdxl-1.0-promax.safetensors"),
|
|
HuggingFile("xinsir/controlnet-union-sdxl-1.0", "diffusion_pytorch_model.safetensors", save_with_filename="xinsir-controlnet-union-sdxl-1.0.safetensors"),
|
|
HuggingFile("InstantX/FLUX.1-dev-Controlnet-Canny", "diffusion_pytorch_model.safetensors", save_with_filename="instantx-flux.1-dev-controlnet-canny.safetensors"),
|
|
HuggingFile("InstantX/FLUX.1-dev-Controlnet-Union", "diffusion_pytorch_model.safetensors", save_with_filename="instantx-flux.1-dev-controlnet-union.safetensors"),
|
|
HuggingFile("Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro", "diffusion_pytorch_model.safetensors", save_with_filename="shakker-labs-flux.1-dev-controlnet-union-pro.safetensors"),
|
|
HuggingFile("TheMistoAI/MistoLine_Flux.dev", "mistoline_flux.dev_v1.safetensors"),
|
|
HuggingFile("XLabs-AI/flux-controlnet-collections", "flux-canny-controlnet-v3.safetensors"),
|
|
HuggingFile("XLabs-AI/flux-controlnet-collections", "flux-depth-controlnet-v3.safetensors"),
|
|
HuggingFile("XLabs-AI/flux-controlnet-collections", "flux-hed-controlnet-v3.safetensors"),
|
|
HuggingFile("alimama-creative/FLUX.1-dev-Controlnet-Inpainting-Alpha", "diffusion_pytorch_model.safetensors", save_with_filename="alimama-creative-flux.1-dev-controlnet-inpainting-alpha.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3.5-controlnets", "sd3.5_large_controlnet_canny.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3.5-controlnets", "sd3.5_large_controlnet_depth.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3.5-controlnets", "sd3.5_large_controlnet_blur.safetensors"),
|
|
HuggingFile("Shakker-Labs/FLUX.1-dev-ControlNet-Depth", "diffusion_pytorch_model.safetensors", save_with_filename="shakker-labs-flux.1-dev-controlnet-depth.safetensors"),
|
|
], folder_name="controlnet")
|
|
|
|
KNOWN_DIFF_CONTROLNETS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_canny_fp16.safetensors"),
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_depth_fp16.safetensors"),
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_hed_fp16.safetensors"),
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_mlsd_fp16.safetensors"),
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_normal_fp16.safetensors"),
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_openpose_fp16.safetensors"),
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_scribble_fp16.safetensors"),
|
|
HuggingFile("kohya-ss/ControlNet-diff-modules", "diff_control_sd15_seg_fp16.safetensors"),
|
|
], folder_name="diff_controlnet")
|
|
|
|
KNOWN_APPROX_VAES: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("madebyollin/taesd", "taesd_decoder.safetensors", show_in_ui=False),
|
|
HuggingFile("madebyollin/taesd", "taesd_encoder.safetensors", show_in_ui=False),
|
|
HuggingFile("madebyollin/taesdxl", "taesdxl_decoder.safetensors", show_in_ui=False),
|
|
HuggingFile("madebyollin/taesdxl", "taesdxl_encoder.safetensors", show_in_ui=False),
|
|
# todo: these are both the encoder and decoder, so it is not clear what should be done here
|
|
# HuggingFile("madebyollin/taef1", "diffusion_pytorch_model.safetensors", save_with_filename="taef1_decoder.safetensors", show_in_ui=False),
|
|
# HuggingFile("madebyollin/taesd3", "diffusion_pytorch_model.safetensors", save_with_filename="taesd3_decoder.safetensors", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_decoder.pth", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taesd_encoder.pth", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taesdxl_encoder.pth", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taesdxl_decoder.pth", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taesd3_encoder.pth", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taesd3_decoder.pth", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taef1_encoder.pth", show_in_ui=False),
|
|
UrlFile("https://raw.githubusercontent.com/madebyollin/taesd/main/taef1_decoder.pth", show_in_ui=False),
|
|
# todo: update this with the video VAEs
|
|
], folder_name="vae_approx")
|
|
|
|
KNOWN_VAES: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("stabilityai/sdxl-vae", "sdxl_vae.safetensors"),
|
|
HuggingFile("stabilityai/sd-vae-ft-mse-original", "vae-ft-mse-840000-ema-pruned.safetensors"),
|
|
# this is the flux VAE
|
|
HuggingFile("Comfy-Org/HiDream-I1_ComfyUI", "split_files/vae/ae.safetensors"),
|
|
HuggingFile("Comfy-Org/mochi_preview_repackaged", "split_files/vae/mochi_vae.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanVideo_repackaged", "split_files/vae/hunyuan_video_vae_bf16.safetensors"),
|
|
HuggingFile("comfyanonymous/cosmos_1.0_text_encoder_and_VAE_ComfyUI", "vae/cosmos_cv8x8x8_1.0.safetensors"),
|
|
HuggingFile("Comfy-Org/Lumina_Image_2.0_Repackaged", "split_files/vae/ae.safetensors", save_with_filename="lumina_image_2.0-ae.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/vae/wan_2.1_vae.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/vae/wan2.2_vae.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image_ComfyUI", "split_files/vae/qwen_image_vae.safetensors"),
|
|
# Flux 2
|
|
HuggingFile("Comfy-Org/flux2-dev", "split_files/vae/flux2-vae.safetensors"),
|
|
# Z Image Turbo
|
|
HuggingFile("Comfy-Org/z_image_turbo", "split_files/vae/ae.safetensors", save_with_filename="z_image_turbo_vae.safetensors"),
|
|
# Hunyuan Image
|
|
HuggingFile("Comfy-Org/HunyuanImage_2.1_ComfyUI", "split_files/vae/hunyuan_image_2.1_vae_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanImage_2.1_ComfyUI", "split_files/vae/hunyuan_image_refiner_vae_fp16.safetensors"),
|
|
], folder_name="vae")
|
|
|
|
KNOWN_HUGGINGFACE_MODEL_REPOS: Final[Set[str]] = {
|
|
'JingyeChen22/textdiffuser2_layout_planner',
|
|
'JingyeChen22/textdiffuser2-full-ft',
|
|
'microsoft/Phi-4-mini-instruct',
|
|
'llava-hf/llava-v1.6-mistral-7b-hf',
|
|
'facebook/nllb-200-distilled-1.3B',
|
|
'THUDM/chatglm3-6b',
|
|
'roborovski/superprompt-v1',
|
|
'Qwen/Qwen2-VL-7B-Instruct',
|
|
'microsoft/Florence-2-large-ft',
|
|
'google/paligemma2-10b-pt-896',
|
|
'google/paligemma2-28b-pt-896',
|
|
'google/paligemma-3b-ft-refcoco-seg-896',
|
|
'microsoft/phi-4',
|
|
'appmana/Cosmos-1.0-Prompt-Upsampler-12B-Text2World-hf',
|
|
'llava-hf/llava-onevision-qwen2-7b-si-hf',
|
|
'llava-hf/llama3-llava-next-8b-hf',
|
|
}
|
|
|
|
KNOWN_UNET_MODELS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("ByteDance/Hyper-SD", "Hyper-SDXL-1step-Unet-Comfyui.fp16.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-schnell", "flux1-schnell.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-dev", "flux1-dev.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-Fill-dev", "flux1-fill-dev.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-Canny-dev", "flux1-canny-dev.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-Depth-dev", "flux1-depth-dev.safetensors"),
|
|
HuggingFile("black-forest-labs/FLUX.1-Kontext-dev", "flux1-kontext-dev.safetensors"),
|
|
HuggingFile("Kijai/flux-fp8", "flux1-dev-fp8.safetensors"),
|
|
HuggingFile("Kijai/flux-fp8", "flux1-schnell-fp8.safetensors"),
|
|
HuggingFile("Comfy-Org/mochi_preview_repackaged", "split_files/diffusion_models/mochi_preview_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/mochi_preview_repackaged", "split_files/diffusion_models/mochi_preview_fp8_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanVideo_repackaged", "split_files/diffusion_models/hunyuan_video_t2v_720p_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanVideo_repackaged", "split_files/diffusion_models/hunyuan_video_image_to_video_720p_bf16.safetensors"),
|
|
HuggingFile("mcmonkey/cosmos-1.0", "Cosmos-1_0-Diffusion-14B-Text2World.safetensors"),
|
|
HuggingFile("mcmonkey/cosmos-1.0", "Cosmos-1_0-Diffusion-14B-Video2World.safetensors"),
|
|
HuggingFile("mcmonkey/cosmos-1.0", "Cosmos-1_0-Diffusion-7B-Text2World.safetensors"),
|
|
HuggingFile("mcmonkey/cosmos-1.0", "Cosmos-1_0-Diffusion-7B-Video2World.safetensors"),
|
|
HuggingFile("Comfy-Org/Lumina_Image_2.0_Repackaged", "split_files/diffusion_models/lumina_2_model_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_i2v_480p_14B_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_i2v_480p_14B_fp16.safetensors", show_in_ui=False),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_i2v_480p_14B_fp8_e4m3fn.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_i2v_720p_14B_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_i2v_720p_14B_fp16.safetensors", show_in_ui=False),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_i2v_720p_14B_fp8_e4m3fn.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_t2v_1.3B_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_t2v_1.3B_fp16.safetensors", show_in_ui=False),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_t2v_14B_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_t2v_14B_fp16.safetensors", show_in_ui=False),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_t2v_14B_fp8_e4m3fn.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanVideo_repackaged", "split_files/diffusion_models/hunyuan_video_v2_replace_image_to_video_720p_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/HiDream-I1_ComfyUI", "split_files/diffusion_models/hidream_i1_dev_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/HiDream-I1_ComfyUI", "split_files/diffusion_models/hidream_i1_full_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/HiDream-I1_ComfyUI", "split_files/diffusion_models/hidream_e1_full_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Cosmos_Predict2_repackaged", "cosmos_predict2_2B_t2i.safetensors"),
|
|
HuggingFile("Comfy-Org/Cosmos_Predict2_repackaged", "cosmos_predict2_14B_t2i.safetensors"),
|
|
HuggingFile("Comfy-Org/Cosmos_Predict2_repackaged", "cosmos_predict2_2B_video2world_480p_16fps.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_vace_14B_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/diffusion_models/wan2.1_fun_camera_v1.1_1.3B_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.2_ComfyUI_Repackaged", "split_files/diffusion_models/wan2.2_ti2v_5B_fp16.safetensors"),
|
|
HuggingFile("lodestones/Chroma", "chroma-unlocked-v37.safetensors"),
|
|
HuggingFile("QuantStack/Wan2.2-T2V-A14B-GGUF", "HighNoise/Wan2.2-T2V-A14B-HighNoise-Q8_0.gguf"),
|
|
HuggingFile("QuantStack/Wan2.2-T2V-A14B-GGUF", "HighNoise/Wan2.2-T2V-A14B-HighNoise-Q4_K_M.gguf"),
|
|
HuggingFile("QuantStack/Wan2.2-T2V-A14B-GGUF", "LowNoise/Wan2.2-T2V-A14B-LowNoise-Q8_0.gguf"),
|
|
HuggingFile("QuantStack/Wan2.2-T2V-A14B-GGUF", "LowNoise/Wan2.2-T2V-A14B-LowNoise-Q4_K_M.gguf"),
|
|
HuggingFile("city96/Qwen-Image-gguf", "qwen-image-Q4_K_M.gguf"),
|
|
HuggingFile("city96/Qwen-Image-gguf", "qwen-image-Q8_0.gguf"),
|
|
HuggingFile("Comfy-Org/Qwen-Image_ComfyUI", "split_files/diffusion_models/qwen_image_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image_ComfyUI", "split_files/diffusion_models/qwen_image_fp8_e4m3fn.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image_ComfyUI", "non_official/diffusion_models/qwen_image_distill_full_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image_ComfyUI", "non_official/diffusion_models/qwen_image_distill_full_fp8_e4m3fn.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image-Edit_ComfyUI", "split_files/diffusion_models/qwen_image_edit_2509_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image-Edit_ComfyUI", "split_files/diffusion_models/qwen_image_edit_2509_fp8_e4m3fn.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image-Edit_ComfyUI", "split_files/diffusion_models/qwen_image_edit_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image-Edit_ComfyUI", "split_files/diffusion_models/qwen_image_edit_fp8_e4m3fn.safetensors"),
|
|
# Flux 2
|
|
HuggingFile("Comfy-Org/flux2-dev", "split_files/diffusion_models/flux2_dev_fp8mixed.safetensors"),
|
|
# Z Image Turbo
|
|
HuggingFile("Comfy-Org/z_image_turbo", "split_files/diffusion_models/z_image_turbo_bf16.safetensors"),
|
|
# Omnigen 2
|
|
HuggingFile("Comfy-Org/Omnigen2_ComfyUI_repackaged", "split_files/diffusion_models/omnigen2_fp16.safetensors"),
|
|
# Hunyuan Image
|
|
HuggingFile("Comfy-Org/HunyuanImage_2.1_ComfyUI", "split_files/diffusion_models/hunyuanimage2.1_bf16.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanImage_2.1_ComfyUI", "split_files/diffusion_models/hunyuanimage2.1_refiner_bf16.safetensors"),
|
|
# Ovis
|
|
HuggingFile("Comfy-Org/Ovis-Image", "split_files/diffusion_models/ovis_image_bf16.safetensors"),
|
|
], folder_names=["diffusion_models", "unet"])
|
|
KNOWN_CLIP_MODELS: Final[KnownDownloadables] = KnownDownloadables([
|
|
# todo: is this correct?
|
|
HuggingFile("comfyanonymous/flux_text_encoders", "t5xxl_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/flux_text_encoders", "t5xxl_fp8_e4m3fn.safetensors"),
|
|
HuggingFile("Comfy-Org/mochi_preview_repackaged", "split_files/text_encoders/t5xxl_fp8_e4m3fn_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanVideo_repackaged", "split_files/text_encoders/llava_llama3_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanVideo_repackaged", "split_files/text_encoders/llava_llama3_fp8_scaled.safetensors"),
|
|
HuggingFile("stabilityai/stable-diffusion-3-medium", "text_encoders/clip_g.safetensors"),
|
|
HuggingFile("comfyanonymous/flux_text_encoders", "clip_l.safetensors", save_with_filename="clip_l.safetensors"),
|
|
# uses names from https://comfyanonymous.github.io/ComfyUI_examples/audio/
|
|
HuggingFile("google-t5/t5-base", "model.safetensors", save_with_filename="t5_base.safetensors"),
|
|
HuggingFile("zer0int/CLIP-GmP-ViT-L-14", "ViT-L-14-TEXT-detail-improved-hiT-GmP-TE-only-HF.safetensors"),
|
|
HuggingFile("comfyanonymous/cosmos_1.0_text_encoder_and_VAE_ComfyUI", "text_encoders/oldt5_xxl_fp16.safetensors"),
|
|
HuggingFile("comfyanonymous/cosmos_1.0_text_encoder_and_VAE_ComfyUI", "text_encoders/oldt5_xxl_fp8_e4m3fn_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/Lumina_Image_2.0_Repackaged", "split_files/text_encoders/gemma_2_2b_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/text_encoders/umt5_xxl_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/Wan_2.1_ComfyUI_repackaged", "split_files/text_encoders/umt5_xxl_fp8_e4m3fn_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/HiDream-I1_ComfyUI", "split_files/text_encoders/clip_l_hidream.safetensors"),
|
|
HuggingFile("Comfy-Org/HiDream-I1_ComfyUI", "split_files/text_encoders/clip_g_hidream.safetensors"),
|
|
HuggingFile("Comfy-Org/HiDream-I1_ComfyUI", "split_files/text_encoders/llama_3.1_8b_instruct_fp8_scaled.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image_ComfyUI", "split_files/text_encoders/qwen_2.5_vl_7b.safetensors"),
|
|
HuggingFile("Comfy-Org/Qwen-Image_ComfyUI", "split_files/text_encoders/qwen_2.5_vl_7b_fp8_scaled.safetensors"),
|
|
# Flux 2
|
|
HuggingFile("Comfy-Org/flux2-dev", "split_files/text_encoders/mistral_3_small_flux2_fp8.safetensors"),
|
|
HuggingFile("Comfy-Org/flux2-dev", "split_files/text_encoders/mistral_3_small_flux2_bf16.safetensors"),
|
|
# Z Image Turbo
|
|
HuggingFile("Comfy-Org/z_image_turbo", "split_files/text_encoders/qwen_3_4b.safetensors"),
|
|
# Omnigen 2
|
|
HuggingFile("Comfy-Org/Omnigen2_ComfyUI_repackaged", "split_files/text_encoders/qwen_2.5_vl_fp16.safetensors"),
|
|
# Hunyuan Image
|
|
HuggingFile("Comfy-Org/HunyuanImage_2.1_ComfyUI", "split_files/text_encoders/byt5_small_glyphxl_fp16.safetensors"),
|
|
HuggingFile("Comfy-Org/HunyuanImage_2.1_ComfyUI", "split_files/text_encoders/qwen_2.5_vl_7b.safetensors"),
|
|
], folder_names=["clip", "text_encoders"])
|
|
|
|
KNOWN_STYLE_MODELS: Final[KnownDownloadables] = KnownDownloadables([
|
|
HuggingFile("black-forest-labs/FLUX.1-Redux-dev", "flux1-redux-dev.safetensors"),
|
|
], folder_name="style_models")
|
|
|
|
_known_models_db: list[KnownDownloadables] = [
|
|
KNOWN_CHECKPOINTS,
|
|
KNOWN_VAES,
|
|
KNOWN_LORAS,
|
|
KNOWN_UNET_MODELS,
|
|
KNOWN_APPROX_VAES,
|
|
KNOWN_DIFF_CONTROLNETS,
|
|
KNOWN_CLIP_MODELS,
|
|
KNOWN_CLIP_VISION_MODELS,
|
|
KNOWN_CONTROLNETS,
|
|
KNOWN_GLIGEN_MODELS,
|
|
KNOWN_IMAGE_ONLY_CHECKPOINTS,
|
|
KNOWN_UNCLIP_CHECKPOINTS,
|
|
KNOWN_UPSCALERS,
|
|
KNOWN_STYLE_MODELS,
|
|
]
|
|
|
|
|
|
def _is_known_model_in_models_db(obj: list[Downloadable] | KnownDownloadables):
|
|
return any(candidate is obj or candidate.data is obj for candidate in _known_models_db)
|
|
|
|
|
|
def _get_known_models_for_folder_name(folder_name: str) -> List[Downloadable]:
|
|
return list(chain.from_iterable([candidate for candidate in _known_models_db if folder_name in candidate]))
|
|
|
|
|
|
def add_known_models(folder_name: str, known_models: Optional[List[Downloadable]] | Downloadable = None, *models: Downloadable) -> MutableSequence[Downloadable]:
|
|
if isinstance(known_models, Downloadable):
|
|
models = [known_models] + list(models) or []
|
|
known_models = None
|
|
|
|
if known_models is None:
|
|
try:
|
|
known_models = next(candidate for candidate in _known_models_db if folder_name in candidate)
|
|
except StopIteration:
|
|
add_model_folder_path(folder_name, extensions=supported_pt_extensions)
|
|
known_models = KnownDownloadables([], folder_name=folder_name)
|
|
|
|
# check if any of the pre-existing known models already reference this list
|
|
if not _is_known_model_in_models_db(known_models):
|
|
if not isinstance(known_models, KnownDownloadables):
|
|
# wrap it
|
|
known_models = KnownDownloadables(known_models)
|
|
# meets protocol at this point
|
|
_known_models_db.append(known_models)
|
|
|
|
if len(models) < 1:
|
|
return known_models
|
|
|
|
if args.disable_known_models:
|
|
logger.warning(f"Known models have been disabled in the options (while adding {folder_name}/{','.join(map(str, models))})")
|
|
|
|
pre_existing = frozenset(known_models)
|
|
known_models.extend([model for model in models if model not in pre_existing])
|
|
return known_models
|
|
|
|
|
|
@_deprecate_method(version="1.0.0", message="use get_huggingface_repo_list instead")
|
|
def huggingface_repos() -> List[str]:
|
|
return get_huggingface_repo_list()
|
|
|
|
|
|
def get_huggingface_repo_list(*extra_cache_dirs: str) -> List[str]:
|
|
if len(extra_cache_dirs) == 0:
|
|
extra_cache_dirs = folder_paths.get_folder_paths("huggingface_cache")
|
|
|
|
# all in cache directories
|
|
try:
|
|
default_cache_dir = [scan_cache_dir()]
|
|
except CacheNotFound as exc_info:
|
|
default_cache_dir = []
|
|
existing_repo_ids = frozenset(
|
|
cache_item.repo_id for cache_item in \
|
|
reduce(operator.or_,
|
|
map(lambda cache_info: cache_info.repos, default_cache_dir + [scan_cache_dir(cache_dir=cache_dir) for cache_dir in extra_cache_dirs if os.path.isdir(cache_dir)]))
|
|
if cache_item.repo_type == "model" or cache_item.repo_type == "space"
|
|
)
|
|
|
|
# also check local-dir style directories
|
|
existing_local_dir_repos = set()
|
|
local_dirs = folder_paths.get_folder_paths("huggingface")
|
|
for local_dir_root in local_dirs:
|
|
# enumerate all the two-directory paths
|
|
if not os.path.isdir(local_dir_root):
|
|
continue
|
|
|
|
for user_dir in Path(local_dir_root).iterdir():
|
|
for model_dir in user_dir.iterdir():
|
|
existing_local_dir_repos.add(f"{user_dir.name}/{model_dir.name}")
|
|
|
|
known_repo_ids = frozenset(KNOWN_HUGGINGFACE_MODEL_REPOS)
|
|
if args.disable_known_models:
|
|
return list(existing_repo_ids | existing_local_dir_repos)
|
|
else:
|
|
return list(existing_repo_ids | existing_local_dir_repos | known_repo_ids)
|
|
|
|
|
|
def get_or_download_huggingface_repo(repo_id: str, cache_dirs: Optional[list] = None, local_dirs: Optional[list] = None, force: bool = False, subset: bool = False) -> Optional[str]:
|
|
with comfy_tqdm():
|
|
return _get_or_download_huggingface_repo(repo_id, cache_dirs, local_dirs, force=force, subset=subset)
|
|
|
|
|
|
def _get_or_download_huggingface_repo(repo_id: str, cache_dirs: Optional[list] = None, local_dirs: Optional[list] = None, force: bool = False, subset: bool = False) -> Optional[str]:
|
|
cache_dirs = cache_dirs or folder_paths.get_folder_paths("huggingface_cache")
|
|
local_dirs = local_dirs or folder_paths.get_folder_paths("huggingface")
|
|
cache_dirs_snapshots, local_dirs_snapshots = _get_cache_hits(cache_dirs, local_dirs, repo_id, subset=subset)
|
|
|
|
local_dirs_cache_hit = len(local_dirs_snapshots) > 0
|
|
cache_dirs_cache_hit = len(cache_dirs_snapshots) > 0
|
|
logger.debug(f"cache {'hit' if local_dirs_cache_hit or cache_dirs_cache_hit else 'miss'} for repo_id={repo_id} because local_dirs={local_dirs_cache_hit}, cache_dirs={cache_dirs_cache_hit}")
|
|
|
|
# if we're in forced local directory mode, only use the local dir snapshots, and otherwise, download
|
|
if args.force_hf_local_dir_mode:
|
|
# todo: we still have to figure out a way to download things to the right places by default
|
|
if len(local_dirs_snapshots) > 0 and not force:
|
|
return local_dirs_snapshots[0]
|
|
elif not args.disable_known_models:
|
|
destination = os.path.join(local_dirs[0], repo_id)
|
|
logger.debug(f"downloading repo_id={repo_id}, local_dir={destination}")
|
|
return snapshot_download(repo_id, local_dir=destination, force_download=force)
|
|
|
|
snapshots = local_dirs_snapshots + cache_dirs_snapshots
|
|
if len(snapshots) > 0 and not force:
|
|
return snapshots[0]
|
|
elif not args.disable_known_models:
|
|
logger.debug(f"downloading repo_id={repo_id}")
|
|
return snapshot_download(repo_id, force_download=force)
|
|
|
|
# this repo was not found
|
|
return None
|
|
|
|
|
|
def _get_cache_hits(cache_dirs: Sequence[str], local_dirs: Sequence[str], repo_id, subset=False):
|
|
local_dirs_snapshots = []
|
|
cache_dirs_snapshots = []
|
|
# find all the pre-existing downloads for this repo_id
|
|
try:
|
|
repo_files = set(_hf_fs.ls(repo_id, detail=False))
|
|
except:
|
|
repo_files = []
|
|
|
|
if len(repo_files) > 0:
|
|
for local_dir in local_dirs:
|
|
local_path = Path(local_dir) / repo_id
|
|
local_files = frozenset(f"{repo_id}/{f.relative_to(local_path)}" for f in local_path.rglob("*") if f.is_file())
|
|
# fix path representation
|
|
local_files = frozenset(f.replace("\\", "/") for f in local_files)
|
|
# remove .huggingface
|
|
local_files = frozenset(f for f in local_files if not f.startswith(f"{repo_id}/.huggingface") and not f.startswith(f"{repo_id}/.cache"))
|
|
if len(local_files) > 0 and ((subset and local_files.issubset(repo_files)) or (not subset and repo_files.issubset(local_files))):
|
|
local_dirs_snapshots.append(str(local_path))
|
|
else:
|
|
# an empty repository or unknown repository info, trust that if the directory exists, it matches
|
|
for local_dir in local_dirs:
|
|
local_path = Path(local_dir) / repo_id
|
|
if local_path.is_dir():
|
|
local_dirs_snapshots.append(str(local_path))
|
|
|
|
for cache_dir in (None, *cache_dirs):
|
|
try:
|
|
cache_dirs_snapshots.append(snapshot_download(repo_id, local_files_only=True, cache_dir=cache_dir))
|
|
except FileNotFoundError:
|
|
continue
|
|
except:
|
|
continue
|
|
return cache_dirs_snapshots, local_dirs_snapshots
|
|
|
|
|
|
def _delete_repo_from_huggingface_cache(repo_id: str, cache_dir: Optional[str] = None) -> List[str]:
|
|
results = scan_cache_dir(cache_dir)
|
|
matching = [repo for repo in results.repos if repo.repo_id == repo_id]
|
|
if len(matching) == 0:
|
|
return []
|
|
revisions: List[str] = []
|
|
for repo in matching:
|
|
for revision_info in repo.revisions:
|
|
revisions.append(revision_info.commit_hash)
|
|
results.delete_revisions(*revisions).execute()
|
|
return revisions
|