refactor: switch eval datasets to HuggingFace source
- Replace GitHub/berkeley direct downloads with HF datasets API - MMLU: cais/mmlu (all config), map val->validation split, write per-subject CSV - HumanEval: openai/openai_humaneval - IFEval: google/IFEval - Enables HF_ENDPOINT mirror for faster downloads in CN
This commit is contained in:
@@ -20,6 +20,7 @@ from typing import Dict, Iterator, List, Optional, Sequence, Tuple
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import torch
|
import torch
|
||||||
import tqdm
|
import tqdm
|
||||||
|
from datasets import load_dataset
|
||||||
|
|
||||||
from astrai.inference import InferenceEngine
|
from astrai.inference import InferenceEngine
|
||||||
from astrai.model import AutoModel
|
from astrai.model import AutoModel
|
||||||
@@ -29,9 +30,7 @@ from astrai.tokenize import AutoTokenizer
|
|||||||
# Config
|
# Config
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
HUMANEVAL_URL = (
|
HUMANEVAL_HF_DATASET = "openai/openai_humaneval"
|
||||||
"https://github.com/openai/human-eval/raw/master/data/HumanEval.jsonl.gz"
|
|
||||||
)
|
|
||||||
|
|
||||||
STOP_SEQUENCES = [
|
STOP_SEQUENCES = [
|
||||||
"\nclass ",
|
"\nclass ",
|
||||||
@@ -64,21 +63,16 @@ class EvalConfig:
|
|||||||
problem_indices: Optional[List[int]] = None
|
problem_indices: Optional[List[int]] = None
|
||||||
|
|
||||||
|
|
||||||
def download(url: str, path: str):
|
def download(path: str):
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
return
|
return
|
||||||
import gzip
|
|
||||||
import urllib.request
|
|
||||||
|
|
||||||
os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
|
os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
|
||||||
print(f"Downloading {url} ...")
|
print(f"Downloading HumanEval from HuggingFace ({HUMANEVAL_HF_DATASET}) ...")
|
||||||
tmp = path + ".tmp"
|
ds = load_dataset(HUMANEVAL_HF_DATASET, split="test")
|
||||||
urllib.request.urlretrieve(url, tmp)
|
with open(path, "w", encoding="utf-8") as f:
|
||||||
with gzip.open(tmp, "rb") as f_in:
|
for item in ds:
|
||||||
with open(path, "wb") as f_out:
|
f.write(json.dumps(item, ensure_ascii=False) + "\n")
|
||||||
f_out.write(f_in.read())
|
print(f" saved {len(ds)} problems to {path}")
|
||||||
os.remove(tmp)
|
|
||||||
print(f" saved to {path}")
|
|
||||||
|
|
||||||
|
|
||||||
def load_jsonl(path: str) -> List[dict]:
|
def load_jsonl(path: str) -> List[dict]:
|
||||||
@@ -318,7 +312,7 @@ def run_pipeline(cfg: EvalConfig) -> Dict:
|
|||||||
with open(cfg.test_only, encoding="utf-8") as f:
|
with open(cfg.test_only, encoding="utf-8") as f:
|
||||||
generated = json.load(f)
|
generated = json.load(f)
|
||||||
else:
|
else:
|
||||||
download(HUMANEVAL_URL, cfg.data_path)
|
download(cfg.data_path)
|
||||||
|
|
||||||
problems = load_jsonl(cfg.data_path)
|
problems = load_jsonl(cfg.data_path)
|
||||||
if cfg.problem_indices:
|
if cfg.problem_indices:
|
||||||
|
|||||||
@@ -14,21 +14,17 @@ import argparse
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import urllib.request
|
|
||||||
from typing import Callable, Dict, List, Optional
|
from typing import Callable, Dict, List, Optional
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
import tqdm
|
import tqdm
|
||||||
|
from datasets import load_dataset
|
||||||
|
|
||||||
from astrai.inference import InferenceEngine
|
from astrai.inference import InferenceEngine
|
||||||
from astrai.model import AutoModel
|
from astrai.model import AutoModel
|
||||||
from astrai.tokenize import AutoTokenizer
|
from astrai.tokenize import AutoTokenizer
|
||||||
|
|
||||||
IFEVAL_URL = (
|
IFEVAL_HF_DATASET = "google/IFEval"
|
||||||
"https://raw.githubusercontent.com/google-research/"
|
|
||||||
"google-research/master/instruction_following_eval/data/input_data.jsonl"
|
|
||||||
)
|
|
||||||
|
|
||||||
CONSTRAINT_VERIFIERS: Dict[str, Callable[[str, dict], bool]] = {}
|
CONSTRAINT_VERIFIERS: Dict[str, Callable[[str, dict], bool]] = {}
|
||||||
|
|
||||||
|
|
||||||
@@ -310,15 +306,12 @@ def download_ifeval(data_path: str):
|
|||||||
if os.path.exists(data_path):
|
if os.path.exists(data_path):
|
||||||
return
|
return
|
||||||
os.makedirs(os.path.dirname(data_path) or ".", exist_ok=True)
|
os.makedirs(os.path.dirname(data_path) or ".", exist_ok=True)
|
||||||
print(f"Downloading IFEval from {IFEVAL_URL} ...")
|
print(f"Downloading IFEval from HuggingFace ({IFEVAL_HF_DATASET}) ...")
|
||||||
tmp = data_path + ".tmp"
|
ds = load_dataset(IFEVAL_HF_DATASET, split="train")
|
||||||
urllib.request.urlretrieve(IFEVAL_URL, tmp)
|
with open(data_path, "w", encoding="utf-8") as f:
|
||||||
with open(tmp, "rb") as f_in:
|
for item in ds:
|
||||||
content = f_in.read()
|
f.write(json.dumps(item, ensure_ascii=False) + "\n")
|
||||||
with open(data_path, "wb") as f_out:
|
print(f" saved {len(ds)} items to {data_path}")
|
||||||
f_out.write(content)
|
|
||||||
os.remove(tmp)
|
|
||||||
print(f" saved to {data_path}")
|
|
||||||
|
|
||||||
|
|
||||||
def load_problems(data_path: str) -> List[dict]:
|
def load_problems(data_path: str) -> List[dict]:
|
||||||
|
|||||||
@@ -4,18 +4,17 @@ import argparse
|
|||||||
import csv
|
import csv
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
from collections import defaultdict
|
||||||
import tarfile
|
|
||||||
|
|
||||||
import requests
|
|
||||||
import torch
|
import torch
|
||||||
import torch.nn.functional as F
|
import torch.nn.functional as F
|
||||||
import tqdm
|
import tqdm
|
||||||
|
from datasets import load_dataset
|
||||||
|
|
||||||
from astrai.model import AutoModel
|
from astrai.model import AutoModel
|
||||||
from astrai.tokenize import AutoTokenizer
|
from astrai.tokenize import AutoTokenizer
|
||||||
|
|
||||||
MMLU_URL = "https://people.eecs.berkeley.edu/~hendrycks/data.tar"
|
MMLU_HF_DATASET = "cais/mmlu"
|
||||||
MMLU_SUBJECTS = [
|
MMLU_SUBJECTS = [
|
||||||
"abstract_algebra",
|
"abstract_algebra",
|
||||||
"anatomy",
|
"anatomy",
|
||||||
@@ -77,38 +76,40 @@ MMLU_SUBJECTS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def _download_and_extract(url: str, data_dir: str):
|
def _write_subject_csv(data_dir: str, split: str, subject: str, rows: list[dict]):
|
||||||
tar_path = os.path.join(data_dir, "data.tar")
|
split_dir = os.path.join(data_dir, split)
|
||||||
os.makedirs(data_dir, exist_ok=True)
|
os.makedirs(split_dir, exist_ok=True)
|
||||||
print(f"Downloading MMLU data from {url}...")
|
path = os.path.join(split_dir, f"{subject}_{split}.csv")
|
||||||
resp = requests.get(url, stream=True, timeout=300)
|
with open(path, "w", encoding="utf-8", newline="") as f:
|
||||||
resp.raise_for_status()
|
writer = csv.writer(f)
|
||||||
total = int(resp.headers.get("content-length", 0))
|
for row in rows:
|
||||||
with tqdm.tqdm(total=total, unit="B", unit_scale=True, desc=" Download") as bar:
|
writer.writerow(row)
|
||||||
with open(tar_path, "wb") as f:
|
|
||||||
for chunk in resp.iter_content(chunk_size=8192):
|
|
||||||
f.write(chunk)
|
|
||||||
bar.update(len(chunk))
|
|
||||||
print("Extracting...")
|
|
||||||
with tarfile.open(tar_path, "r") as tf:
|
|
||||||
tf.extractall(data_dir)
|
|
||||||
os.remove(tar_path)
|
|
||||||
|
|
||||||
|
|
||||||
def download_mmlu(data_dir: str):
|
def download_mmlu(data_dir: str):
|
||||||
_download_and_extract(MMLU_URL, data_dir)
|
print(f"Downloading MMLU from HuggingFace ({MMLU_HF_DATASET}) ...")
|
||||||
src = os.path.join(data_dir, "data")
|
letters = ("A", "B", "C", "D")
|
||||||
if os.path.exists(src):
|
split_map = {"dev": "dev", "val": "validation", "test": "test"}
|
||||||
for item in os.listdir(src):
|
for local_split, hf_split in split_map.items():
|
||||||
src_item = os.path.join(src, item)
|
ds = load_dataset(MMLU_HF_DATASET, "all", split=hf_split)
|
||||||
dst_item = os.path.join(data_dir, item)
|
grouped: dict[str, list[dict]] = defaultdict(list)
|
||||||
if os.path.exists(dst_item):
|
for item in tqdm.tqdm(ds, desc=f" {local_split}", leave=False):
|
||||||
if os.path.isdir(dst_item):
|
subject = item["subject"]
|
||||||
shutil.rmtree(dst_item)
|
choices = item["choices"]
|
||||||
else:
|
ans_letter = letters[item["answer"]]
|
||||||
os.remove(dst_item)
|
grouped[subject].append(
|
||||||
os.rename(src_item, dst_item)
|
[
|
||||||
os.rmdir(src)
|
item["question"],
|
||||||
|
f"A){choices[0]}",
|
||||||
|
f"B){choices[1]}",
|
||||||
|
f"C){choices[2]}",
|
||||||
|
f"D){choices[3]}",
|
||||||
|
ans_letter,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for subject, rows in grouped.items():
|
||||||
|
_write_subject_csv(data_dir, local_split, subject, rows)
|
||||||
|
print(f" {local_split}: {len(ds)} items, {len(grouped)} subjects")
|
||||||
print(f"MMLU data saved to {data_dir}")
|
print(f"MMLU data saved to {data_dir}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user