| """Evaluate fine-tuned model on standard LLM benchmarks. |
| |
| This script runs as a Hugging Face Job to evaluate the model on standard |
| benchmarks (MMLU, HellaSwag, ARC, etc.) using lm-evaluation-harness. |
| """ |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import json |
| import os |
| import subprocess |
| from datetime import datetime |
| from pathlib import Path |
| from huggingface_hub import HfApi |
|
|
| def run_benchmarks(model_id: str, output_dir: str, use_adapter: bool = False, base_model: str = None): |
| """Run standard benchmarks using lm-eval.""" |
| |
| tasks = [ |
| "mmlu", |
| "hellaswag", |
| "arc_challenge", |
| "truthfulqa_mc2", |
| "gsm8k", |
| "winogrande", |
| ] |
|
|
| |
| cmd = [ |
| "lm_eval", |
| "--model", "hf", |
| "--tasks", ",".join(tasks), |
| "--device", "cuda:0", |
| "--batch_size", "8", |
| "--output_path", output_dir, |
| "--log_samples" |
| ] |
|
|
| |
| if use_adapter and base_model: |
| model_args = f"pretrained={base_model},peft={model_id},dtype=float16" |
| else: |
| model_args = f"pretrained={model_id},dtype=float16" |
|
|
| cmd.extend(["--model_args", model_args]) |
|
|
| print(f"\nRunning benchmarks on: {model_id}") |
| print(f"Tasks: {', '.join(tasks)}") |
| print(f"Output: {output_dir}\n") |
| print("Command:", " ".join(cmd), "\n") |
|
|
| |
| try: |
| result = subprocess.run(cmd, check=True, capture_output=True, text=True) |
| print(result.stdout) |
| if result.stderr: |
| print("STDERR:", result.stderr) |
| return True |
| except subprocess.CalledProcessError as e: |
| print(f"✗ Benchmark failed: {e}") |
| print("STDOUT:", e.stdout) |
| print("STDERR:", e.stderr) |
| return False |
|
|
| def extract_results(results_dir: Path) -> dict: |
| """Extract results from lm-eval output.""" |
| results_file = results_dir / "results.json" |
|
|
| if not results_file.exists(): |
| print(f"⚠️ Results file not found: {results_file}") |
| return {} |
|
|
| with open(results_file, 'r') as f: |
| data = json.load(f) |
|
|
| |
| results = data.get("results", {}) |
| summary = {} |
|
|
| for task, metrics in results.items(): |
| |
| if "acc,none" in metrics: |
| summary[task] = metrics["acc,none"] |
| elif "acc_norm,none" in metrics: |
| summary[task] = metrics["acc_norm,none"] |
| elif "exact_match,none" in metrics: |
| summary[task] = metrics["exact_match,none"] |
| else: |
| |
| summary[task] = list(metrics.values())[0] if metrics else 0 |
|
|
| return summary |
|
|
| def main(): |
| """Run standard benchmark evaluation.""" |
| print("=" * 70) |
| print("NATO Doctrine Model - Standard LLM Benchmarks") |
| print("=" * 70) |
|
|
| |
| adapter_model = "AndreasThinks/mistral-7b-nato-doctrine" |
| base_model = "mistralai/Mistral-7B-Instruct-v0.3" |
|
|
| |
| results_dir = Path("benchmark_results") |
| results_dir.mkdir(exist_ok=True) |
|
|
| base_output = results_dir / "base_model" |
| ft_output = results_dir / "finetuned_model" |
|
|
| |
| print("\n[1/2] Running benchmarks on BASE model...") |
| print("=" * 70) |
| base_success = run_benchmarks( |
| model_id=base_model, |
| output_dir=str(base_output), |
| use_adapter=False |
| ) |
|
|
| |
| print("\n[2/2] Running benchmarks on FINE-TUNED model...") |
| print("=" * 70) |
| ft_success = run_benchmarks( |
| model_id=adapter_model, |
| output_dir=str(ft_output), |
| use_adapter=True, |
| base_model=base_model |
| ) |
|
|
| |
| if base_success and ft_success: |
| print("\n" + "=" * 70) |
| print("BENCHMARK COMPARISON") |
| print("=" * 70) |
|
|
| base_results = extract_results(base_output) |
| ft_results = extract_results(ft_output) |
|
|
| print(f"\n{'Benchmark':<20} {'Base':<12} {'Fine-tuned':<12} {'Change':<12} {'Status'}") |
| print("-" * 70) |
|
|
| comparison = {} |
| for task in base_results: |
| if task in ft_results: |
| base_score = base_results[task] * 100 |
| ft_score = ft_results[task] * 100 |
| delta = ft_score - base_score |
| delta_pct = (delta / base_score * 100) if base_score > 0 else 0 |
|
|
| |
| if abs(delta_pct) < 5: |
| status = "✅" |
| elif abs(delta_pct) < 15: |
| status = "⚠️" |
| else: |
| status = "❌" |
|
|
| print(f"{task:<20} {base_score:>10.2f}% {ft_score:>11.2f}% {delta_pct:>+10.1f}% {status}") |
|
|
| comparison[task] = { |
| "base_score": round(base_score, 2), |
| "finetuned_score": round(ft_score, 2), |
| "delta": round(delta, 2), |
| "delta_percent": round(delta_pct, 2) |
| } |
|
|
| print("\n" + "=" * 70) |
| print("Legend: ✅ <5% change | ⚠️ 5-15% change | ❌ >15% change") |
| print("=" * 70) |
|
|
| |
| comparison_data = { |
| "model": adapter_model, |
| "base_model": base_model, |
| "evaluation_date": datetime.now().isoformat(), |
| "benchmarks": comparison, |
| "base_results": base_results, |
| "finetuned_results": ft_results |
| } |
|
|
| comparison_file = results_dir / "benchmark_comparison.json" |
| with open(comparison_file, 'w') as f: |
| json.dump(comparison_data, f, indent=2) |
|
|
| print(f"\nComparison saved to: {comparison_file}") |
|
|
| |
| token = os.environ.get("HF_TOKEN") |
| if token: |
| print("\nUploading results to Hub...") |
| try: |
| api = HfApi(token=token) |
| api.upload_file( |
| path_or_fileobj=str(comparison_file), |
| path_in_repo=f"results/standard_benchmarks_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json", |
| repo_id=adapter_model, |
| repo_type="model" |
| ) |
| print("✅ Results uploaded to model repository") |
| except Exception as e: |
| print(f"⚠️ Could not upload results: {e}") |
|
|
| print("\n✅ Standard benchmark evaluation complete!") |
|
|
| if __name__ == "__main__": |
| main() |
|
|