From f63e1a74b33e28028a55208f423f5d14298b7d7d Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Thu, 13 Jun 2024 17:53:03 +0800 Subject: [PATCH 01/10] Duplicate check v2 --- python/llm/src/ipex_llm/__init__.py | 4 ++- .../llm/src/ipex_llm/utils/ipex_importer.py | 27 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/python/llm/src/ipex_llm/__init__.py b/python/llm/src/ipex_llm/__init__.py index a796dcbfb9d..e11ac0af4cb 100644 --- a/python/llm/src/ipex_llm/__init__.py +++ b/python/llm/src/ipex_llm/__init__.py @@ -33,7 +33,9 @@ if BIGDL_IMPORT_IPEX: # Import Intel Extension for PyTorch as ipex if XPU version is installed from .utils.ipex_importer import ipex_importer - ipex_importer.import_ipex() + # Avoid duplicate import + if ipex_importer.get_ipex_version() is None: + ipex_importer.import_ipex() # Default is true, set to true to auto patching bigdl-llm to ipex_llm. BIGDL_COMPATIBLE_MODE = os.getenv("BIGDL_COMPATIBLE_MODE", 'True').lower() in ('true', '1', 't') diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index 3fb543af6d4..793a66c864b 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -19,14 +19,35 @@ import builtins import sys from ipex_llm.utils.common import log4Error -import inspect + # Save the original __import__ function -original_import = builtins.__import__ +RAW_IMPORT = builtins.__import__ ipex_duplicate_import_error = "intel_extension_for_pytorch has already been automatically " + \ "imported. Please avoid importing it again!" +def replace_import(): + builtins.__import__ = custom_ipex_import + + +def revert_import(): + builtins.__import__ = RAW_IMPORT + + +def custom_ipex_import(name, globals=None, locals=None, fromlist=(), level=0): + """ + Custom import function to avoid importing ipex again + """ + if fromlist is not None or '.' in name: + return RAW_IMPORT(name, globals, locals, fromlist, level) + # Only check ipex for main thread + if name == "ipex" or name == "intel_extension_for_pytorch": + log4Error.invalidInputError(False, + ipex_duplicate_import_error) + return RAW_IMPORT(name, globals, locals, fromlist, level) + + class IPEXImporter: """ Auto import Intel Extension for PyTorch as ipex, @@ -71,6 +92,8 @@ def import_ipex(self): ipex_duplicate_import_error) self.directly_import_ipex() self.ipex_version = ipex.__version__ + # Replace builtin import to avoid duplicate ipex import + replace_import() logging.info("intel_extension_for_pytorch auto imported") def directly_import_ipex(self): From 76a5342483caf9e850908d30a075b41d848eef0b Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Thu, 13 Jun 2024 18:00:27 +0800 Subject: [PATCH 02/10] Add into convert --- python/llm/src/ipex_llm/transformers/convert.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/llm/src/ipex_llm/transformers/convert.py b/python/llm/src/ipex_llm/transformers/convert.py index 0766244ddf1..ca449a3227e 100644 --- a/python/llm/src/ipex_llm/transformers/convert.py +++ b/python/llm/src/ipex_llm/transformers/convert.py @@ -773,6 +773,9 @@ def ggml_convert_low_bit(model, qtype, optimize_model=True, f"{list(gguf_mixed_qtype.keys())[index]} " f"format......") modules_to_not_convert = [] if modules_to_not_convert is None else modules_to_not_convert + # Disable ipex duplicate import checker + from ipex_llm.utils.ipex_importer import revert_import + revert_import() # using ipex_llm optimizer before changing to bigdl linear _enable_ipex = get_enable_ipex() From 40b51d8f46fcdaf6c59710d9cfdccdc03ad09ae3 Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Thu, 13 Jun 2024 18:04:00 +0800 Subject: [PATCH 03/10] Code style --- python/llm/src/ipex_llm/utils/ipex_importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index 793a66c864b..cda2f1efaed 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -28,7 +28,7 @@ def replace_import(): - builtins.__import__ = custom_ipex_import + builtins.__import__ = custom_ipex_import def revert_import(): From 830e34cc802f5166e52e54e2c5d68a6846e1a76b Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Tue, 18 Jun 2024 10:29:58 +0800 Subject: [PATCH 04/10] Add gguf support, add check to avoid duplicate replace and revert --- python/llm/src/ipex_llm/transformers/gguf/api.py | 3 +++ python/llm/src/ipex_llm/utils/ipex_importer.py | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/python/llm/src/ipex_llm/transformers/gguf/api.py b/python/llm/src/ipex_llm/transformers/gguf/api.py index 05203fe0bda..ff197b3218b 100644 --- a/python/llm/src/ipex_llm/transformers/gguf/api.py +++ b/python/llm/src/ipex_llm/transformers/gguf/api.py @@ -30,6 +30,9 @@ def load_gguf_model(fpath: str, dtype: torch.dtype = torch.float, low_bit: str = "sym_int4"): from .gguf import GGUFFileLoader + # Disable ipex duplicate import checker + from ipex_llm.utils.ipex_importer import revert_import + revert_import loader = GGUFFileLoader(fpath) model_family = loader.config["general.architecture"] diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index cda2f1efaed..54977dcdc25 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -21,18 +21,26 @@ from ipex_llm.utils.common import log4Error -# Save the original __import__ function -RAW_IMPORT = builtins.__import__ +RAW_IMPORT = None +IS_IMPORT_REPLACED = False ipex_duplicate_import_error = "intel_extension_for_pytorch has already been automatically " + \ "imported. Please avoid importing it again!" def replace_import(): - builtins.__import__ = custom_ipex_import + # Avoid multiple replacement + if not IS_IMPORT_REPLACED and RAW_IMPORT is None: + # Save the original __import__ function + RAW_IMPORT = builtins.__import__ + builtins.__import__ = custom_ipex_import + IS_IMPORT_REPLACED = True def revert_import(): - builtins.__import__ = RAW_IMPORT + # Only revert once + if RAW_IMPORT is not None and IS_IMPORT_REPLACED: + builtins.__import__ = RAW_IMPORT + IS_IMPORT_REPLACED = False def custom_ipex_import(name, globals=None, locals=None, fromlist=(), level=0): From bf9a90a3d8d81c44ba7bace18d191acb729b1d0b Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Tue, 18 Jun 2024 11:00:03 +0800 Subject: [PATCH 05/10] Gloabl var --- python/llm/src/ipex_llm/utils/ipex_importer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index 54977dcdc25..7254afbe7d7 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -28,6 +28,7 @@ def replace_import(): + global RAW_IMPORT, IS_IMPORT_REPLACED # Avoid multiple replacement if not IS_IMPORT_REPLACED and RAW_IMPORT is None: # Save the original __import__ function @@ -37,6 +38,7 @@ def replace_import(): def revert_import(): + global RAW_IMPORT, IS_IMPORT_REPLACED # Only revert once if RAW_IMPORT is not None and IS_IMPORT_REPLACED: builtins.__import__ = RAW_IMPORT From f83ba40adfcb3209af5dce3d869a76510d73b9f2 Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Tue, 18 Jun 2024 11:19:18 +0800 Subject: [PATCH 06/10] Add calling module to avoid raise exception in submodule --- .../llm/src/ipex_llm/utils/ipex_importer.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index 7254afbe7d7..c7c05a3556f 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -18,6 +18,7 @@ import logging import builtins import sys +import inspect from ipex_llm.utils.common import log4Error @@ -45,12 +46,32 @@ def revert_import(): IS_IMPORT_REPLACED = False +def get_calling_package(): + """ + Return calling package name, e.g., ipex_llm.transformers + """ + # Get the current stack frame + frame = inspect.currentframe() + # Get the caller's frame + caller_frame = frame.f_back.f_back + # Get the caller's module + module = inspect.getmodule(caller_frame) + if module: + # Return the module's package name + return module.__package__ + return None + + def custom_ipex_import(name, globals=None, locals=None, fromlist=(), level=0): """ Custom import function to avoid importing ipex again """ if fromlist is not None or '.' in name: return RAW_IMPORT(name, globals, locals, fromlist, level) + # Avoid raise exception in submodule import + calling = get_calling_package() + if calling is not None: + return RAW_IMPORT(name, globals, locals, fromlist, level) # Only check ipex for main thread if name == "ipex" or name == "intel_extension_for_pytorch": log4Error.invalidInputError(False, From e34d5ea9105a68f16607502a14302841ac4d6e87 Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Tue, 18 Jun 2024 12:23:11 +0800 Subject: [PATCH 07/10] Code style --- python/llm/src/ipex_llm/utils/ipex_importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index c7c05a3556f..e8d1725394c 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -68,7 +68,7 @@ def custom_ipex_import(name, globals=None, locals=None, fromlist=(), level=0): """ if fromlist is not None or '.' in name: return RAW_IMPORT(name, globals, locals, fromlist, level) - # Avoid raise exception in submodule import + # Avoid errors in submodule import calling = get_calling_package() if calling is not None: return RAW_IMPORT(name, globals, locals, fromlist, level) From 7e6ca712fb793a6247828a0702cac00e9a768515 Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Tue, 18 Jun 2024 12:24:59 +0800 Subject: [PATCH 08/10] Fix bug --- python/llm/src/ipex_llm/transformers/gguf/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/llm/src/ipex_llm/transformers/gguf/api.py b/python/llm/src/ipex_llm/transformers/gguf/api.py index ff197b3218b..95ebba3b57a 100644 --- a/python/llm/src/ipex_llm/transformers/gguf/api.py +++ b/python/llm/src/ipex_llm/transformers/gguf/api.py @@ -32,7 +32,7 @@ def load_gguf_model(fpath: str, dtype: torch.dtype = torch.float, low_bit: str = from .gguf import GGUFFileLoader # Disable ipex duplicate import checker from ipex_llm.utils.ipex_importer import revert_import - revert_import + revert_import() loader = GGUFFileLoader(fpath) model_family = loader.config["general.architecture"] From e80fc3061e7ae32743fb5e94eb54c1639eb79f79 Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Wed, 19 Jun 2024 12:16:23 +0800 Subject: [PATCH 09/10] Add IPEX_DUPLICATE_CHECKER --- python/llm/src/ipex_llm/__init__.py | 2 +- python/llm/src/ipex_llm/utils/ipex_importer.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/python/llm/src/ipex_llm/__init__.py b/python/llm/src/ipex_llm/__init__.py index e11ac0af4cb..1969aca0eb4 100644 --- a/python/llm/src/ipex_llm/__init__.py +++ b/python/llm/src/ipex_llm/__init__.py @@ -26,7 +26,7 @@ import sys import types -# Default is false, set to true to auto importing Intel Extension for PyTorch. +# Default is True, set to False to disable auto importing Intel Extension for PyTorch. USE_NPU = os.getenv("BIGDL_USE_NPU", 'False').lower() in ('true', '1', 't') BIGDL_IMPORT_IPEX = os.getenv("BIGDL_IMPORT_IPEX", 'True').lower() in ('true', '1', 't') BIGDL_IMPORT_IPEX = not USE_NPU and BIGDL_IMPORT_IPEX diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index e8d1725394c..769b1cb7c4a 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -18,10 +18,13 @@ import logging import builtins import sys +import os import inspect from ipex_llm.utils.common import log4Error +# Default is True, set to False to disable IPEX duplicate checker +IPEX_DUPLICATE_CHECKER = os.getenv("IPEX_DUPLICATE_CHECKER", 'True').lower() in ('true', '1', 't') RAW_IMPORT = None IS_IMPORT_REPLACED = False ipex_duplicate_import_error = "intel_extension_for_pytorch has already been automatically " + \ @@ -39,6 +42,8 @@ def replace_import(): def revert_import(): + if not IPEX_DUPLICATE_CHECKER: + return global RAW_IMPORT, IS_IMPORT_REPLACED # Only revert once if RAW_IMPORT is not None and IS_IMPORT_REPLACED: @@ -124,7 +129,8 @@ def import_ipex(self): self.directly_import_ipex() self.ipex_version = ipex.__version__ # Replace builtin import to avoid duplicate ipex import - replace_import() + if IPEX_DUPLICATE_CHECKER: + replace_import() logging.info("intel_extension_for_pytorch auto imported") def directly_import_ipex(self): From dd5d39b37445af48a86df75d85f1c038fee0aacd Mon Sep 17 00:00:00 2001 From: Qiyuan Gong Date: Wed, 19 Jun 2024 15:40:42 +0800 Subject: [PATCH 10/10] Change IPEX_DUPLICATE_CHECKER to BIGDL_CHECK_DUPLICATE_IMPORT --- python/llm/src/ipex_llm/utils/ipex_importer.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/llm/src/ipex_llm/utils/ipex_importer.py b/python/llm/src/ipex_llm/utils/ipex_importer.py index 769b1cb7c4a..aa02b15f802 100644 --- a/python/llm/src/ipex_llm/utils/ipex_importer.py +++ b/python/llm/src/ipex_llm/utils/ipex_importer.py @@ -24,7 +24,8 @@ # Default is True, set to False to disable IPEX duplicate checker -IPEX_DUPLICATE_CHECKER = os.getenv("IPEX_DUPLICATE_CHECKER", 'True').lower() in ('true', '1', 't') +BIGDL_CHECK_DUPLICATE_IMPORT = os.getenv("BIGDL_CHECK_DUPLICATE_IMPORT", + 'True').lower() in ('true', '1', 't') RAW_IMPORT = None IS_IMPORT_REPLACED = False ipex_duplicate_import_error = "intel_extension_for_pytorch has already been automatically " + \ @@ -42,7 +43,7 @@ def replace_import(): def revert_import(): - if not IPEX_DUPLICATE_CHECKER: + if not BIGDL_CHECK_DUPLICATE_IMPORT: return global RAW_IMPORT, IS_IMPORT_REPLACED # Only revert once @@ -129,7 +130,7 @@ def import_ipex(self): self.directly_import_ipex() self.ipex_version = ipex.__version__ # Replace builtin import to avoid duplicate ipex import - if IPEX_DUPLICATE_CHECKER: + if BIGDL_CHECK_DUPLICATE_IMPORT: replace_import() logging.info("intel_extension_for_pytorch auto imported")