|
import gradio as gr |
|
import numpy as np |
|
from transformers import pipeline |
|
from sentence_transformers import SentenceTransformer |
|
from sklearn.metrics.pairwise import cosine_similarity |
|
import PyPDF2 |
|
import torch |
|
import gc |
|
|
|
|
|
stt_model = pipeline("automatic-speech-recognition", model="openai/whisper-small", torch_dtype=torch.float16) |
|
conversation_model = pipeline("text-generation", model="facebook/blenderbot-400M-distill", torch_dtype=torch.float16) |
|
tts_model = pipeline("text-to-speech", model="facebook/fastspeech2-en-ljspeech", torch_dtype=torch.float16) |
|
|
|
|
|
embedding_model = SentenceTransformer('all-MiniLM-L6-v2') |
|
|
|
|
|
def parse_resume(pdf): |
|
"""Extract text from an uploaded PDF file.""" |
|
reader = PyPDF2.PdfReader(pdf) |
|
text = "\n".join(page.extract_text() for page in reader.pages if page.extract_text()) |
|
sections = {"Resume Content": text} |
|
return sections |
|
|
|
|
|
def process_job_description(job_desc): |
|
"""Encode the job description for analysis.""" |
|
return embedding_model.encode(job_desc) |
|
|
|
|
|
def process_resume(pdf): |
|
resume_content = parse_resume(pdf) |
|
resume_embeddings = { |
|
section: embedding_model.encode(content) for section, content in resume_content.items() |
|
} |
|
return resume_embeddings |
|
|
|
|
|
def generate_question(user_input, resume_embeddings): |
|
"""Find the most relevant section in the resume and generate a question.""" |
|
user_embedding = embedding_model.encode(user_input) |
|
similarities = { |
|
section: cosine_similarity([user_embedding], [embedding])[0][0] |
|
for section, embedding in resume_embeddings.items() |
|
} |
|
most_relevant_section = max(similarities, key=similarities.get) |
|
return f"Based on your experience in {most_relevant_section}, can you elaborate more?" |
|
|
|
|
|
def generate_audio(text): |
|
"""Convert text to audio using Hugging Face TTS model.""" |
|
audio_data = tts_model(text, return_tensors=True)["waveform"] |
|
return audio_data |
|
|
|
|
|
class MockInterview: |
|
def __init__(self): |
|
self.resume_embeddings = None |
|
self.job_desc_embedding = None |
|
self.interview_active = False |
|
|
|
def upload_inputs(self, resume, job_desc): |
|
self.resume_embeddings = process_resume(resume) |
|
self.job_desc_embedding = process_job_description(job_desc) |
|
self.interview_active = True |
|
question = "Tell me about yourself." |
|
audio_output = generate_audio(question) |
|
return "Resume and job description processed. Starting the interview.", audio_output |
|
|
|
def conduct_interview(self, audio_file): |
|
if not self.interview_active: |
|
return "Please upload your resume and job description first.", None |
|
|
|
|
|
transcription = stt_model(audio_file)["text"] |
|
if not transcription.strip(): |
|
return "No audio detected. Please try again.", None |
|
|
|
|
|
question = generate_question(transcription, self.resume_embeddings) |
|
audio_output = generate_audio(question) |
|
return transcription, audio_output |
|
|
|
def end_interview(self): |
|
self.interview_active = False |
|
audio_output = generate_audio("Thank you for participating in the interview. Goodbye!") |
|
return "Interview ended. Thank you for participating.", audio_output |
|
|
|
mock_interview = MockInterview() |
|
|
|
def upload_inputs(resume, job_desc): |
|
return mock_interview.upload_inputs(resume, job_desc) |
|
|
|
def conduct_interview(audio_file): |
|
return mock_interview.conduct_interview(audio_file) |
|
|
|
def end_interview(): |
|
return mock_interview.end_interview() |
|
|
|
interface = gr.Blocks() |
|
with interface: |
|
gr.Markdown("""# Mock Interview AI |
|
Upload your resume and job description, then engage in a realistic audio-based interview simulation.""") |
|
|
|
with gr.Row(): |
|
resume_input = gr.File(label="Upload Resume (PDF)") |
|
job_desc_input = gr.Textbox(label="Paste Job Description") |
|
upload_button = gr.Button("Upload and Start Interview") |
|
|
|
with gr.Row(): |
|
audio_input = gr.Audio(type="filepath", label="Respond with Your Answer") |
|
transcription_output = gr.Textbox(label="Transcription") |
|
question_output = gr.Audio(label="Question Audio") |
|
submit_button = gr.Button("Submit Response") |
|
end_button = gr.Button("End Interview") |
|
|
|
upload_button.click(upload_inputs, inputs=[resume_input, job_desc_input], outputs=[transcription_output, question_output]) |
|
submit_button.click(conduct_interview, inputs=[audio_input], outputs=[transcription_output, question_output]) |
|
end_button.click(end_interview, outputs=[transcription_output, question_output]) |
|
|
|
if __name__ == "__main__": |
|
interface.launch() |