Spaces:
Runtime error
Runtime error
File size: 4,403 Bytes
aaec566 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
import numpy as np
import torch
from typing import List, Union, Dict
from transformers import AutoTokenizer, AutoModel
from pathlib import Path
import json
class LocalEmbedder:
def __init__(self, model_name: str, device: str = None, batch_size: int = 32):
"""
Ініціалізація локальної моделі для ембедінгів
Args:
model_name: назва або шлях до моделі (з HuggingFace або локальна)
device: пристрій для обчислень ('cuda', 'cpu' або None - автовибір)
batch_size: розмір батчу для інференсу
"""
self.model_name = model_name
self.batch_size = batch_size
# Визначення пристрою
if device is None:
self.device = 'cuda' if torch.cuda.is_available() else 'cpu'
else:
self.device = device
# Завантаження моделі та токенізатора
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModel.from_pretrained(model_name).to(self.device)
self.model.eval()
# Максимальна довжина послідовності
self.max_length = self.tokenizer.model_max_length
if self.max_length > 512:
self.max_length = 512
def _normalize_embeddings(self, embeddings: np.ndarray) -> np.ndarray:
"""
L2-нормалізація ембедінгів
Args:
embeddings: матриця ембедінгів
Returns:
np.ndarray: нормалізована матриця ембедінгів
"""
norms = np.linalg.norm(embeddings, axis=1, keepdims=True)
return embeddings / norms
def get_embeddings(self, texts: Union[str, List[str]]) -> np.ndarray:
"""
Отримання ембедінгів для тексту або списку текстів
Args:
texts: текст або список текстів
Returns:
np.ndarray: матриця нормалізованих ембедінгів
"""
if isinstance(texts, str):
texts = [texts]
all_embeddings = []
with torch.no_grad():
for i in range(0, len(texts), self.batch_size):
batch_texts = texts[i:i + self.batch_size]
# Токенізація
encoded = self.tokenizer.batch_encode_plus(
batch_texts,
padding=True,
truncation=True,
max_length=self.max_length,
return_tensors='pt'
)
# Переміщуємо тензори на потрібний пристрій
input_ids = encoded['input_ids'].to(self.device)
attention_mask = encoded['attention_mask'].to(self.device)
# Отримуємо ембедінги
outputs = self.model(
input_ids=input_ids,
attention_mask=attention_mask
)
# Використовуємо [CLS] токен як ембедінг
embeddings = outputs.last_hidden_state[:, 0, :]
all_embeddings.append(embeddings.cpu().numpy())
# Об'єднуємо всі батчі
embeddings = np.vstack(all_embeddings)
# Нормалізуємо ембедінги
normalized_embeddings = self._normalize_embeddings(embeddings)
return normalized_embeddings
def get_model_info(self) -> Dict[str, any]:
"""
Отримання інформації про модель
Returns:
Dict: інформація про модель
"""
return {
'model_name': self.model_name,
'device': self.device,
'embedding_size': self.model.config.hidden_size,
'max_length': self.max_length,
'batch_size': self.batch_size
} |