Spaces:
Running
Running
File size: 7,777 Bytes
4ad5efa |
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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
"""
Утиліти для роботи з Google Embeddings API.
Цей файл повинен бути розміщений у modules/ai_analysis/google_embeddings_utils.py
"""
import os
import logging
from typing import List, Dict, Any, Optional
import time
logger = logging.getLogger(__name__)
# Перевірка наявності необхідних бібліотек
try:
from google import genai
GOOGLE_GENAI_AVAILABLE = True
logger.info("Google GenAI SDK успішно імпортовано")
except ImportError as e:
logger.warning(f"Google GenAI SDK не встановлено: {e}. Використання Google Embeddings буде вимкнено.")
GOOGLE_GENAI_AVAILABLE = False
class GoogleEmbeddingsManager:
"""
Менеджер для роботи з Google Embeddings API.
"""
def __init__(self, api_key=None, model_name="text-embedding-004", task_type="retrieval_query"):
"""
Ініціалізація менеджера Google Embeddings.
Args:
api_key (str, optional): API ключ для Google API. Якщо не вказано, спробує використати GEMINI_API_KEY з середовища.
model_name (str): Назва моделі ембедингів.
task_type (str): Тип задачі для ембедингів. Може бути "retrieval_query" або "retrieval_document".
"""
self.api_key = api_key or os.getenv("GEMINI_API_KEY")
self.model_name = model_name
self.task_type = task_type
self.client = None
self.initialized = False
# Спроба ініціалізації клієнта
self._initialize_client()
def _initialize_client(self):
"""
Ініціалізує клієнт Google GenAI API.
Returns:
bool: True, якщо ініціалізація успішна, False в іншому випадку.
"""
if not GOOGLE_GENAI_AVAILABLE:
logger.error("Google GenAI SDK не встановлено. Встановіть пакет: pip install google-genai")
return False
if not self.api_key:
logger.error("API ключ для Google API не вказано. Встановіть змінну GEMINI_API_KEY.")
return False
try:
# Ініціалізація клієнта
genai.configure(api_key=self.api_key)
self.client = genai.Client()
self.initialized = True
logger.info(f"Клієнт Google GenAI успішно ініціалізовано для моделі {self.model_name}")
return True
except Exception as e:
logger.error(f"Помилка при ініціалізації клієнта Google GenAI: {e}")
return False
def get_embeddings(self, texts, batch_size=8, retry_attempts=3, retry_delay=1):
"""
Отримує ембединги для списку текстів.
Args:
texts (list): Список текстів для ембедингу.
batch_size (int): Розмір батча для обробки.
retry_attempts (int): Кількість спроб у випадку помилки.
retry_delay (int): Затримка між спробами в секундах.
Returns:
list: Список ембедингів для кожного тексту або None у випадку помилки.
"""
if not self.initialized:
if not self._initialize_client():
return None
if not texts:
logger.warning("Порожній список текстів для ембедингу")
return []
# Переконуємося, що input завжди список
if not isinstance(texts, list):
texts = [texts]
try:
all_embeddings = []
# Обробка по батчам для ефективності
for i in range(0, len(texts), batch_size):
batch = texts[i:i + batch_size]
# Спроби з повторами у випадку помилки
for attempt in range(retry_attempts):
try:
result = self.client.models.embed_content(
model=self.model_name,
contents=batch,
config={"task_type": self.task_type}
)
# Вилучення ембедингів
batch_embeddings = [embedding.values for embedding in result.embeddings]
all_embeddings.extend(batch_embeddings)
break
except Exception as e:
if attempt == retry_attempts - 1:
logger.error(f"Не вдалося отримати ембединги після {retry_attempts} спроб: {e}")
return None
logger.warning(f"Спроба {attempt+1} невдала: {e}. Повторна спроба через {retry_delay} сек.")
time.sleep(retry_delay)
logger.info(f"Успішно отримано {len(all_embeddings)} ембедингів від Google API")
return all_embeddings
except Exception as e:
logger.error(f"Помилка при отриманні ембедингів від Google API: {e}")
return None
def get_embedding_dimension(self):
"""
Отримує розмірність ембедингів.
Returns:
int: Розмірність ембедингів або 0 у випадку помилки.
"""
if not self.initialized:
if not self._initialize_client():
return 0
try:
# Отримуємо ембединг для тестового тексту
result = self.client.models.embed_content(
model=self.model_name,
contents=["Test"],
config={"task_type": self.task_type}
)
# Отримуємо розмірність
[embedding] = result.embeddings
return len(embedding.values)
except Exception as e:
logger.error(f"Помилка при отриманні розмірності ембедингів: {e}")
return 0
# Приклад використання
if __name__ == "__main__":
# Налаштування логування
logging.basicConfig(level=logging.INFO)
# Ініціалізація менеджера
manager = GoogleEmbeddingsManager()
# Отримання розмірності ембедингів
dimension = manager.get_embedding_dimension()
print(f"Розмірність ембедингів: {dimension}")
# Отримання ембедингів для текстів
texts = ["Це тестовий текст", "Це ще один тестовий текст"]
embeddings = manager.get_embeddings(texts)
if embeddings:
print(f"Отримано {len(embeddings)} ембедингів")
print(f"Розмірність першого ембедингу: {len(embeddings[0])}") |