sguertl's picture
Hide DeepSeek-R1 8B as option
6e63545 verified
import os
import streamlit as st
from openai import OpenAI
import base64
import json
import requests
import re
import pandas as pd
from huggingface_hub import InferenceClient
HF_MODEL_MISTRAL = "mistralai/Mistral-7B-Instruct-v0.3"
HF_MODEL_LLAMA = "meta-llama/Llama-3.3-70B-Instruct"
HF_MODEL_DEEPSEEK = "deepseek-ai/DeepSeek-R1-Distill-Llama-8B"
UML_PROMPTS_DOC_URL = os.environ['UML_PROMPTS_DOC_URL']
ERD_PROMPTS_DOC_URL = os.environ['ERD_PROMPTS_DOC_URL']
STEP1_SYSTEM_PROMPT = "STEP1 SYSPROMPT"
STEP1_USER_PROMPT = "STEP1 USERPROMPT"
STEP2_SYSTEM_PROMPT = "STEP2 SYSPROMPT"
STEP2_USER_PROMPT = "STEP2 USERPROMPT"
STEP3A_SYSTEM_PROMPT = "STEP3A SYSPROMPT"
STEP3A_USER_PROMPT = "STEP3A USERPROMPT"
STEP3B_SYSTEM_PROMPT = "STEP3B SYSPROMPT"
STEP3B_USER_PROMPT = "STEP3B USERPROMPT"
def fetch_prompts_from_google_doc(diagram_type="UML"):
if diagram_type == "UML":
response = requests.get(UML_PROMPTS_DOC_URL)
elif diagram_type == "ERD":
response = requests.get(ERD_PROMPTS_DOC_URL)
if response.status_code != 200:
raise Exception("Failed to fetch document")
text = response.text
prompts = {}
pattern = r"\{BEGIN (.*?)\}([\s\S]*?)\{END \1\}"
matches = re.findall(pattern, text)
for key, content in matches:
prompts[key.strip()] = content.strip()
return prompts
# Step 1: Extract PlantUML Code
def extract_plantuml_code(client_openai, uploaded_file, model_choice, prompts):
st.write("Model: ", model_choice)
encoded_image = base64.b64encode(uploaded_file.getvalue()).decode("utf-8")
response = client_openai.chat.completions.create(
model=model_choice,
messages=[
{
"role": "system",
"content": prompts[STEP1_SYSTEM_PROMPT],
},
{
"role": "user",
"content": [
{"type": "text", "text": prompts[STEP1_USER_PROMPT]},
{
"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{encoded_image}"},
},
],
},
],
temperature=0.2,
top_p=0.1,
max_tokens=4096,
)
return response.choices[0].message.content
# Step 2: Compare PlantUML Code
def compare_plantuml(client_openai, client_hf_mistral, client_hf_llama, client_hf_deepseek, plantuml_instructor, plantuml_student, model_choice, prompts, diagram_type="UML"):
st.write("Model: ", model_choice)
user_prompt=f"""
{prompts[STEP2_USER_PROMPT]}
**Instructor's {diagram_type} Diagram:**
{plantuml_instructor}
**Student's {diagram_type} Diagram:**
{plantuml_student}
"""
if model_choice in [HF_MODEL_MISTRAL]:
response = client_hf_mistral.chat_completion(
[
{
"role": "system",
"content": prompts[STEP2_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
elif model_choice in [HF_MODEL_LLAMA]:
response = client_hf_llama.chat_completion(
[
{
"role": "system",
"content": prompts[STEP2_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
elif model_choice in [HF_MODEL_DEEPSEEK]:
response = client_hf_deepseek.chat_completion(
[
{
"role": "system",
"content": prompts[STEP2_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
else:
response = client_openai.chat.completions.create(
model=model_choice,
messages=[
{
"role": "system",
"content": prompts[STEP2_SYSTEM_PROMPT],
},
{
"role": "user",
"content": user_prompt,
},
],
temperature=0.2,
top_p=0.1,
max_tokens=4096,
)
return response.choices[0].message.content
# Step 3A: Generate Student Feedback
def generate_student_feedback(client_openai, client_hf_mistral, client_hf_llama, client_hf_deepseek, differences, model_choice, prompts):
st.write("Model (Student Feedback):", model_choice)
user_prompt=f"""
{prompts[STEP3A_USER_PROMPT]}
{json.dumps(differences, indent=2)}
"""
if model_choice in [HF_MODEL_MISTRAL]:
response = client_hf_mistral.chat_completion(
[
{
"role": "system",
"content": prompts[STEP3A_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
elif model_choice in [HF_MODEL_LLAMA]:
response = client_hf_llama.chat_completion(
[
{
"role": "system",
"content": prompts[STEP3A_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
elif model_choice in [HF_MODEL_DEEPSEEK]:
response = client_hf_deepseek.chat_completion(
[
{
"role": "system",
"content": prompts[STEP2_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
else:
response = client_openai.chat.completions.create(
model=model_choice,
messages=[
{
"role": "system",
"content": prompts[STEP3A_SYSTEM_PROMPT],
},
{
"role": "user",
"content": user_prompt,
},
],
temperature=0.2,
top_p=0.1,
max_tokens=4096,
)
return response.choices[0].message.content
# Step 3B: Generate Educator Feedback
def generate_educator_feedback(client_openai, client_hf_mistral, client_hf_llama, client_hf_deepseek, differences, model_choice, prompts):
st.write("Model (Educator Feedback): ", model_choice)
user_prompt=f"""
{prompts[STEP3B_USER_PROMPT]}
{json.dumps(differences, indent=2)}
"""
if model_choice in [HF_MODEL_MISTRAL]:
response = client_hf_mistral.chat_completion(
[
{
"role": "system",
"content": prompts[STEP3B_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
elif model_choice in [HF_MODEL_LLAMA]:
response = client_hf_llama.chat_completion(
[
{
"role": "system",
"content": prompts[STEP3B_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
elif model_choice in [HF_MODEL_DEEPSEEK]:
response = client_hf_deepseek.chat_completion(
[
{
"role": "system",
"content": prompts[STEP2_SYSTEM_PROMPT],
},
{"role": "user", "content": user_prompt},
],
max_tokens=1024,
temperature=0.2,
)
return response["choices"][0]["message"]["content"]
else:
response = client_openai.chat.completions.create(
model=model_choice,
messages=[
{
"role": "system",
"content": prompts[STEP3B_SYSTEM_PROMPT],
},
{
"role": "user",
"content": user_prompt,
},
],
temperature=0.2,
top_p=0.1,
max_tokens=4096,
)
return response.choices[0].message.content
# Streamlit app layout
st.set_page_config(
page_title="LLM-based Analysis and Feedback of a UML or ER Diagram",
page_icon="πŸ“",
initial_sidebar_state="expanded",
)
st.title("LLM-based Analysis and Feedback of a UML or ERD Diagram")
st.write("The pipeline consists of three steps:")
st.write("1. Extract PlantUML code from the uploaded UML or ER diagrams using GPT-4o or GPT-4o Mini.")
st.write("2. Compare the extracted PlantUML code.")
st.write("3. Analyse the differences and present them in a structured format.")
diagram_type = st.selectbox("Select the diagram type", ["UML", "ERD"])
prompts = fetch_prompts_from_google_doc(diagram_type)
openai_api_key = st.text_input("OpenAI API key", type="password")
hf_api_key = st.text_input("Hugging Face API key", type="password")
if openai_api_key and hf_api_key:
client_openai = OpenAI(api_key=openai_api_key)
client_hf_mistral = InferenceClient(model=HF_MODEL_MISTRAL, token=hf_api_key)
client_hf_llama = InferenceClient(model=HF_MODEL_LLAMA, token=hf_api_key)
client_hf_deepseek = InferenceClient(model=HF_MODEL_DEEPSEEK, token=hf_api_key)
model_choice_step1 = st.selectbox("Select the model for Step 1", ["gpt-4o", "gpt-4o-mini"])
model_choice_step2 = st.selectbox("Select the model for Step 2", [HF_MODEL_MISTRAL, HF_MODEL_LLAMA, "gpt-4o", "gpt-4o-mini"])
model_choice_step3 = st.selectbox("Select the model for Step 3", [HF_MODEL_MISTRAL, HF_MODEL_LLAMA, "gpt-4o", "gpt-4o-mini"])
st.subheader("Step 1: PlantUML Code Extraction using GPT-4o or GPT-4o Mini")
col1, col2 = st.columns(2)
with col1:
uploaded_instructor_solution = st.file_uploader(
"Upload Instructor " + ("UML" if diagram_type == 'UML' else "ER") + " Diagram", type=["jpg", "jpeg", "png"]
)
with col2:
uploaded_student_solution = st.file_uploader(
"Upload Student " + ("UML" if diagram_type == 'UML' else "ER") + " Diagram", type=["jpg", "jpeg", "png"]
)
if (uploaded_instructor_solution is not None and uploaded_student_solution is not None):
try:
with st.spinner(
"Extracting PlantUML code from the uploaded " + ("UML" if diagram_type == 'UML' else "ER") + " diagrams..."
):
with col1:
st.image(
uploaded_instructor_solution,
caption="Uploaded Instructor " + ("UML" if diagram_type == 'UML' else "ER") + " Diagram",
use_container_width=True,
)
st.write("")
plantuml_instructor_solution = extract_plantuml_code(
client_openai, uploaded_instructor_solution, model_choice_step1, prompts
)
with col2:
st.write("")
st.image(
uploaded_student_solution,
caption="Uploaded Student " + ("UML" if diagram_type == 'UML' else "ER") + " Diagram",
use_container_width=True,
)
st.write("")
plantuml_student_solution = extract_plantuml_code(
client_openai, uploaded_student_solution, model_choice_step1, prompts
)
st.write("Extracted PlantUML Code")
col1, col2 = st.columns(2)
with col1:
st.text_area(
"PlantUML Code for Instructor Solution",
plantuml_instructor_solution,
height=600,
)
with col2:
st.text_area(
"PlantUML Code for Student Solution",
plantuml_student_solution,
height=600,
)
st.subheader("Step 2: " + ("UML" if diagram_type == 'UML' else "ER") + " Diagram Comparison")
with st.spinner("Comparing instructor and student " + ("UML" if diagram_type == 'UML' else "ER") + " diagrams..."):
differences = compare_plantuml(
client_openai,
client_hf_mistral,
client_hf_llama,
client_hf_deepseek,
plantuml_instructor_solution,
plantuml_student_solution,
model_choice_step2,
prompts,
diagram_type
)
with st.expander("View differences"):
for difference in differences.split("\n"):
st.write(difference)
st.subheader("Step 3: Structured Feedback")
with st.spinner("Preparing structured feedback..."):
student_feedback = generate_student_feedback(client_openai, client_hf_mistral, client_hf_llama, client_hf_deepseek, differences, model_choice_step3, prompts)
educator_feedback = generate_educator_feedback(client_openai, client_hf_mistral, client_hf_llama, client_hf_deepseek, differences, model_choice_step3, prompts)
col1, col2 = st.columns(2)
with col1:
st.write("Student Feedback")
st.markdown(f"{student_feedback}")
with col2:
st.write("Educator Feedback")
st.markdown(f"{educator_feedback}")
except Exception as e:
st.error(f"Error: {e}")
else:
if not openai_api_key:
st.error("Please provide a valid OpenAI API key.")
else:
st.error("Please provide a valid Hugging Face API key.")