Upload 14 files
Browse files- app.py +167 -0
- app/__init__.py +0 -0
- app/__pycache__/__init__.cpython-312.pyc +0 -0
- app/__pycache__/app.cpython-312.pyc +0 -0
- app/__pycache__/context.cpython-312.pyc +0 -0
- app/__pycache__/grammar.cpython-312.pyc +0 -0
- app/__pycache__/main.cpython-312.pyc +0 -0
- app/__pycache__/pronunciation.cpython-312.pyc +0 -0
- app/__pycache__/questions.cpython-312.pyc +0 -0
- app/__pycache__/sentiment.cpython-312.pyc +0 -0
- app/confidence_analysis.py +22 -0
- app/context_analysis.py +40 -0
- app/questions.py +22 -0
- requirement.txt +140 -0
app.py
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import whisper
|
2 |
+
import gradio as gr
|
3 |
+
import torch
|
4 |
+
from transformers import BertTokenizer, BertForSequenceClassification
|
5 |
+
from app.questions import get_question
|
6 |
+
|
7 |
+
# Load Whisper model
|
8 |
+
whisper_model = whisper.load_model("small")
|
9 |
+
|
10 |
+
# Load the pre-trained model and tokenizer for confidence analysis
|
11 |
+
confidence_model = BertForSequenceClassification.from_pretrained('RiteshAkhade/confidence_model')
|
12 |
+
confidence_tokenizer = BertTokenizer.from_pretrained('RiteshAkhade/confidence_model')
|
13 |
+
|
14 |
+
# Load pre-trained context analysis model (BERT-based)
|
15 |
+
context_model = BertForSequenceClassification.from_pretrained('RiteshAkhade/context_model')
|
16 |
+
context_tokenizer = BertTokenizer.from_pretrained('RiteshAkhade/context_model')
|
17 |
+
|
18 |
+
# Function to perform context analysis using the BERT model
|
19 |
+
def predict_relevance(question, answer):
|
20 |
+
if not answer.strip(): # Check for empty answers
|
21 |
+
return "Irrelevant"
|
22 |
+
|
23 |
+
inputs = context_tokenizer(question, answer, return_tensors="pt", padding=True, truncation=True)
|
24 |
+
context_model.eval()
|
25 |
+
|
26 |
+
with torch.no_grad():
|
27 |
+
outputs = context_model(**inputs)
|
28 |
+
logits = outputs.logits
|
29 |
+
probabilities = torch.softmax(logits, dim=-1)
|
30 |
+
threshold = 0.5
|
31 |
+
relevant_prob = probabilities[0, 1] # Probability for relevant class
|
32 |
+
|
33 |
+
if relevant_prob > threshold:
|
34 |
+
return "Relevant"
|
35 |
+
else:
|
36 |
+
return "Irrelevant"
|
37 |
+
|
38 |
+
# Function to perform confidence analysis
|
39 |
+
def predict_confidence(question, answer):
|
40 |
+
inputs = confidence_tokenizer(question, answer, return_tensors="pt", padding=True, truncation=True)
|
41 |
+
confidence_model.eval()
|
42 |
+
|
43 |
+
with torch.no_grad():
|
44 |
+
outputs = confidence_model(**inputs)
|
45 |
+
logits = outputs.logits
|
46 |
+
predictions = torch.argmax(logits, dim=-1)
|
47 |
+
return "Confident" if predictions.item() == 1 else "Not Confident"
|
48 |
+
|
49 |
+
# Questions from questions.py
|
50 |
+
def fetch_questions():
|
51 |
+
return [get_question(i) for i in range(6)]
|
52 |
+
|
53 |
+
questions = fetch_questions()
|
54 |
+
current_question_index = 0
|
55 |
+
|
56 |
+
# Function to show the current question
|
57 |
+
def show_question():
|
58 |
+
global current_question_index
|
59 |
+
question = questions[current_question_index]
|
60 |
+
return question
|
61 |
+
|
62 |
+
# Function to move to the next question
|
63 |
+
def next_question():
|
64 |
+
global current_question_index
|
65 |
+
current_question_index = (current_question_index + 1) % len(questions)
|
66 |
+
return show_question(), None, "", "", ""
|
67 |
+
|
68 |
+
# Function to transcribe the audio input and perform both context and confidence analyses
|
69 |
+
def transcribe_and_analyze(audio, question):
|
70 |
+
try:
|
71 |
+
# Load and process audio using Whisper
|
72 |
+
audio = whisper.load_audio(audio)
|
73 |
+
audio = whisper.pad_or_trim(audio)
|
74 |
+
mel = whisper.log_mel_spectrogram(audio).to(whisper_model.device)
|
75 |
+
options = whisper.DecodingOptions(fp16=False)
|
76 |
+
result = whisper.decode(whisper_model, mel, options)
|
77 |
+
|
78 |
+
# Get the transcribed text
|
79 |
+
transcribed_text = result.text
|
80 |
+
|
81 |
+
# Perform context and confidence analysis
|
82 |
+
context_result = predict_relevance(question, transcribed_text)
|
83 |
+
confidence_result = predict_confidence(question, transcribed_text)
|
84 |
+
|
85 |
+
# Return the results
|
86 |
+
return transcribed_text, context_result, confidence_result
|
87 |
+
except Exception as e:
|
88 |
+
return f"Error: {str(e)}", "", ""
|
89 |
+
|
90 |
+
# Gradio interface
|
91 |
+
with gr.Blocks() as demo:
|
92 |
+
|
93 |
+
gr.HTML('''
|
94 |
+
<style>
|
95 |
+
body {
|
96 |
+
background-color: #f0f0f0;
|
97 |
+
}
|
98 |
+
#title {
|
99 |
+
color: grey;
|
100 |
+
font-size: 30px;
|
101 |
+
text-align: center;
|
102 |
+
margin-bottom: 20px;
|
103 |
+
}
|
104 |
+
.transcribe-btn, .next-btn {
|
105 |
+
background-color: #4CAF50;
|
106 |
+
color: white;
|
107 |
+
font-size: 16px;
|
108 |
+
padding: 10px 20px;
|
109 |
+
border-radius: 5px;
|
110 |
+
cursor: pointer;
|
111 |
+
margin-top: 10px;
|
112 |
+
}
|
113 |
+
.transcribe-btn:hover, .next-btn:hover {
|
114 |
+
background-color: #45a049;
|
115 |
+
}
|
116 |
+
#question-box {
|
117 |
+
font-size: 20px;
|
118 |
+
color: #555;
|
119 |
+
text-align: center;
|
120 |
+
}
|
121 |
+
#text-box {
|
122 |
+
font-size: 18px;
|
123 |
+
color: #333;
|
124 |
+
}
|
125 |
+
#context-box, #confidence-box {
|
126 |
+
font-size: 18px;
|
127 |
+
color: #333;
|
128 |
+
}
|
129 |
+
</style>
|
130 |
+
''')
|
131 |
+
|
132 |
+
# Title
|
133 |
+
gr.Markdown("<h1 id='title'>INTERVIEW PREPARATION MODEL</h1>")
|
134 |
+
|
135 |
+
# Question display
|
136 |
+
with gr.Row():
|
137 |
+
question_display = gr.Textbox(label="Interview Question", value=show_question(), interactive=False, elem_id="question-box")
|
138 |
+
|
139 |
+
# Audio input and transcription section
|
140 |
+
with gr.Row():
|
141 |
+
audio_input = gr.Audio(type="filepath", label="Record Your Answer")
|
142 |
+
|
143 |
+
# Separate text boxes for the transcribed text, context, and confidence analysis
|
144 |
+
with gr.Row():
|
145 |
+
transcribed_text = gr.Textbox(label="Your Answer (Transcription)", interactive=False, lines=5, elem_id="text-box")
|
146 |
+
|
147 |
+
with gr.Row():
|
148 |
+
context_analysis_result = gr.Textbox(label="Context Analysis", interactive=False, elem_id="context-box")
|
149 |
+
|
150 |
+
with gr.Row():
|
151 |
+
confidence_analysis_result = gr.Textbox(label="Confidence Analysis", interactive=False, elem_id="confidence-box")
|
152 |
+
|
153 |
+
# Automatically transcribe the audio and analyze context and confidence when audio is provided
|
154 |
+
audio_input.change(fn=transcribe_and_analyze,
|
155 |
+
inputs=[audio_input, question_display],
|
156 |
+
outputs=[transcribed_text, context_analysis_result, confidence_analysis_result])
|
157 |
+
|
158 |
+
# Button to get the next question
|
159 |
+
with gr.Row():
|
160 |
+
next_button = gr.Button("Next Question", elem_classes="next-btn")
|
161 |
+
|
162 |
+
# Clear audio, transcription, context, and confidence when moving to the next question
|
163 |
+
next_button.click(next_question,
|
164 |
+
outputs=[question_display, audio_input, transcribed_text, context_analysis_result, confidence_analysis_result])
|
165 |
+
|
166 |
+
# Launch app
|
167 |
+
demo.launch(share=True)
|
app/__init__.py
ADDED
File without changes
|
app/__pycache__/__init__.cpython-312.pyc
ADDED
Binary file (128 Bytes). View file
|
|
app/__pycache__/app.cpython-312.pyc
ADDED
Binary file (790 Bytes). View file
|
|
app/__pycache__/context.cpython-312.pyc
ADDED
Binary file (1.79 kB). View file
|
|
app/__pycache__/grammar.cpython-312.pyc
ADDED
Binary file (565 Bytes). View file
|
|
app/__pycache__/main.cpython-312.pyc
ADDED
Binary file (767 Bytes). View file
|
|
app/__pycache__/pronunciation.cpython-312.pyc
ADDED
Binary file (818 Bytes). View file
|
|
app/__pycache__/questions.cpython-312.pyc
ADDED
Binary file (826 Bytes). View file
|
|
app/__pycache__/sentiment.cpython-312.pyc
ADDED
Binary file (1.11 kB). View file
|
|
app/confidence_analysis.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import BertTokenizer, BertForSequenceClassification
|
2 |
+
import torch
|
3 |
+
|
4 |
+
|
5 |
+
|
6 |
+
model = BertForSequenceClassification.from_pretrained('./confidence_model')
|
7 |
+
tokenizer = BertTokenizer.from_pretrained('./confidence_tokenizer')
|
8 |
+
|
9 |
+
def predict_confidence(question, answer):
|
10 |
+
inputs = tokenizer(question, answer, return_tensors="pt", padding=True, truncation=True)
|
11 |
+
model.eval()
|
12 |
+
|
13 |
+
with torch.no_grad():
|
14 |
+
outputs = model(**inputs)
|
15 |
+
logits = outputs.logits
|
16 |
+
predictions = torch.argmax(logits, dim=-1)
|
17 |
+
return "Confident" if predictions.item() == 1 else "Not Confident"
|
18 |
+
|
19 |
+
# Example
|
20 |
+
question = "What is your experience with Python?"
|
21 |
+
answer = "I dont have any experience in Python"
|
22 |
+
print(predict_confidence(question, answer))
|
app/context_analysis.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import BertTokenizer, BertForSequenceClassification
|
2 |
+
import torch
|
3 |
+
|
4 |
+
|
5 |
+
|
6 |
+
|
7 |
+
model = BertForSequenceClassification.from_pretrained('./test_model')
|
8 |
+
|
9 |
+
tokenizer = BertForSequenceClassification.from_pretrained('./test_tokenizer')
|
10 |
+
|
11 |
+
|
12 |
+
def predict_relevance(question, answer):
|
13 |
+
|
14 |
+
if not answer.strip(): # Check for empty answers
|
15 |
+
return "Irrelevant"
|
16 |
+
|
17 |
+
|
18 |
+
inputs = tokenizer(question, answer, return_tensors="pt", padding=True, truncation=True)
|
19 |
+
model.eval()
|
20 |
+
|
21 |
+
with torch.no_grad():
|
22 |
+
outputs = model(**inputs)
|
23 |
+
logits = outputs.logits
|
24 |
+
probabilities = torch.softmax(logits, dim=-1)
|
25 |
+
# Adjust the threshold
|
26 |
+
threshold = 0.5
|
27 |
+
prediction = torch.argmax(probabilities, dim=-1)
|
28 |
+
relevant_prob = probabilities[0, 1] # Probability for relevant class
|
29 |
+
|
30 |
+
#threshold logic
|
31 |
+
if relevant_prob > threshold:
|
32 |
+
return "Relevant"
|
33 |
+
else:
|
34 |
+
return "Irrelevant"
|
35 |
+
|
36 |
+
# Example
|
37 |
+
question = "What is your experience with Python?"
|
38 |
+
answer = "I have minimal experience with java, mostly for small automation tasks." # Empty answer
|
39 |
+
result = predict_relevance(question, answer)
|
40 |
+
print(f"Relevance: {result}")
|
app/questions.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# app/questions.py
|
2 |
+
|
3 |
+
# List of interview questions
|
4 |
+
questions = [
|
5 |
+
"What is your experience with Python?",
|
6 |
+
"Can you explain the concept of OOP?",
|
7 |
+
"Describe a time you faced a challenge and how you overcame it.",
|
8 |
+
"What are your strengths and weaknesses?",
|
9 |
+
"How do you handle working under pressure?",
|
10 |
+
"What are your career goals in the next five years?"
|
11 |
+
]
|
12 |
+
|
13 |
+
# Function to get a question based on an index or randomly
|
14 |
+
def get_question(index=None):
|
15 |
+
if index is not None and 0 <= index < len(questions):
|
16 |
+
return questions[index]
|
17 |
+
else:
|
18 |
+
return "Invalid question index."
|
19 |
+
|
20 |
+
# Option to get the next question from the list
|
21 |
+
def get_all_questions():
|
22 |
+
return questions
|
requirement.txt
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
accelerate==1.0.1
|
2 |
+
aiofiles==23.2.1
|
3 |
+
aiohappyeyeballs==2.4.3
|
4 |
+
aiohttp==3.10.10
|
5 |
+
aiosignal==1.3.1
|
6 |
+
annotated-types==0.7.0
|
7 |
+
anyio==4.6.0
|
8 |
+
asttokens==2.4.1
|
9 |
+
attrs==24.2.0
|
10 |
+
blinker==1.8.2
|
11 |
+
captcha==0.6.0
|
12 |
+
certifi==2024.8.30
|
13 |
+
cffi==1.17.1
|
14 |
+
charset-normalizer==3.3.2
|
15 |
+
click==8.1.7
|
16 |
+
cmudict==1.0.31
|
17 |
+
comm==0.2.2
|
18 |
+
datasets==3.0.1
|
19 |
+
debugpy==1.8.7
|
20 |
+
decorator==5.1.1
|
21 |
+
dill==0.3.8
|
22 |
+
executing==2.1.0
|
23 |
+
fastapi==0.115.0
|
24 |
+
ffmpy==0.4.0
|
25 |
+
filelock==3.16.1
|
26 |
+
Flask==3.0.3
|
27 |
+
frozenlist==1.4.1
|
28 |
+
fsspec==2024.6.1
|
29 |
+
gradio==5.0.2
|
30 |
+
gradio_client==1.4.0
|
31 |
+
gTTS==2.5.3
|
32 |
+
h11==0.14.0
|
33 |
+
httpcore==1.0.6
|
34 |
+
httpx==0.27.2
|
35 |
+
huggingface-hub==0.25.1
|
36 |
+
idna==3.10
|
37 |
+
importlib_metadata==8.5.0
|
38 |
+
importlib_resources==6.4.5
|
39 |
+
ipykernel==6.29.5
|
40 |
+
ipython==8.29.0
|
41 |
+
itsdangerous==2.2.0
|
42 |
+
jedi==0.19.1
|
43 |
+
Jinja2==3.1.4
|
44 |
+
joblib==1.4.2
|
45 |
+
jupyter_client==8.6.3
|
46 |
+
jupyter_core==5.7.2
|
47 |
+
language_tool_python==2.8.1
|
48 |
+
llvmlite==0.43.0
|
49 |
+
markdown-it-py==3.0.0
|
50 |
+
MarkupSafe==2.1.5
|
51 |
+
matplotlib-inline==0.1.7
|
52 |
+
mdurl==0.1.2
|
53 |
+
more-itertools==10.5.0
|
54 |
+
mpmath==1.3.0
|
55 |
+
multidict==6.1.0
|
56 |
+
multiprocess==0.70.16
|
57 |
+
nest-asyncio==1.6.0
|
58 |
+
networkx==3.3
|
59 |
+
nltk==3.9.1
|
60 |
+
numba==0.60.0
|
61 |
+
numpy==2.0.2
|
62 |
+
nvidia-cublas-cu12==12.1.3.1
|
63 |
+
nvidia-cuda-cupti-cu12==12.1.105
|
64 |
+
nvidia-cuda-nvrtc-cu12==12.1.105
|
65 |
+
nvidia-cuda-runtime-cu12==12.1.105
|
66 |
+
nvidia-cudnn-cu12==9.1.0.70
|
67 |
+
nvidia-cufft-cu12==11.0.2.54
|
68 |
+
nvidia-curand-cu12==10.3.2.106
|
69 |
+
nvidia-cusolver-cu12==11.4.5.107
|
70 |
+
nvidia-cusparse-cu12==12.1.0.106
|
71 |
+
nvidia-nccl-cu12==2.20.5
|
72 |
+
nvidia-nvjitlink-cu12==12.6.77
|
73 |
+
nvidia-nvtx-cu12==12.1.105
|
74 |
+
openai-whisper @ git+https://github.com/openai/whisper.git@25639fc17ddc013d56c594bfbf7644f2185fad84
|
75 |
+
orjson==3.10.7
|
76 |
+
packaging==24.1
|
77 |
+
pandas==2.2.3
|
78 |
+
parso==0.8.4
|
79 |
+
pexpect==4.9.0
|
80 |
+
pillow==10.4.0
|
81 |
+
platformdirs==4.3.6
|
82 |
+
prompt_toolkit==3.0.48
|
83 |
+
pronouncing==0.2.0
|
84 |
+
propcache==0.2.0
|
85 |
+
psutil==6.1.0
|
86 |
+
ptyprocess==0.7.0
|
87 |
+
pure_eval==0.2.3
|
88 |
+
pyarrow==17.0.0
|
89 |
+
PyAudio==0.2.14
|
90 |
+
pycparser==2.22
|
91 |
+
pydantic==2.9.2
|
92 |
+
pydantic_core==2.23.4
|
93 |
+
pydub==0.25.1
|
94 |
+
Pygments==2.18.0
|
95 |
+
python-dateutil==2.9.0.post0
|
96 |
+
python-multipart==0.0.12
|
97 |
+
pytz==2024.2
|
98 |
+
PyYAML==6.0.2
|
99 |
+
pyzmq==26.2.0
|
100 |
+
regex==2024.9.11
|
101 |
+
requests==2.32.3
|
102 |
+
rich==13.9.2
|
103 |
+
ruff==0.6.9
|
104 |
+
safetensors==0.4.5
|
105 |
+
scikit-learn==1.5.2
|
106 |
+
scipy==1.14.1
|
107 |
+
semantic-version==2.10.0
|
108 |
+
setuptools==75.1.0
|
109 |
+
shellingham==1.5.4
|
110 |
+
six==1.16.0
|
111 |
+
sniffio==1.3.1
|
112 |
+
sounddevice==0.5.0
|
113 |
+
SpeechRecognition==3.10.4
|
114 |
+
stack-data==0.6.3
|
115 |
+
starlette==0.38.6
|
116 |
+
sympy==1.13.3
|
117 |
+
textblob==0.18.0.post0
|
118 |
+
threadpoolctl==3.5.0
|
119 |
+
tiktoken==0.8.0
|
120 |
+
tokenizers==0.20.0
|
121 |
+
tomlkit==0.12.0
|
122 |
+
torch==2.4.1
|
123 |
+
tornado==6.4.1
|
124 |
+
tqdm==4.66.5
|
125 |
+
traitlets==5.14.3
|
126 |
+
transformers==4.45.1
|
127 |
+
triton==3.0.0
|
128 |
+
typer==0.12.5
|
129 |
+
typing_extensions==4.12.2
|
130 |
+
tzdata==2024.2
|
131 |
+
urllib3==2.2.3
|
132 |
+
uvicorn==0.31.1
|
133 |
+
vaderSentiment==3.3.2
|
134 |
+
wcwidth==0.2.13
|
135 |
+
websockets==12.0
|
136 |
+
Werkzeug==3.0.4
|
137 |
+
wheel==0.44.0
|
138 |
+
xxhash==3.5.0
|
139 |
+
yarl==1.15.4
|
140 |
+
zipp==3.20.2
|