mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
refactor(benchmark): delegate model loading to tasks and support CIFAR-100
- Extract model loading logic from benchmark CLI into task-owned prepare_benchmark - Add RetrievalEncoder class wrapping DINO with optional hash compression - Add accelerate dependency for device management - Switch dataset from CIFAR-10 to CIFAR-100 with fine_label column
This commit is contained in:
@@ -1,18 +1,42 @@
|
||||
"""Benchmark runner for executing evaluations."""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from typing import Any, Callable, cast
|
||||
|
||||
import lancedb
|
||||
from benchmarks.datasets import HuggingFaceDataset, LocalDataset
|
||||
from benchmarks.tasks import get_task
|
||||
from configs.models import BenchmarkConfig, DatasetSourceConfig
|
||||
from configs.models import BenchmarkConfig, DatasetSourceConfig, ModelConfig
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
def _create_task(config: BenchmarkConfig, model_config: ModelConfig | None) -> Any:
|
||||
"""Create benchmark task with task-specific model settings.
|
||||
|
||||
Args:
|
||||
config: Benchmark configuration.
|
||||
model_config: Optional model configuration for task-owned loading.
|
||||
|
||||
Returns:
|
||||
Benchmark task instance.
|
||||
"""
|
||||
task_kwargs: dict[str, Any] = {"top_k": config.task.top_k}
|
||||
|
||||
if config.task.type == "retrieval" and model_config is not None:
|
||||
task_kwargs.update(
|
||||
{
|
||||
"dino_model": model_config.dino_model,
|
||||
"compression_dim": model_config.compression_dim,
|
||||
"compressor_path": model_config.compressor_path,
|
||||
}
|
||||
)
|
||||
|
||||
return get_task(config.task.type, **task_kwargs)
|
||||
|
||||
|
||||
def create_dataset(config: DatasetSourceConfig) -> Any:
|
||||
"""Create a dataset instance from configuration.
|
||||
|
||||
@@ -130,10 +154,30 @@ def _print_benchmark_info(
|
||||
console.print(table)
|
||||
|
||||
|
||||
def _print_benchmark_results(results: dict[str, Any]) -> None:
|
||||
"""Print benchmark results using Rich table.
|
||||
|
||||
Args:
|
||||
results: Final benchmark metrics.
|
||||
"""
|
||||
table = Table(title="Benchmark Results", show_header=False)
|
||||
table.add_column("Metric", style="cyan", no_wrap=True)
|
||||
table.add_column("Value", style="green")
|
||||
|
||||
for key, value in results.items():
|
||||
if isinstance(value, float):
|
||||
table.add_row(key, f"{value:.4f}")
|
||||
continue
|
||||
table.add_row(key, str(value))
|
||||
|
||||
console.print(table)
|
||||
|
||||
|
||||
def run_benchmark(
|
||||
model: Any,
|
||||
processor: Any,
|
||||
config: BenchmarkConfig,
|
||||
model_config: ModelConfig | None = None,
|
||||
model_name: str = "model",
|
||||
) -> dict[str, Any]:
|
||||
"""Run benchmark evaluation.
|
||||
@@ -148,6 +192,7 @@ def run_benchmark(
|
||||
model: Feature extraction model.
|
||||
processor: Image preprocessor.
|
||||
config: Benchmark configuration.
|
||||
model_config: Optional model configuration for task-owned loading.
|
||||
model_name: Model name for table naming.
|
||||
|
||||
Returns:
|
||||
@@ -171,6 +216,23 @@ def run_benchmark(
|
||||
f"Dataset {config.dataset.path} does not have train/test splits"
|
||||
)
|
||||
|
||||
task = _create_task(config, model_config)
|
||||
|
||||
resolver = getattr(task, "prepare_benchmark", None)
|
||||
if callable(resolver):
|
||||
prepare_benchmark = cast(
|
||||
Callable[[Any, Any, str], tuple[Any, Any, str]],
|
||||
resolver,
|
||||
)
|
||||
model, processor, model_name = prepare_benchmark(
|
||||
model,
|
||||
processor,
|
||||
model_name,
|
||||
)
|
||||
|
||||
if model is None or processor is None:
|
||||
raise ValueError("Benchmark task did not provide a valid model and processor")
|
||||
|
||||
# Infer vector dimension from a sample
|
||||
sample = train_dataset[0]
|
||||
sample_image = sample["img"]
|
||||
@@ -191,16 +253,17 @@ def run_benchmark(
|
||||
f"[yellow]Table '{table_name}' already has {table_count} entries, skipping database build.[/yellow]"
|
||||
)
|
||||
else:
|
||||
# Create and run benchmark task
|
||||
task = get_task(config.task.type, top_k=config.task.top_k)
|
||||
console.print(
|
||||
f"[cyan]Building database[/cyan] with {len(train_dataset)} training samples..."
|
||||
)
|
||||
task.build_database(model, processor, train_dataset, table, config.batch_size)
|
||||
table_count = table.count_rows()
|
||||
|
||||
_print_benchmark_info(config, vector_dim, table_name, table_count)
|
||||
|
||||
# Run evaluation (results with Rich table will be printed by the task)
|
||||
task = get_task(config.task.type, top_k=config.task.top_k)
|
||||
console.print(f"[cyan]Evaluating[/cyan] on {len(test_dataset)} test samples...")
|
||||
results = task.evaluate(model, processor, test_dataset, table, config.batch_size)
|
||||
_print_benchmark_results(results)
|
||||
|
||||
return results
|
||||
|
||||
Reference in New Issue
Block a user