refactor: update import paths and benchmark discovery

Updated import paths to use direct module references instead of relative paths. Implemented dynamic benchmark discovery based on the contents of the tests/ directory, allowing for more flexible benchmark configuration without requiring code changes. This change improves maintainability and makes it easier to add new benchmarks.
This commit is contained in:
2026-02-21 17:28:52 +03:00
parent 0dc4359755
commit fcda2be4a9
12 changed files with 68 additions and 66 deletions

View File

@@ -13,7 +13,7 @@ from pathlib import Path
# Добавляем путь к исходникам, чтобы импортировать base # Добавляем путь к исходникам, чтобы импортировать base
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
from src.benchmarks.base import TEST_SEPARATOR from benchmark import TEST_SEPARATOR
def convert_tests(test_dir: str) -> None: def convert_tests(test_dir: str) -> None:
"""Конвертирует все тесты в указанной директории.""" """Конвертирует все тесты в указанной директории."""

View File

@@ -19,7 +19,7 @@ from pymongo import MongoClient
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
from src.constants import TEST_SEPARATOR from src.constants import TEST_SEPARATOR
from src.models.ollama_client import OllamaClient from ollama_client import OllamaClient
def sanitize_filename(filename: str) -> str: def sanitize_filename(filename: str) -> str:
""" """

View File

@@ -20,7 +20,7 @@ from typing import Dict, List, Optional
# Добавляем путь к исходникам, чтобы импортировать ollama_client # Добавляем путь к исходникам, чтобы импортировать ollama_client
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
from src.models.ollama_client import OllamaClient from ollama_client import OllamaClient
from src.constants import TEST_SEPARATOR from src.constants import TEST_SEPARATOR
def generate_translation_test(ollama: OllamaClient, model: str) -> Dict[str, str]: def generate_translation_test(ollama: OllamaClient, model: str) -> Dict[str, str]:

View File

@@ -4,7 +4,7 @@ import os
import re import re
from typing import Dict, Any, List, Optional from typing import Dict, Any, List, Optional
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from models.ollama_client import OllamaClient from ollama_client import OllamaClient
from constants import TEST_SEPARATOR from constants import TEST_SEPARATOR
class Benchmark(ABC): class Benchmark(ABC):
@@ -159,7 +159,7 @@ class Benchmark(ABC):
Returns: Returns:
Результаты бенчмарка Результаты бенчмарка
""" """
from utils.scoring import get_all_scores from scoring import get_all_scores
test_cases = self.load_test_data() test_cases = self.load_test_data()
results = [] results = []

View File

@@ -1,12 +0,0 @@
import logging
import json
import os
from typing import Dict, Any, List
from benchmarks.base import Benchmark
from constants import TEST_SEPARATOR
class CodegenBenchmark(Benchmark):
"""Бенчмарк для тестирования генерации кода."""
def __init__(self):
super().__init__("codegen", "prompts/codegen.txt", "tests/codegen")

View File

@@ -1,8 +0,0 @@
import logging
from benchmarks.base import Benchmark
class CustomBenchmark(Benchmark):
"""Бенчмарк для универсальных тестов, где инструкция передается в самом тест-кейсе."""
def __init__(self):
super().__init__("custom", "prompts/custom.txt", "tests/custom")

View File

@@ -1,12 +0,0 @@
import logging
import json
import os
from typing import Dict, Any, List
from benchmarks.base import Benchmark
from constants import TEST_SEPARATOR
class SummarizationBenchmark(Benchmark):
"""Бенчмарк для тестирования пересказов."""
def __init__(self):
super().__init__("summarization", "prompts/summarization.txt", "tests/summarization")

View File

@@ -1,12 +0,0 @@
import logging
import json
import os
from typing import Dict, Any, List
from benchmarks.base import Benchmark
from constants import TEST_SEPARATOR
class TranslationBenchmark(Benchmark):
"""Бенчмарк для тестирования перевода."""
def __init__(self):
super().__init__("translation", "prompts/translation.txt", "tests/translation")

View File

@@ -1,12 +1,10 @@
import logging import logging
import argparse import argparse
from typing import List import os
from models.ollama_client import OllamaClient from typing import List, Dict
from benchmarks.translation import TranslationBenchmark from ollama_client import OllamaClient
from benchmarks.summarization import SummarizationBenchmark from benchmark import Benchmark
from benchmarks.codegen import CodegenBenchmark from report import ReportGenerator
from benchmarks.custom import CustomBenchmark
from utils.report import ReportGenerator
def setup_logging(verbose: bool = False): def setup_logging(verbose: bool = False):
"""Настройка логирования.""" """Настройка логирования."""
@@ -19,6 +17,40 @@ def setup_logging(verbose: bool = False):
] ]
) )
def discover_benchmarks() -> Dict[str, type]:
"""
Динамическое обнаружение бенчмарков на основе папок в tests/.
Returns:
Словарь с именами бенчмарков и соответствующими классами Benchmark
"""
benchmarks = {}
tests_dir = "tests"
if not os.path.exists(tests_dir):
logging.warning(f"Directory {tests_dir} not found")
return benchmarks
for benchmark_name in os.listdir(tests_dir):
benchmark_path = os.path.join(tests_dir, benchmark_name)
if os.path.isdir(benchmark_path):
prompt_path = f"prompts/{benchmark_name}.txt"
if os.path.exists(prompt_path):
benchmarks[benchmark_name] = type(
benchmark_name.capitalize() + "Benchmark",
(Benchmark,),
{
"__init__": lambda self, name=benchmark_name, prompt=prompt_path, tests=benchmark_path: Benchmark.__init__(self, name, prompt, tests)
}
)
else:
logging.warning(f"Prompt file not found for benchmark: {benchmark_name}")
if not benchmarks:
logging.warning("No benchmarks found in tests/ directory")
return benchmarks
def run_benchmarks(ollama_client: OllamaClient, model_name: str, benchmarks: List[str], context_size: int = None) -> List[dict]: def run_benchmarks(ollama_client: OllamaClient, model_name: str, benchmarks: List[str], context_size: int = None) -> List[dict]:
""" """
Запуск выбранных бенчмарков. Запуск выбранных бенчмарков.
@@ -32,12 +64,7 @@ def run_benchmarks(ollama_client: OllamaClient, model_name: str, benchmarks: Lis
Returns: Returns:
Список результатов бенчмарков Список результатов бенчмарков
""" """
benchmark_classes = { benchmark_classes = discover_benchmarks()
'translation': TranslationBenchmark,
'summarization': SummarizationBenchmark,
'codegen': CodegenBenchmark,
'custom': CustomBenchmark
}
results = [] results = []
@@ -58,17 +85,36 @@ def main():
parser = argparse.ArgumentParser(description='LLM Benchmarking Tool') parser = argparse.ArgumentParser(description='LLM Benchmarking Tool')
parser.add_argument('-m', '--model', required=True, help='Название модели для тестирования') parser.add_argument('-m', '--model', required=True, help='Название модели для тестирования')
parser.add_argument('-u', '--ollama-url', default='http://localhost:11434', help='URL подключения к Ollama серверу') parser.add_argument('-u', '--ollama-url', default='http://localhost:11434', help='URL подключения к Ollama серверу')
parser.add_argument('-c', '--context-size', type=int, default=32000, help='Размер контекста для модели (по умолчанию 32000)') parser.add_argument('-c', '--context-size', type=int, help='Размер контекста для модели (по умолчанию 32000)')
parser.add_argument('-b', '--benchmarks', nargs='+', default=['translation', 'summarization', 'codegen'], parser.add_argument('-b', '--benchmarks', nargs='+', default=None,
help='Список бенчмарков для выполнения (translation, summarization, codegen, custom)') help='Список бенчмарков для выполнения (по умолчанию все доступные)')
parser.add_argument('-o', '--output', default='results', help='Директория для сохранения результатов') parser.add_argument('-o', '--output', default='results', help='Директория для сохранения результатов')
parser.add_argument('-v', '--verbose', action='store_true', help='Подробный режим вывода') parser.add_argument('-v', '--verbose', action='store_true', help='Подробный режим вывода')
args = parser.parse_args() args = parser.parse_args()
# Настройка логирования # Определяем доступные бенчмарки
available_benchmarks = discover_benchmarks()
if not available_benchmarks:
logging.error("No benchmarks found")
return 1
# Если не указаны бенчмарки, запускаем все доступные
if args.benchmarks is None:
args.benchmarks = list(available_benchmarks.keys())
else:
# Проверяем, что все указанные бенчмарки существуют
for benchmark_name in args.benchmarks:
if benchmark_name not in available_benchmarks:
logging.warning(f"Benchmark '{benchmark_name}' not found. Available: {list(available_benchmarks.keys())}")
# Настройка логирования (до любых логирующих вызовов)
setup_logging(args.verbose) setup_logging(args.verbose)
# Обновляем help сообщение с реальными доступными бенчмарками
available_list = ", ".join(sorted(available_benchmarks.keys()))
logging.info(f"Available benchmarks: {available_list}")
logging.info(f"Running benchmarks: {', '.join(args.benchmarks)}")
logging.info(f"Starting benchmarking for model: {args.model}") logging.info(f"Starting benchmarking for model: {args.model}")
logging.info(f"Ollama URL: {args.ollama_url}") logging.info(f"Ollama URL: {args.ollama_url}")
logging.info(f"Benchmarks to run: {', '.join(args.benchmarks)}") logging.info(f"Benchmarks to run: {', '.join(args.benchmarks)}")