Source code for eval_framework.tasks.task
from abc import ABC, abstractmethod
from collections.abc import Iterable, Sequence
from enum import Enum
from typing import TYPE_CHECKING, Any
from pydantic import BaseModel, ConfigDict
from eval_framework.shared.types import BaseMetricContext, Completion
from template_formatting.formatter import BaseFormatter, Message
if TYPE_CHECKING:
from eval_framework.llm.base import BaseLLM
from eval_framework.metrics.base import BaseMetric
[docs]
class ResponseType(Enum):
COMPLETION = "completion"
LOGLIKELIHOODS = "loglikelihoods"
[docs]
class Sample(BaseModel):
model_config = ConfigDict(extra="forbid")
id: int
subject: str
messages: list[Message]
ground_truth: str | list[str] | None
possible_completions: list[str] | None
context: BaseMetricContext | list[BaseMetricContext] | None = None
[docs]
class Task(ABC):
"""The contract a caller relies on to run an evaluation"""
[docs]
@abstractmethod
def iterate_samples(self, num_samples: int | None = None) -> Iterable[Sample]: ...
[docs]
@abstractmethod
def generate_completions(
self,
llm: "BaseLLM",
samples: list[Sample],
stop_sequences: list[str] | None = None,
max_tokens: int | None = None,
fail_on_error: bool = True,
) -> list[Completion]:
"""Run ``llm`` over ``samples`` and return their completions."""
[docs]
@abstractmethod
def get_response_type(self) -> ResponseType: ...
[docs]
@abstractmethod
def display_name(self) -> str:
"""Human-readable display name. Is allowed to have special characters and whitespaces."""
...
[docs]
class EvalFactory(ABC):
"""Produces a registered benchmark's eval.
The registry stores one factory per eval. This allows the factory to be
constructed without constructing all evals. Going via this ABC allows
the factory instances to contain state specifically relevant to the
eval, as well as supporting different strategies for instantiating it.
E.g. eager vs lazy loading of the required dependencies.
"""
[docs]
@abstractmethod
def id(self) -> str:
"Canonical key used to register this benchmark"
[docs]
@abstractmethod
def response_type(self) -> ResponseType:
"""The eval's response type"""
[docs]
@abstractmethod
def metrics(self) -> list[type["BaseMetric"]]:
"""The eval's metrics"""
[docs]
@abstractmethod
def subjects(self) -> list[Any]:
"""The eval's subjects"""
[docs]
@abstractmethod
def display_name(self) -> str:
"""Human-readable display name. Is allowed to have special characters and whitespaces."""
[docs]
@abstractmethod
def create(
self,
num_fewshot: int,
custom_subjects: list[str] | None,
custom_hf_revision: str | None,
user_prompt_suffix: str | None = None,
seed: int | None = None,
) -> Task: ...
[docs]
@abstractmethod
def markdown_doc(self, formatters: Sequence[BaseFormatter]) -> str:
"""Render the eval's documentation as markdown."""
...