GraphGen / graphgen /evaluate.py
chenzihong-gavin
init
acd7cf4
"""Evaluate the quality of the generated text using various metrics"""
import os
import json
import argparse
import pandas as pd
from dotenv import load_dotenv
from .models import LengthEvaluator, MTLDEvaluator, RewardEvaluator, TextPair, UniEvaluator
from .utils import logger, set_logger
sys_path = os.path.abspath(os.path.dirname(__file__))
set_logger(os.path.join(sys_path, "cache", "logs", "evaluate.log"))
load_dotenv()
def evaluate_length(corpus, tokenizer_name):
length_evaluator = LengthEvaluator(
tokenizer_name=tokenizer_name
)
logger.info("Length evaluator loaded")
scores = length_evaluator.get_average_score(corpus)
logger.info("Length scores: %s", scores)
return scores
def evaluate_mtld(corpus):
mtld_evaluator = MTLDEvaluator()
logger.info("MTLD evaluator loaded")
scores = mtld_evaluator.get_average_score(corpus)
logger.info("MTLD scores: %s", scores)
min_max_scores = mtld_evaluator.get_min_max_score(corpus)
logger.info("MTLD min max scores: %s", min_max_scores)
return scores, min_max_scores
def evaluate_reward(corpus, reward_model_names):
scores = []
for reward_name in reward_model_names:
reward_evaluator = RewardEvaluator(
reward_name=reward_name
)
logger.info("Loaded reward model: %s", reward_name)
average_score = reward_evaluator.get_average_score(corpus)
logger.info("%s scores: %s", reward_name, average_score)
min_max_scores = reward_evaluator.get_min_max_score(corpus)
logger.info("%s min max scores: %s", reward_name, min_max_scores)
scores.append({
'reward_name': reward_name.split('/')[-1],
'score': average_score,
'min_max_scores': min_max_scores
})
del reward_evaluator
clean_gpu_cache()
return scores
def evaluate_uni(corpus, uni_model_name):
uni_evaluator = UniEvaluator(
model_name=uni_model_name
)
logger.info("Uni evaluator loaded with model %s", uni_model_name)
uni_scores = uni_evaluator.get_average_score(corpus)
for key, value in uni_scores.items():
logger.info("Uni %s scores: %s", key, value)
min_max_scores = uni_evaluator.get_min_max_score(corpus)
for key, value in min_max_scores.items():
logger.info("Uni %s min max scores: %s", key, value)
del uni_evaluator
clean_gpu_cache()
return (uni_scores['naturalness'], uni_scores['coherence'], uni_scores['understandability'],
min_max_scores['naturalness'], min_max_scores['coherence'], min_max_scores['understandability'])
def clean_gpu_cache():
import torch
if torch.cuda.is_available():
torch.cuda.empty_cache()
if __name__ == '__main__':
import torch.multiprocessing as mp
parser = argparse.ArgumentParser()
parser.add_argument('--folder', type=str, default='cache/data', help='folder to load data')
parser.add_argument('--output', type=str, default='cache/output', help='path to save output')
parser.add_argument('--tokenizer', type=str, default='cl100k_base', help='tokenizer name')
parser.add_argument('--reward', type=str, default='OpenAssistant/reward-model-deberta-v3-large-v2',
help='Comma-separated list of reward models')
parser.add_argument('--uni', type=str, default='MingZhong/unieval-sum', help='uni model name')
args = parser.parse_args()
if not os.path.exists(args.folder):
raise ValueError(f"Folder {args.folder} does not exist")
if not os.path.exists(args.output):
os.makedirs(args.output)
reward_models = args.reward.split(',')
results = []
logger.info("Data loaded from %s", args.folder)
mp.set_start_method('spawn')
for file in os.listdir(args.folder):
if file.endswith('.json'):
logger.info("Processing %s", file)
with open(os.path.join(args.folder, file), 'r', encoding='utf-8') as f:
data = json.load(f)
data = [TextPair(
question=data[key]['question'],
answer=data[key]['answer']
) for key in data]
length_scores = evaluate_length(data, args.tokenizer)
mtld_scores, min_max_mtld_scores = evaluate_mtld(data)
reward_scores = evaluate_reward(data, reward_models)
uni_naturalness_scores, uni_coherence_scores, uni_understandability_scores, \
min_max_uni_naturalness_scores, min_max_uni_coherence_scores, min_max_uni_understandability_scores \
= evaluate_uni(data, args.uni)
result = {
'file': file,
'number': len(data),
'length': length_scores,
'mtld': mtld_scores,
'mtld_min_max': min_max_mtld_scores,
'uni_naturalness': uni_naturalness_scores,
'uni_coherence': uni_coherence_scores,
'uni_understandability': uni_understandability_scores,
'uni_naturalness_min_max': min_max_uni_naturalness_scores,
'uni_coherence_min_max': min_max_uni_coherence_scores,
'uni_understandability_min_max': min_max_uni_understandability_scores
}
for reward_score in reward_scores:
result[reward_score['reward_name']] = reward_score['score']
result[f"{reward_score['reward_name']}_min_max"] = reward_score['min_max_scores']
results.append(result)
results = pd.DataFrame(results)
results.to_csv(os.path.join(args.output, 'evaluation.csv'), index=False)