Spaces:
Running
Running
Trista Yao
commited on
Commit
·
59b9f80
1
Parent(s):
ec649be
add eval code
Browse files- app.py +124 -46
- requirements.txt +5 -1
app.py
CHANGED
@@ -1,62 +1,140 @@
|
|
1 |
import streamlit as st
|
2 |
from transformers import pipeline
|
3 |
-
from
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
-
|
|
|
|
|
|
|
6 |
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
col2.subheader(f"{ p['label'] }: { round(p['score'] * 100, 1)}%")
|
21 |
|
|
|
|
|
22 |
|
|
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
-
#
|
|
|
|
|
26 |
|
27 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
-
# st.title("ResumeTailor")
|
30 |
-
# st.write("Optimize your resume for specific job descriptions")
|
31 |
|
32 |
-
# col1, col2 = st.columns(2)
|
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 |
-
# # st.download_button(
|
59 |
-
# # "Download Refined Resume",
|
60 |
-
# # refined_resume,
|
61 |
-
# # file_name="refined_resume.txt"
|
62 |
-
# # )
|
|
|
1 |
import streamlit as st
|
2 |
from transformers import pipeline
|
3 |
+
from bert_score import score
|
4 |
+
import torch
|
5 |
+
import numpy as np
|
6 |
+
from sentence_transformers import SentenceTransformer
|
7 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
8 |
+
from rouge import Rouge
|
9 |
|
10 |
+
# Load the model once at app startup
|
11 |
+
@st.cache_resource
|
12 |
+
def load_embedding_model():
|
13 |
+
return SentenceTransformer('all-MiniLM-L6-v2')
|
14 |
|
15 |
+
embedding_model = load_embedding_model()
|
16 |
+
rouge = Rouge()
|
17 |
+
# 还有我们自己的模型
|
18 |
+
# 在fine-tuned model上传到huggingface后,可以用pipeline来加载模型
|
19 |
+
# pipeline = pipeline(model="your_username/your_model_name")
|
20 |
+
# 之后我们可以继续用pipeline来直接调用模型得到prediction, 详见后
|
21 |
|
22 |
+
# Just using F1 for simplicity now
|
23 |
+
def calculate_bert_score(candidate, reference):
|
24 |
+
# Make sure inputs are in list format as required by BERTScore
|
25 |
+
if isinstance(candidate, str):
|
26 |
+
candidate = [candidate]
|
27 |
+
if isinstance(reference, str):
|
28 |
+
reference = [reference]
|
29 |
+
|
30 |
+
# Calculate the score
|
31 |
+
P, R, F1 = score(candidate, reference, lang="en", return_hash=False)
|
32 |
+
# Return F1 as a float (converting from tensor)
|
33 |
+
return F1.item()
|
34 |
|
35 |
+
# Function to calculate cosine similarity
|
36 |
+
def calculate_cosine_similarity(text1, text2):
|
37 |
+
# Get embeddings
|
38 |
+
embedding1 = embedding_model.encode([text1])[0]
|
39 |
+
embedding2 = embedding_model.encode([text2])[0]
|
40 |
+
|
41 |
+
# Reshape for sklearn's cosine_similarity
|
42 |
+
embedding1 = embedding1.reshape(1, -1)
|
43 |
+
embedding2 = embedding2.reshape(1, -1)
|
44 |
+
|
45 |
+
# Calculate similarity
|
46 |
+
similarity = cosine_similarity(embedding1, embedding2)[0][0]
|
47 |
+
return similarity
|
48 |
|
49 |
+
# Function to calculate ROUGE scores
|
50 |
+
def calculate_rouge_scores(candidate, reference):
|
51 |
+
try:
|
52 |
+
scores = rouge.get_scores(candidate, reference)[0]
|
53 |
+
return {
|
54 |
+
'rouge-1': scores['rouge-1']['f'],
|
55 |
+
'rouge-l': scores['rouge-l']['f']
|
56 |
+
}
|
57 |
+
except:
|
58 |
+
# Handle empty strings or other issues
|
59 |
+
return {'rouge-1': 0, 'rouge-l': 0}
|
60 |
|
61 |
+
# UI
|
62 |
+
st.set_page_config(page_title="Resume Refinement Tool", layout="wide")
|
|
|
63 |
|
64 |
+
st.title("ResumeTailor")
|
65 |
+
st.write("Optimize your resume for specific job descriptions")
|
66 |
|
67 |
+
col1, col2 = st.columns(2)
|
68 |
|
69 |
+
with col1:
|
70 |
+
st.header("Inputs")
|
71 |
+
resume_text = st.text_area(
|
72 |
+
"Paste your resume work experience here",
|
73 |
+
height=300,
|
74 |
+
placeholder="Describe your work experience..."
|
75 |
+
)
|
76 |
+
|
77 |
+
job_description = st.text_area(
|
78 |
+
"Paste the job description here",
|
79 |
+
height=300,
|
80 |
+
placeholder="Paste the job description..."
|
81 |
+
)
|
82 |
+
|
83 |
+
if st.button("Refine Resume", type="primary"):
|
84 |
+
# 在这里调用模型
|
85 |
+
# For example:
|
86 |
+
# prediction = pipeline(resume_text, job_description)
|
87 |
+
refined_resume = "This would be the refined resume after model processing" # 现在这个是hard code的prediction
|
88 |
+
refined_score = 0.85 # Example hardcoded score
|
89 |
+
# 其实最终应该是下面的算法
|
90 |
+
# original_bertscore = calculate_bert_score(resume_text, job_description)
|
91 |
+
# refined_bertscore = calculate_bert_score(refined_resume, job_description)
|
92 |
+
# delta_bertscore = refined_score - original_score
|
93 |
|
94 |
+
# original_cosine_sim = calculate_cosine_similarity(resume_text, job_description)
|
95 |
+
# refined_cosine_sim = calculate_cosine_similarity(refined_resume, job_description)
|
96 |
+
# delta_cosine_sim = refined_cosine_sim - original_cosine_sim
|
97 |
|
98 |
+
# original_rouge = calculate_rouge_scores(resume_text, job_description)
|
99 |
+
# refined_rouge = calculate_rouge_scores(refined_resume, job_description)
|
100 |
+
# delta_rouge1 = refined_rouge['rouge-1'] - original_rouge['rouge-1']
|
101 |
+
# delta_rougel = refined_rouge['rouge-l'] - original_rouge['rouge-l']
|
102 |
+
|
103 |
+
with col2:
|
104 |
+
st.header("Results")
|
105 |
+
st.text_area("Refined Work Experience", value=refined_resume, height=300)
|
106 |
+
st.subheader("Similarity Score")
|
107 |
+
# Below is just hardcoded for now
|
108 |
+
st.metric("BERT Score (F1)", value=f"{refined_score:.2f}", delta=f"{refined_score - 0.75:.2f}")
|
109 |
+
# 其实应该是
|
110 |
+
# st.metric("BERT Score (F1)", value=f"{refined_bertscore:.2f}", delta=f"{delta_score:.2f}")
|
111 |
+
# st.metric("Cosine Similarity", value=f"{refined_cosine_sim:.2f}", delta=f"{delta_cosine_sim:.2f}")
|
112 |
+
# st.metric("ROUGE-1 (F1)", value=f"{refined_rouge['rouge-1']:.2f}", delta=f"{delta_rouge1:.2f}")
|
113 |
+
# st.metric("ROUGE-L (F1)", value=f"{refined_rouge['rouge-l']:.2f}", delta=f"{delta_rougel:.2f}")
|
114 |
|
|
|
|
|
115 |
|
|
|
116 |
|
117 |
+
|
118 |
+
|
119 |
+
'''
|
120 |
+
Below is a demo code to use hot-dog classification model
|
121 |
+
'''
|
122 |
+
# from PIL import Image
|
123 |
+
|
124 |
+
# pipeline = pipeline(task="image-classification", model="julien-c/hotdog-not-hotdog")
|
125 |
+
|
126 |
+
# st.title("Hot Dog? Or Not?")
|
127 |
+
|
128 |
+
# file_name = st.file_uploader("Upload a hot dog candidate image")
|
129 |
+
|
130 |
+
# if file_name is not None:
|
131 |
+
# col1, col2 = st.columns(2)
|
132 |
+
|
133 |
+
# image = Image.open(file_name)
|
134 |
+
# col1.image(image, use_column_width=True)
|
135 |
+
# predictions = pipeline(image)
|
136 |
+
|
137 |
+
# col2.header("Probabilities")
|
138 |
+
# for p in predictions:
|
139 |
+
# col2.subheader(f"{ p['label'] }: { round(p['score'] * 100, 1)}%")
|
140 |
+
|
|
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
@@ -1,2 +1,6 @@
|
|
1 |
transformers
|
2 |
-
torch
|
|
|
|
|
|
|
|
|
|
1 |
transformers
|
2 |
+
torch
|
3 |
+
bert_score
|
4 |
+
Rouge
|
5 |
+
sentence-transformers
|
6 |
+
scikit-learn
|