Spaces:
Sleeping
Sleeping
import gradio as gr | |
from transformers import pipeline | |
import re | |
# โ Load Hugging Face summarization/chat model | |
summarizer = pipeline("text-generation", model="mistralai/Mistral-7B-Instruct-v0.1") | |
# โ Highlight matching and find missing keywords | |
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS | |
def compare_keywords(resume_text, job_desc): | |
resume_words = set(re.findall(r"\b\w{3,}\b", resume_text.lower())) - ENGLISH_STOP_WORDS | |
job_words = set(re.findall(r"\b\w{3,}\b", job_desc.lower())) - ENGLISH_STOP_WORDS | |
matched = resume_words & job_words | |
missing = job_words - resume_words | |
return matched, missing | |
def highlight_keywords(resume_text, matched): | |
highlighted = resume_text | |
for word in sorted(matched, key=len, reverse=True): | |
highlighted = re.sub(rf"\b({re.escape(word)})\b", r"**\1**", highlighted, flags=re.IGNORECASE) | |
return highlighted | |
# ๐ Use LLM to extract missing keywords contextually from JD | |
def extract_missing_keywords_with_llm(job_desc, resume_text): | |
prompt = f""" | |
You are an expert resume evaluator. | |
Given the job description and the resume, identify important skills, tools, and concepts in the job description that are missing or weakly represented in the resume. | |
List only the missing or insufficiently addressed keywords in bullet format. | |
Job Description: | |
{job_desc} | |
Resume: | |
{resume_text} | |
""" | |
result = summarizer(prompt, max_new_tokens=300, do_sample=True, temperature=0.7)[0]['generated_text'] | |
return result.strip() | |
# ๐ Prompt for dynamic section classification and feedback | |
def build_dynamic_prompt(job_desc, resume_text, analyze_with_jd): | |
prompt = f""" | |
You are an expert resume analyst. | |
Classify the content of the resume into meaningful categories based on the text (e.g., Technical Skills, Soft Skills, Certifications, Projects, Work Experience, Education, Personal Information). | |
You do not need a fixed list of section namesโchoose the most suitable ones based on the content. | |
Then: | |
- For each section, summarize its contents. | |
- If a job description is provided, compare each section against it. | |
- Highlight missing or weak areas relevant to the job. | |
- Provide smart, actionable suggestions to improve each section. | |
- Output in structured Markdown with headings for each section. | |
""" | |
if analyze_with_jd and job_desc: | |
prompt += f"\nJob Description:\n{job_desc}\n" | |
prompt += f"\nResume:\n{resume_text}" | |
return prompt | |
# ๐ง Function to call Hugging Face model and get structured resume feedback | |
def analyze_resume(job_desc, resume_text, analyze_with_jd): | |
if not resume_text.strip(): | |
return "โ ๏ธ Please paste your resume text." | |
user_prompt = build_dynamic_prompt(job_desc, resume_text, analyze_with_jd) | |
try: | |
response = summarizer(user_prompt, max_new_tokens=768, do_sample=True, temperature=0.7)[0]['generated_text'] | |
cleaned = re.sub(rf".*?{re.escape(resume_text)}", "", response, flags=re.DOTALL).strip() | |
if analyze_with_jd and job_desc: | |
matched, _ = compare_keywords(resume_text, job_desc) | |
highlighted_resume = highlight_keywords(resume_text, matched) | |
llm_missing_keywords = extract_missing_keywords_with_llm(job_desc, resume_text) | |
return f"### ๐ Resume with Highlighted Matches\n\n{highlighted_resume}\n\n---\n**โ Matched Keywords:** {', '.join(sorted(matched)) or 'None'}\n\n**โ LLM-Inferred Missing Keywords:**\n{llm_missing_keywords}\n\n---\n{cleaned}" | |
return cleaned | |
except Exception as e: | |
return f"โ Error: {str(e)}" | |
# ๐๏ธ Gradio UI | |
def create_ui(): | |
with gr.Blocks() as demo: | |
with gr.Row(): | |
with gr.Column(): | |
analyze_checkbox = gr.Checkbox(label="Analyze with Job Description", value=True) | |
job_desc = gr.Textbox(label="Job Description", lines=6, placeholder="Paste job description here...") | |
resume_text = gr.Textbox(label="Resume Text", lines=16, placeholder="Paste resume content here...") | |
with gr.Column(): | |
output_analysis = gr.Markdown(label="Resume Analysis and Suggestions") | |
resume_text.change(fn=analyze_resume, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_analysis) | |
job_desc.change(fn=analyze_resume, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_analysis) | |
return demo | |
if __name__ == '__main__': | |
create_ui().launch() | |