mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-25 08:26:21 +02:00
Structure the tech specs directory (#836)
Tech spec some subdirectories for different languages
This commit is contained in:
parent
48da6c5f8b
commit
e7efb673ef
423 changed files with 0 additions and 0 deletions
675
docs/tech-specs/ru/embeddings-batch-processing.ru.md
Normal file
675
docs/tech-specs/ru/embeddings-batch-processing.ru.md
Normal file
|
|
@ -0,0 +1,675 @@
|
|||
---
|
||||
layout: default
|
||||
title: "Техническая спецификация пакетной обработки эмбеддингов"
|
||||
parent: "Russian (Beta)"
|
||||
---
|
||||
|
||||
# Техническая спецификация пакетной обработки эмбеддингов
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## Обзор
|
||||
|
||||
Эта спецификация описывает оптимизации для сервиса эмбеддингов, предназначенные для поддержки пакетной обработки нескольких текстов в одном запросе. Текущая реализация обрабатывает один текст за раз, что не позволяет использовать значительные преимущества, которые предоставляют модели эмбеддингов при обработке пакетов.
|
||||
|
||||
1. **Неэффективность обработки одного текста**: Текущая реализация оборачивает отдельные тексты в список, что не позволяет в полной мере использовать возможности пакетной обработки FastEmbed.
|
||||
2. **Накладные расходы на запрос для каждого текста**: Для каждого текста требуется отдельная передача сообщения Pulsar.
|
||||
3. **Неэффективность вывода модели**: Модели эмбеддингов имеют фиксированные накладные расходы на пакет; небольшие пакеты приводят к неэффективному использованию ресурсов GPU/CPU.
|
||||
4. **Последовательная обработка в вызывающих сервисах**: Основные сервисы перебирают элементы и вызывают эмбеддинги по одному.
|
||||
|
||||
## Цели
|
||||
|
||||
**Поддержка пакетного API**: Обеспечить возможность обработки нескольких текстов в одном запросе.
|
||||
**Обратная совместимость**: Сохранить поддержку запросов для обработки одного текста.
|
||||
**Значительное повышение производительности**: Стремиться к увеличению производительности в 5-10 раз для массовых операций.
|
||||
**Снижение задержки на текст**: Уменьшить среднюю задержку при создании эмбеддингов для нескольких текстов.
|
||||
**Эффективность использования памяти**: Обрабатывать пакеты без чрезмерного потребления памяти.
|
||||
**Независимость от провайдера**: Поддерживать пакетную обработку для FastEmbed, Ollama и других провайдеров.
|
||||
**Миграция вызывающих сервисов**: Обновить все сервисы, вызывающие эмбеддинги, для использования пакетного API, где это целесообразно.
|
||||
|
||||
## Контекст
|
||||
|
||||
### Текущая реализация - Сервис эмбеддингов
|
||||
|
||||
Реализация эмбеддингов в `trustgraph-flow/trustgraph/embeddings/fastembed/processor.py` демонстрирует значительную неэффективность:
|
||||
|
||||
```python
|
||||
# fastembed/processor.py line 56
|
||||
async def on_embeddings(self, text, model=None):
|
||||
use_model = model or self.default_model
|
||||
self._load_model(use_model)
|
||||
|
||||
vecs = self.embeddings.embed([text]) # Single text wrapped in list
|
||||
|
||||
return [v.tolist() for v in vecs]
|
||||
```
|
||||
|
||||
**Проблемы:**
|
||||
|
||||
1. **Размер пакета 1**: Метод `embed()` FastEmbed оптимизирован для пакетной обработки, но мы всегда вызываем его с `[text]` - пакетом размера 1.
|
||||
|
||||
2. **Накладные расходы на каждый запрос**: Каждый запрос на получение эмбеддингов влечет за собой:
|
||||
Сериализацию/десериализацию сообщения Pulsar.
|
||||
Задержку сетевого обмена.
|
||||
Накладные расходы на запуск инференса модели.
|
||||
Накладные расходы на асинхронное планирование Python.
|
||||
|
||||
3. **Ограничение схемы**: Схема `EmbeddingsRequest` поддерживает только один текстовый фрагмент:
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsRequest:
|
||||
text: str = "" # Single text only
|
||||
```
|
||||
|
||||
### Текущие вызывающие стороны - последовательная обработка
|
||||
|
||||
#### 1. API-шлюз
|
||||
|
||||
**Файл:** `trustgraph-flow/trustgraph/gateway/dispatch/embeddings.py`
|
||||
|
||||
Шлюз принимает запросы на однострочное создание векторных представлений через HTTP/WebSocket и перенаправляет их в сервис создания векторных представлений. В настоящее время нет пакетного интерфейса.
|
||||
|
||||
```python
|
||||
class EmbeddingsRequestor(ServiceRequestor):
|
||||
# Handles single EmbeddingsRequest -> EmbeddingsResponse
|
||||
request_schema=EmbeddingsRequest, # Single text only
|
||||
response_schema=EmbeddingsResponse,
|
||||
```
|
||||
|
||||
**Влияние:** Внешние клиенты (веб-приложения, скрипты) должны выполнять N HTTP-запросов для встраивания N текстов.
|
||||
|
||||
#### 2. Сервис встраивания документов
|
||||
|
||||
**Файл:** `trustgraph-flow/trustgraph/embeddings/document_embeddings/embeddings.py`
|
||||
|
||||
Обрабатывает фрагменты документов по одному.
|
||||
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
v = msg.value()
|
||||
|
||||
# Single chunk per request
|
||||
resp = await flow("embeddings-request").request(
|
||||
EmbeddingsRequest(text=v.chunk)
|
||||
)
|
||||
vectors = resp.vectors
|
||||
```
|
||||
|
||||
**Влияние:** Каждый фрагмент документа требует отдельного вызова для создания эмбеддинга. Документ, состоящий из 100 фрагментов, = 100 запросов на создание эмбеддингов.
|
||||
|
||||
#### 3. Сервис создания графовых эмбеддингов
|
||||
|
||||
**Файл:** `trustgraph-flow/trustgraph/embeddings/graph_embeddings/embeddings.py`
|
||||
|
||||
Выполняет итерации по сущностям и создает эмбеддинг для каждой из них последовательно:
|
||||
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
for entity in v.entities:
|
||||
# Serial embedding - one entity at a time
|
||||
vectors = await flow("embeddings-request").embed(
|
||||
text=entity.context
|
||||
)
|
||||
entities.append(EntityEmbeddings(
|
||||
entity=entity.entity,
|
||||
vectors=vectors,
|
||||
chunk_id=entity.chunk_id,
|
||||
))
|
||||
```
|
||||
|
||||
**Влияние:** Сообщение, содержащее 50 сущностей, приводит к 50 последовательным запросам на создание векторных представлений. Это серьезное препятствие при построении графа знаний.
|
||||
|
||||
#### 4. Сервис создания векторных представлений строк
|
||||
|
||||
**Файл:** `trustgraph-flow/trustgraph/embeddings/row_embeddings/embeddings.py`
|
||||
|
||||
Выполняет итерации по уникальным текстам и создает векторное представление для каждого из них последовательно:
|
||||
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
for text, (index_name, index_value) in texts_to_embed.items():
|
||||
# Serial embedding - one text at a time
|
||||
vectors = await flow("embeddings-request").embed(text=text)
|
||||
|
||||
embeddings_list.append(RowIndexEmbedding(
|
||||
index_name=index_name,
|
||||
index_value=index_value,
|
||||
text=text,
|
||||
vectors=vectors
|
||||
))
|
||||
```
|
||||
|
||||
**Влияние:** Обработка таблицы с 100 уникальными индексированными значениями = 100 последовательных запросов на создание векторных представлений.
|
||||
|
||||
#### 5. EmbeddingsClient (Базовый клиент)
|
||||
|
||||
**Файл:** `trustgraph-base/trustgraph/base/embeddings_client.py`
|
||||
|
||||
Клиент, используемый всеми процессорами потоков, поддерживает только создание векторных представлений для одного текстового фрагмента:
|
||||
|
||||
```python
|
||||
class EmbeddingsClient(RequestResponse):
|
||||
async def embed(self, text, timeout=30):
|
||||
resp = await self.request(
|
||||
EmbeddingsRequest(text=text), # Single text
|
||||
timeout=timeout
|
||||
)
|
||||
return resp.vectors
|
||||
```
|
||||
|
||||
**Влияние:** Все клиенты, использующие этот компонент, ограничены операциями с одним текстовым фрагментом.
|
||||
|
||||
#### 6. Инструменты командной строки
|
||||
|
||||
**Файл:** `trustgraph-cli/trustgraph/cli/invoke_embeddings.py`
|
||||
|
||||
Инструмент командной строки принимает один текстовый аргумент:
|
||||
|
||||
```python
|
||||
def query(url, flow_id, text, token=None):
|
||||
result = flow.embeddings(text=text) # Single text
|
||||
vectors = result.get("vectors", [])
|
||||
```
|
||||
|
||||
**Влияние:** Пользователи не могут выполнять пакетную вставку из командной строки. Обработка файла текстов требует N вызовов.
|
||||
|
||||
#### 7. Python SDK
|
||||
|
||||
Python SDK предоставляет два клиентских класса для взаимодействия со службами TrustGraph. Оба поддерживают только вставку одного текста.
|
||||
|
||||
**Файл:** `trustgraph-base/trustgraph/api/flow.py`
|
||||
|
||||
```python
|
||||
class FlowInstance:
|
||||
def embeddings(self, text):
|
||||
"""Get embeddings for a single text"""
|
||||
input = {"text": text}
|
||||
return self.request("service/embeddings", input)["vectors"]
|
||||
```
|
||||
|
||||
**Файл:** `trustgraph-base/trustgraph/api/socket_client.py`
|
||||
|
||||
```python
|
||||
class SocketFlowInstance:
|
||||
def embeddings(self, text: str, **kwargs: Any) -> Dict[str, Any]:
|
||||
"""Get embeddings for a single text via WebSocket"""
|
||||
request = {"text": text}
|
||||
return self.client._send_request_sync(
|
||||
"embeddings", self.flow_id, request, False
|
||||
)
|
||||
```
|
||||
|
||||
**Влияние:** Разработчикам Python, использующим SDK, необходимо перебирать тексты и выполнять N отдельных API-запросов. Поддержка пакетной обработки векторов для пользователей SDK отсутствует.
|
||||
|
||||
### Влияние на производительность
|
||||
|
||||
Для типичного извлечения данных (1000 текстовых фрагментов):
|
||||
**Текущая ситуация:** 1000 отдельных запросов, 1000 вызовов модели для получения векторов.
|
||||
**Пакетная обработка (batch_size=32):** 32 запроса, 32 вызова модели для получения векторов (снижение на 96,8%).
|
||||
|
||||
Для получения векторов графа (сообщение с 50 сущностями):
|
||||
**Текущая ситуация:** 50 последовательных вызовов `await`, ~5-10 секунд.
|
||||
**Пакетная обработка:** 1-2 пакетных вызова, ~0,5-1 секунда (улучшение в 5-10 раз).
|
||||
|
||||
Библиотеки FastEmbed и аналогичные достигают почти линейного увеличения производительности при увеличении размера пакета до пределов аппаратного обеспечения (обычно 32-128 текстов на пакет).
|
||||
|
||||
## Техническое проектирование
|
||||
|
||||
### Архитектура
|
||||
|
||||
Оптимизация пакетной обработки векторов требует изменений в следующих компонентах:
|
||||
|
||||
#### 1. **Улучшение схемы данных**
|
||||
Расширить `EmbeddingsRequest` для поддержки нескольких текстов.
|
||||
Расширить `EmbeddingsResponse` для возврата нескольких наборов векторов.
|
||||
Сохранить обратную совместимость с запросами для одного текста.
|
||||
|
||||
Модуль: `trustgraph-base/trustgraph/schema/services/llm.py`
|
||||
|
||||
#### 2. **Улучшение базового сервиса**
|
||||
Обновить `EmbeddingsService` для обработки пакетных запросов.
|
||||
Добавить конфигурацию размера пакета.
|
||||
Реализовать обработку запросов с учетом пакетной обработки.
|
||||
|
||||
Модуль: `trustgraph-base/trustgraph/base/embeddings_service.py`
|
||||
|
||||
#### 3. **Обновления для процессоров провайдеров**
|
||||
Обновить процессор FastEmbed для передачи полного пакета в `embed()`.
|
||||
Обновить процессор Ollama для обработки пакетов (если поддерживается).
|
||||
Добавить последовательную обработку в качестве запасного варианта для провайдеров, не поддерживающих пакетную обработку.
|
||||
|
||||
Модули:
|
||||
`trustgraph-flow/trustgraph/embeddings/fastembed/processor.py`
|
||||
`trustgraph-flow/trustgraph/embeddings/ollama/processor.py`
|
||||
|
||||
#### 4. **Улучшение клиентской библиотеки**
|
||||
Добавить метод пакетной обработки векторов в `EmbeddingsClient`.
|
||||
Поддерживать как одиночные, так и пакетные API.
|
||||
Добавить автоматическую пакетную обработку для больших входных данных.
|
||||
|
||||
Модуль: `trustgraph-base/trustgraph/base/embeddings_client.py`
|
||||
|
||||
#### 5. **Обновления для вызывающего кода - процессоров потоков**
|
||||
Обновить `graph_embeddings` для пакетной обработки контекстов сущностей.
|
||||
Обновить `row_embeddings` для пакетной обработки текстов для индексации.
|
||||
Обновить `document_embeddings`, если пакетная обработка сообщений возможна.
|
||||
|
||||
Модули:
|
||||
`trustgraph-flow/trustgraph/embeddings/graph_embeddings/embeddings.py`
|
||||
`trustgraph-flow/trustgraph/embeddings/row_embeddings/embeddings.py`
|
||||
`trustgraph-flow/trustgraph/embeddings/document_embeddings/embeddings.py`
|
||||
|
||||
#### 6. **Улучшение API-шлюза**
|
||||
Добавить конечную точку для пакетной обработки векторов.
|
||||
Поддерживать массив текстов в теле запроса.
|
||||
|
||||
Модуль: `trustgraph-flow/trustgraph/gateway/dispatch/embeddings.py`
|
||||
|
||||
#### 7. **Улучшение инструмента командной строки (CLI)**
|
||||
Добавить поддержку нескольких текстов или ввода из файла.
|
||||
Добавить параметр размера пакета.
|
||||
|
||||
Модуль: `trustgraph-cli/trustgraph/cli/invoke_embeddings.py`
|
||||
|
||||
#### 8. **Улучшение Python SDK**
|
||||
Добавить метод `embeddings_batch()` в `FlowInstance`.
|
||||
Добавить метод `embeddings_batch()` в `SocketFlowInstance`.
|
||||
Поддерживать как одиночные, так и пакетные API для пользователей SDK.
|
||||
|
||||
Модули:
|
||||
`trustgraph-base/trustgraph/api/flow.py`
|
||||
`trustgraph-base/trustgraph/api/socket_client.py`
|
||||
|
||||
### Модели данных
|
||||
|
||||
#### EmbeddingsRequest
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsRequest:
|
||||
texts: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
Использование:
|
||||
Одиночный текст: `EmbeddingsRequest(texts=["hello world"])`
|
||||
Пакетный режим: `EmbeddingsRequest(texts=["text1", "text2", "text3"])`
|
||||
|
||||
#### EmbeddingsResponse
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsResponse:
|
||||
error: Error | None = None
|
||||
vectors: list[list[list[float]]] = field(default_factory=list)
|
||||
```
|
||||
|
||||
Структура ответа:
|
||||
`vectors[i]` содержит набор векторов для `texts[i]`
|
||||
Каждый набор векторов имеет размер `list[list[float]]` (модели могут возвращать несколько векторов для одного текста)
|
||||
Пример: 3 текста → `vectors` имеет 3 записи, каждая из которых содержит векторные представления этого текста
|
||||
|
||||
### API
|
||||
|
||||
#### EmbeddingsClient
|
||||
|
||||
```python
|
||||
class EmbeddingsClient(RequestResponse):
|
||||
async def embed(
|
||||
self,
|
||||
texts: list[str],
|
||||
timeout: float = 300,
|
||||
) -> list[list[list[float]]]:
|
||||
"""
|
||||
Embed one or more texts in a single request.
|
||||
|
||||
Args:
|
||||
texts: List of texts to embed
|
||||
timeout: Timeout for the operation
|
||||
|
||||
Returns:
|
||||
List of vector sets, one per input text
|
||||
"""
|
||||
resp = await self.request(
|
||||
EmbeddingsRequest(texts=texts),
|
||||
timeout=timeout
|
||||
)
|
||||
if resp.error:
|
||||
raise RuntimeError(resp.error.message)
|
||||
return resp.vectors
|
||||
```
|
||||
|
||||
#### Конечная точка API Gateway для встраиваемых объектов
|
||||
|
||||
Обновленная конечная точка, поддерживающая однократную или пакетную генерацию встраиваемых объектов:
|
||||
|
||||
```
|
||||
POST /api/v1/embeddings
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"texts": ["text1", "text2", "text3"],
|
||||
"flow_id": "default"
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"vectors": [
|
||||
[[0.1, 0.2, ...]],
|
||||
[[0.3, 0.4, ...]],
|
||||
[[0.5, 0.6, ...]]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Детали реализации
|
||||
|
||||
#### Этап 1: Изменения схемы
|
||||
|
||||
**EmbeddingsRequest:**
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsRequest:
|
||||
texts: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
**Ответ Embeddings:**
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsResponse:
|
||||
error: Error | None = None
|
||||
vectors: list[list[list[float]]] = field(default_factory=list)
|
||||
```
|
||||
|
||||
**Обновлен класс EmbeddingsService.on_request:**
|
||||
```python
|
||||
async def on_request(self, msg, consumer, flow):
|
||||
request = msg.value()
|
||||
id = msg.properties()["id"]
|
||||
model = flow("model")
|
||||
|
||||
vectors = await self.on_embeddings(request.texts, model=model)
|
||||
response = EmbeddingsResponse(error=None, vectors=vectors)
|
||||
|
||||
await flow("response").send(response, properties={"id": id})
|
||||
```
|
||||
|
||||
#### Фаза 2: Обновление процессора FastEmbed
|
||||
|
||||
**Текущая (неэффективная):**
|
||||
```python
|
||||
async def on_embeddings(self, text, model=None):
|
||||
use_model = model or self.default_model
|
||||
self._load_model(use_model)
|
||||
vecs = self.embeddings.embed([text]) # Batch of 1
|
||||
return [v.tolist() for v in vecs]
|
||||
```
|
||||
|
||||
**Обновлено:**
|
||||
```python
|
||||
async def on_embeddings(self, texts: list[str], model=None):
|
||||
"""Embed texts - processes all texts in single model call"""
|
||||
if not texts:
|
||||
return []
|
||||
|
||||
use_model = model or self.default_model
|
||||
self._load_model(use_model)
|
||||
|
||||
# FastEmbed handles the full batch efficiently
|
||||
all_vecs = list(self.embeddings.embed(texts))
|
||||
|
||||
# Return list of vector sets, one per input text
|
||||
return [[v.tolist()] for v in all_vecs]
|
||||
```
|
||||
|
||||
#### Фаза 3: Обновление сервиса графовых вложений
|
||||
|
||||
**Текущая (последовательная):**
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
entities = []
|
||||
for entity in v.entities:
|
||||
vectors = await flow("embeddings-request").embed(text=entity.context)
|
||||
entities.append(EntityEmbeddings(...))
|
||||
```
|
||||
|
||||
**Обновлено (пакетно):**
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
# Collect all contexts
|
||||
contexts = [entity.context for entity in v.entities]
|
||||
|
||||
# Single batch embedding call
|
||||
all_vectors = await flow("embeddings-request").embed(texts=contexts)
|
||||
|
||||
# Pair results with entities
|
||||
entities = [
|
||||
EntityEmbeddings(
|
||||
entity=entity.entity,
|
||||
vectors=vectors[0], # First vector from the set
|
||||
chunk_id=entity.chunk_id,
|
||||
)
|
||||
for entity, vectors in zip(v.entities, all_vectors)
|
||||
]
|
||||
```
|
||||
|
||||
#### Фаза 4: Обновление сервиса встраивания данных.
|
||||
|
||||
**Текущая (последовательная):**
|
||||
```python
|
||||
for text, (index_name, index_value) in texts_to_embed.items():
|
||||
vectors = await flow("embeddings-request").embed(text=text)
|
||||
embeddings_list.append(RowIndexEmbedding(...))
|
||||
```
|
||||
|
||||
**Обновлено (пакетно):**
|
||||
```python
|
||||
# Collect texts and metadata
|
||||
texts = list(texts_to_embed.keys())
|
||||
metadata = list(texts_to_embed.values())
|
||||
|
||||
# Single batch embedding call
|
||||
all_vectors = await flow("embeddings-request").embed(texts=texts)
|
||||
|
||||
# Pair results
|
||||
embeddings_list = [
|
||||
RowIndexEmbedding(
|
||||
index_name=meta[0],
|
||||
index_value=meta[1],
|
||||
text=text,
|
||||
vectors=vectors[0] # First vector from the set
|
||||
)
|
||||
for text, meta, vectors in zip(texts, metadata, all_vectors)
|
||||
]
|
||||
```
|
||||
|
||||
#### Фаза 5: Улучшение инструмента командной строки (CLI).
|
||||
|
||||
**Обновленный CLI:**
|
||||
```python
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(...)
|
||||
|
||||
parser.add_argument(
|
||||
'text',
|
||||
nargs='*', # Zero or more texts
|
||||
help='Text(s) to convert to embedding vectors',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-f', '--file',
|
||||
help='File containing texts (one per line)',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--batch-size',
|
||||
type=int,
|
||||
default=32,
|
||||
help='Batch size for processing (default: 32)',
|
||||
)
|
||||
```
|
||||
|
||||
Использование:
|
||||
```bash
|
||||
# Single text (existing)
|
||||
tg-invoke-embeddings "hello world"
|
||||
|
||||
# Multiple texts
|
||||
tg-invoke-embeddings "text one" "text two" "text three"
|
||||
|
||||
# From file
|
||||
tg-invoke-embeddings -f texts.txt --batch-size 64
|
||||
```
|
||||
|
||||
#### Фаза 6: Улучшение SDK для Python
|
||||
|
||||
**FlowInstance (HTTP-клиент):**
|
||||
|
||||
```python
|
||||
class FlowInstance:
|
||||
def embeddings(self, texts: list[str]) -> list[list[list[float]]]:
|
||||
"""
|
||||
Get embeddings for one or more texts.
|
||||
|
||||
Args:
|
||||
texts: List of texts to embed
|
||||
|
||||
Returns:
|
||||
List of vector sets, one per input text
|
||||
"""
|
||||
input = {"texts": texts}
|
||||
return self.request("service/embeddings", input)["vectors"]
|
||||
```
|
||||
|
||||
**SocketFlowInstance (клиент WebSocket):**
|
||||
|
||||
```python
|
||||
class SocketFlowInstance:
|
||||
def embeddings(self, texts: list[str], **kwargs: Any) -> list[list[list[float]]]:
|
||||
"""
|
||||
Get embeddings for one or more texts via WebSocket.
|
||||
|
||||
Args:
|
||||
texts: List of texts to embed
|
||||
|
||||
Returns:
|
||||
List of vector sets, one per input text
|
||||
"""
|
||||
request = {"texts": texts}
|
||||
response = self.client._send_request_sync(
|
||||
"embeddings", self.flow_id, request, False
|
||||
)
|
||||
return response["vectors"]
|
||||
```
|
||||
|
||||
**Примеры использования SDK:**
|
||||
|
||||
```python
|
||||
# Single text
|
||||
vectors = flow.embeddings(["hello world"])
|
||||
print(f"Dimensions: {len(vectors[0][0])}")
|
||||
|
||||
# Batch embedding
|
||||
texts = ["text one", "text two", "text three"]
|
||||
all_vectors = flow.embeddings(texts)
|
||||
|
||||
# Process results
|
||||
for text, vecs in zip(texts, all_vectors):
|
||||
print(f"{text}: {len(vecs[0])} dimensions")
|
||||
```
|
||||
|
||||
## Соображения безопасности
|
||||
|
||||
**Ограничения на размер запроса**: Установите максимальный размер пакета для предотвращения исчерпания ресурсов.
|
||||
**Обработка таймаутов**: Адаптируйте таймауты в соответствии с размером пакета.
|
||||
**Ограничения памяти**: Отслеживайте использование памяти для больших пакетов.
|
||||
**Проверка входных данных**: Проверяйте все тексты в пакете перед обработкой.
|
||||
|
||||
## Соображения производительности
|
||||
|
||||
### Ожидаемые улучшения
|
||||
|
||||
**Производительность:**
|
||||
Для одного текста: ~10-50 текстов/секунду (в зависимости от модели).
|
||||
Для пакета (размер 32): ~200-500 текстов/секунду (улучшение в 5-10 раз).
|
||||
|
||||
**Задержка на текст:**
|
||||
Для одного текста: 50-200 мс на текст.
|
||||
Для пакета (размер 32): 5-20 мс на текст (в среднем).
|
||||
|
||||
**Улучшения для конкретных сервисов:**
|
||||
|
||||
| Сервис | Текущее значение | Пакетный режим | Улучшение |
|
||||
|---------|---------|---------|-------------|
|
||||
| Векторные представления графов (50 сущностей) | 5-10 секунд | 0.5-1 секунда | 5-10x |
|
||||
| Векторные представления строк (100 текстов) | 10-20 секунд | 1-2 секунды | 5-10x |
|
||||
| Импорт документов (1000 фрагментов) | 100-200 секунд | 10-30 секунд | 5-10x |
|
||||
|
||||
### Параметры конфигурации
|
||||
|
||||
```python
|
||||
# Recommended defaults
|
||||
DEFAULT_BATCH_SIZE = 32
|
||||
MAX_BATCH_SIZE = 128
|
||||
BATCH_TIMEOUT_MULTIPLIER = 2.0
|
||||
```
|
||||
|
||||
## Стратегия тестирования
|
||||
|
||||
### Модульное тестирование
|
||||
Обработка однострочных вложений (обратная совместимость)
|
||||
Обработка пустых пакетов
|
||||
Применение максимального размера пакета
|
||||
Обработка ошибок при частичных сбоях пакета
|
||||
|
||||
### Интеграционное тестирование
|
||||
Полная обработка пакетов через Pulsar
|
||||
Обработка пакетов сервисом графовых вложений
|
||||
Обработка пакетов сервисом строковых вложений
|
||||
API-шлюз для пакетных операций
|
||||
|
||||
### Тестирование производительности
|
||||
Сравнение производительности при обработке отдельных элементов и пакетов
|
||||
Использование памяти при различных размерах пакетов
|
||||
Анализ распределения задержек
|
||||
|
||||
## План миграции
|
||||
|
||||
Это версия с критическими изменениями. Все этапы реализованы одновременно.
|
||||
|
||||
### Этап 1: Изменения схемы
|
||||
Заменить `text: str` на `texts: list[str]` в EmbeddingsRequest
|
||||
Изменить тип `vectors` на `list[list[list[float]]]` в EmbeddingsResponse
|
||||
|
||||
### Этап 2: Обновление процессоров
|
||||
Обновить сигнатуру `on_embeddings` в процессорах FastEmbed и Ollama
|
||||
Обрабатывать полный пакет за один вызов модели
|
||||
|
||||
### Этап 3: Обновление клиентской части
|
||||
Обновить `EmbeddingsClient.embed()` для приема `texts: list[str]`
|
||||
|
||||
### Этап 4: Обновление вызывающего кода
|
||||
Обновить graph_embeddings для пакетной обработки контекстов сущностей
|
||||
Обновить row_embeddings для пакетной обработки текстов индекса
|
||||
Обновить document_embeddings для использования новой схемы
|
||||
Обновить инструмент командной строки
|
||||
|
||||
### Этап 5: API-шлюз
|
||||
Обновить конечную точку для вложений в соответствии с новой схемой
|
||||
|
||||
### Этап 6: Python SDK
|
||||
Обновить сигнатуру `FlowInstance.embeddings()`
|
||||
Обновить сигнатуру `SocketFlowInstance.embeddings()`
|
||||
|
||||
## Открытые вопросы
|
||||
|
||||
**Потоковая передача больших пакетов**: Следует ли нам поддерживать потоковую передачу результатов для очень больших пакетов (>100 текстов)?
|
||||
**Ограничения, специфичные для поставщиков**: Как нам обрабатывать поставщиков с разными максимальными размерами пакетов?
|
||||
**Обработка частичных сбоев**: Если один текст в пакете завершается сбоем, следует ли нам завершать весь пакет или возвращать частичные результаты?
|
||||
**Пакетная обработка документов**: Следует ли нам выполнять пакетную обработку по нескольким сообщениям Chunk или сохранять обработку для каждого сообщения?
|
||||
|
||||
## Ссылки
|
||||
|
||||
[Документация FastEmbed](https://github.com/qdrant/fastembed)
|
||||
[API вложений Ollama](https://github.com/ollama/ollama)
|
||||
[Реализация сервиса вложений](trustgraph-base/trustgraph/base/embeddings_service.py)
|
||||
[Оптимизация производительности GraphRAG](graphrag-performance-optimization.md)
|
||||
Loading…
Add table
Add a link
Reference in a new issue