ebm4subjects 0.5.1__py3-none-any.whl → 0.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ebm4subjects/ebm_model.py CHANGED
@@ -13,13 +13,16 @@ from ebm4subjects import prepare_data
13
13
  from ebm4subjects.chunker import Chunker
14
14
  from ebm4subjects.duckdb_client import Duckdb_client
15
15
  from ebm4subjects.ebm_logging import EbmLogger, NullLogger, XGBLogging
16
- from ebm4subjects.embedding_generator import EmbeddingGenerator
16
+ from ebm4subjects.embedding_generator import (
17
+ EmbeddingGeneratorHuggingFaceTEI,
18
+ EmbeddingGeneratorInternal,
19
+ EmbeddingGeneratorMock,
20
+ )
17
21
 
18
22
 
19
23
  class EbmModel:
20
24
  def __init__(
21
25
  self,
22
- embedding_model_name: str | Any,
23
26
  embedding_dimensions: int | str,
24
27
  chunk_tokenizer: str | Any,
25
28
  max_chunk_count: int | str,
@@ -39,7 +42,9 @@ class EbmModel:
39
42
  collection_name: str = "my_collection",
40
43
  use_altLabels: bool = True,
41
44
  hnsw_index_params: dict | str | None = None,
42
- model_args: dict | str | None = None,
45
+ embedding_model_name: str | None = None,
46
+ embedding_model_type: str = "internal",
47
+ embedding_model_args: dict | str | None = None,
43
48
  encode_args_vocab: dict | str | None = None,
44
49
  encode_args_documents: dict | str | None = None,
45
50
  log_path: str | None = None,
@@ -94,11 +99,14 @@ class EbmModel:
94
99
 
95
100
  # Parameters for embedding generator
96
101
  self.generator = None
102
+ self.embedding_model_type = embedding_model_type
97
103
  self.embedding_model_name = embedding_model_name
98
104
  self.embedding_dimensions = int(embedding_dimensions)
99
- if isinstance(model_args, str) or not model_args:
100
- model_args = ast.literal_eval(model_args) if model_args else {}
101
- self.model_args = model_args
105
+ if isinstance(embedding_model_args, str) or not embedding_model_args:
106
+ embedding_model_args = (
107
+ ast.literal_eval(embedding_model_args) if embedding_model_args else {}
108
+ )
109
+ self.embedding_model_args = embedding_model_args
102
110
  if isinstance(encode_args_vocab, str) or not encode_args_vocab:
103
111
  encode_args_vocab = (
104
112
  ast.literal_eval(encode_args_vocab) if encode_args_vocab else {}
@@ -171,12 +179,25 @@ class EbmModel:
171
179
  None
172
180
  """
173
181
  if self.generator is None:
174
- self.logger.info("initializing embedding generator")
175
- self.generator = EmbeddingGenerator(
176
- model_name=self.embedding_model_name,
177
- embedding_dimensions=self.embedding_dimensions,
178
- **self.model_args,
179
- )
182
+ if self.embedding_model_type == "internal":
183
+ self.logger.info("initializing internal embedding generator")
184
+ self.generator = EmbeddingGeneratorInternal(
185
+ model_name=self.embedding_model_name,
186
+ embedding_dimensions=self.embedding_dimensions,
187
+ **self.embedding_model_args,
188
+ )
189
+ elif self.embedding_model_type == "mock":
190
+ self.logger.info("initializing mock embedding generator")
191
+ self.generator = EmbeddingGeneratorMock(self.embedding_dimensions)
192
+ elif self.embedding_model_type == "HuggingFaceTEI":
193
+ self.logger.info("initializing API embedding generator")
194
+ self.generator = EmbeddingGeneratorHuggingFaceTEI(
195
+ embedding_dimensions=self.embedding_dimensions,
196
+ **self.embedding_model_args,
197
+ )
198
+ else:
199
+ self.logger.error("unsupportet API for embedding generator")
200
+ raise NotImplementedError
180
201
 
181
202
  def init_logger(
182
203
  self, log_path: str | None = None, logger: logging.Logger | None = None
@@ -1,30 +1,124 @@
1
1
  import os
2
2
 
3
3
  import numpy as np
4
+ import requests
4
5
  from sentence_transformers import SentenceTransformer
5
6
 
6
7
 
7
8
  class EmbeddingGenerator:
9
+ """
10
+ A base class for embedding generators.
11
+ """
12
+
13
+ def __init__(self) -> None:
14
+ """
15
+ Base method fot the initialization of an EmbeddingGenerator.
16
+ """
17
+ pass
18
+
19
+ def generate_embeddings(self, texts: list[str], **kwargs) -> np.ndarray:
20
+ """
21
+ Base method fot the creating embeddings with an EmbeddingGenerator.
22
+
23
+ Args:
24
+ texts (list[str]): A list of input texts.
25
+ **kwargs: Additional keyword arguments.
26
+
27
+ Returns:
28
+ np.ndarray: A numpy array of shape (len(texts), embedding_dimensions)
29
+ containing the generated embeddings.
30
+ """
31
+ pass
32
+
33
+
34
+ class EmbeddingGeneratorAPI(EmbeddingGenerator):
35
+ """
36
+ A base class for API embedding generators.
37
+
38
+ Attributes:
39
+ embedding_dimensions (int): The dimensionality of the generated embeddings.
40
+ """
41
+
42
+ def __init__(
43
+ self,
44
+ embedding_dimensions: int,
45
+ **kwargs,
46
+ ) -> None:
47
+ """
48
+ Initializes the API EmbeddingGenerator.
49
+
50
+ Sets the embedding dimensions, and initiliazes and
51
+ prepares a session with the API.
52
+ """
53
+
54
+ self.embedding_dimensions = embedding_dimensions
55
+
56
+ self.session = requests.Session()
57
+ self.api_address = kwargs.get("api_address")
58
+ self.headers = kwargs.get("headers", {"Content-Type": "application/json"})
59
+
60
+
61
+ class EmbeddingGeneratorHuggingFaceTEI(EmbeddingGeneratorAPI):
62
+ """
63
+ A class for generating embeddings using the HuggingFaceTEI API.
64
+ """
65
+
66
+ def generate_embeddings(self, texts: list[str], **kwargs) -> np.ndarray:
67
+ """
68
+ Generates embeddings for a list of input texts using a model
69
+ via the HuggingFaceTEI API.
70
+
71
+ Args:
72
+ texts (list[str]): A list of input texts.
73
+ **kwargs: Additional keyword arguments to pass to the
74
+ SentenceTransformer model.
75
+
76
+ Returns:
77
+ np.ndarray: A numpy array of shape (len(texts), embedding_dimensions)
78
+ containing the generated embeddings.
79
+ """
80
+ # prepare list for return
81
+ embeddings = []
82
+
83
+ # Check if the input list is empty
84
+ if not texts:
85
+ # If empty, return an empty numpy array with the correct shape
86
+ return np.empty((0, self.embedding_dimensions))
87
+
88
+ # process each text
89
+ for text in texts:
90
+ # send a request to the HuggingFaceTEI API
91
+ data = {"inputs": text}
92
+ response = self.session.post(
93
+ self.api_address, headers=self.headers, json=data
94
+ )
95
+
96
+ # add generated embeddings to return list if request was successfull
97
+ if response.status_code == 200:
98
+ embeddings.append(response.json()[0])
99
+ else:
100
+ embeddings.append([0 for _ in range(self.embedding_dimensions)])
101
+
102
+ return np.array(embeddings)
103
+
104
+
105
+ class EmbeddingGeneratorInternal(EmbeddingGenerator):
8
106
  """
9
107
  A class for generating embeddings using a given SentenceTransformer model.
10
108
 
11
109
  Args:
12
- model_name (str, SentenceTransformer): The name of the SentenceTransformer
13
- model or an SentenceTransformer model to use.
110
+ model_name (str): The name of the SentenceTransformer model.
14
111
  embedding_dimensions (int): The dimensionality of the generated embeddings.
15
112
  **kwargs: Additional keyword arguments to pass to the model.
16
113
 
17
114
  Attributes:
18
115
  model_name (str): The name of the SentenceTransformer model.
19
116
  embedding_dimensions (int): The dimensionality of the generated embeddings.
20
- model (SentenceTransformer): The SentenceTransformer model instance.
21
117
  """
22
118
 
23
- def __init__(
24
- self, model_name: str | SentenceTransformer, embedding_dimensions: int, **kwargs
25
- ) -> None:
119
+ def __init__(self, model_name: str, embedding_dimensions: int, **kwargs) -> None:
26
120
  """
27
- Initializes the EmbeddingGenerator.
121
+ Initializes the internal EmbeddingGenerator.
28
122
 
29
123
  Sets the model name, embedding dimensions, and creates a
30
124
  SentenceTransformer model instance.
@@ -34,13 +128,9 @@ class EmbeddingGenerator:
34
128
 
35
129
  # Create a SentenceTransformer model instance with the given
36
130
  # model name and embedding dimensions
37
- # or set model to the given SentenceTransformer
38
- if type(model_name) is str:
39
- self.model = SentenceTransformer(
40
- model_name, truncate_dim=embedding_dimensions, **kwargs
41
- )
42
- else:
43
- self.model = model_name
131
+ self.model = SentenceTransformer(
132
+ model_name, truncate_dim=embedding_dimensions, **kwargs
133
+ )
44
134
 
45
135
  # Disabel parallelism for tokenizer
46
136
  # Needed because process might be already parallelized
@@ -68,3 +158,44 @@ class EmbeddingGenerator:
68
158
 
69
159
  # Generate embeddings using the SentenceTransformer model and return them
70
160
  return self.model.encode(texts, **kwargs)
161
+
162
+
163
+ class EmbeddingGeneratorMock(EmbeddingGenerator):
164
+ """
165
+ A mock class for generating fake embeddings. Used for testing.
166
+
167
+ Args:
168
+ embedding_dimensions (int): The dimensionality of the generated embeddings.
169
+ **kwargs: Additional keyword arguments to pass to the model.
170
+
171
+ Attributes:
172
+ embedding_dimensions (int): The dimensionality of the generated embeddings.
173
+ """
174
+
175
+ def __init__(self, embedding_dimensions: int, **kwargs) -> None:
176
+ """
177
+ Initializes the mock EmbeddingGenerator.
178
+
179
+ Sets the embedding dimensions.
180
+ """
181
+ self.embedding_dimensions = embedding_dimensions
182
+
183
+ def generate_embeddings(self, texts: list[str], **kwargs) -> np.ndarray:
184
+ """
185
+ Generates embeddings for a list of input texts.
186
+
187
+ Args:
188
+ texts (list[str]): A list of input texts.
189
+ **kwargs: Additional keyword arguments.
190
+
191
+ Returns:
192
+ np.ndarray: A numpy array of shape (len(texts), embedding_dimensions)
193
+ containing the generated embeddings.
194
+ """
195
+ # Check if the input list is empty
196
+ if not texts:
197
+ # If empty, return an empty numpy array with the correct shape
198
+ return np.empty((0, self.embedding_dimensions))
199
+
200
+ # Generate mock embeddings return them
201
+ return np.ones((len(texts), 1024))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ebm4subjects
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Embedding Based Matching for Automated Subject Indexing
5
5
  Author: Deutsche Nationalbibliothek
6
6
  Maintainer-email: Clemens Rietdorf <c.rietdorf@dnb.de>, Maximilian Kähler <m.kaehler@dnb.de>
@@ -3,10 +3,10 @@ ebm4subjects/analyzer.py,sha256=lqX7AF8WsvwIavgtnmoVQ0i3wzBJJSeH47EiEwoLKGg,1664
3
3
  ebm4subjects/chunker.py,sha256=HcEFJtKWHFYZL8DmZcHGXLPGEkCqHZhh_0kSqyYVsdE,6764
4
4
  ebm4subjects/duckdb_client.py,sha256=8lDIpj2o2VTEtjHC_vTYrI5-RNXZnWMft45bS6z9B_k,13031
5
5
  ebm4subjects/ebm_logging.py,sha256=xkbqeVhSCNuhMwkx2yoIX8_D3z9DcsauZEmHhR1gaS0,5962
6
- ebm4subjects/ebm_model.py,sha256=PVFtljF3oZK8u0lA6df82lsTdAD8H1Y9CHvWq1jWF2M,29125
7
- ebm4subjects/embedding_generator.py,sha256=DZhZxkjcsy_4NA62_2V-4UPbIUkg5qMPat_cIgsoIAA,2609
6
+ ebm4subjects/ebm_model.py,sha256=5LpZtYM3vZEyyJTTaQCsHzpsDLlJDdkvP8G61fPWrjs,30227
7
+ ebm4subjects/embedding_generator.py,sha256=tPnb8XsNNNU4bYtjtc408eWI8KrZMyY8TI9d43AWHKo,6634
8
8
  ebm4subjects/prepare_data.py,sha256=vQ-BdXkIP3iZJdPXol0WDlY8cRFMHkjzzL7oC7EbouE,3084
9
- ebm4subjects-0.5.1.dist-info/METADATA,sha256=QkOBvOAI49_AUipc3yAH6RVG9OVUs_8jO64Bjfy561U,8274
10
- ebm4subjects-0.5.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- ebm4subjects-0.5.1.dist-info/licenses/LICENSE,sha256=RpvAZSjULHvoTR_esTlucJ08-zdQydnoqQLbqOh9Ub8,13826
12
- ebm4subjects-0.5.1.dist-info/RECORD,,
9
+ ebm4subjects-0.5.2.dist-info/METADATA,sha256=pzoU6iJv3Cxh8q5656uUWac1t_QXuwuQUiGVfC7dklM,8274
10
+ ebm4subjects-0.5.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
11
+ ebm4subjects-0.5.2.dist-info/licenses/LICENSE,sha256=RpvAZSjULHvoTR_esTlucJ08-zdQydnoqQLbqOh9Ub8,13826
12
+ ebm4subjects-0.5.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any