Files
wehub-resource-sync 6b7e6b44f1
Python Build and Type Check / python-ci (ubuntu-latest, 3.11) (push) Has been cancelled
Python Build and Type Check / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Build and Type Check / python-ci (windows-latest, 3.11) (push) Has been cancelled
Python Build and Type Check / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Integration Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Integration Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Notebook Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Notebook Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Smoke Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Smoke Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Unit Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Unit Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
gh-pages / build (push) Has been cancelled
Python Publish (pypi) / Upload release to PyPI (push) Has been cancelled
Spellcheck / spellcheck (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:37:31 +08:00

192 lines
6.5 KiB
Python

# Copyright (c) 2024 Microsoft Corporation.
# Licensed under the MIT License
"""Completion Abstract Base Class."""
from abc import ABC, abstractmethod
from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Unpack
from graphrag_llm.threading.embedding_thread_runner import embedding_thread_runner
if TYPE_CHECKING:
from collections.abc import Iterator
from graphrag_cache import Cache, CacheKeyCreator
from graphrag_llm.config import ModelConfig
from graphrag_llm.metrics import MetricsProcessor, MetricsStore
from graphrag_llm.rate_limit import RateLimiter
from graphrag_llm.retry import Retry
from graphrag_llm.threading.embedding_thread_runner import (
ThreadedLLMEmbeddingFunction,
ThreadedLLMEmbeddingResponseHandler,
)
from graphrag_llm.tokenizer import Tokenizer
from graphrag_llm.types import LLMEmbeddingArgs, LLMEmbeddingResponse
class LLMEmbedding(ABC):
"""Abstract base class for language model embeddings."""
@abstractmethod
def __init__(
self,
*,
model_id: str,
model_config: "ModelConfig",
tokenizer: "Tokenizer",
metrics_store: "MetricsStore",
metrics_processor: "MetricsProcessor | None" = None,
rate_limiter: "RateLimiter | None" = None,
retrier: "Retry | None" = None,
cache: "Cache | None" = None,
cache_key_creator: "CacheKeyCreator",
**kwargs: Any,
):
"""Initialize the LLMEmbedding.
Args
----
model_id: str
The model ID, e.g., "openai/gpt-4o".
model_config: ModelConfig
The configuration for the language model.
tokenizer: Tokenizer
The tokenizer to use.
metrics_store: MetricsStore | None (default=None)
The metrics store to use.
metrics_processor: MetricsProcessor | None (default: None)
The metrics processor to use.
rate_limiter: RateLimiter | None (default=None)
The rate limiter to use.
retrier: Retry | None (default=None)
The retry strategy to use.
cache: Cache | None (default=None)
Optional cache for embeddings.
cache_key_creator: CacheKeyCreator | None (default=None)
Optional cache key creator function.
(dict[str, Any]) -> str
**kwargs: Any
Additional keyword arguments.
"""
raise NotImplementedError
@abstractmethod
def embedding(
self, /, **kwargs: Unpack["LLMEmbeddingArgs"]
) -> "LLMEmbeddingResponse":
"""Sync embedding method."""
raise NotImplementedError
@abstractmethod
async def embedding_async(
self, /, **kwargs: Unpack["LLMEmbeddingArgs"]
) -> "LLMEmbeddingResponse":
"""Async embedding method."""
raise NotImplementedError
@contextmanager
def embedding_thread_pool(
self,
*,
response_handler: "ThreadedLLMEmbeddingResponseHandler",
concurrency: int,
queue_limit: int = 0,
) -> "Iterator[ThreadedLLMEmbeddingFunction]":
"""Run an embedding thread pool.
Args
----
response_handler: ThreadedLLMEmbeddingResponseHandler
The callback function to handle embedding responses.
(request_id, response|exception) -> Awaitable[None] | None
concurrency: int
The number of threads to spin up in a thread pool.
queue_limit: int (default=0)
The maximum number of items allowed in the input queue.
0 means unlimited.
Set this to a value to create backpressure on the caller.
Yields
------
ThreadedLLMEmbeddingFunction:
A function that can be used to submit embedding requests to the thread pool.
(input, request_id, **kwargs) -> None
The thread pool will process the requests and invoke the provided callback
with the responses.
same signature as LLMEmbeddingFunction but requires a `request_id` parameter
to identify the request and does not return anything.
"""
with embedding_thread_runner(
embedding=self.embedding,
response_handler=response_handler,
concurrency=concurrency,
queue_limit=queue_limit,
metrics_store=self.metrics_store,
) as embedding:
yield embedding
def embedding_batch(
self,
embedding_requests: list["LLMEmbeddingArgs"],
*,
concurrency: int,
queue_limit: int = 0,
) -> list["LLMEmbeddingResponse | Exception"]:
"""Process a batch of embedding requests using a thread pool.
Args
----
embedding_requests: list[LLMEmbeddingArgs]
A list of embedding request arguments to process in parallel.
batch_size: int
The number of inputs to process in each batch.
concurrency: int
The number of threads to spin up in a thread pool.
queue_limit: int (default=0)
The maximum number of items allowed in the input queue.
0 means unlimited.
Set this to a value to create backpressure on the caller.
Returns
-------
list[LLMEmbeddingResponse | Exception]
A list of embedding responses or exceptions for each input.
"""
results: list[LLMEmbeddingResponse | Exception] = [None] * len(
embedding_requests
) # type: ignore
def handle_response(
request_id: str,
response: "LLMEmbeddingResponse | Exception",
) -> None:
index = int(request_id)
results[index] = response
with self.embedding_thread_pool(
response_handler=handle_response,
concurrency=concurrency,
queue_limit=queue_limit,
) as embedding:
for idx, embedding_request in enumerate(embedding_requests):
embedding(request_id=str(idx), **embedding_request)
return results
@property
@abstractmethod
def metrics_store(self) -> "MetricsStore":
"""Metrics store."""
raise NotImplementedError
@property
@abstractmethod
def tokenizer(self) -> "Tokenizer":
"""Tokenizer."""
raise NotImplementedError