Mohinikathro commited on
Commit
50b5b5d
·
verified ·
1 Parent(s): ebe6196

changes made to app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -131
app.py CHANGED
@@ -1,54 +1,36 @@
1
- import json
2
  import gradio as gr
3
- from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
4
  import torch
5
  import os
6
- import sys
7
 
8
-
9
- # ===============================
10
- # Device and Model Setup
11
- # ===============================
12
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
13
- hf_token = os.environ.get("HF_TOKEN", None)
14
 
15
- #Load the model
16
- model_path = "AI-Mock-Interviewer/T5"
17
- tokenizer = AutoTokenizer.from_pretrained(model_path)
18
- model = AutoModelForSeq2SeqLM.from_pretrained(model_path)
19
- model.to(device)
20
 
21
- if torch.cuda.is_available():
22
- model = torch.compile(model)
 
 
23
 
24
 
25
- # ------------------- UPDATED SYSTEM PROMPT -------------------
26
  system_prompt = """
27
- You are conducting a mock technical interview. The candidate's experience level can be entry-level, mid-level, or senior-level. Generate questions and follow-up questions based on the domain and the candidate's experience level. Consider these aspects:
28
- 1. The question should be relevant to the domain (e.g., software engineering, machine learning) and appropriate for the candidate's experience level.
29
- 2. Ensure each question is unique and does not repeat previously asked questions.
30
- 3. Ensure each question covers a different sub-topic within the domain, avoiding redundancy.
31
- 4. If no clear follow-up can be derived, generate a fresh, related question from a different aspect of the domain.
 
 
32
  Important: Ensure that each question is clear, concise, and allows the candidate to demonstrate their technical and communicative abilities effectively.
33
  """
34
 
35
  # Define sub-topic categories for different domains
36
  subtopic_keywords = {
37
- "data analysis": [
38
- "data cleaning", "missing data", "outliers",
39
- "feature engineering", "EDA", "trend analysis",
40
- "data visualization"
41
- ],
42
- "machine learning": [
43
- "supervised learning", "unsupervised learning",
44
- "model evaluation", "bias-variance tradeoff",
45
- "overfitting", "hyperparameter tuning"
46
- ],
47
- "software engineering": [
48
- "agile methodology", "code optimization",
49
- "design patterns", "database design",
50
- "testing strategies"
51
- ],
52
  }
53
 
54
  def identify_subtopic(question, domain):
@@ -60,17 +42,12 @@ def identify_subtopic(question, domain):
60
  return subtopic
61
  return None
62
 
63
- # We'll keep global sets here only if needed as a fallback:
64
- asked_questions = set()
65
- asked_subtopics = set()
66
-
67
- def generate_question(prompt, domain, state=None):
68
- """
69
- Generates a unique question based on the prompt and domain.
70
- Uses 'state' to track uniqueness in the conversation session.
71
- """
72
- while True:
73
- full_prompt = system_prompt + "\n" + prompt
74
  inputs = tokenizer(full_prompt, return_tensors="pt").to(device)
75
  outputs = model.generate(
76
  inputs["input_ids"],
@@ -83,115 +60,72 @@ def generate_question(prompt, domain, state=None):
83
  do_sample=True,
84
  pad_token_id=tokenizer.eos_token_id,
85
  )
86
- question = tokenizer.decode(outputs[0], skip_special_tokens=True)
87
- question = question.replace(full_prompt, "").strip()
88
-
89
- # Ensure question ends with a question mark
90
  if not question.endswith("?"):
91
  question = question.split("?")[0] + "?"
92
-
93
- # Identify the subtopic
94
  subtopic = identify_subtopic(question, domain)
95
 
96
- if state is not None:
97
- # Use session-level sets to ensure uniqueness
98
- if (question not in state["asked_questions"] and
99
- (subtopic is None or subtopic not in state["asked_subtopics"])):
100
  state["asked_questions"].add(question)
101
  if subtopic:
102
  state["asked_subtopics"].add(subtopic)
103
  return question
104
- else:
105
- # Fallback to global sets if no state is provided
106
- if question not in asked_questions and (subtopic is None or subtopic not in asked_subtopics):
107
- asked_questions.add(question)
108
- if subtopic:
109
- asked_subtopics.add(subtopic)
110
- return question
111
 
112
- def reset_state(domain, company, level):
113
- """
114
- Resets or initializes the session state.
115
- """
116
  return {
117
- "domain": domain,
118
- "company": company,
119
- "level": level,
120
- "asked_questions": set(),
121
- "asked_subtopics": set(),
122
- "conversation": [] # List of {"role": ..., "content": ...}
123
  }
124
 
125
- def start_interview(domain, company, level):
126
- """
127
- Initializes a new interactive interview session with the first question.
128
- """
129
- state = reset_state(domain, company, level)
130
- prompt = (f"Domain: {domain}. "
131
- + (f"Company: {company}. " if company else "")
132
- + f"Candidate experience level: {level}. "
133
- "Generate the first question:")
134
-
135
  question = generate_question(prompt, domain, state)
136
- state["conversation"].append({"role": "Interviewer", "content": question})
137
  return state["conversation"], state
138
 
139
  def submit_response(candidate_response, state):
140
- """
141
- Accepts the candidate's response, updates conversation, generates the next question.
142
- Allows quitting the interview by typing 'quit'.
143
- """
144
- if candidate_response.strip().lower() == "quit":
145
- state["conversation"].append({"role": "Candidate", "content": candidate_response})
146
- state["conversation"].append({"role": "Interviewer", "content": "Interview session has ended. Thank you for participating!"})
147
- return state["conversation"], state
148
-
149
- state["conversation"].append({"role": "Candidate", "content": candidate_response})
150
- prompt = (f"Domain: {state['domain']}. "
151
- f"Candidate's experience level: {state['level']}. "
152
- "Generate the next interview question:")
153
-
154
  question = generate_question(prompt, state["domain"], state)
155
- state["conversation"].append({"role": "Interviewer", "content": question})
156
  return state["conversation"], state
157
 
158
  # Build an interactive Gradio interface using Blocks
159
  with gr.Blocks() as demo:
160
  gr.Markdown("# Interactive Mock Interview")
 
161
  with gr.Row():
162
- domain_input = gr.Textbox(label="Domain", placeholder="e.g. Software Engineering")
163
- company_input = gr.Textbox(label="Company (Optional)", placeholder="e.g. Google")
164
- level_input = gr.Dropdown(
165
- label="Experience Level",
166
- choices=["Entry-Level", "Mid-Level", "Senior-Level"],
167
- value="Entry-Level"
168
- )
169
-
170
  start_button = gr.Button("Start Interview")
171
- chatbot = gr.Chatbot(label="Interview Conversation", type="messages")
172
-
173
  with gr.Row():
174
- response_input = gr.Textbox(label="Your Response", placeholder="Type 'quit' to end the interview")
175
  submit_button = gr.Button("Submit")
176
-
177
- # State to hold session data
178
- state = gr.State()
179
-
180
- # Start interview
181
- start_button.click(
182
- start_interview,
183
- inputs=[domain_input, company_input, level_input],
184
- outputs=[chatbot, state]
185
- )
186
-
187
- # Submit response
188
- submit_button.click(
189
- submit_response,
190
- inputs=[response_input, state],
191
- outputs=[chatbot, state]
192
- ).then(
193
- lambda: "", None, response_input # Clear input box after submission
194
  )
195
 
196
-
197
- demo.launch()
 
 
1
  import gradio as gr
2
+ from transformers import AutoTokenizer, T5ForConditionalGeneration
3
  import torch
4
  import os
 
5
 
6
+ # Set up device
 
 
 
7
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 
8
 
9
+ #access_token = os.getenv["HF_TOKEN"]
 
 
 
 
10
 
11
+ # Load model and tokenizer
12
+ model_name = "vai0511/flan-t5-ai-mock-interviewer"
13
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
14
+ model = T5ForConditionalGeneration.from_pretrained(model_name)
15
 
16
 
17
+ # System prompt to guide the interview generation
18
  system_prompt = """
19
+ You are conducting a mock technical interview. Generate questions and follow-up questions based on the domain provided. Consider these aspects:
20
+ 1. The question should be relevant to the domain (e.g., software engineering, machine learning).
21
+ 2. For follow-up questions, analyze the candidate's last response and ask questions that probe deeper into their understanding, challenge their approach, or request clarification.
22
+ 3. The follow-up question should aim to explore the candidate's depth of knowledge and ability to adapt.
23
+ 4. Ensure each question is unique and does not repeat previously asked questions.
24
+ 5. Ensure each question covers a different sub-topic within the domain, avoiding redundancy.
25
+ 6. If no clear follow-up can be derived, generate a fresh, related question from a different aspect of the domain.
26
  Important: Ensure that each question is clear, concise, and allows the candidate to demonstrate their technical and communicative abilities effectively.
27
  """
28
 
29
  # Define sub-topic categories for different domains
30
  subtopic_keywords = {
31
+ "data analysis": ["data cleaning", "missing data", "outliers", "feature engineering", "EDA", "trend analysis", "data visualization"],
32
+ "machine learning": ["supervised learning", "unsupervised learning", "model evaluation", "bias-variance tradeoff", "overfitting", "hyperparameter tuning"],
33
+ "software engineering": ["agile methodology", "code optimization", "design patterns", "database design", "testing strategies"],
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
  def identify_subtopic(question, domain):
 
42
  return subtopic
43
  return None
44
 
45
+ def generate_question(prompt, domain, state=None, max_attempts=10):
46
+ """Generate a unique interview question while ensuring no repetition."""
47
+ attempts = 0
48
+ while attempts < max_attempts:
49
+ attempts += 1
50
+ full_prompt = f"{system_prompt.strip()}\n{prompt.strip()}"
 
 
 
 
 
51
  inputs = tokenizer(full_prompt, return_tensors="pt").to(device)
52
  outputs = model.generate(
53
  inputs["input_ids"],
 
60
  do_sample=True,
61
  pad_token_id=tokenizer.eos_token_id,
62
  )
63
+ question = tokenizer.decode(outputs[0], skip_special_tokens=True).strip()
 
 
 
64
  if not question.endswith("?"):
65
  question = question.split("?")[0] + "?"
66
+
 
67
  subtopic = identify_subtopic(question, domain)
68
 
69
+ # Ensure uniqueness within the session state
70
+ if state:
71
+ if question not in state["asked_questions"] and (subtopic is None or subtopic not in state["asked_subtopics"]):
 
72
  state["asked_questions"].add(question)
73
  if subtopic:
74
  state["asked_subtopics"].add(subtopic)
75
  return question
 
 
 
 
 
 
 
76
 
77
+ raise RuntimeError("Failed to generate a unique question after multiple attempts.")
78
+
79
+ def reset_state(domain, company):
80
+ """Reset session state for a new interview."""
81
  return {
82
+ "domain": domain,
83
+ "company": company,
84
+ "asked_questions": set(),
85
+ "asked_subtopics": set(),
86
+ "conversation": [] # List of tuples: (speaker, message)
 
87
  }
88
 
89
+ def start_interview(domain, company):
90
+ """Start a new interview session."""
91
+ state = reset_state(domain, company)
92
+ prompt = f"Domain: {domain}. " + (f"Company: {company}. " if company else "") + "Generate the first question:"
 
 
 
 
 
 
93
  question = generate_question(prompt, domain, state)
94
+ state["conversation"].append(("Interviewer", question))
95
  return state["conversation"], state
96
 
97
  def submit_response(candidate_response, state):
98
+ """Accept the candidate's response, update the conversation, and generate a follow-up question."""
99
+ state["conversation"].append(("Candidate", candidate_response))
100
+ prompt = f"Domain: {state['domain']}. Candidate's last response: {candidate_response}. Generate a follow-up question with a new perspective:"
 
 
 
 
 
 
 
 
 
 
 
101
  question = generate_question(prompt, state["domain"], state)
102
+ state["conversation"].append(("Interviewer", question))
103
  return state["conversation"], state
104
 
105
  # Build an interactive Gradio interface using Blocks
106
  with gr.Blocks() as demo:
107
  gr.Markdown("# Interactive Mock Interview")
108
+
109
  with gr.Row():
110
+ domain_input = gr.Textbox(label="Domain")
111
+ company_input = gr.Textbox(label="Company (Optional)")
112
+
 
 
 
 
 
113
  start_button = gr.Button("Start Interview")
114
+ chatbot = gr.Chatbot(label="Interview Conversation")
115
+
116
  with gr.Row():
117
+ response_input = gr.Textbox(label="Your Response")
118
  submit_button = gr.Button("Submit")
119
+
120
+ # Maintain session state across interactions
121
+ state = gr.State({}) # Initialize state properly
122
+
123
+ # Clicking start initializes the interview and shows the first question
124
+ start_button.click(start_interview, inputs=[domain_input, company_input], outputs=[chatbot, state])
125
+
126
+ # Submitting a response updates the conversation with a follow-up question
127
+ submit_button.click(submit_response, inputs=[response_input, state], outputs=[chatbot, state]).then(
128
+ lambda _: "", inputs=[response_input], outputs=[response_input] # Clear response input after submission
 
 
 
 
 
 
 
 
129
  )
130
 
131
+ demo.launch()