diff --git a/scripts/convert_json_to_txt.py b/scripts/convert_json_to_txt.py index fa230e6..008b326 100644 --- a/scripts/convert_json_to_txt.py +++ b/scripts/convert_json_to_txt.py @@ -13,7 +13,7 @@ from pathlib import Path # Добавляем путь к исходникам, чтобы импортировать base 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: """Конвертирует все тесты в указанной директории.""" diff --git a/scripts/generate_summarization_from_mongo.py b/scripts/generate_summarization_from_mongo.py index 620f53f..2bd2a6b 100644 --- a/scripts/generate_summarization_from_mongo.py +++ b/scripts/generate_summarization_from_mongo.py @@ -19,7 +19,7 @@ from pymongo import MongoClient sys.path.insert(0, str(Path(__file__).parent.parent)) from src.constants import TEST_SEPARATOR -from src.models.ollama_client import OllamaClient +from ollama_client import OllamaClient def sanitize_filename(filename: str) -> str: """ diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index 80f691a..fcf2cd3 100755 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -20,7 +20,7 @@ from typing import Dict, List, Optional # Добавляем путь к исходникам, чтобы импортировать ollama_client 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 def generate_translation_test(ollama: OllamaClient, model: str) -> Dict[str, str]: diff --git a/src/benchmarks/base.py b/src/benchmark.py similarity index 99% rename from src/benchmarks/base.py rename to src/benchmark.py index f13c5f5..0ddd092 100644 --- a/src/benchmarks/base.py +++ b/src/benchmark.py @@ -4,7 +4,7 @@ import os import re from typing import Dict, Any, List, Optional from abc import ABC, abstractmethod -from models.ollama_client import OllamaClient +from ollama_client import OllamaClient from constants import TEST_SEPARATOR class Benchmark(ABC): @@ -159,7 +159,7 @@ class Benchmark(ABC): Returns: Результаты бенчмарка """ - from utils.scoring import get_all_scores + from scoring import get_all_scores test_cases = self.load_test_data() results = [] diff --git a/src/benchmarks/codegen.py b/src/benchmarks/codegen.py deleted file mode 100644 index 534db9c..0000000 --- a/src/benchmarks/codegen.py +++ /dev/null @@ -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") diff --git a/src/benchmarks/custom.py b/src/benchmarks/custom.py deleted file mode 100644 index 4e939e4..0000000 --- a/src/benchmarks/custom.py +++ /dev/null @@ -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") \ No newline at end of file diff --git a/src/benchmarks/summarization.py b/src/benchmarks/summarization.py deleted file mode 100644 index 14b1254..0000000 --- a/src/benchmarks/summarization.py +++ /dev/null @@ -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") diff --git a/src/benchmarks/translation.py b/src/benchmarks/translation.py deleted file mode 100644 index 67353d0..0000000 --- a/src/benchmarks/translation.py +++ /dev/null @@ -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") diff --git a/src/main.py b/src/main.py index cdcff7c..12698c2 100644 --- a/src/main.py +++ b/src/main.py @@ -1,12 +1,10 @@ import logging import argparse -from typing import List -from models.ollama_client import OllamaClient -from benchmarks.translation import TranslationBenchmark -from benchmarks.summarization import SummarizationBenchmark -from benchmarks.codegen import CodegenBenchmark -from benchmarks.custom import CustomBenchmark -from utils.report import ReportGenerator +import os +from typing import List, Dict +from ollama_client import OllamaClient +from benchmark import Benchmark +from report import ReportGenerator 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]: """ Запуск выбранных бенчмарков. @@ -32,12 +64,7 @@ def run_benchmarks(ollama_client: OllamaClient, model_name: str, benchmarks: Lis Returns: Список результатов бенчмарков """ - benchmark_classes = { - 'translation': TranslationBenchmark, - 'summarization': SummarizationBenchmark, - 'codegen': CodegenBenchmark, - 'custom': CustomBenchmark - } + benchmark_classes = discover_benchmarks() results = [] @@ -58,17 +85,36 @@ def main(): parser = argparse.ArgumentParser(description='LLM Benchmarking Tool') parser.add_argument('-m', '--model', required=True, help='Название модели для тестирования') 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('-b', '--benchmarks', nargs='+', default=['translation', 'summarization', 'codegen'], - help='Список бенчмарков для выполнения (translation, summarization, codegen, custom)') + parser.add_argument('-c', '--context-size', type=int, help='Размер контекста для модели (по умолчанию 32000)') + parser.add_argument('-b', '--benchmarks', nargs='+', default=None, + help='Список бенчмарков для выполнения (по умолчанию все доступные)') parser.add_argument('-o', '--output', default='results', help='Директория для сохранения результатов') parser.add_argument('-v', '--verbose', action='store_true', help='Подробный режим вывода') 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) + # Обновляем 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"Ollama URL: {args.ollama_url}") logging.info(f"Benchmarks to run: {', '.join(args.benchmarks)}") diff --git a/src/models/ollama_client.py b/src/ollama_client.py similarity index 100% rename from src/models/ollama_client.py rename to src/ollama_client.py diff --git a/src/utils/report.py b/src/report.py similarity index 100% rename from src/utils/report.py rename to src/report.py diff --git a/src/utils/scoring.py b/src/scoring.py similarity index 100% rename from src/utils/scoring.py rename to src/scoring.py