Evaluation¶
xaytune provides two evaluation paths: custom dataset evaluation with evaluate() and benchmark evaluation with benchmark_evaluate().
evaluate()¶
Evaluate a model on a custom dataset with configurable metrics.
from xaytune.eval import evaluate
results = evaluate(
model="output/my-finetune",
dataset=[{"input_ids": ..., "labels": ...}],
metrics=["loss", "perplexity"],
)
print(results)
# {'loss': 1.234, 'perplexity': 3.435}
Function Signature¶
def evaluate(
*,
model: Any,
dataset: list[dict[str, Any]],
metrics: list[str] | None = None,
) -> dict[str, float]:
| Parameter | Type | Default | Description |
|---|---|---|---|
model |
model object or str |
required | A model instance or path to load from |
dataset |
list[dict] |
required | List of data batches to evaluate on |
metrics |
list[str] | None |
["loss", "perplexity"] |
Metric names to compute (must be in metric_registry) |
Returns: dict[str, float] mapping metric names to their computed values.
Note
When model is a string path, xaytune automatically loads the model and tokenizer using xaytune.models.load_model().
benchmark_evaluate()¶
Run standard benchmarks using lm-eval.
from xaytune.eval.benchmarks import benchmark_evaluate
results = benchmark_evaluate(
model="meta-llama/Llama-3.1-8B",
benchmarks=["mmlu", "gsm8k", "hellaswag"],
num_fewshot=5,
)
for task, metrics in results.items():
print(f"{task}: {metrics}")
Function Signature¶
def benchmark_evaluate(
*,
model: str,
benchmarks: list[str],
num_fewshot: int | None = None,
) -> dict[str, dict[str, Any]]:
| Parameter | Type | Default | Description |
|---|---|---|---|
model |
str |
required | Model path or Hugging Face Hub name |
benchmarks |
list[str] |
required | List of benchmark task names |
num_fewshot |
int | None |
None |
Number of few-shot examples (benchmark default if None) |
Returns: Nested dict {task_name: {metric_name: value}}.
Built-in Metrics¶
xaytune ships three metrics, registered in xaytune.eval.metrics.metric_registry:
| Metric | Function | Description |
|---|---|---|
loss |
compute_loss |
Mean cross-entropy loss. evaluate() and the training evaluation callback weight each batch's loss by its valid next-token target count, giving the mean over every target in the dataset; direct callers may pass weights (one non-negative count per loss). Without weights, losses are averaged plainly, for backward compatibility. |
perplexity |
compute_perplexity |
exp of the mean loss, weighted exactly as loss is: by target count from evaluate() and the training callback, by weights when a direct caller passes them, and plainly otherwise. |
token_accuracy |
compute_token_accuracy |
Fraction of next-token targets predicted correctly: the logits at i against the label at i + 1, labels of -100 excluded |
Custom Metrics¶
Register your own metrics with the @register_metric decorator:
from xaytune.eval.metrics import register_metric
@register_metric("bleu")
def compute_bleu(predictions, references, **kwargs):
# Your BLEU implementation here
...
return score
Once registered, custom metrics can be used anywhere metrics are accepted:
Or in YAML config:
CLI Usage¶
Benchmark Evaluation¶
Dataset Evaluation¶
Model Comparison¶
Compare two models side-by-side on the same benchmarks:
This prints a table showing each model's score on every benchmark metric.
Agent Evaluation¶
Evaluate agent performance on tool-use tasks with evaluate_agent(). Scores a dataset of prompt-response pairs across four metrics.
from xaytune.eval.agent_metrics import evaluate_agent
results = evaluate_agent(
responses=[
{"prompt": "Search for cats", "response": "<tool_call>..."},
],
expected_tools=["search"],
success_markers=["Done"],
max_steps=5,
)
# {'tool_use_accuracy': 0.85, 'task_success_rate': 0.90, ...}
Agent Metrics¶
| Metric | Description |
|---|---|
tool_use_accuracy |
Fraction of samples where the correct tools were called |
task_success_rate |
Fraction of samples that completed the task |
step_efficiency |
Average efficiency score (fewer tool calls = higher) |
error_recovery_rate |
Fraction of samples that recovered after tool errors |
evaluate_agent(responses, *, expected_tools=None, required_args=None, success_markers=None, failure_markers=None, max_steps=10, optimal_steps=None, error_indicators=None, parser=None)
¶
Source code in xaytune/eval/agent_metrics.py
compute_tool_use_accuracy(responses, *args, expected_tools=None, required_args=None, parser=None, **kwargs)
¶
Source code in xaytune/eval/agent_metrics.py
compute_task_success_rate(responses, *args, success_markers=None, failure_markers=None, parser=None, **kwargs)
¶
Source code in xaytune/eval/agent_metrics.py
compute_step_efficiency(responses, *args, max_steps=10, optimal_steps=None, parser=None, **kwargs)
¶
Source code in xaytune/eval/agent_metrics.py
compute_error_recovery_rate(responses, *args, error_indicators=None, parser=None, **kwargs)
¶
Source code in xaytune/eval/agent_metrics.py
Full API Reference¶
evaluate(*, model, dataset, metrics=None)
¶
Evaluate a model on a list of batches and compute metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Any
|
A model instance or HuggingFace model name string. |
required |
dataset
|
list[dict[str, Any]]
|
List of batch dicts (each passable to |
required |
metrics
|
list[str] | None
|
Metric names to compute (default: |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
Dict mapping metric names to computed values. |
For a causal LM, token_accuracy compares the logits at each position
with the next label, and loss and perplexity are means over every
next-token target in the dataset -- each batch's loss weighted by its
target count -- so batching the same examples differently gives the same
answer. Labels of -100 are not targets.
Source code in xaytune/eval/evaluate.py
benchmark_evaluate(*, model, benchmarks, num_fewshot=None)
¶
Run lm-eval-harness benchmarks against a HuggingFace model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
HuggingFace model name or local path. |
required |
benchmarks
|
list[str]
|
Benchmark task names (e.g. |
required |
num_fewshot
|
int | None
|
Number of few-shot examples. |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, dict[str, Any]]
|
Dict mapping benchmark names to their result dicts. |
Raises:
| Type | Description |
|---|---|
ImportError
|
If |
Source code in xaytune/eval/benchmarks.py
compute_loss(losses, *args, weights=None, **kwargs)
¶
Mean loss over the dataset: weighted by each batch's target count when given.
0.0 when there is nothing to average -- no losses, or no targets.
Source code in xaytune/eval/metrics.py
compute_perplexity(losses, *args, weights=None, **kwargs)
¶
Perplexity: exp of the mean loss, weighted as :func:compute_loss weights it.
0.0 when there is nothing to average, as :func:compute_loss reports.
Source code in xaytune/eval/metrics.py
compute_token_accuracy(predictions, references, *args, **kwargs)
¶
Fraction of targets whose prediction matches.
Pairs are compared as given. For a causal LM they must already be aligned
next-token pairs (:func:xaytune.eval.causal.next_token_pairs): the
logits at i against the token at i + 1.