mirror of
https://github.com/SakanaAI/doc-to-lora.git
synced 2026-07-26 17:11:02 +02:00
fix eval (logging + reformat csv)
This commit is contained in:
parent
76d2b154fd
commit
83ffaefd9b
2 changed files with 105 additions and 48 deletions
|
|
@ -161,6 +161,9 @@ def _extract_model_info(eval_trainer) -> tuple[str, bool]:
|
||||||
if "/" in model_name:
|
if "/" in model_name:
|
||||||
model_name = model_name.split("/")[-1]
|
model_name = model_name.split("/")[-1]
|
||||||
|
|
||||||
|
if getattr(eval_trainer.args, "run_name", None):
|
||||||
|
model_name += f"_{eval_trainer.args.run_name}"
|
||||||
|
|
||||||
return model_name, is_hypernet
|
return model_name, is_hypernet
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -215,7 +218,7 @@ def _sort_length_groups(length_groups: set[str]) -> list[str]:
|
||||||
return (1, 0, 0) # Put "overall" after numerical ranges
|
return (1, 0, 0) # Put "overall" after numerical ranges
|
||||||
try:
|
try:
|
||||||
# Parse "low-high" format
|
# Parse "low-high" format
|
||||||
low, high = map(int, length_group.split("-"))
|
low, high = map(float, length_group.split("-"))
|
||||||
return (0, low, high)
|
return (0, low, high)
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
return (2, 0, 0) # Put any malformed strings last
|
return (2, 0, 0) # Put any malformed strings last
|
||||||
|
|
@ -232,8 +235,8 @@ def create_metrics_csv(
|
||||||
csv_suffix: str = "",
|
csv_suffix: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Create a human-readable CSV file from evaluation metrics with hierarchical columns.
|
Create a CSV file with columns: model_name, group_len, tasks, num_samples, and all available metrics.
|
||||||
One row per model with columns structured as task_metric_lengthgroup.
|
One row per model-length-task combination.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
metrics_dict: Dictionary containing evaluation metrics for each dataset/split
|
metrics_dict: Dictionary containing evaluation metrics for each dataset/split
|
||||||
|
|
@ -249,48 +252,94 @@ def create_metrics_csv(
|
||||||
all_metrics, all_length_groups, all_splits = _parse_metrics_for_csv(metrics_dict)
|
all_metrics, all_length_groups, all_splits = _parse_metrics_for_csv(metrics_dict)
|
||||||
|
|
||||||
# Sort for consistent ordering
|
# Sort for consistent ordering
|
||||||
all_metrics = sorted(all_metrics)
|
|
||||||
all_length_groups = _sort_length_groups(all_length_groups)
|
all_length_groups = _sort_length_groups(all_length_groups)
|
||||||
all_splits = sorted(all_splits)
|
all_splits = sorted(all_splits)
|
||||||
|
|
||||||
# Create single row with hierarchical columns
|
# Create rows for each model-length-task combination
|
||||||
row_data = {
|
rows = []
|
||||||
"model": model_name,
|
|
||||||
"model_type": "hypernet" if is_hypernet_model else "base",
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create hierarchical column structure: task_metric_lengthgroup
|
|
||||||
for task in all_splits:
|
for task in all_splits:
|
||||||
metrics = metrics_dict[task]
|
metrics = metrics_dict[task]
|
||||||
is_qa_task = any(qa_task in task for qa_task in CLOSED_QA_DATASETS)
|
|
||||||
|
|
||||||
for metric in all_metrics:
|
for length_group in all_length_groups:
|
||||||
# Skip inappropriate metrics for the task type
|
# Initialize row with basic info
|
||||||
if is_qa_task and ("rougeL" in metric):
|
row = {
|
||||||
continue
|
"model_name": model_name,
|
||||||
if not is_qa_task and ("qa_f1" in metric):
|
"group_len": length_group,
|
||||||
continue
|
"tasks": task,
|
||||||
|
"num_samples": 0,
|
||||||
|
}
|
||||||
|
|
||||||
for length_group in all_length_groups:
|
# Look for all metrics for this task and length group
|
||||||
if length_group == "overall":
|
if length_group == "overall":
|
||||||
metric_key = f"{task}_{metric}"
|
# Look for overall metrics (no length suffix)
|
||||||
column_name = f"{task}_{metric}_overall"
|
for metric_key in metrics:
|
||||||
else:
|
if not metric_key.startswith(f"{task}_"):
|
||||||
metric_key = f"{task}_{metric}_len_{length_group}"
|
continue
|
||||||
column_name = f"{task}_{metric}_{length_group}"
|
|
||||||
|
|
||||||
value = metrics.get(metric_key, "N/A")
|
# Skip length-specific metrics
|
||||||
# Handle None values and convert to string
|
if "_len_" in metric_key:
|
||||||
if value is None or value == "None":
|
continue
|
||||||
value = "N/A"
|
|
||||||
elif isinstance(value, (int, float)):
|
|
||||||
value = f"{value:.4f}"
|
|
||||||
|
|
||||||
row_data[column_name] = value
|
# Extract metric name after task prefix
|
||||||
|
metric_name = metric_key[len(task) + 1 :]
|
||||||
|
if metric_name in [
|
||||||
|
"samples_per_second",
|
||||||
|
"steps_per_second",
|
||||||
|
"model_preparation_time",
|
||||||
|
"runtime",
|
||||||
|
]:
|
||||||
|
# Skip timing and performance metrics
|
||||||
|
continue
|
||||||
|
|
||||||
# Create DataFrame with single row
|
# Handle num_samples specially
|
||||||
if len(row_data) > 2: # More than just model and model_type
|
if metric_name.startswith("num_samples_"):
|
||||||
df = pd.DataFrame([row_data])
|
row["num_samples"] = metrics[metric_key]
|
||||||
|
else:
|
||||||
|
# Add all other metrics as columns
|
||||||
|
row[metric_name] = metrics[metric_key]
|
||||||
|
else:
|
||||||
|
# Look for length-specific metrics
|
||||||
|
for metric_key in metrics:
|
||||||
|
if not metric_key.startswith(f"{task}_"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Only process metrics for this specific length group
|
||||||
|
if f"_len_{length_group}" not in metric_key:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Extract metric name (remove task prefix and length suffix)
|
||||||
|
metric_part = metric_key[len(task) + 1 :]
|
||||||
|
metric_name = metric_part.replace(f"_len_{length_group}", "")
|
||||||
|
if metric_name in [
|
||||||
|
"samples_per_second",
|
||||||
|
"steps_per_second",
|
||||||
|
"model_preparation_time",
|
||||||
|
"runtime",
|
||||||
|
]:
|
||||||
|
# Skip timing and performance metrics
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Handle num_samples specially
|
||||||
|
if metric_name.startswith("num_samples_"):
|
||||||
|
row["num_samples"] = metrics[metric_key]
|
||||||
|
else:
|
||||||
|
# Add all other metrics as columns
|
||||||
|
row[metric_name] = metrics[metric_key]
|
||||||
|
|
||||||
|
# Fill missing metrics with N/A for consistent columns
|
||||||
|
for metric in all_metrics:
|
||||||
|
if metric not in row and not metric.startswith("num_samples"):
|
||||||
|
row[metric] = "N/A"
|
||||||
|
|
||||||
|
rows.append(row)
|
||||||
|
|
||||||
|
# Create DataFrame
|
||||||
|
if rows:
|
||||||
|
df = pd.DataFrame(rows)
|
||||||
|
|
||||||
|
# Sort by tasks, then by length group
|
||||||
|
df = df.sort_values(["tasks"]).reset_index(drop=True)
|
||||||
|
|
||||||
# Construct filename
|
# Construct filename
|
||||||
csv_filename = "evaluation_results"
|
csv_filename = "evaluation_results"
|
||||||
|
|
@ -594,6 +643,15 @@ def evaluate(
|
||||||
datasets[ds_name] = _get_tokenized_dataset(ds_name, split)
|
datasets[ds_name] = _get_tokenized_dataset(ds_name, split)
|
||||||
print(datasets)
|
print(datasets)
|
||||||
|
|
||||||
|
# truncating num val samples
|
||||||
|
max_eval_samples_per_ds = getattr(args, "max_val_samples_per_ds", 0)
|
||||||
|
if split == "validation" and max_eval_samples_per_ds > 0:
|
||||||
|
print(f"Truncating all validation ds to {max_eval_samples_per_ds} samples")
|
||||||
|
for ds_name, ds in datasets.items():
|
||||||
|
val_indices = np.random.permutation(len(ds))[:max_eval_samples_per_ds]
|
||||||
|
datasets[ds_name] = ds.select(val_indices)
|
||||||
|
print(datasets)
|
||||||
|
|
||||||
gen_kwargs = dict(
|
gen_kwargs = dict(
|
||||||
do_sample=False,
|
do_sample=False,
|
||||||
max_new_tokens=256,
|
max_new_tokens=256,
|
||||||
|
|
|
||||||
|
|
@ -100,12 +100,11 @@ class Evaluator:
|
||||||
else:
|
else:
|
||||||
self.accum_metrics[key] += v
|
self.accum_metrics[key] += v
|
||||||
for start, end in LENGTH_BINS:
|
for start, end in LENGTH_BINS:
|
||||||
key = f"{k}_len_{start}_{end}"
|
key_w_len = f"{key}_len_{start}-{end}"
|
||||||
if key not in self.accum_metrics:
|
if key_w_len not in self.accum_metrics:
|
||||||
# add key here so that it shows up in the output
|
# add key here so that it shows up in the output
|
||||||
self.accum_metrics[key] = [0]
|
self.accum_metrics[key_w_len] = [0]
|
||||||
self.count[key] = [0]
|
self.count[key_w_len] = [0]
|
||||||
|
|
||||||
# split samples into length groups, calculate metric for each group
|
# split samples into length groups, calculate metric for each group
|
||||||
if lengths is not None:
|
if lengths is not None:
|
||||||
for start, end in LENGTH_BINS:
|
for start, end in LENGTH_BINS:
|
||||||
|
|
@ -129,11 +128,11 @@ class Evaluator:
|
||||||
)
|
)
|
||||||
for k, v in metric.items():
|
for k, v in metric.items():
|
||||||
if k.startswith("n_"):
|
if k.startswith("n_"):
|
||||||
key = f"{k[2:]}_len_{start}_{end}"
|
key = f"{k[2:]}_len_{start}-{end}"
|
||||||
self.count[f"{k[2:]}_len_{start}_{end}"].append(v)
|
self.count[key].append(v)
|
||||||
else:
|
else:
|
||||||
key = f"{k}_len_{start}_{end}"
|
key = f"{k}_len_{start}-{end}"
|
||||||
self.accum_metrics[f"{k}_len_{start}_{end}"] += v
|
self.accum_metrics[key] += v
|
||||||
|
|
||||||
def compute(self):
|
def compute(self):
|
||||||
# Get result across entire eval set
|
# Get result across entire eval set
|
||||||
|
|
@ -141,11 +140,11 @@ class Evaluator:
|
||||||
k: np.sum(v) / np.sum(self.count[k]) if np.sum(v) != 0 else "None"
|
k: np.sum(v) / np.sum(self.count[k]) if np.sum(v) != 0 else "None"
|
||||||
for k, v in self.accum_metrics.items()
|
for k, v in self.accum_metrics.items()
|
||||||
}
|
}
|
||||||
for k, v in self.count.items():
|
# for k, v in self.count.items():
|
||||||
if "_len_" in k:
|
# if "_len_" in k:
|
||||||
result[k.replace("_len_", "_num_samples_len_")] = sum(v)
|
# result[k.replace("_len_", "_num_samples_len_")] = sum(v)
|
||||||
else:
|
# else:
|
||||||
result[k + "_num_samples"] = sum(v)
|
# result[k + "_num_samples"] = sum(v)
|
||||||
# Reset batch statistics
|
# Reset batch statistics
|
||||||
self.reset()
|
self.reset()
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue