hendrycks_test.py 4.59 KB
Newer Older
Andy Zou's avatar
Andy Zou committed
1
import csv
Jonathan Tow's avatar
Jonathan Tow committed
2
3
import random
from lm_eval.base import MultipleChoiceTask
Andy Zou's avatar
Andy Zou committed
4
from ..utils import sh
Jonathan Tow's avatar
Jonathan Tow committed
5
6
7
8
9
10
11
12
13
14
15
from pathlib import Path

SUBJECTS = ['abstract_algebra', 'anatomy', 'astronomy', 'business_ethics', 'clinical_knowledge', 'college_biology',
            'college_chemistry', 'college_computer_science', 'college_mathematics', 'college_medicine', 'college_physics',
            'computer_security', 'conceptual_physics', 'econometrics', 'electrical_engineering', 'elementary_mathematics',
            'formal_logic', 'global_facts', 'high_school_biology', 'high_school_chemistry', 'high_school_computer_science',
            'high_school_european_history', 'high_school_geography', 'high_school_government_and_politics', 'high_school_macroeconomics',
            'high_school_mathematics', 'high_school_microeconomics', 'high_school_physics', 'high_school_psychology', 'high_school_statistics',
            'high_school_us_history', 'high_school_world_history', 'human_aging', 'human_sexuality', 'international_law', 'jurisprudence',
            'logical_fallacies', 'machine_learning', 'management', 'marketing', 'medical_genetics', 'miscellaneous', 'moral_disputes',
            'moral_scenarios', 'nutrition', 'philosophy', 'prehistory', 'professional_accounting', 'professional_law', 'professional_medicine',
Andy Zou's avatar
Andy Zou committed
16
17
18
19
20
21
            'professional_psychology', 'public_relations', 'security_studies', 'sociology', 'us_foreign_policy', 'virology', 'world_religions']


def create_all_tasks():
    """Creates a dictionary of tasks from a list of subjects
    :return: {task_name: task}
Andy Zou's avatar
Andy Zou committed
22
        e.g. {hendrycksTest-abstract_algebra: Task, hendrycksTest-anatomy: Task}
Andy Zou's avatar
Andy Zou committed
23
24
    """
    return {
Andy Zou's avatar
Andy Zou committed
25
        f"hendrycksTest-{sub}": create_task(sub) for sub in SUBJECTS
Andy Zou's avatar
Andy Zou committed
26
27
    }

Jonathan Tow's avatar
Jonathan Tow committed
28

Andy Zou's avatar
Andy Zou committed
29
30
31
32
33
34
def create_task(subject):
    class HendrycksTest(GeneralHendrycksTest):
        def __init__(self):
            super().__init__(subject)
    return HendrycksTest

Jonathan Tow's avatar
Jonathan Tow committed
35

Andy Zou's avatar
Andy Zou committed
36
class GeneralHendrycksTest(MultipleChoiceTask):
Leo Gao's avatar
Leo Gao committed
37
    VERSION = 0
Jonathan Tow's avatar
Jonathan Tow committed
38
    DATASET_PATH = Path("data/hendrycksTest/")
Andy Zou's avatar
Andy Zou committed
39
40
41
42
43
44

    def __init__(self, subject):
        self.subject = subject
        super().__init__()

    def download(self):
Jonathan Tow's avatar
Jonathan Tow committed
45
        if not self.DATASET_PATH.exists():
Andy Zou's avatar
Andy Zou committed
46
47
            sh("""
                mkdir -p data
Leo Gao's avatar
Leo Gao committed
48
                wget -c https://people.eecs.berkeley.edu/~hendrycks/data.tar -P data/
Andy Zou's avatar
minor  
Andy Zou committed
49
50
51
                tar -xf data/data.tar -C data/
                rm data/data.tar
                mv data/data data/hendrycksTest
Andy Zou's avatar
Andy Zou committed
52
53
54
                """)

    def has_training_docs(self):
Andy Zou's avatar
Andy Zou committed
55
        return True
Andy Zou's avatar
Andy Zou committed
56
57

    def has_validation_docs(self):
58
        return True
Andy Zou's avatar
Andy Zou committed
59
60
61
62

    def has_test_docs(self):
        return True

Jonathan Tow's avatar
Jonathan Tow committed
63
    def _convert_standard(self, doc):
64
65
66
        def format_example(doc, choices):
            """
                Question: <prompt>
67
                Choices:
68
69
70
71
72
73
                A. <choice1>
                B. <choice2>
                C. <choice3>
                D. <choice4>
                Answer:
            """
74
            prompt = "Question: " + doc[0] + "\nChoices:\n"
75
76
            prompt += "".join([f"{choices[j]}. {doc[j+1]}\n" for j in range(4)])
            prompt += "Answer:"
77
78
            return prompt
        choices = ['A', 'B', 'C', 'D']
Jonathan Tow's avatar
Jonathan Tow committed
79
        return {
80
            "query": format_example(doc, choices),
Jonathan Tow's avatar
Jonathan Tow committed
81
            "choices": doc[1:5],
82
            "gold": choices.index(doc[5])
Jonathan Tow's avatar
Jonathan Tow committed
83
        }
Andy Zou's avatar
Andy Zou committed
84

Jonathan Tow's avatar
Jonathan Tow committed
85
    def _load_docs(self, filename):
Andy Zou's avatar
Andy Zou committed
86
        reader = csv.reader(open(filename, 'r'), quotechar='"', delimiter=',')
Jonathan Tow's avatar
Jonathan Tow committed
87
        return (self._convert_standard(doc) for doc in reader)
Andy Zou's avatar
Andy Zou committed
88
89

    def training_docs(self):
90
91
92
93
94
        docs = []
        for train_dir in ["auxiliary_train", "dev"]:
            for f in (self.DATASET_PATH / train_dir).iterdir():
                docs.extend(self._load_docs(f))
        return docs
Andy Zou's avatar
Andy Zou committed
95
96

    def validation_docs(self):
97
98
        filename = self.DATASET_PATH / "val" / f"{self.subject}_val.csv"
        return self._load_docs(filename)
Andy Zou's avatar
Andy Zou committed
99
100

    def test_docs(self):
Jonathan Tow's avatar
Jonathan Tow committed
101
        filename = self.DATASET_PATH / "test" / f"{self.subject}_test.csv"
Andy Zou's avatar
Andy Zou committed
102
        return self._load_docs(filename)
Andy Zou's avatar
Andy Zou committed
103

104
    def fewshot_examples(self, k, rnd):
Leo Gao's avatar
Leo Gao committed
105
106
        # fewshot_examples is not just sampling from train_docs because dev is 
        # in the same distribution as val/test but auxiliary_train isn't
107

Jonathan Tow's avatar
Jonathan Tow committed
108
        filename = self.DATASET_PATH / "dev" / f"{self.subject}_dev.csv"
109
110
111
112
113

        if self._fewshot_docs is None:
            self._fewshot_docs = list(self._load_docs(filename))

        return rnd.sample(list(self._fewshot_docs), k)
Andy Zou's avatar
Andy Zou committed
114
115
116

    def fewshot_description(self):
        subject = self.subject.replace("_", " ")
Jonathan Tow's avatar
Jonathan Tow committed
117
118
119
120
        return f"The following are multiple choice questions (with answers) about {subject}."

    def doc_to_text(self, doc):
        return doc["query"]