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
131 lines
4.4 KiB
Python
131 lines
4.4 KiB
Python
# Copyright (c) 2024 Microsoft Corporation.
|
|
# Licensed under the MIT License
|
|
|
|
"""Default Metrics Processor."""
|
|
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
from graphrag_llm.metrics.metrics_processor import MetricsProcessor
|
|
from graphrag_llm.model_cost_registry import model_cost_registry
|
|
from graphrag_llm.types import LLMCompletionResponse, LLMEmbeddingResponse
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import AsyncIterator, Iterator
|
|
|
|
from graphrag_llm.config import ModelConfig
|
|
from graphrag_llm.types import (
|
|
LLMCompletionChunk,
|
|
Metrics,
|
|
)
|
|
|
|
|
|
class DefaultMetricsProcessor(MetricsProcessor):
|
|
"""Default metrics processor that does nothing."""
|
|
|
|
def __init__(self, **kwargs: Any) -> None:
|
|
"""Initialize DefaultMetricsProcessor."""
|
|
|
|
def process_metrics(
|
|
self,
|
|
*,
|
|
model_config: "ModelConfig",
|
|
metrics: "Metrics",
|
|
input_args: dict[str, Any],
|
|
response: "LLMCompletionResponse \
|
|
| Iterator[LLMCompletionChunk] \
|
|
| AsyncIterator[LLMCompletionChunk] \
|
|
| LLMEmbeddingResponse",
|
|
) -> None:
|
|
"""Process metrics."""
|
|
self._process_metrics_common(
|
|
model_config=model_config,
|
|
metrics=metrics,
|
|
input_args=input_args,
|
|
response=response,
|
|
)
|
|
|
|
def _process_metrics_common(
|
|
self,
|
|
*,
|
|
model_config: "ModelConfig",
|
|
metrics: "Metrics",
|
|
input_args: dict[str, Any],
|
|
response: "LLMCompletionResponse \
|
|
| Iterator[LLMCompletionChunk] \
|
|
| AsyncIterator[LLMCompletionChunk] \
|
|
| LLMEmbeddingResponse",
|
|
) -> None:
|
|
if isinstance(response, LLMCompletionResponse):
|
|
self._process_lm_chat_completion(
|
|
model_config=model_config,
|
|
metrics=metrics,
|
|
input_args=input_args,
|
|
response=response,
|
|
)
|
|
elif isinstance(response, LLMEmbeddingResponse):
|
|
self._process_lm_embedding_response(
|
|
model_config=model_config,
|
|
metrics=metrics,
|
|
input_args=input_args,
|
|
response=response,
|
|
)
|
|
|
|
def _process_lm_chat_completion(
|
|
self,
|
|
model_config: "ModelConfig",
|
|
metrics: "Metrics",
|
|
input_args: dict[str, Any],
|
|
response: "LLMCompletionResponse",
|
|
) -> None:
|
|
"""Process LMChatCompletion metrics."""
|
|
prompt_tokens = response.usage.prompt_tokens if response.usage else 0
|
|
completion_tokens = response.usage.completion_tokens if response.usage else 0
|
|
total_tokens = prompt_tokens + completion_tokens
|
|
|
|
if total_tokens > 0:
|
|
metrics["responses_with_tokens"] = 1
|
|
metrics["prompt_tokens"] = prompt_tokens
|
|
metrics["completion_tokens"] = completion_tokens
|
|
metrics["total_tokens"] = total_tokens
|
|
|
|
model_id = f"{model_config.model_provider}/{model_config.model}"
|
|
model_costs = model_cost_registry.get_model_costs(model_id)
|
|
|
|
if not model_costs:
|
|
return
|
|
|
|
input_cost = prompt_tokens * model_costs["input_cost_per_token"]
|
|
output_cost = completion_tokens * model_costs["output_cost_per_token"]
|
|
total_cost = input_cost + output_cost
|
|
|
|
metrics["responses_with_cost"] = 1
|
|
metrics["input_cost"] = input_cost
|
|
metrics["output_cost"] = output_cost
|
|
metrics["total_cost"] = total_cost
|
|
|
|
def _process_lm_embedding_response(
|
|
self,
|
|
model_config: "ModelConfig",
|
|
metrics: "Metrics",
|
|
input_args: dict[str, Any],
|
|
response: "LLMEmbeddingResponse",
|
|
) -> None:
|
|
"""Process LLMEmbeddingResponse metrics."""
|
|
prompt_tokens = response.usage.prompt_tokens if response.usage else 0
|
|
|
|
if prompt_tokens > 0:
|
|
metrics["responses_with_tokens"] = 1
|
|
metrics["prompt_tokens"] = prompt_tokens
|
|
metrics["total_tokens"] = prompt_tokens
|
|
|
|
model_id = f"{model_config.model_provider}/{model_config.model}"
|
|
model_costs = model_cost_registry.get_model_costs(model_id)
|
|
|
|
if not model_costs:
|
|
return
|
|
|
|
input_cost = prompt_tokens * model_costs["input_cost_per_token"]
|
|
metrics["responses_with_cost"] = 1
|
|
metrics["input_cost"] = input_cost
|
|
metrics["total_cost"] = input_cost
|