Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -258,20 +258,18 @@ def extract_skills_and_work(text):
|
|
258 |
#####################################
|
259 |
# Function: Summarize Resume Text - Optimized
|
260 |
#####################################
|
261 |
-
def summarize_resume_text(resume_text
|
262 |
"""
|
263 |
Generates a structured summary of the resume text - optimized for speed
|
264 |
"""
|
265 |
start_time = time.time()
|
266 |
|
267 |
-
|
268 |
-
|
269 |
-
# First, generate a quick summary
|
270 |
max_input_length = 1024 # Model limit
|
271 |
|
272 |
# Only summarize the first portion of text for speed
|
273 |
text_to_summarize = resume_text[:min(len(resume_text), max_input_length)]
|
274 |
-
base_summary = summarizer(text_to_summarize)[0]['summary_text']
|
275 |
|
276 |
# Extract information in parallel where possible
|
277 |
with concurrent.futures.ThreadPoolExecutor() as executor:
|
@@ -301,23 +299,20 @@ def summarize_resume_text(resume_text, models):
|
|
301 |
#####################################
|
302 |
# Function: Compare Candidate Summary to Company Prompt - Optimized
|
303 |
#####################################
|
|
|
304 |
@st.cache_data(show_spinner=False)
|
305 |
-
def compute_suitability(candidate_summary, company_prompt,
|
306 |
"""
|
307 |
Compute the similarity between candidate summary and company prompt.
|
308 |
Returns a score in the range [0, 1] and execution time.
|
309 |
"""
|
310 |
start_time = time.time()
|
311 |
|
312 |
-
feature_extractor = models['feature_extractor']
|
313 |
|
314 |
-
# Extract features (embeddings)
|
315 |
-
|
316 |
-
|
317 |
-
company_future = executor.submit(feature_extractor, company_prompt)
|
318 |
-
|
319 |
-
candidate_features = candidate_future.result()
|
320 |
-
company_features = company_future.result()
|
321 |
|
322 |
# Convert to numpy arrays and flatten if needed
|
323 |
candidate_vec = np.mean(np.array(candidate_features[0]), axis=0)
|
@@ -369,7 +364,7 @@ if uploaded_file is not None and company_prompt and st.button("Analyze Resume"):
|
|
369 |
else:
|
370 |
# Step 2: Generate summary
|
371 |
status_text.text("Step 2/3: Analyzing resume and generating summary...")
|
372 |
-
summary, summarization_time = summarize_resume_text(resume_text
|
373 |
progress_bar.progress(75)
|
374 |
|
375 |
# Display summary
|
@@ -379,7 +374,8 @@ if uploaded_file is not None and company_prompt and st.button("Analyze Resume"):
|
|
379 |
|
380 |
# Step 3: Compute similarity
|
381 |
status_text.text("Step 3/3: Calculating compatibility with company profile...")
|
382 |
-
|
|
|
383 |
progress_bar.progress(100)
|
384 |
|
385 |
# Clear status messages
|
|
|
258 |
#####################################
|
259 |
# Function: Summarize Resume Text - Optimized
|
260 |
#####################################
|
261 |
+
def summarize_resume_text(resume_text):
|
262 |
"""
|
263 |
Generates a structured summary of the resume text - optimized for speed
|
264 |
"""
|
265 |
start_time = time.time()
|
266 |
|
267 |
+
# First, generate a quick summary using pre-loaded model
|
|
|
|
|
268 |
max_input_length = 1024 # Model limit
|
269 |
|
270 |
# Only summarize the first portion of text for speed
|
271 |
text_to_summarize = resume_text[:min(len(resume_text), max_input_length)]
|
272 |
+
base_summary = models['summarizer'](text_to_summarize)[0]['summary_text']
|
273 |
|
274 |
# Extract information in parallel where possible
|
275 |
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
|
299 |
#####################################
|
300 |
# Function: Compare Candidate Summary to Company Prompt - Optimized
|
301 |
#####################################
|
302 |
+
# Fixed: Use underscore prefix for non-hashable arguments to tell Streamlit not to hash them
|
303 |
@st.cache_data(show_spinner=False)
|
304 |
+
def compute_suitability(candidate_summary, company_prompt, _feature_extractor=None):
|
305 |
"""
|
306 |
Compute the similarity between candidate summary and company prompt.
|
307 |
Returns a score in the range [0, 1] and execution time.
|
308 |
"""
|
309 |
start_time = time.time()
|
310 |
|
311 |
+
feature_extractor = _feature_extractor or models['feature_extractor']
|
312 |
|
313 |
+
# Extract features (embeddings)
|
314 |
+
candidate_features = feature_extractor(candidate_summary)
|
315 |
+
company_features = feature_extractor(company_prompt)
|
|
|
|
|
|
|
|
|
316 |
|
317 |
# Convert to numpy arrays and flatten if needed
|
318 |
candidate_vec = np.mean(np.array(candidate_features[0]), axis=0)
|
|
|
364 |
else:
|
365 |
# Step 2: Generate summary
|
366 |
status_text.text("Step 2/3: Analyzing resume and generating summary...")
|
367 |
+
summary, summarization_time = summarize_resume_text(resume_text)
|
368 |
progress_bar.progress(75)
|
369 |
|
370 |
# Display summary
|
|
|
374 |
|
375 |
# Step 3: Compute similarity
|
376 |
status_text.text("Step 3/3: Calculating compatibility with company profile...")
|
377 |
+
# Pass the feature extractor with an underscore prefix to avoid hashing issues
|
378 |
+
similarity_score, similarity_time = compute_suitability(summary, company_prompt, _feature_extractor=models['feature_extractor'])
|
379 |
progress_bar.progress(100)
|
380 |
|
381 |
# Clear status messages
|