-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrun_choice_iso.py
More file actions
196 lines (158 loc) · 6.44 KB
/
Copy pathrun_choice_iso.py
File metadata and controls
196 lines (158 loc) · 6.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import os
import argparse
import torch
import numpy as np
import pandas as pd
import torch.nn.functional as F
from utils import general_utils
from utils import data_utils
from utils import model_utils
def forward_pass(model, tokenizer, choices):
"""
Args:
- choices (list): list of strings, where each string is a prompt
Perform a single forward pass over a testcase
(i.e., a prompt with choices) and computes perplexities
for each choice.
"""
# Forward pass to get nll and convert to ppl
ppl = []
for choice_index, prompt in enumerate(choices):
with torch.no_grad():
prompt = tokenizer(prompt, return_tensors='pt').to("cuda")
if "token_type_ids" in prompt:
prompt.pop("token_type_ids")
output = model(
input_ids=prompt["input_ids"],
labels=prompt["input_ids"]
)
# logits of the prompt tokens
logits = output.logits
labels = prompt["input_ids"]
shift_logits = logits[..., :-1, :].contiguous()
shift_labels = labels[..., 1:].contiguous()
# Flatten the tokens
vocab_size = shift_logits.size(-1)
shift_logits = shift_logits.view(-1, vocab_size)
shift_labels = shift_labels.view(-1)
log_probs = F.log_softmax(shift_logits, dim=-1)
true_log_probs = log_probs.gather(dim=1, index=shift_labels.view(-1, 1)).squeeze()
# Cast to float32 and compute nll and ppl
true_log_probs = true_log_probs.float()
nll = -true_log_probs.mean()
ppl.append(np.exp(nll.item()))
return ppl
@general_utils.timer
def main(llm, abstracts_fpath):
"""
Args:
- llm (str): HF model name
- abstracts_fpath (str): path to the abstracts csv file
"""
np.random.seed(42)
# Load dataset
df = pd.read_csv(abstracts_fpath)
# Load prompt template
prompt_template = data_utils.read_prompt_template(llm)
# Load model, tokenizer
model, tokenizer = model_utils.load_model_and_tokenizer(llm)
PPL_A_and_B = []
true_labels = []
# To collect sentence's abstract index
# So later when eval accuracy, we produce
# a single accuracy per abstract over all sentences
if aggregate_within_sentence:
abstract_mask = []
for abstract_index, abstract in enumerate(df["combined_abstract"]):
if eval_isolated_sentences:
# Individual sentences from both abstracts
# where both abstracts are lists of sentences
# where the sentences have choices in them (background etc discarded)
original_collection, incorrect_collection = data_utils.extract_abstract_pair_isolated_sentences(abstract)
else:
raise NotImplementedError()
for original_abstract, incorrect_abstract in zip(original_collection, incorrect_collection):
# Depending on how many sentences each abstract has,
# we record the abstract index for each sentence.
if aggregate_within_sentence:
abstract_mask.append(abstract_index)
# Randomly shuffle to determine which abstract is A and which is B,
# keep a record of the correct choice, which is used to determine
# later if the model's choice is correct
if np.random.rand() > 0.5:
original_abstract, incorrect_abstract = incorrect_abstract, original_abstract
choice_true = "B"
else:
choice_true = "A"
# choices is [prompt_A, prompt_B]
# where each prompt is the question + one of the abstracts as option.
choices = data_utils.prepare_prompt_multiple_choice_harness(
original_abstract, incorrect_abstract, prompt_template,
)
print(
f"-"*70 + "\n",
f"*** Abstract index: {abstract_index} ***",
)
ppl = forward_pass(model, tokenizer, choices)
PPL_A_and_B.append(ppl)
true_labels.append(0 if choice_true == "A" else 1)
PPL_A_and_B = np.array(PPL_A_and_B)
true_labels = np.array(true_labels)
# Compute accuracy
tie_indices = []
pred_labels = np.ones(PPL_A_and_B.shape[0], dtype=np.int32)
for i, (ppl_A, ppl_B) in enumerate(PPL_A_and_B):
if ppl_A < ppl_B:
pred_labels[i] = 0
elif ppl_A > ppl_B:
pred_labels[i] = 1
else:
pred_labels[i] = -1
tie_indices.append(i)
print(f"Number of ties: {len(tie_indices)}")
# Accuracy after removing ties
acc = np.sum(pred_labels == true_labels) / (PPL_A_and_B.shape[0])
print(f"Accuracy: {acc}")
np.save(f"{results_dir}/PPL_A_and_B_iso.npy", PPL_A_and_B)
np.save(f"{results_dir}/labels_iso.npy", true_labels)
if aggregate_within_sentence:
np.save(f"{results_dir}/abstract_mask_iso.npy", abstract_mask)
if __name__ == "__main__":
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
parser = argparse.ArgumentParser()
parser.add_argument("--use_human_abstract", type=str, default="True")
if parser.parse_args().use_human_abstract == "True":
use_human_abstract = True
else:
use_human_abstract = False
eval_isolated_sentences = True
aggregate_within_sentence = True
llms = [
"meta-llama/Llama-2-7b-hf",
"meta-llama/Llama-2-13b-hf",
"meta-llama/Llama-2-70b-hf",
"tiiuae/falcon-40b",
"tiiuae/falcon-40b-instruct",
"meta-llama/Llama-2-7b-chat-hf",
"meta-llama/Llama-2-13b-chat-hf",
"meta-llama/Llama-2-70b-chat-hf",
"facebook/galactica-6.7b",
"facebook/galactica-30b",
"facebook/galactica-120b",
"mistralai/Mistral-7B-v0.1",
"mistralai/Mistral-7B-Instruct-v0.1",
"tiiuae/falcon-180B",
"tiiuae/falcon-180B-chat"
]
for llm in llms:
if use_human_abstract:
type_of_abstract = 'human_abstracts'
abstracts_fpath = "testcases/BrainBench_Human_v0.1.csv"
else:
type_of_abstract = 'llm_abstracts'
abstracts_fpath = "testcases/BrainBench_GPT-4_v0.1.csv"
results_dir = f"model_results/{llm.replace('/', '--')}/{type_of_abstract}"
if not os.path.exists(results_dir):
os.makedirs(results_dir)
main(llm, abstracts_fpath)