Upload src/interleavedeval_gpt4o.py with huggingface_hub
Browse files- src/interleavedeval_gpt4o.py +239 -0
src/interleavedeval_gpt4o.py
ADDED
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
+
import requests
|
3 |
+
import json
|
4 |
+
import pdb
|
5 |
+
import time
|
6 |
+
from tqdm import tqdm
|
7 |
+
import copy
|
8 |
+
import random
|
9 |
+
|
10 |
+
# ----------------------------------
|
11 |
+
# OpenAI API Key
|
12 |
+
API_KEY = "<your_openai_key"
|
13 |
+
|
14 |
+
IMAGE_TOKEN = "<image>"
|
15 |
+
|
16 |
+
MODEL_VERSION = "gpt-4o" # choose different openai model version
|
17 |
+
|
18 |
+
import argparse
|
19 |
+
parser = argparse.ArgumentParser(description="Input file")
|
20 |
+
|
21 |
+
parser.add_argument('--file_name', type=str, help='evaluation file name')
|
22 |
+
|
23 |
+
args = parser.parse_args()
|
24 |
+
|
25 |
+
# path to model's prediction file
|
26 |
+
input_path = f"<predition_dir>/{args.file_name}.json"
|
27 |
+
# path to evaluation results with GPT-4o
|
28 |
+
output_path = f"<eval_dir>/{args.file_name}_interleaved_eval.json"
|
29 |
+
|
30 |
+
|
31 |
+
with open(input_path, "r") as file:
|
32 |
+
data = json.load(file)
|
33 |
+
|
34 |
+
|
35 |
+
# Function to encode the image
|
36 |
+
def encode_image(image_path):
|
37 |
+
with open(image_path, "rb") as image_file:
|
38 |
+
return base64.b64encode(image_file.read()).decode('utf-8')
|
39 |
+
|
40 |
+
|
41 |
+
eval_instructions = {
|
42 |
+
"text_quality": "In this task, you need to evaluate the text quality of the given output . Text quality is how clear, coherent, and error-free the OUTPUT text is. Consider grammar, spelling, readability, coherence with context (i.e., task instructions and inputs), and whether it’s duplicate as input. This evaluation considers grammar, spelling, punctuation, readability, the logical flow of ideas, and you should substantially penalize duplication, i.e., the output text is severely duplicate with the instruction or input text. Provide your rating on a scale from 1 to 5 based on the criteria below: A rating of 1 indicates the text quality is extremely poor, characterized by frequent grammatical errors, numerous spelling mistakes, poor punctuation, very difficult readability, a lack of logical flow and coherence, and largely contains duplicated content from the input. A rating of 2 indicates somewhat poor text quality, with several grammatical errors, noticeable spelling mistakes, inconsistent punctuation, hard-to-read content, and inconsistent flow and coherence. A rating of 3 indicates somehow acceptable text quality, with occasional grammatical errors, few spelling mistakes, mostly correct punctuation, generally readable content that may require some effort, basic logical flow and coherence, and contains some duplicated content from the input. A rating of 4 indicates somewhat good text quality, with rare grammatical errors, very few spelling mistakes, correct punctuation, easy-to-read and understand content, and mostly logical flow and coherent structure. A rating of 5 indicates extremely good text quality, with no grammatical errors, no spelling mistakes, perfect punctuation, very easy-to-read and understand content, excellent logical flow and coherence, and do not contain duplicated content from the input.\n",
|
43 |
+
|
44 |
+
"perceptual_quality": "In this task, you need to evaluate the image quality of the images. Image quality measures the extent to which a generated image appears visually convincing, natural, and free from distortions or artifacts. This evaluation considers how accurately the image mimics reality without unnatural disruptions in its structure, colors, or composition. Provide your rating on a scale from 1 to 5 based on the criteria below: A rating of 1 indicates the image quality is extremely poor, characterized by significant visual issues such as heavy distortions, numerous artifacts, unnatural colors, and structural disruptions, making the image appear highly unrealistic and unconvincing. A rating of 2 indicates somewhat poor image quality, with noticeable visual issues including distortions, artifacts, and color inaccuracies, as well as some structural disruptions, leading to an image that appears somewhat unrealistic and unconvincing. A rating of 3 indicates somehow acceptable image quality, with occasional visual issues such as minor distortions, artifacts, and slight color inaccuracies, but generally maintaining a structure that mimics reality to an acceptable extent. A rating of 4 indicates somewhat good image quality, with rare visual issues, minimal distortions, few artifacts, and accurate colors, maintaining a mostly natural and convincing appearance with very few structural disruptions. A rating of 5 indicates extremely good image quality, with no visual issues, no distortions or artifacts, perfect color accuracy, and a completely natural and convincing appearance without any structural disruptions, accurately mimicking reality. \n",
|
45 |
+
|
46 |
+
"image_coherence": "In this task, you need to evaluate the image coherence of the input interleaved content that consists of both text and multiple images. Image coherence includes but not limit to the following perspectives: (1) Style coherence: Whether the selection of textures, color palette, lighting setups, brush techniques, or rendering styles can give the image a coherent look and feel. (2) Subject coherence: the consistency in subject’s representation includes maintaining recognizable physical attributes, clothing, and behavioral traits across various scenes. You should penalize for image duplication, where the output images are too similar/replicate with the input images, or within the output images themselves. Provide your rating in the scale from 1 to 5 based on the criteria below: A rating of 1 indicates the coherence is extremely poor, characterized by a complete lack of style coherence with mismatched textures, color palettes, lighting setups, and rendering styles, along with subject incoherence where physical attributes, clothing, and behavioral traits are inconsistent and unrecognizable across scenes. Output images are significantly duplicated with each other or with input images. A rating of 2 indicates somewhat poor coherence, with noticeable inconsistencies in style coherence, including textures, color palettes, lighting setups, and rendering styles, and subject coherence, where physical attributes, clothing, and behavioral traits are often inconsistent and difficult to recognize across scenes. A rating of 3 indicates somehow acceptable coherence, where there are occasional inconsistencies in style coherence, including textures, color palettes, lighting setups, and rendering styles, and subject coherence, where physical attributes, clothing, and behavioral traits are generally consistent but may have minor variations. Images are duplicated to some extent but acceptable. A rating of 4 indicates somewhat good coherence, with rare inconsistencies in style coherence, including textures, color palettes, lighting setups, and rendering styles, and subject coherence, where physical attributes, clothing, and behavioral traits are mostly consistent and recognizable across scenes. A rating of 5 indicates extremely good coherence, with perfect style coherence, including textures, color palettes, lighting setups, and rendering styles, and subject coherence, where physical attributes, clothing, and behavioral traits are consistently maintained and easily recognizable across all scenes. No image duplication. \n",
|
47 |
+
|
48 |
+
"text_image_coherence": "In this task, you need to evaluate the text-to-image coherence of the input interleaved content that consists of both text and multiple images. Text-to-image coherence refers to the alignment and harmonious integration between textual and visual elements. This coherence goes beyond mere semantic similarity, aiming to enhance the quality, coherence, and communicative effectiveness of the content. It encompasses how text and images align with each other, conveying a unified and cohesive narrative. You should perform the evaluation in a pairwise manner, i.e., consider each text-image pair one by one and accumulate the scores. Provide your rating on a scale from 1 to 5 based on the criteria below: A rating of 1 indicates the text-to-image coherence is extremely poor, with text and images showing significant misalignment and no meaningful connection, resulting in a disjointed and confusing narrative. A rating of 2 indicates somewhat poor coherence, with noticeable misalignment between text and images, where the connections are weak and the narrative is only partially cohesive. A rating of 3 indicates somehow acceptable coherence, with occasional misalignment between text and images, where the connections are generally clear but may have minor inconsistencies, leading to a mostly cohesive narrative. A rating of 4 indicates somewhat good coherence, with strong alignment between text and images, where the connections are clear and consistent, resulting in a cohesive and well-integrated narrative. A rating of 5 indicates extremely good coherence, with perfect alignment between text and images, where the connections are seamless and fully integrated, resulting in a highly cohesive and effective narrative. \n",
|
49 |
+
|
50 |
+
"helpfulness": "In this task, you need to evaluate the helpfulness aspect of the input interleaved content that consists of both text and multiple images. Helpfulness measures how well the output text and images follow the task instruction and provide complete information to achieve the task. Also, consider whether the outputs follow a reasonable logic flow. Provide your rating on a scale from 1 to 5 based on the criteria below: A rating of 1 indicates the helpfulness is extremely poor, with output text and images being totally not following the task instruction, lacking logical flow, and failing to provide necessary information, resulting in an incomplete and unhelpful content. A rating of 2 indicates somewhat poor helpfulness, with output text and images being partially follow the task instruction, showing inconsistent logical flow, and providing limited information, leading to a content that is somewhat incomplete and not very helpful. A rating of 3 indicates somehow acceptable helpfulness, with output text and images being generally follow the instruction, maintaining a reasonable logical flow, and providing a fair amount of necessary information. A rating of 4 indicates somewhat good helpfulness, with output text and images following the task instruction and a clear logical flow, and providing most of the necessary information, resulting in a content that is mostly complete and helpful. A rating of 5 indicates extremely good helpfulness, with output text and images accurately following the instruction, following a natural and logical flow, and providing all necessary information, resulting in a content that is complete and highly helpful. \n",
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
headers = {
|
56 |
+
"Content-Type": "application/json",
|
57 |
+
"Authorization": f"Bearer {API_KEY}"
|
58 |
+
}
|
59 |
+
|
60 |
+
# ---------------------------------
|
61 |
+
|
62 |
+
score_collection = {}
|
63 |
+
aspect_list = []
|
64 |
+
|
65 |
+
for k in eval_instructions.keys():
|
66 |
+
aspect_list.append(k)
|
67 |
+
score_collection[k] = 0
|
68 |
+
|
69 |
+
cnt = 0
|
70 |
+
rated_instances = []
|
71 |
+
|
72 |
+
def find_first_occurrence(s):
|
73 |
+
for index, char in enumerate(s):
|
74 |
+
if char in '12345':
|
75 |
+
return index, char
|
76 |
+
return -1, None
|
77 |
+
|
78 |
+
for instance in tqdm(data):
|
79 |
+
|
80 |
+
text_flag = True
|
81 |
+
image_flag = True
|
82 |
+
instance["eval_scores"] = {}
|
83 |
+
|
84 |
+
valid_aspects = copy.deepcopy(aspect_list)
|
85 |
+
removed_aspects = []
|
86 |
+
|
87 |
+
# process the context and prediction from the model output file
|
88 |
+
|
89 |
+
input_text = instance["input_text"] # the input instruction and (optionally) the context
|
90 |
+
num_input_images = input_text.count("<image>")
|
91 |
+
|
92 |
+
images = instance["image"]
|
93 |
+
input_images = images[:num_input_images]
|
94 |
+
output_images = images[num_input_images:]
|
95 |
+
if len(output_images) == 0:
|
96 |
+
image_flag = False
|
97 |
+
|
98 |
+
input_text = instance["input_text"]
|
99 |
+
output_text = instance["output_text"].replace("\n### Assistant:", "") # the prediction text. note that it must contain <image> special tokens and the amount needs to be the same with generated images
|
100 |
+
output_text = output_text.strip()
|
101 |
+
|
102 |
+
if len(output_text) == 0:
|
103 |
+
text_flag = False
|
104 |
+
|
105 |
+
if image_flag is False and text_flag is False:
|
106 |
+
removed_aspects = valid_aspects
|
107 |
+
valid_aspects = []
|
108 |
+
elif image_flag is False and text_flag is True:
|
109 |
+
valid_aspects = ["text_quality", "helpfulness"]
|
110 |
+
removed_aspects = ["perceptual_quality", "image_coherence", "text_image_coherence"]
|
111 |
+
elif image_flag is True and text_flag is False:
|
112 |
+
valid_aspects = ["perceptual_quality", "image_coherence", "helpfulness"]
|
113 |
+
removed_aspects = ["text_quality", "text_image_coherence"]
|
114 |
+
|
115 |
+
for rm_aspect in removed_aspects:
|
116 |
+
instance["eval_scores"][rm_aspect] = [0, "None. Empty output."]
|
117 |
+
score_collection[rm_aspect] += 0
|
118 |
+
|
119 |
+
input_image_conent = []
|
120 |
+
output_image_conent = []
|
121 |
+
if len(input_images) > 0:
|
122 |
+
for img_p in input_images:
|
123 |
+
enc = encode_image(img_p)
|
124 |
+
img_dict = {
|
125 |
+
"type": "image_url",
|
126 |
+
"image_url": {
|
127 |
+
"url": f"data:image/jpeg;base64,{enc}"
|
128 |
+
}
|
129 |
+
}
|
130 |
+
input_image_conent.append(img_dict)
|
131 |
+
if len(output_images) > 0:
|
132 |
+
for img_p in output_images:
|
133 |
+
enc = encode_image(img_p)
|
134 |
+
img_dict = {
|
135 |
+
"type": "image_url",
|
136 |
+
"image_url": {
|
137 |
+
"url": f"data:image/jpeg;base64,{enc}"
|
138 |
+
}
|
139 |
+
}
|
140 |
+
output_image_conent.append(img_dict)
|
141 |
+
|
142 |
+
for valid_asp in valid_aspects:
|
143 |
+
eval_content_list = []
|
144 |
+
if valid_asp == "text_quality":
|
145 |
+
content_input = f"Here is the task instruction and the input text (which you should NOT consider their quality in your evaluation): <INPUT> {input_text} <\INPUT>\n. Based on the instruction and the input, you need to evaluate the text quality of the: <OUTPUT> {output_text} <\OUTPUT>. Please make sure that your only loot at the text inside <OUTPUT> and <\OUTPUT>. You should only predict the numerical score. Also give a short explanation after your rating. Now give your numerical rating and evaluation: "
|
146 |
+
text_dict = {
|
147 |
+
"type": "text",
|
148 |
+
"text": content_input
|
149 |
+
}
|
150 |
+
eval_content_list = [text_dict]
|
151 |
+
elif valid_asp == "perceptual_quality":
|
152 |
+
content_input = f"Here are the images you need to evaluate. You should only predict the numerical score. Also give a short explanation after your rating. Now give your numerical rating and evaluation: "
|
153 |
+
text_dict = {
|
154 |
+
"type": "text",
|
155 |
+
"text": content_input
|
156 |
+
}
|
157 |
+
eval_content_list = [text_dict] + output_image_conent
|
158 |
+
elif valid_asp == "image_coherence":
|
159 |
+
content_input = f"Here is the task instruction and the input text and images (which you should NOT consider their quality in your evaluation): <INPUT> {input_text} <\INPUT>\n."
|
160 |
+
content_output = f"Based on the instruction and the input images, you need to evaluate the image coherence of the output images in the following. Please make sure that your only loot at the output images to rate whether they are coherent with input images without duplication. You should only predict the numerical score. Also give a short explanation after your rating. Now give your numerical rating and evaluation: "
|
161 |
+
text_dict_in = {
|
162 |
+
"type": "text",
|
163 |
+
"text": content_input
|
164 |
+
}
|
165 |
+
text_dict_out = {
|
166 |
+
"type": "text",
|
167 |
+
"text": content_output
|
168 |
+
}
|
169 |
+
eval_content_list = [text_dict_in] + input_image_conent + [text_dict_out] + output_image_conent
|
170 |
+
elif valid_asp == "text_image_coherence":
|
171 |
+
content_input = f"Here is the task instruction and the input text and images (which you should NOT consider their quality in your evaluation): <INPUT> {input_text} <\INPUT>\n."
|
172 |
+
content_output = f"Based on the instruction, you need to evaluate the coherence following output text {output_text} and images in a pairwise manner. Please make sure that your only loot at the output text and images to rate whether they are coherent. You should only predict the numerical score. Also give a short explanation after your rating. Now give your numerical rating and evaluation: "
|
173 |
+
text_dict_in = {
|
174 |
+
"type": "text",
|
175 |
+
"text": content_input
|
176 |
+
}
|
177 |
+
text_dict_out = {
|
178 |
+
"type": "text",
|
179 |
+
"text": content_output
|
180 |
+
}
|
181 |
+
eval_content_list = [text_dict_in] + [text_dict_out] + output_image_conent
|
182 |
+
elif valid_asp == "helpfulness":
|
183 |
+
content_input = f"Here is the task instruction and the input text and images (which you should NOT consider their quality in your evaluation): <INPUT> {input_text} <\INPUT>\n."
|
184 |
+
content_output = f"Based on the instruction and the input, you need to evaluate the helpfulness of the following text {output_text} and images. You should only predict the numerical score. Also give a short explanation after your rating. Now give your numerical rating and evaluation: "
|
185 |
+
text_dict_in = {
|
186 |
+
"type": "text",
|
187 |
+
"text": content_input
|
188 |
+
}
|
189 |
+
text_dict_out = {
|
190 |
+
"type": "text",
|
191 |
+
"text": content_output
|
192 |
+
}
|
193 |
+
eval_content_list = [text_dict_in] + input_image_conent + [text_dict_out] + output_image_conent
|
194 |
+
|
195 |
+
|
196 |
+
eval_instruct = eval_instructions[valid_asp]
|
197 |
+
try:
|
198 |
+
payload = {
|
199 |
+
"model": MODEL_VERSION,
|
200 |
+
"messages": [
|
201 |
+
{
|
202 |
+
"role": "system",
|
203 |
+
"content": eval_instruct
|
204 |
+
},
|
205 |
+
{
|
206 |
+
"role": "user",
|
207 |
+
"content": eval_content_list
|
208 |
+
}
|
209 |
+
],
|
210 |
+
"max_tokens": 300
|
211 |
+
}
|
212 |
+
|
213 |
+
response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
|
214 |
+
raw_eval = response.json()["choices"][0]["message"]["content"]
|
215 |
+
index, eval_score = find_first_occurrence(raw_eval)
|
216 |
+
eval_score = float(eval_score)
|
217 |
+
if eval_score == -1:
|
218 |
+
print("cannot detect score...")
|
219 |
+
continue
|
220 |
+
|
221 |
+
instance["eval_scores"][valid_asp] = [eval_score, raw_eval]
|
222 |
+
score_collection[valid_asp] += eval_score
|
223 |
+
|
224 |
+
except Exception as e:
|
225 |
+
print(f"An error occurred: {e}")
|
226 |
+
|
227 |
+
rated_instances.append(instance)
|
228 |
+
cnt += 1
|
229 |
+
|
230 |
+
|
231 |
+
with open(output_path, 'w') as file:
|
232 |
+
json.dump(rated_instances, file, indent=4)
|
233 |
+
|
234 |
+
|
235 |
+
for eval_aspect, score in score_collection.items():
|
236 |
+
avg_score = score / cnt
|
237 |
+
avg_score = round(avg_score, 2)
|
238 |
+
print(f"{eval_aspect}: ", avg_score)
|
239 |
+
|