@@ -1662,10 +1662,37 @@ def download(cls, pretrained_model_name, **kwargs) -> str | os.PathLike:
16621662 force_download = force_download ,
16631663 token = token ,
16641664 )
1665+ filenames = {sibling .rfilename for sibling in info .siblings }
1666+ else :
1667+ # We are offline (either the user asked for `local_files_only` or the `model_info` call above
1668+ # failed), so the repo's file listing needed to compute the allow/ignore patterns below cannot be
1669+ # fetched. Source the listing from the cached snapshot instead: it holds exactly the (already
1670+ # filtered) files a previous online call downloaded, so both code paths compute the same patterns
1671+ # and `snapshot_download` validates the cached snapshot against them (catching e.g. a download
1672+ # that was interrupted midway). If the config isn't cached, skip straight to `snapshot_download`
1673+ # below, which raises the appropriate offline not-found error.
1674+ try :
1675+ config_file = hf_hub_download (
1676+ pretrained_model_name ,
1677+ cls .config_name ,
1678+ cache_dir = cache_dir ,
1679+ revision = revision ,
1680+ token = token ,
1681+ local_files_only = True ,
1682+ )
1683+ except LocalEntryNotFoundError :
1684+ config_file = None
1685+
1686+ if config_file is not None :
1687+ snapshot_folder = Path (config_file ).parent
1688+ if local_files_only :
1689+ filenames = {
1690+ f .relative_to (snapshot_folder ).as_posix () for f in snapshot_folder .rglob ("*" ) if f .is_file ()
1691+ }
1692+
16651693 config_dict = cls ._dict_from_json_file (config_file )
16661694 ignore_filenames = config_dict .pop ("_ignore_files" , [])
16671695
1668- filenames = {sibling .rfilename for sibling in info .siblings }
16691696 if variant is not None and _check_legacy_sharding_variant_format (filenames = filenames , variant = variant ):
16701697 warn_msg = (
16711698 f"Warning: The repository contains sharded checkpoints for variant '{ variant } ' maybe in a deprecated format. "
@@ -1680,9 +1707,11 @@ def download(cls, pretrained_model_name, **kwargs) -> str | os.PathLike:
16801707 logger .warning (warn_msg )
16811708
16821709 filenames = set (filenames ) - set (ignore_filenames )
1683- if revision in DEPRECATED_REVISION_ARGS and version .parse (
1684- version .parse (__version__ ).base_version
1685- ) >= version .parse ("0.22.0" ):
1710+ if (
1711+ not local_files_only
1712+ and revision in DEPRECATED_REVISION_ARGS
1713+ and version .parse (version .parse (__version__ ).base_version ) >= version .parse ("0.22.0" )
1714+ ):
16861715 warn_deprecated_model_variant (pretrained_model_name , token , variant , revision , filenames )
16871716
16881717 custom_components , folder_names = _get_custom_components_and_folders (
@@ -1767,40 +1796,20 @@ def download(cls, pretrained_model_name, **kwargs) -> str | os.PathLike:
17671796
17681797 # Don't download index files of forbidden patterns either
17691798 ignore_patterns = ignore_patterns + [f"{ i } .index.*json" for i in ignore_patterns ]
1770- re_ignore_pattern = [re .compile (fnmatch .translate (p )) for p in ignore_patterns ]
1771- re_allow_pattern = [re .compile (fnmatch .translate (p )) for p in allow_patterns ]
17721799
1773- expected_files = [f for f in filenames if not any (p .match (f ) for p in re_ignore_pattern )]
1774- expected_files = [f for f in expected_files if any (p .match (f ) for p in re_allow_pattern )]
1800+ if not local_files_only :
1801+ re_ignore_pattern = [re .compile (fnmatch .translate (p )) for p in ignore_patterns ]
1802+ re_allow_pattern = [re .compile (fnmatch .translate (p )) for p in allow_patterns ]
17751803
1776- snapshot_folder = Path ( config_file ). parent
1777- pipeline_is_cached = all (( snapshot_folder / f ). is_file ( ) for f in expected_files )
1804+ expected_files = [ f for f in filenames if not any ( p . match ( f ) for p in re_ignore_pattern )]
1805+ expected_files = [ f for f in expected_files if any ( p . match ( f ) for p in re_allow_pattern )]
17781806
1779- if pipeline_is_cached and not force_download :
1780- # if the pipeline is cached, we can directly return it
1781- # else call snapshot_download
1782- return snapshot_folder
1807+ pipeline_is_cached = all ((snapshot_folder / f ).is_file () for f in expected_files )
17831808
1784- else :
1785- # We are offline (either the user asked for `local_files_only` or `model_info` failed above).
1786- # diffusers only ever caches a filtered subset of a repo (skipping e.g. `.gitattributes`), but
1787- # newer `huggingface_hub` versions make `snapshot_download` validate that the cached snapshot is
1788- # complete and raise for the missing files. The resolved config file lives inside the cached
1789- # snapshot folder, so return that folder directly. If the config isn't cached, fall through to
1790- # `snapshot_download` below, which raises the not-found error handled together with a failed
1791- # `model_info` call.
1792- try :
1793- config_file = hf_hub_download (
1794- pretrained_model_name ,
1795- cls .config_name ,
1796- cache_dir = cache_dir ,
1797- revision = revision ,
1798- token = token ,
1799- local_files_only = True ,
1800- )
1801- return Path (config_file ).parent
1802- except LocalEntryNotFoundError :
1803- pass
1809+ if pipeline_is_cached and not force_download :
1810+ # if the pipeline is cached, we can directly return it
1811+ # else call snapshot_download
1812+ return snapshot_folder
18041813
18051814 user_agent = {"pipeline_class" : cls .__name__ }
18061815 if custom_pipeline is not None and not custom_pipeline .endswith (".py" ):
@@ -1843,7 +1852,7 @@ def download(cls, pretrained_model_name, **kwargs) -> str | os.PathLike:
18431852
18441853 return cached_folder
18451854
1846- except FileNotFoundError :
1855+ except FileNotFoundError as e :
18471856 # Means we tried to load pipeline with `local_files_only=True` but the files have not been found in local cache.
18481857 # This can happen in two cases:
18491858 # 1. If the user passed `local_files_only=True` => we raise the error directly
@@ -1854,9 +1863,9 @@ def download(cls, pretrained_model_name, **kwargs) -> str | os.PathLike:
18541863 else :
18551864 # 2. we forced `local_files_only=True` when `model_info` failed
18561865 raise EnvironmentError (
1857- f"Cannot load model { pretrained_model_name } : model is not cached locally and an error occurred "
1858- " while trying to fetch metadata from the Hub. Please check out the root cause in the stacktrace "
1859- " above."
1866+ f"Cannot load model { pretrained_model_name } : the model is not fully cached locally ( { e } ) and an"
1867+ " error occurred while trying to fetch metadata from the Hub. Please check out the root cause in"
1868+ " the stacktrace above."
18601869 ) from model_info_call_error
18611870
18621871 @classmethod
0 commit comments