From b5d0069da455b80e034f1d8c24a142c152daf358 Mon Sep 17 00:00:00 2001 From: eaidova Date: Tue, 21 May 2024 19:10:16 +0400 Subject: [PATCH 1/4] optionally enable export if not exported model provided --- optimum/intel/openvino/modeling_base.py | 130 +++++++++++++++++- .../intel/openvino/modeling_base_seq2seq.py | 26 +++- 2 files changed, 154 insertions(+), 2 deletions(-) diff --git a/optimum/intel/openvino/modeling_base.py b/optimum/intel/openvino/modeling_base.py index 7937deea52..2be0619c60 100644 --- a/optimum/intel/openvino/modeling_base.py +++ b/optimum/intel/openvino/modeling_base.py @@ -20,16 +20,20 @@ from typing import Dict, Optional, Union import openvino -from huggingface_hub import hf_hub_download +from huggingface_hub import hf_hub_download, HfApi from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE from openvino import Core, convert_model from openvino._offline_transformations import apply_moc_transformations, compress_model_transformation from transformers import GenerationConfig, PretrainedConfig from transformers.file_utils import add_start_docstrings from transformers.generation import GenerationMixin +from transformers import AutoConfig from optimum.exporters.onnx import OnnxConfig +from optimum.exporters.tasks import TasksManager from optimum.modeling_base import OptimizedModel +from optimum.utils import CONFIG_NAME +from optimum.modeling_base import FROM_PRETRAINED_START_DOCSTRING from ...exporters.openvino import export, main_export from ..utils.import_utils import is_nncf_available @@ -524,3 +528,127 @@ def can_generate(self) -> bool: if isinstance(self, GenerationMixin): return True return False + + @classmethod + @add_start_docstrings(FROM_PRETRAINED_START_DOCSTRING) + def from_pretrained( + cls, + model_id: Union[str, Path], + export: Optional[bool] = None, + force_download: bool = False, + use_auth_token: Optional[str] = None, + cache_dir: str = HUGGINGFACE_HUB_CACHE, + subfolder: str = "", + config: Optional[PretrainedConfig] = None, + local_files_only: bool = False, + trust_remote_code: bool = False, + revision: Optional[str] = None, + **kwargs, + ) -> "OptimizedModel": + """ + Returns: + `OptimizedModel`: The loaded optimized model. + """ + if isinstance(model_id, Path): + model_id = model_id.as_posix() + + from_transformers = kwargs.pop("from_transformers", None) + if from_transformers is not None: + logger.warning( + "The argument `from_transformers` is deprecated, and will be removed in optimum 2.0. Use `export` instead" + ) + export = from_transformers + + if len(model_id.split("@")) == 2: + if revision is not None: + logger.warning( + f"The argument `revision` was set to {revision} but will be ignored for {model_id.split('@')[1]}" + ) + model_id, revision = model_id.split("@") + + library_name = TasksManager.infer_library_from_model( + model_id, subfolder, revision, cache_dir, use_auth_token=use_auth_token + ) + + if library_name == "timm": + config = PretrainedConfig.from_pretrained(model_id, subfolder, revision) + + if config is None: + if os.path.isdir(os.path.join(model_id, subfolder)) and cls.config_name == CONFIG_NAME: + if CONFIG_NAME in os.listdir(os.path.join(model_id, subfolder)): + config = AutoConfig.from_pretrained( + os.path.join(model_id, subfolder, CONFIG_NAME), trust_remote_code=trust_remote_code + ) + elif CONFIG_NAME in os.listdir(model_id): + config = AutoConfig.from_pretrained( + os.path.join(model_id, CONFIG_NAME), trust_remote_code=trust_remote_code + ) + logger.info( + f"config.json not found in the specified subfolder {subfolder}. Using the top level config.json." + ) + else: + raise OSError(f"config.json not found in {model_id} local folder") + else: + config = cls._load_config( + model_id, + revision=revision, + cache_dir=cache_dir, + use_auth_token=use_auth_token, + force_download=force_download, + subfolder=subfolder, + trust_remote_code=trust_remote_code, + ) + elif isinstance(config, (str, os.PathLike)): + config = cls._load_config( + config, + revision=revision, + cache_dir=cache_dir, + use_auth_token=use_auth_token, + force_download=force_download, + subfolder=subfolder, + trust_remote_code=trust_remote_code, + ) + + if export is None: + export = cls._check_export_status(model_id, revision, subfolder) + + if not export and trust_remote_code: + logger.warning( + "The argument `trust_remote_code` is to be used along with export=True. It will be ignored." + ) + elif export and trust_remote_code is None: + trust_remote_code = False + + + from_pretrained_method = cls._from_transformers if export else cls._from_pretrained + + return from_pretrained_method( + model_id=model_id, + config=config, + revision=revision, + cache_dir=cache_dir, + force_download=force_download, + use_auth_token=use_auth_token, + subfolder=subfolder, + local_files_only=local_files_only, + trust_remote_code=trust_remote_code, + **kwargs, + ) + + @classmethod + def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str] = None, subfolder: str = ""): + model_dir = Path(model_id) + if subfolder is not None: + model_dir = model_dir / subfolder + if model_dir.is_dir(): + return not (model_dir / OV_XML_FILE_NAME).exists() or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() + + hf_api = HfApi() + try: + model_info = hf_api.model_info(model_id, revision=revision or "main") + normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + model_files = [file.rfilename for file in model_info.siblings if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder)] + ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + return not ov_model_path in model_files or not ov_model_path.replace(".xml", ".bin") in model_files + except Exception: + return True diff --git a/optimum/intel/openvino/modeling_base_seq2seq.py b/optimum/intel/openvino/modeling_base_seq2seq.py index fb53f9b2e2..9fbad00c82 100644 --- a/optimum/intel/openvino/modeling_base_seq2seq.py +++ b/optimum/intel/openvino/modeling_base_seq2seq.py @@ -20,7 +20,7 @@ from typing import Dict, Optional, Union import openvino -from huggingface_hub import hf_hub_download +from huggingface_hub import hf_hub_download, HfApi from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE from openvino._offline_transformations import apply_moc_transformations, compress_model_transformation from transformers import GenerationConfig, PretrainedConfig @@ -362,3 +362,27 @@ def half(self): def forward(self, *args, **kwargs): raise NotImplementedError + + + @classmethod + def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str] = None, subfolder: str = ""): + model_dir = Path(model_id) + if subfolder is not None: + model_dir = model_dir / subfolder + if model_dir.is_dir(): + encoder_exists = (model_dir / OV_ENCODER_NAME).exists() and (model_dir / OV_ENCODER_NAME.replace(".xml", ".bin")).exists() + decoder_exists = (model_dir / OV_DECODER_NAME).exists() and (model_dir / OV_DECODER_NAME.replace(".xml", ".bin")).exists() + return not encoder_exists or not decoder_exists + + hf_api = HfApi() + try: + model_info = hf_api.model_info(model_id, revision=revision or "main") + normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + model_files = [file.rfilename for file in model_info.siblings if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder)] + for model_name in [OV_ENCODER_NAME, OV_DECODER_NAME]: + ov_model_path = model_name if subfolder is None else f"{normalized_subfolder}/{model_name}" + if not ov_model_path in model_files or not ov_model_path.replace(".xml", ".bin") in model_files: + return True + return False + except Exception: + return True \ No newline at end of file From ebe5c0f26dd492788cea710a7aa60ec08c94b8f9 Mon Sep 17 00:00:00 2001 From: eaidova Date: Thu, 23 May 2024 18:26:13 +0400 Subject: [PATCH 2/4] support stable diffusion --- optimum/intel/openvino/modeling_base.py | 28 +++++++------ .../intel/openvino/modeling_base_seq2seq.py | 25 +++++++----- optimum/intel/openvino/modeling_diffusion.py | 39 ++++++++++++++++++- 3 files changed, 70 insertions(+), 22 deletions(-) diff --git a/optimum/intel/openvino/modeling_base.py b/optimum/intel/openvino/modeling_base.py index 2be0619c60..929f9fe40e 100644 --- a/optimum/intel/openvino/modeling_base.py +++ b/optimum/intel/openvino/modeling_base.py @@ -20,20 +20,18 @@ from typing import Dict, Optional, Union import openvino -from huggingface_hub import hf_hub_download, HfApi +from huggingface_hub import HfApi, hf_hub_download from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE from openvino import Core, convert_model from openvino._offline_transformations import apply_moc_transformations, compress_model_transformation -from transformers import GenerationConfig, PretrainedConfig +from transformers import AutoConfig, GenerationConfig, PretrainedConfig from transformers.file_utils import add_start_docstrings from transformers.generation import GenerationMixin -from transformers import AutoConfig from optimum.exporters.onnx import OnnxConfig from optimum.exporters.tasks import TasksManager -from optimum.modeling_base import OptimizedModel +from optimum.modeling_base import FROM_PRETRAINED_START_DOCSTRING, OptimizedModel from optimum.utils import CONFIG_NAME -from optimum.modeling_base import FROM_PRETRAINED_START_DOCSTRING from ...exporters.openvino import export, main_export from ..utils.import_utils import is_nncf_available @@ -608,7 +606,7 @@ def from_pretrained( subfolder=subfolder, trust_remote_code=trust_remote_code, ) - + if export is None: export = cls._check_export_status(model_id, revision, subfolder) @@ -619,7 +617,6 @@ def from_pretrained( elif export and trust_remote_code is None: trust_remote_code = False - from_pretrained_method = cls._from_transformers if export else cls._from_pretrained return from_pretrained_method( @@ -641,14 +638,21 @@ def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str if subfolder is not None: model_dir = model_dir / subfolder if model_dir.is_dir(): - return not (model_dir / OV_XML_FILE_NAME).exists() or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() - - hf_api = HfApi() + return ( + not (model_dir / OV_XML_FILE_NAME).exists() + or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() + ) + + hf_api = HfApi() try: model_info = hf_api.model_info(model_id, revision=revision or "main") normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() - model_files = [file.rfilename for file in model_info.siblings if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder)] + model_files = [ + file.rfilename + for file in model_info.siblings + if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) + ] ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" - return not ov_model_path in model_files or not ov_model_path.replace(".xml", ".bin") in model_files + return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files except Exception: return True diff --git a/optimum/intel/openvino/modeling_base_seq2seq.py b/optimum/intel/openvino/modeling_base_seq2seq.py index 9fbad00c82..d81a1d7858 100644 --- a/optimum/intel/openvino/modeling_base_seq2seq.py +++ b/optimum/intel/openvino/modeling_base_seq2seq.py @@ -20,7 +20,7 @@ from typing import Dict, Optional, Union import openvino -from huggingface_hub import hf_hub_download, HfApi +from huggingface_hub import HfApi, hf_hub_download from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE from openvino._offline_transformations import apply_moc_transformations, compress_model_transformation from transformers import GenerationConfig, PretrainedConfig @@ -363,26 +363,33 @@ def half(self): def forward(self, *args, **kwargs): raise NotImplementedError - @classmethod def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str] = None, subfolder: str = ""): model_dir = Path(model_id) if subfolder is not None: model_dir = model_dir / subfolder if model_dir.is_dir(): - encoder_exists = (model_dir / OV_ENCODER_NAME).exists() and (model_dir / OV_ENCODER_NAME.replace(".xml", ".bin")).exists() - decoder_exists = (model_dir / OV_DECODER_NAME).exists() and (model_dir / OV_DECODER_NAME.replace(".xml", ".bin")).exists() + encoder_exists = (model_dir / OV_ENCODER_NAME).exists() and ( + model_dir / OV_ENCODER_NAME.replace(".xml", ".bin") + ).exists() + decoder_exists = (model_dir / OV_DECODER_NAME).exists() and ( + model_dir / OV_DECODER_NAME.replace(".xml", ".bin") + ).exists() return not encoder_exists or not decoder_exists - - hf_api = HfApi() + + hf_api = HfApi() try: model_info = hf_api.model_info(model_id, revision=revision or "main") normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() - model_files = [file.rfilename for file in model_info.siblings if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder)] + model_files = [ + file.rfilename + for file in model_info.siblings + if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) + ] for model_name in [OV_ENCODER_NAME, OV_DECODER_NAME]: ov_model_path = model_name if subfolder is None else f"{normalized_subfolder}/{model_name}" - if not ov_model_path in model_files or not ov_model_path.replace(".xml", ".bin") in model_files: + if ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files: return True return False except Exception: - return True \ No newline at end of file + return True diff --git a/optimum/intel/openvino/modeling_diffusion.py b/optimum/intel/openvino/modeling_diffusion.py index 1b880e736c..d548d203a1 100644 --- a/optimum/intel/openvino/modeling_diffusion.py +++ b/optimum/intel/openvino/modeling_diffusion.py @@ -35,7 +35,7 @@ ) from diffusers.schedulers.scheduling_utils import SCHEDULER_CONFIG_NAME from diffusers.utils import CONFIG_NAME, is_invisible_watermark_available -from huggingface_hub import snapshot_download +from huggingface_hub import HfApi, snapshot_download from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE from openvino._offline_transformations import compress_model_transformation from openvino.runtime import Core @@ -411,6 +411,43 @@ def _from_transformers( **kwargs, ) + @classmethod + def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str] = None, subfolder: str = ""): + sub_model_dirs = [DIFFUSION_MODEL_UNET_SUBFOLDER, DIFFUSION_MODEL_VAE_DECODER_SUBFOLDER] + + def check_model_part_status(model_id, subfolder, revision): + model_dir = Path(model_id) + if subfolder is not None: + model_dir = model_dir / subfolder + if model_dir.is_dir(): + return ( + not (model_dir / OV_XML_FILE_NAME).exists() + or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() + ) + + hf_api = HfApi() + try: + model_info = hf_api.model_info(model_id, revision=revision or "main") + normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + model_files = [ + file.rfilename + for file in model_info.siblings + if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) + ] + ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files + except Exception: + return True + + for sub_model_dir in sub_model_dirs: + sub_model = sub_model_dir if not subfolder else f"{Path(subfolder).as_posix()}/{sub_model_dir}" + + status = check_model_part_status(model_id, sub_model, revision) + if status: + return True + + return False + def to(self, device: str): if isinstance(device, str): self._device = device.upper() From a7cfa5df879d0d64ae980be4edb908092543d79a Mon Sep 17 00:00:00 2001 From: eaidova Date: Thu, 23 May 2024 19:19:41 +0400 Subject: [PATCH 3/4] support offline mode --- optimum/intel/openvino/modeling_base.py | 58 +++++++++++----- .../intel/openvino/modeling_base_seq2seq.py | 66 +++++++++++++------ optimum/intel/openvino/modeling_diffusion.py | 56 +++++++++++----- 3 files changed, 127 insertions(+), 53 deletions(-) diff --git a/optimum/intel/openvino/modeling_base.py b/optimum/intel/openvino/modeling_base.py index 929f9fe40e..ea88de26da 100644 --- a/optimum/intel/openvino/modeling_base.py +++ b/optimum/intel/openvino/modeling_base.py @@ -20,8 +20,8 @@ from typing import Dict, Optional, Union import openvino -from huggingface_hub import HfApi, hf_hub_download -from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE +from huggingface_hub import HfApi, hf_hub_download, try_to_load_from_cache +from huggingface_hub.constants import HF_HUB_OFFLINE, HUGGINGFACE_HUB_CACHE from openvino import Core, convert_model from openvino._offline_transformations import apply_moc_transformations, compress_model_transformation from transformers import AutoConfig, GenerationConfig, PretrainedConfig @@ -608,7 +608,7 @@ def from_pretrained( ) if export is None: - export = cls._check_export_status(model_id, revision, subfolder) + export = cls._check_export_status(model_id, revision, subfolder, cache_dir, local_files_only or HF_HUB_OFFLINE) if not export and trust_remote_code: logger.warning( @@ -633,7 +633,14 @@ def from_pretrained( ) @classmethod - def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str] = None, subfolder: str = ""): + def _check_export_status( + cls, + model_id: Union[str, Path], + revision: Optional[str] = None, + subfolder: str = "", + cache_dir: str = HUGGINGFACE_HUB_CACHE, + local_files_only: bool = HF_HUB_OFFLINE, + ): model_dir = Path(model_id) if subfolder is not None: model_dir = model_dir / subfolder @@ -642,17 +649,32 @@ def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str not (model_dir / OV_XML_FILE_NAME).exists() or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() ) - - hf_api = HfApi() - try: - model_info = hf_api.model_info(model_id, revision=revision or "main") - normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() - model_files = [ - file.rfilename - for file in model_info.siblings - if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) - ] - ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" - return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files - except Exception: - return True + normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + cache_model_path = try_to_load_from_cache( + model_id, ov_model_path, cache_dir=cache_dir, revision=revision or "main", repo_type="model" + ) + cache_bin_path = try_to_load_from_cache( + model_id, + ov_model_path.replace(".xml", ".bin"), + cache_dir=cache_dir, + revision=revision or "main", + repo_type="model", + ) + cache_status = cache_bin_path is not None and cache_model_path is not None + + if not cache_status and not local_files_only: + hf_api = HfApi() + try: + model_info = hf_api.model_info(model_id, revision=revision or "main") + model_files = [ + file.rfilename + for file in model_info.siblings + if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) + ] + ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files + except Exception: + return True + + return not cache_status diff --git a/optimum/intel/openvino/modeling_base_seq2seq.py b/optimum/intel/openvino/modeling_base_seq2seq.py index d81a1d7858..fc1c3c5337 100644 --- a/optimum/intel/openvino/modeling_base_seq2seq.py +++ b/optimum/intel/openvino/modeling_base_seq2seq.py @@ -20,8 +20,8 @@ from typing import Dict, Optional, Union import openvino -from huggingface_hub import HfApi, hf_hub_download -from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE +from huggingface_hub import HfApi, hf_hub_download, try_to_load_from_cache +from huggingface_hub.constants import HF_HUB_OFFLINE, HUGGINGFACE_HUB_CACHE from openvino._offline_transformations import apply_moc_transformations, compress_model_transformation from transformers import GenerationConfig, PretrainedConfig from transformers.file_utils import add_start_docstrings @@ -364,7 +364,14 @@ def forward(self, *args, **kwargs): raise NotImplementedError @classmethod - def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str] = None, subfolder: str = ""): + def _check_export_status( + cls, + model_id: Union[str, Path], + revision: Optional[str] = None, + subfolder: str = "", + cache_dir: str = HUGGINGFACE_HUB_CACHE, + local_files_only: bool = HF_HUB_OFFLINE, + ): model_dir = Path(model_id) if subfolder is not None: model_dir = model_dir / subfolder @@ -377,19 +384,40 @@ def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str ).exists() return not encoder_exists or not decoder_exists - hf_api = HfApi() - try: - model_info = hf_api.model_info(model_id, revision=revision or "main") - normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() - model_files = [ - file.rfilename - for file in model_info.siblings - if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) - ] - for model_name in [OV_ENCODER_NAME, OV_DECODER_NAME]: - ov_model_path = model_name if subfolder is None else f"{normalized_subfolder}/{model_name}" - if ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files: - return True - return False - except Exception: - return True + cache_status = [] + normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + + for model_name in [OV_ENCODER_NAME, OV_DECODER_NAME]: + ov_model_path = model_name if subfolder is None else f"{normalized_subfolder}/{model_name}" + cache_model_path = try_to_load_from_cache( + model_id, ov_model_path, cache_dir=cache_dir, revision=revision or "main", repo_type="model" + ) + cache_bin_path = try_to_load_from_cache( + model_id, + ov_model_path.replace(".xml", ".bin"), + cache_dir=cache_dir, + revision=revision or "main", + repo_type="model", + ) + + cache_status.append(cache_model_path is not None and cache_bin_path is not None) + + if not all(cache_status) and not local_files_only: + hf_api = HfApi() + try: + model_info = hf_api.model_info(model_id, revision=revision or "main") + normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + model_files = [ + file.rfilename + for file in model_info.siblings + if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) + ] + for model_name in [OV_ENCODER_NAME, OV_DECODER_NAME]: + ov_model_path = model_name if subfolder is None else f"{normalized_subfolder}/{model_name}" + if ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files: + return True + return False + except Exception: + return True + + return not all(cache_status) diff --git a/optimum/intel/openvino/modeling_diffusion.py b/optimum/intel/openvino/modeling_diffusion.py index d548d203a1..2e7cf7708e 100644 --- a/optimum/intel/openvino/modeling_diffusion.py +++ b/optimum/intel/openvino/modeling_diffusion.py @@ -35,8 +35,8 @@ ) from diffusers.schedulers.scheduling_utils import SCHEDULER_CONFIG_NAME from diffusers.utils import CONFIG_NAME, is_invisible_watermark_available -from huggingface_hub import HfApi, snapshot_download -from huggingface_hub.constants import HUGGINGFACE_HUB_CACHE +from huggingface_hub import HfApi, snapshot_download, try_to_load_from_cache +from huggingface_hub.constants import HF_HUB_OFFLINE, HUGGINGFACE_HUB_CACHE from openvino._offline_transformations import compress_model_transformation from openvino.runtime import Core from transformers import CLIPFeatureExtractor, CLIPTokenizer @@ -412,7 +412,14 @@ def _from_transformers( ) @classmethod - def _check_export_status(cls, model_id: Union[str, Path], revision: Optional[str] = None, subfolder: str = ""): + def _check_export_status( + cls, + model_id: Union[str, Path], + revision: Optional[str] = None, + subfolder: str = "", + cache_dir: str = HUGGINGFACE_HUB_CACHE, + local_files_only: bool = HF_HUB_OFFLINE, + ): sub_model_dirs = [DIFFUSION_MODEL_UNET_SUBFOLDER, DIFFUSION_MODEL_VAE_DECODER_SUBFOLDER] def check_model_part_status(model_id, subfolder, revision): @@ -425,19 +432,36 @@ def check_model_part_status(model_id, subfolder, revision): or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() ) - hf_api = HfApi() - try: - model_info = hf_api.model_info(model_id, revision=revision or "main") - normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() - model_files = [ - file.rfilename - for file in model_info.siblings - if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) - ] - ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" - return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files - except Exception: - return True + normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + cache_model_path = try_to_load_from_cache( + model_id, ov_model_path, cache_dir=cache_dir, revision=revision or "main", repo_type="model" + ) + cache_bin_path = try_to_load_from_cache( + model_id, + ov_model_path.replace(".xml", ".bin"), + cache_dir=cache_dir, + revision=revision or "main", + repo_type="model", + ) + cache_status = cache_bin_path is not None and cache_model_path is not None + + if not cache_status and not local_files_only: + hf_api = HfApi() + try: + model_info = hf_api.model_info(model_id, revision=revision or "main") + model_files = [ + file.rfilename + for file in model_info.siblings + if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) + ] + ov_model_path = ( + OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + ) + return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files + except Exception: + return True + return not cache_status for sub_model_dir in sub_model_dirs: sub_model = sub_model_dir if not subfolder else f"{Path(subfolder).as_posix()}/{sub_model_dir}" From ff1a2e0a4d919e398b2f8efb9572bc1f81a48de5 Mon Sep 17 00:00:00 2001 From: eaidova Date: Thu, 23 May 2024 20:24:49 +0400 Subject: [PATCH 4/4] fix subfolder --- optimum/intel/openvino/modeling_base.py | 13 +++++++------ optimum/intel/openvino/modeling_base_seq2seq.py | 4 ++-- optimum/intel/openvino/modeling_diffusion.py | 10 ++++------ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/optimum/intel/openvino/modeling_base.py b/optimum/intel/openvino/modeling_base.py index ea88de26da..a644b7adb7 100644 --- a/optimum/intel/openvino/modeling_base.py +++ b/optimum/intel/openvino/modeling_base.py @@ -608,8 +608,9 @@ def from_pretrained( ) if export is None: - export = cls._check_export_status(model_id, revision, subfolder, cache_dir, local_files_only or HF_HUB_OFFLINE) - + export = cls._check_export_status( + model_id, revision, subfolder, cache_dir, local_files_only or HF_HUB_OFFLINE + ) if not export and trust_remote_code: logger.warning( "The argument `trust_remote_code` is to be used along with export=True. It will be ignored." @@ -642,15 +643,15 @@ def _check_export_status( local_files_only: bool = HF_HUB_OFFLINE, ): model_dir = Path(model_id) - if subfolder is not None: + if subfolder: model_dir = model_dir / subfolder if model_dir.is_dir(): return ( not (model_dir / OV_XML_FILE_NAME).exists() or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() ) - normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() - ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + normalized_subfolder = None if not subfolder else Path(subfolder).as_posix() + ov_model_path = OV_XML_FILE_NAME if not subfolder else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" cache_model_path = try_to_load_from_cache( model_id, ov_model_path, cache_dir=cache_dir, revision=revision or "main", repo_type="model" ) @@ -672,7 +673,7 @@ def _check_export_status( for file in model_info.siblings if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) ] - ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + ov_model_path = OV_XML_FILE_NAME if not subfolder else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files except Exception: return True diff --git a/optimum/intel/openvino/modeling_base_seq2seq.py b/optimum/intel/openvino/modeling_base_seq2seq.py index fc1c3c5337..50dddd0c14 100644 --- a/optimum/intel/openvino/modeling_base_seq2seq.py +++ b/optimum/intel/openvino/modeling_base_seq2seq.py @@ -406,14 +406,14 @@ def _check_export_status( hf_api = HfApi() try: model_info = hf_api.model_info(model_id, revision=revision or "main") - normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() + normalized_subfolder = None if not subfolder else Path(subfolder).as_posix() model_files = [ file.rfilename for file in model_info.siblings if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) ] for model_name in [OV_ENCODER_NAME, OV_DECODER_NAME]: - ov_model_path = model_name if subfolder is None else f"{normalized_subfolder}/{model_name}" + ov_model_path = model_name if not subfolder else f"{normalized_subfolder}/{model_name}" if ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files: return True return False diff --git a/optimum/intel/openvino/modeling_diffusion.py b/optimum/intel/openvino/modeling_diffusion.py index 2e7cf7708e..5671d40999 100644 --- a/optimum/intel/openvino/modeling_diffusion.py +++ b/optimum/intel/openvino/modeling_diffusion.py @@ -424,7 +424,7 @@ def _check_export_status( def check_model_part_status(model_id, subfolder, revision): model_dir = Path(model_id) - if subfolder is not None: + if subfolder: model_dir = model_dir / subfolder if model_dir.is_dir(): return ( @@ -432,8 +432,8 @@ def check_model_part_status(model_id, subfolder, revision): or not (model_dir / OV_XML_FILE_NAME.replace(".xml", ".bin")).exists() ) - normalized_subfolder = None if subfolder is None else Path(subfolder).as_posix() - ov_model_path = OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" + normalized_subfolder = None if not subfolder else Path(subfolder).as_posix() + ov_model_path = OV_XML_FILE_NAME if not subfolder else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" cache_model_path = try_to_load_from_cache( model_id, ov_model_path, cache_dir=cache_dir, revision=revision or "main", repo_type="model" ) @@ -455,9 +455,7 @@ def check_model_part_status(model_id, subfolder, revision): for file in model_info.siblings if normalized_subfolder is None or file.rfilename.startswith(normalized_subfolder) ] - ov_model_path = ( - OV_XML_FILE_NAME if subfolder is None else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" - ) + ov_model_path = OV_XML_FILE_NAME if not subfolder else f"{normalized_subfolder}/{OV_XML_FILE_NAME}" return ov_model_path not in model_files or ov_model_path.replace(".xml", ".bin") not in model_files except Exception: return True