-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathtunable_classifier.py
More file actions
129 lines (99 loc) · 3.71 KB
/
Copy pathtunable_classifier.py
File metadata and controls
129 lines (99 loc) · 3.71 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
'''
Created on Feb 6, 2024
@author: immanueltrummer
'''
import argparse
import openai
import pandas as pd
import time
client = openai.OpenAI()
def create_single_text_prompt(text, label):
""" Create prompt for classifying one single text.
Args:
text: text to classify.
label: correct class label (empty if unavailable).
Returns:
Prompt for text classification.
"""
task = 'Is the sentiment positive or negative?'
answer_format = 'Answer ("pos"/"neg")'
return f'{text}\n{task}\n{answer_format}:{label}'
def create_prompt(text, samples):
""" Generates prompt for sentiment classification.
Args:
text: classify this text.
samples: integrate these samples into prompt.
Returns:
Input for LLM.
"""
parts = []
for _, row in samples.iterrows():
sample_text = row['text']
sample_label = row['sentiment']
prompt = create_single_text_prompt(sample_text, sample_label)
parts += [prompt]
prompt = create_single_text_prompt(text, '')
parts += [prompt]
return '\n'.join(parts)
def call_llm(prompt, model, max_tokens, out_tokens):
""" Query large language model and return answer.
Args:
prompt: input prompt for language model.
model: name of OpenAI model to choose.
max_tokens: maximal output length in tokens.
out_tokens: prioritize these token IDs in output.
Returns:
Answer by language model and total number of tokens.
"""
optional_parameters = {}
if max_tokens:
optional_parameters['max_tokens'] = max_tokens
if out_tokens:
logit_bias = {int(tid):100 for tid in out_tokens.split(',')}
optional_parameters['logit_bias'] = logit_bias
for nr_retries in range(1, 4):
try:
response = client.chat.completions.create(
model=model,
messages=[
{'role':'user', 'content':prompt}
],
**optional_parameters, temperature=0
)
answer = response.choices[0].message.content
nr_tokens = response.usage.total_tokens
return answer, nr_tokens
except Exception as e:
print(f'Exception: {e}')
time.sleep(nr_retries * 2)
raise Exception('Cannot query OpenAI model!')
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('file_path', type=str, help='Path to input file')
parser.add_argument('model', type=str, help='Name of OpenAI model')
parser.add_argument('max_tokens', type=int, help='Maximal output size')
parser.add_argument('out_tokens', type=str, help='Tokens to prioritize')
parser.add_argument('nr_samples', type=int, help='Number of samples')
parser.add_argument('sample_path', type=str, help='Path to samples')
args = parser.parse_args()
df = pd.read_csv(args.file_path)
samples = pd.DataFrame()
if args.nr_samples:
samples = pd.read_csv(args.sample_path)
samples = samples[:args.nr_samples]
nr_correct = 0
nr_tokens = 0
for _, row in df.iterrows():
text = row['text']
prompt = create_prompt(text, samples)
label, current_tokens = call_llm(
prompt, args.model,
args.max_tokens,
args.out_tokens)
ground_truth = row['sentiment']
if label == ground_truth:
nr_correct += 1
nr_tokens += current_tokens
print(f'Label: {label}; Ground truth: {ground_truth}')
print(f'Number of correct labels:\t{nr_correct}')
print(f'Number of tokens used :\t{nr_tokens}')