Spaces:
Running
Running
File size: 4,437 Bytes
3c06ec2 9332f7e cdf6731 02bafb6 f6c9488 b925d82 02bafb6 b925d82 02bafb6 f93c703 b925d82 1221d76 b925d82 f6c9488 b925d82 f6c9488 b925d82 f6c9488 7c8d169 b925d82 749f56d f6c9488 9332f7e 749f56d b925d82 749f56d 9332f7e 749f56d 9332f7e cdf6731 b925d82 38b8d8b fc823d8 38b8d8b b925d82 38b8d8b b925d82 6e31e76 b925d82 9332f7e b925d82 fc823d8 b925d82 9332f7e b925d82 9332f7e 50c02b0 cdf6731 6e31e76 cdf6731 9332f7e b925d82 6e31e76 f6c9488 9332f7e eb3933a 749f56d 38b8d8b f6c9488 6e31e76 f6c9488 b925d82 f6c9488 b925d82 f6c9488 b925d82 f6c9488 6e31e76 9332f7e cdf6731 b925d82 9332f7e f8fa1b3 9332f7e cdf6731 f8fa1b3 3c06ec2 9332f7e 1ab7e62 9332f7e dfb4653 6e31e76 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
import gradio as gr
from transformers import pipeline
import re
import os
from huggingface_hub import login
import spacy
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
# Authenticate with Hugging Face
login(token=os.environ.get("HUGGINGFACEHUB_API_TOKEN"))
# Load summarization model
summarizer = pipeline("text2text-generation", model="declare-lab/flan-alpaca-base")
# Load SpaCy English model
nlp = spacy.load("en_core_web_sm")
# π Use SpaCy to extract nouns and proper nouns (contextually relevant keywords)
def extract_relevant_keywords(text):
doc = nlp(text.lower())
return set(
token.text for token in doc
if token.pos_ in {"NOUN", "PROPN"} and not token.is_stop and len(token.text) > 2
)
# Compare keywords with semantic filtering
def compare_keywords(resume_text, job_desc):
resume_words = extract_relevant_keywords(resume_text)
job_words = extract_relevant_keywords(job_desc)
matched = resume_words & job_words
missing = job_words - resume_words
return matched, missing
# Highlight matched keywords in the resume
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
# LLM-based missing keyword extraction
def extract_missing_keywords_with_llm(job_desc, resume_text):
prompt = f"""
Given the following job description and resume, list the important skills, tools, and concepts from the job description that are missing or weakly represented in the resume.
Job Description:
{job_desc}
Resume:
{resume_text}
Only list the missing keywords as bullet points.
"""
result = summarizer(prompt, max_new_tokens=300, do_sample=True)[0]
return result.get('generated_text', result.get('summary_text', str(result))).strip()
# Resume improvement prompt
def build_dynamic_prompt(job_desc, resume_text, analyze_with_jd):
prompt = f"""
Analyze the resume below and organize it into meaningful categories (e.g., Skills, Education, Work Experience, etc.).
If a job description is provided, compare it against the resume and suggest improvements section by section.
Job Description:
{job_desc if analyze_with_jd else '[None provided]'}
Resume:
{resume_text}
Return structured Markdown with headers for each section and improvement suggestions.
"""
return prompt
# Generate analysis result
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:
result = summarizer(user_prompt, max_new_tokens=512, do_sample=True)[0]
response_text = result.get('generated_text', result.get('summary_text', str(result))).strip()
if analyze_with_jd and job_desc:
matched, missing = 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
{highlighted_resume}
---
** Matched Keywords (Semantic Comparison):**
{', '.join(sorted(matched)) or 'None'}
** Missing Keywords (Semantic Comparison):**
{', '.join(sorted(missing)) or 'None'}
** LLM-Inferred Missing Keywords:**
{llm_missing_keywords}
---
{response_text}"""
return response_text
except Exception as e:
return f"β Error: {str(e)}"
# Gradio Interface
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...")
analyze_button = gr.Button("Run Analysis")
with gr.Column():
output_analysis = gr.Markdown(label="Resume Analysis and Suggestions")
analyze_button.click(fn=analyze_resume, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_analysis)
return demo
if __name__ == '__main__':
create_ui().launch()
|