# import the relevant packages import os import csv import requests import time import base64 import pandas as pd import numpy as np import openai from openai import OpenAI import gradio as gr import huggingface_hub from datasets import load_dataset api_key = os.environ.get("API_TOKEN") headers = { 'Authorization': 'Bearer ' + api_key, 'Content-Type': 'application/json' } dataset = load_dataset('csv', data_files='https://huggingface.co/datasets/petcoblue/simulation_data/resolve/main/user_agents.csv') user_agents = dataset['train'].to_pandas() user_agents = user_agents.iloc[:,1:] user_batch = user_agents[:10] def encode_image(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode('utf-8') def create_description(row): description = ( f"Imagine that you are currently {int(row['age'])} years old. You have {int(row['num_pets'])} pets " f"and spend an average of ${row['avg_spending']} on Petco purchases. " f"Your engagement with Petco marketing has a score of {int(row['engagement_score'])}. " f"You have an income level of {int(row['income_level'])} and " f"regularly buy items from Petco every {int(row['purchase_regularity'])} months. " f"It has been {int(row['time_since_last_purchase'])} days since your last purchase with Petco." ) return description question = ( "Here are two images of Petco marketing emails:\n" "- Image 0 is shown first.\n" "- Image 1 is shown second.\n" "Which email are you more likely to click through? Just answer with 0 for the first image or 1 for the second image.\n" "Then, provide a list of up to five one-word characteristics of the email you chose that made you want to click through it. Separate each characteristic with a comma.\n\n" "Example response:\n" "1; Characteristics: Appealing, Sale, Bright, Simple, Exclusive\n" ) def query_agent(description, question, image0, image1): base64_image0 = encode_image(image0) base64_image1 = encode_image(image1) payload = { "model": "gpt-4-vision-preview", "messages": [ {"role": "system", "content": description}, { "role": "user", "content": [ {"type": "text", "text": question}, {"type": "image", "image_url": f"data:image/jpeg;base64,{base64_image0}"}, {"type": "image", "image_url": f"data:image/jpeg;base64,{base64_image1}"} ] } ], "max_tokens": 300, "logprobs": True, "top_logprobs": 1 } for attempt in range(3): try: response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload) if response.status_code == 200: data = response.json() preference = data['choices'][0]['message']['content'] top_logprobs = data['choices'][0]['logprobs']['content'][0]['top_logprobs'] return preference, top_logprobs else: print(f"HTTP Error {response.status_code} on attempt {attempt + 1}") except requests.exceptions.RequestException as e: print(f"Request failed on attempt {attempt + 1}: {e}") time.sleep(1) else: print(f"Failed to analyze {image0} and {image1} after 3 attempts.") return None, None def simulate(image0, image1): upload_file(image0) upload_file(image1) preferences = [] reasons = [] probs = [] for index, user_agent in user_batch.iterrows(): description = create_description(user_agent) preference, top_logprobs = query_agent(description, question, image0, image1) prob = np.round(np.exp(top_logprobs[0]['logprob']) * 100, 2) split = preference.split("; Characteristics: ") if len(split) == 2: choice, reasoning = split[0], split[1] else: print(preference) choice, reasoning = split[0], "" preferences.append(0 if "0" in choice else 1) reasons.append(reasoning) probs.append(prob) avg_preference = sum(preferences) / len(preferences) avg_prob = sum(probs) / len(preferences) return avg_preference subtitle = "Upload two images of emails and see which is generally preferred by Petco customers!" from pathlib import Path def upload_file(filepath): name = Path(filepath).name return [gr.UploadButton(visible=False), gr.DownloadButton(label=f"{name}", value=filepath, visible=True)] # with gr.Blocks() as demo: # gr.Markdown("First upload a file and and then you'll be able download it (but only once!)") # with gr.Row(): # u = gr.UploadButton("Upload a file", file_count="single") # d = gr.DownloadButton("Download the file", visible=False) # u.upload(upload_file, u, [u, d]) # d.click(download_file, None, [u, d]) demo = gr.Interface(fn=simulate, inputs=[gr.UploadButton("Click to Upload Email 0", file_types=["image"], file_count="single"), gr.UploadButton("Click to Upload Email 1", file_types=["image"], file_count="single")], outputs="text", title="Pairwise Simulation of Petco Email Preference", description=subtitle ) if __name__ == "__main__": demo.launch()