163 lines
7.8 KiB
Python
163 lines
7.8 KiB
Python
import logging
|
||
import os
|
||
from typing import Dict, Any, List
|
||
from datetime import datetime
|
||
from py_markdown_table.markdown_table import markdown_table
|
||
|
||
class ReportGenerator:
|
||
"""Генератор отчетов в формате Markdown."""
|
||
|
||
def __init__(self):
|
||
self.logger = logging.getLogger(__name__)
|
||
|
||
def generate_benchmark_report(self, results: Dict[str, Any], output_dir: str = "results", model_name: str = None) -> str:
|
||
"""
|
||
Генерация отчета для одного бенчмарка.
|
||
|
||
Args:
|
||
results: Результаты бенчмарка
|
||
output_dir: Директория для сохранения отчета
|
||
model_name: Имя модели (для структурирования результатов)
|
||
|
||
Returns:
|
||
Путь к сгенерированному файлу
|
||
"""
|
||
if model_name:
|
||
model_dir = os.path.join(output_dir, model_name)
|
||
os.makedirs(model_dir, exist_ok=True)
|
||
output_dir = model_dir
|
||
|
||
os.makedirs(output_dir, exist_ok=True)
|
||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||
filename = f"{results['benchmark_name']}_{timestamp}.md"
|
||
file_path = os.path.join(output_dir, filename)
|
||
|
||
with open(file_path, 'w', encoding='utf-8') as f:
|
||
f.write(f"# Отчет бенчмарка: {results['benchmark_name']}\n\n")
|
||
f.write(f"**Дата:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||
f.write(f"**Общее количество тестов:** {results['total_tests']}\n\n")
|
||
f.write(f"**Успешно выполнено:** {results['successful_tests']}\n\n")
|
||
|
||
# Таблица с результатами
|
||
table_data = [
|
||
{
|
||
"Тест": "Тест",
|
||
"Скор": "Скор",
|
||
"Время (с)": "Время (с)",
|
||
"Промпт": "Промпт",
|
||
"Ожидаемый": "Ожидаемый",
|
||
"Ответ модели": "Ответ модели"
|
||
}
|
||
]
|
||
|
||
for result in results['results']:
|
||
if 'error' in result:
|
||
table_data.append({
|
||
"Тест": result['test_case'],
|
||
"Скор": "Ошибка",
|
||
"Время (с)": "-",
|
||
"Промпт": result['prompt'][:50] + "..." if len(result['prompt']) > 50 else result['prompt'],
|
||
"Ожидаемый": result['expected'][:50] + "..." if len(result['expected']) > 50 else result['expected'],
|
||
"Ответ модели": result['error']
|
||
})
|
||
else:
|
||
table_data.append({
|
||
"Тест": result['test_case'],
|
||
"Скор": str(result['score']),
|
||
"Время (с)": f"{result['latency']:.2f}",
|
||
"Промпт": result['prompt'][:50] + "..." if len(result['prompt']) > 50 else result['prompt'],
|
||
"Ожидаемый": result['expected'][:50] + "..." if len(result['expected']) > 50 else result['expected'],
|
||
"Ответ модели": result['model_response'][:50] + "..." if len(result['model_response']) > 50 else result['model_response']
|
||
})
|
||
|
||
f.write("## Результаты тестов\n\n")
|
||
f.write(markdown_table(table_data).get_markdown())
|
||
f.write("\n\n")
|
||
|
||
# Статистика
|
||
successful = [r for r in results['results'] if 'score' in r]
|
||
if successful:
|
||
avg_score = sum(r['score'] for r in successful) / len(successful)
|
||
avg_latency = sum(r['latency'] for r in successful) / len(successful)
|
||
|
||
f.write("## Статистика\n\n")
|
||
f.write(f"- **Средний скор:** {avg_score:.3f}\n")
|
||
f.write(f"- **Среднее время ответа:** {avg_latency:.3f} секунд\n")
|
||
|
||
self.logger.info(f"Report saved to {file_path}")
|
||
return file_path
|
||
|
||
def generate_summary_report(self, all_results: List[Dict[str, Any]], output_dir: str = "results", model_name: str = None) -> str:
|
||
"""
|
||
Генерация сводного отчета по всем бенчмаркам.
|
||
|
||
Args:
|
||
all_results: Список результатов всех бенчмарков
|
||
output_dir: Директория для сохранения отчета
|
||
model_name: Имя модели (для структурирования результатов)
|
||
|
||
Returns:
|
||
Путь к сгенерированному файлу
|
||
"""
|
||
if model_name:
|
||
model_dir = os.path.join(output_dir, model_name)
|
||
os.makedirs(model_dir, exist_ok=True)
|
||
output_dir = model_dir
|
||
|
||
os.makedirs(output_dir, exist_ok=True)
|
||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||
filename = f"summary_{timestamp}.md"
|
||
file_path = os.path.join(output_dir, filename)
|
||
|
||
with open(file_path, 'w', encoding='utf-8') as f:
|
||
f.write("# Сводный отчет по всем бенчмаркам\n\n")
|
||
f.write(f"**Дата:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||
if model_name:
|
||
f.write(f"**Модель:** {model_name}\n\n")
|
||
|
||
# Таблица с общими результатами
|
||
table_data = [
|
||
{
|
||
"Бенчмарк": "Бенчмарк",
|
||
"Тестов": "Тестов",
|
||
"Успешно": "Успешно",
|
||
"Средний скор": "Средний скор",
|
||
"Среднее время": "Среднее время"
|
||
}
|
||
]
|
||
|
||
for result in all_results:
|
||
successful = [r for r in result['results'] if 'score' in r]
|
||
avg_score = sum(r['score'] for r in successful) / len(successful) if successful else 0
|
||
avg_latency = sum(r['latency'] for r in successful) / len(successful) if successful else 0
|
||
|
||
table_data.append({
|
||
"Бенчмарк": result['benchmark_name'],
|
||
"Тестов": str(result['total_tests']),
|
||
"Успешно": str(result['successful_tests']),
|
||
"Средний скор": f"{avg_score:.3f}" if successful else "0",
|
||
"Среднее время": f"{avg_latency:.3f}" if successful else "0"
|
||
})
|
||
|
||
f.write("## Общие результаты\n\n")
|
||
f.write(markdown_table(table_data).get_markdown())
|
||
f.write("\n\n")
|
||
|
||
# Подробности по каждому бенчмарку
|
||
f.write("## Подробности\n\n")
|
||
for result in all_results:
|
||
f.write(f"### {result['benchmark_name']}\n\n")
|
||
f.write(f"- **Тестов:** {result['total_tests']}\n")
|
||
f.write(f"- **Успешно:** {result['successful_tests']}\n")
|
||
|
||
successful = [r for r in result['results'] if 'score' in r]
|
||
if successful:
|
||
avg_score = sum(r['score'] for r in successful) / len(successful)
|
||
avg_latency = sum(r['latency'] for r in successful) / len(successful)
|
||
f.write(f"- **Средний скор:** {avg_score:.3f}\n")
|
||
f.write(f"- **Среднее время:** {avg_latency:.3f} секунд\n")
|
||
f.write("\n")
|
||
|
||
self.logger.info(f"Summary report saved to {file_path}")
|
||
return file_path
|