ai-benchmark/src/utils/report.py

163 lines
7.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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