初始化项目,由ModelHub XC社区提供模型
Model: Blaxzter/LaBSE-sentence-embeddings Source: Original Platform
This commit is contained in:
80
handler.py
Normal file
80
handler.py
Normal file
@@ -0,0 +1,80 @@
|
||||
from typing import Dict, List, Any
|
||||
import time
|
||||
|
||||
import torch
|
||||
from transformers import BertModel, BertTokenizerFast
|
||||
|
||||
|
||||
class EndpointHandler():
|
||||
def __init__(self, path_to_model: str = ".", max_cache_entries: int = 10000):
|
||||
# Preload all the elements you are going to need at inference.
|
||||
# pseudo:
|
||||
self.tokenizer = BertTokenizerFast.from_pretrained(path_to_model)
|
||||
self.model = BertModel.from_pretrained(path_to_model)
|
||||
self.model = self.model.eval()
|
||||
self.cache = {}
|
||||
self.last_cache_cleanup = time.time()
|
||||
self.max_cache_entries = max_cache_entries
|
||||
|
||||
def _lookup_cache(self, inputs):
|
||||
cached_results = {}
|
||||
uncached_inputs = []
|
||||
|
||||
for index, input_string in enumerate(inputs):
|
||||
if input_string in self.cache:
|
||||
cached_results[index] = self.cache[input_string]["pooler_output"]
|
||||
else:
|
||||
uncached_inputs.append((index, input_string))
|
||||
|
||||
return uncached_inputs, cached_results
|
||||
|
||||
def _store_to_cache(self, index, result):
|
||||
# Add timings to cache
|
||||
self.cache[index] = {
|
||||
"pooler_output": result,
|
||||
"last_access": time.time()
|
||||
}
|
||||
|
||||
def _cleanup_cache(self):
|
||||
current_time = time.time()
|
||||
if current_time - self.last_cache_cleanup > 60 and len(self.cache) > self.max_cache_entries:
|
||||
# Sort the cache by last access time
|
||||
sorted_cache = sorted(self.cache.items(), key = lambda x: x[1]["last_access"])
|
||||
|
||||
# Remove the oldest entries
|
||||
for i in range(len(self.cache) - self.max_cache_entries):
|
||||
del self.cache[sorted_cache[i][0]]
|
||||
|
||||
def __call__(self, data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
This method is called whenever a request is made to the endpoint.
|
||||
:param data: { inputs [str]: list of strings to be encoded }
|
||||
:return: A :obj:`list` | `dict`: will be serialized and returned
|
||||
"""
|
||||
inputs = data['inputs']
|
||||
|
||||
# Check cache for inputs
|
||||
uncached_inputs, cached_results = self._lookup_cache(inputs)
|
||||
|
||||
output_results = {}
|
||||
|
||||
# Call model for uncached input
|
||||
if len(uncached_inputs) != 0:
|
||||
model_inputs = [input_string for _, input_string in uncached_inputs]
|
||||
uncached_inputs_tokenized = self.tokenizer(model_inputs, return_tensors = "pt", padding = True)
|
||||
|
||||
with torch.no_grad():
|
||||
uncached_output_tensor = self.model(**uncached_inputs_tokenized)
|
||||
|
||||
uncached_output_list = uncached_output_tensor.pooler_output.tolist()
|
||||
|
||||
# combine cached and uncached results
|
||||
for (index, input_string), result in zip(uncached_inputs, uncached_output_list):
|
||||
self._store_to_cache(input_string, result)
|
||||
output_results[index] = result
|
||||
|
||||
self._cleanup_cache()
|
||||
|
||||
output_results.update(cached_results)
|
||||
|
||||
return [output_results[i] for i in range(len(inputs))]
|
||||
Reference in New Issue
Block a user