diff --git a/docs/source/aligner/rag.rst b/docs/source/aligner/rag.rst index 041527a..c77bafc 100644 --- a/docs/source/aligner/rag.rst +++ b/docs/source/aligner/rag.rst @@ -37,6 +37,10 @@ This offers a RAG approach within LLMs for OM. LLMs4OM uses :math:`O_{source}` a Usage ---------------- +.. sidebar:: + + * ``"load_in_8bit": True`` is used to load the model in 8-bit precision. The default is ``False``. + This guide walks you through the process of ontology matching using the OntoAligner library, leveraging RAG techniques. Starting with the necessary module imports, it defines a task and loads source and target ontologies along with reference matchings. The tutorial then encodes the ontologies using a specialized encoder, configures a retriever and an LLM, and generates predictions. Finally, it demonstrates two postprocessing techniques—heuristic and hybrid—followed by saving the matched alignments in XML format, ready for use or further analysis. .. code-block:: python @@ -66,7 +70,9 @@ This guide walks you through the process of ontology matching using the OntoAlig #Step 4. Configure the Retriever and LLM retriever_config = {"device": 'cuda', "top_k": 5, "threshold": 0.1} llm_config = { - "device": "cuda", "batch_size": 32, + "device": "cuda", + "batch_size": 32, + "load_in_8bit": True, "answer_set": {"yes": ["yes", "true"], "no": ["no", "false"]} } } @@ -98,6 +104,7 @@ This guide walks you through the process of ontology matching using the OntoAlig + In this tutorial, we demonstrated: * Loading and encoding ontologies diff --git a/ontoaligner/aligner/llm/llm.py b/ontoaligner/aligner/llm/llm.py index 738fb4c..cf69509 100644 --- a/ontoaligner/aligner/llm/llm.py +++ b/ontoaligner/aligner/llm/llm.py @@ -65,6 +65,7 @@ def __init__(self, top_p: float=1.0, sleep: int=5, huggingface_access_token: str=None, + load_in_8bit: bool=False, device_map: str='balanced', openai_key: str="None", **kwargs) -> None: @@ -79,6 +80,7 @@ def __init__(self, top_p=top_p, sleep=sleep, huggingface_access_token=huggingface_access_token, + load_in_8bit=load_in_8bit, device_map=device_map, openai_key=openai_key, **kwargs) @@ -465,39 +467,38 @@ def load_tokenizer(self, path: str) -> None: Args: path (str): Path to the pretrained tokenizer. """ - llm_req_special_tk = self.check_list_llms(path, self.llms_with_special_tk) - llm_req_hugging_tk = self.check_list_llms(path, self.llms_with_hugging_tk) + kwargs = {} + if self.kwargs.get("huggingface_access_token"): + kwargs["token"] = self.kwargs["huggingface_access_token"] - if llm_req_special_tk and llm_req_hugging_tk: - self.tokenizer = self.tokenizer.from_pretrained(path, token=self.kwargs['huggingface_access_token'], padding_side="left") - elif llm_req_special_tk: - self.tokenizer = self.tokenizer.from_pretrained(path, padding_side="left") - elif llm_req_hugging_tk: - self.tokenizer = self.tokenizer.from_pretrained(path, token=self.kwargs['huggingface_access_token']) - else: - self.tokenizer = self.tokenizer.from_pretrained(path) - self.tokenizer.pad_token = self.tokenizer.eos_token + if self.check_list_llms(path, self.llms_with_special_tk): + kwargs["padding_side"] = "left" + + self.tokenizer = self.tokenizer.from_pretrained(path, **kwargs) + # Use EOS token for padding if no pad token exists + if self.tokenizer.pad_token is None: + self.tokenizer.pad_token = self.tokenizer.eos_token def load_model(self, path: str) -> None: """ - Loads the model with device-specific configurations and handles requirements for Hugging Face token access. - Adjusts precision and device mapping for non-CPU devices if specified. + Load a pretrained model with optional 8-bit quantization and + Hugging Face authentication. Args: - path (str): Path to the pretrained model. + path (str): Path or Hugging Face model ID. """ - llm_req_hugging_tk = self.check_list_llms(path, self.llms_with_hugging_tk) + kwargs = {} + if self.kwargs.get("huggingface_access_token"): + kwargs["token"] = self.kwargs["huggingface_access_token"] + + if self.kwargs.get("load_in_8bit", False): + from transformers import BitsAndBytesConfig + kwargs["quantization_config"] = BitsAndBytesConfig(load_in_8bit=True) if self.kwargs["device"] != "cpu": - if llm_req_hugging_tk: - self.model = self.model.from_pretrained(path, load_in_8bit=True, device_map=self.kwargs['device_map'], token=self.kwargs['huggingface_access_token']) - else: - self.model = self.model.from_pretrained(path, load_in_8bit=True, device_map="balanced") - else: - self.model = self.model.from_pretrained(path, token=self.kwargs['huggingface_access_token']) - if llm_req_hugging_tk: - self.model = self.model.from_pretrained(path, token=self.kwargs['huggingface_access_token']) - else: - self.model = self.model.from_pretrained(path) + kwargs["device_map"] = self.kwargs["device_map"] + + self.model = self.model.from_pretrained(path, **kwargs) - self.model.to(self.kwargs["device"]) + if self.kwargs["device"] == "cpu": + self.model.to("cpu") diff --git a/pyproject.toml b/pyproject.toml index 064e930..1510511 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,11 +22,11 @@ nltk = "*" owlready2 = "0.50" rdflib = "7.1.1" torch = "^2.8.0" -transformers = "^5.7.0" +transformers = "^5.13.0" rapidfuzz = "3.5.2" -openai = "1.56.0" +openai = "2.44.0" rank_bm25 = "0.2.2" -huggingface-hub = "^1.11.0" +huggingface-hub = "^1.22.0" sentence-transformers = "^5.1.0" bitsandbytes = { version = ">=0.45.1,<1.0.0", markers = "platform_system == 'Linux'" } pykeen = "1.11.1" diff --git a/requirements.txt b/requirements.txt index a995a6c..30d8dbc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,11 +9,11 @@ nltk owlready2==0.50 rdflib==7.1.1 torch==2.8.0 -transformers==4.56.0 +transformers==5.13.0 rapidfuzz==3.5.2 -openai==1.56.0 +openai==2.44.0 rank_bm25==0.2.2 -huggingface-hub==0.34.4 +huggingface-hub==1.22.0 sentence-transformers==5.1.0 bitsandbytes==0.45.1 pykeen==1.11.1 diff --git a/setup.py b/setup.py index 188e1fe..4b30721 100644 --- a/setup.py +++ b/setup.py @@ -23,15 +23,15 @@ "scikit-learn", "tqdm", "nltk", - "openai==1.56.0", + "openai==2.44.0", "owlready2==0.50", "rank_bm25==0.2.2", "rapidfuzz==3.5.2", "rdflib==7.1.1", "sentence-transformers>=5.1.0,<6.0.0", "torch>=2.8.0,<3.0.0", - "transformers==5.7.0", - "huggingface-hub==1.11.0", + "transformers==5.13.0", + "huggingface-hub==1.22.0", "bitsandbytes>=0.45.1,<1.0.0; platform_system == 'Linux'", "pykeen==1.11.1", "scipy==1.15.3", diff --git a/tests/aligners/test_rag_aligner.py b/tests/aligners/test_rag_aligner.py index d12893e..8d49a9b 100644 --- a/tests/aligners/test_rag_aligner.py +++ b/tests/aligners/test_rag_aligner.py @@ -61,7 +61,7 @@ def test_load(self, mock_model_class, mock_tokenizer_class): self.model.load("dummy_path") # Verify tokenizer and model were loaded - mock_tokenizer_class.assert_called_once_with("dummy_path") + mock_tokenizer_class.assert_called_once_with("dummy_path", token="dummy_token") mock_model_class.assert_called_once_with("dummy_path", token="dummy_token") def test_check_answer_set_tokenizer(self):