Ulyha commited on
Commit
f9f2762
·
verified ·
1 Parent(s): 5a5130c

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +90 -0
  2. requirements.txt +6 -0
app.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import pipeline, AutoTokenizer, AutoModel
3
+ import torch
4
+ from sklearn.metrics.pairwise import cosine_similarity
5
+ import numpy as np
6
+
7
+ device = 0 if torch.cuda.is_available() else -1
8
+
9
+ # Загружаем модели
10
+ ner_pipeline = pipeline("ner", model="dslim/bert-base-NER", device=device)
11
+ text_generator = pipeline("text-generation", model="gpt2", device=device)
12
+
13
+ # Sentence Transformer для similarity
14
+ tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
15
+ model = AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
16
+ if torch.cuda.is_available():
17
+ model = model.cuda()
18
+
19
+ def get_embedding(text):
20
+ inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=512, padding=True)
21
+ if torch.cuda.is_available():
22
+ inputs = {k: v.cuda() for k, v in inputs.items()}
23
+ with torch.no_grad():
24
+ outputs = model(**inputs)
25
+ return outputs.last_hidden_state.mean(dim=1).cpu().numpy()
26
+
27
+ def calculate_similarity(resume, job):
28
+ resume_emb = get_embedding(resume)
29
+ job_emb = get_embedding(job)
30
+ similarity = cosine_similarity(resume_emb, job_emb)[0][0]
31
+ return similarity
32
+
33
+ def extract_skills(text):
34
+ entities = ner_pipeline(text)
35
+ skills = []
36
+ for ent in entities:
37
+ if ent['entity'].endswith('MISC') or ent['entity'].endswith('ORG'):
38
+ skills.append(ent['word'])
39
+ return list(set(skills))
40
+
41
+ def generate_recommendations(resume_skills, job_skills):
42
+ missing = [s for s in job_skills if s not in resume_skills]
43
+ if not missing:
44
+ return "Все необходимые навыки присутствуют"
45
+
46
+ prompt = f"Add these skills to resume: {', '.join(missing[:3])}"
47
+ result = text_generator(prompt, max_length=50, num_return_sequences=1, pad_token_id=50256)
48
+ return result[0]['generated_text']
49
+
50
+ def analyze(resume_text, job_text):
51
+ if not resume_text or not job_text:
52
+ return "Заполните оба поля", "", ""
53
+
54
+ # Similarity
55
+ similarity = calculate_similarity(resume_text, job_text)
56
+ match_score = f"Match Score: {similarity*100:.1f}%"
57
+
58
+ # Skills extraction
59
+ resume_skills = extract_skills(resume_text)
60
+ job_skills = extract_skills(job_text)
61
+ missing_skills = [s for s in job_skills if s not in resume_skills]
62
+ skills_gap = f"Missing: {', '.join(missing_skills[:5]) if missing_skills else 'None'}"
63
+
64
+ # Recommendations
65
+ recommendations = generate_recommendations(resume_skills, job_skills)
66
+
67
+ return match_score, skills_gap, recommendations
68
+
69
+ with gr.Blocks() as demo:
70
+ gr.Markdown("# Resume-Job Matcher")
71
+ gr.Markdown("Система сопоставления резюме и вакансий")
72
+
73
+ with gr.Row():
74
+ resume_input = gr.Textbox(label="Resume", lines=10, placeholder="Paste resume here...")
75
+ job_input = gr.Textbox(label="Job Description", lines=10, placeholder="Paste job description here...")
76
+
77
+ analyze_btn = gr.Button("Analyze")
78
+
79
+ with gr.Row():
80
+ match_output = gr.Textbox(label="Match Score")
81
+ skills_output = gr.Textbox(label="Skills Gap")
82
+ recommendations_output = gr.Textbox(label="Recommendations")
83
+
84
+ analyze_btn.click(
85
+ fn=analyze,
86
+ inputs=[resume_input, job_input],
87
+ outputs=[match_output, skills_output, recommendations_output]
88
+ )
89
+
90
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ transformers
2
+ torch
3
+ gradio
4
+ scikit-learn
5
+ numpy
6
+ sentence-transformers