root
commited on
Commit
Β·
da61f37
1
Parent(s):
1ced284
ss
Browse files- app.py +61 -20
- requirements.txt +1 -1
app.py
CHANGED
@@ -20,6 +20,15 @@ import time
|
|
20 |
import faiss
|
21 |
import re
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
# Download NLTK resources
|
24 |
try:
|
25 |
nltk.data.find('tokenizers/punkt')
|
@@ -85,35 +94,57 @@ if 'explanations_generated' not in st.session_state:
|
|
85 |
st.session_state.explanations_generated = False
|
86 |
if 'current_job_description' not in st.session_state:
|
87 |
st.session_state.current_job_description = ""
|
88 |
-
|
89 |
-
|
90 |
-
if '
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
# Separate smaller model for intent analysis
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
|
|
|
|
|
|
|
|
|
|
105 |
|
106 |
@st.cache_resource
|
107 |
def load_embedding_model():
|
108 |
"""Load and cache the BGE embedding model"""
|
109 |
try:
|
110 |
with st.spinner("π Loading BAAI/bge-large-en-v1.5 model..."):
|
111 |
-
|
|
|
|
|
112 |
st.success("β
Embedding model loaded successfully!")
|
113 |
return model
|
114 |
except Exception as e:
|
115 |
st.error(f"β Error loading embedding model: {str(e)}")
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
@st.cache_resource
|
119 |
def load_cross_encoder():
|
@@ -121,12 +152,22 @@ def load_cross_encoder():
|
|
121 |
try:
|
122 |
with st.spinner("π Loading Cross-Encoder ms-marco-MiniLM-L6-v2..."):
|
123 |
from sentence_transformers import CrossEncoder
|
124 |
-
|
|
|
|
|
125 |
st.success("β
Cross-Encoder model loaded successfully!")
|
126 |
return model
|
127 |
except Exception as e:
|
128 |
st.error(f"β Error loading Cross-Encoder model: {str(e)}")
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
|
131 |
def generate_qwen3_response(prompt, tokenizer, model, max_new_tokens=200):
|
132 |
messages = [{"role": "user", "content": prompt}]
|
|
|
20 |
import faiss
|
21 |
import re
|
22 |
|
23 |
+
# Fix for older PyTorch versions that don't have get_default_device
|
24 |
+
if not hasattr(torch, 'get_default_device'):
|
25 |
+
def get_default_device():
|
26 |
+
if torch.cuda.is_available():
|
27 |
+
return torch.device('cuda')
|
28 |
+
else:
|
29 |
+
return torch.device('cpu')
|
30 |
+
torch.get_default_device = get_default_device
|
31 |
+
|
32 |
# Download NLTK resources
|
33 |
try:
|
34 |
nltk.data.find('tokenizers/punkt')
|
|
|
94 |
st.session_state.explanations_generated = False
|
95 |
if 'current_job_description' not in st.session_state:
|
96 |
st.session_state.current_job_description = ""
|
97 |
+
# Load Qwen models with error handling
|
98 |
+
try:
|
99 |
+
if 'qwen3_tokenizer' not in st.session_state:
|
100 |
+
st.session_state.qwen3_tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-14B")
|
101 |
+
if 'qwen3_model' not in st.session_state:
|
102 |
+
st.session_state.qwen3_model = AutoModelForCausalLM.from_pretrained(
|
103 |
+
"Qwen/Qwen3-14B",
|
104 |
+
torch_dtype="auto",
|
105 |
+
device_map="auto"
|
106 |
+
)
|
107 |
+
except Exception as e:
|
108 |
+
st.warning(f"β οΈ Could not load Qwen3-14B: {str(e)}")
|
109 |
+
st.session_state.qwen3_tokenizer = None
|
110 |
+
st.session_state.qwen3_model = None
|
111 |
+
|
112 |
# Separate smaller model for intent analysis
|
113 |
+
try:
|
114 |
+
if 'qwen3_intent_tokenizer' not in st.session_state:
|
115 |
+
st.session_state.qwen3_intent_tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-1.7B")
|
116 |
+
if 'qwen3_intent_model' not in st.session_state:
|
117 |
+
st.session_state.qwen3_intent_model = AutoModelForCausalLM.from_pretrained(
|
118 |
+
"Qwen/Qwen3-1.7B",
|
119 |
+
torch_dtype="auto",
|
120 |
+
device_map="auto"
|
121 |
+
)
|
122 |
+
except Exception as e:
|
123 |
+
st.warning(f"β οΈ Could not load Qwen3-1.7B: {str(e)}")
|
124 |
+
st.session_state.qwen3_intent_tokenizer = None
|
125 |
+
st.session_state.qwen3_intent_model = None
|
126 |
|
127 |
@st.cache_resource
|
128 |
def load_embedding_model():
|
129 |
"""Load and cache the BGE embedding model"""
|
130 |
try:
|
131 |
with st.spinner("π Loading BAAI/bge-large-en-v1.5 model..."):
|
132 |
+
# Try with explicit device specification
|
133 |
+
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
134 |
+
model = SentenceTransformer('BAAI/bge-large-en-v1.5', device=device)
|
135 |
st.success("β
Embedding model loaded successfully!")
|
136 |
return model
|
137 |
except Exception as e:
|
138 |
st.error(f"β Error loading embedding model: {str(e)}")
|
139 |
+
try:
|
140 |
+
# Fallback: try with a smaller model
|
141 |
+
st.warning("π Trying fallback model: all-MiniLM-L6-v2...")
|
142 |
+
model = SentenceTransformer('all-MiniLM-L6-v2')
|
143 |
+
st.success("β
Fallback embedding model loaded!")
|
144 |
+
return model
|
145 |
+
except Exception as e2:
|
146 |
+
st.error(f"β Fallback also failed: {str(e2)}")
|
147 |
+
return None
|
148 |
|
149 |
@st.cache_resource
|
150 |
def load_cross_encoder():
|
|
|
152 |
try:
|
153 |
with st.spinner("π Loading Cross-Encoder ms-marco-MiniLM-L6-v2..."):
|
154 |
from sentence_transformers import CrossEncoder
|
155 |
+
# Try with explicit device specification
|
156 |
+
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
157 |
+
model = CrossEncoder('cross-encoder/ms-marco-MiniLM-L6-v2', device=device)
|
158 |
st.success("β
Cross-Encoder model loaded successfully!")
|
159 |
return model
|
160 |
except Exception as e:
|
161 |
st.error(f"β Error loading Cross-Encoder model: {str(e)}")
|
162 |
+
try:
|
163 |
+
# Fallback: try without device specification
|
164 |
+
st.warning("π Trying Cross-Encoder without device specification...")
|
165 |
+
model = CrossEncoder('cross-encoder/ms-marco-MiniLM-L6-v2')
|
166 |
+
st.success("β
Cross-Encoder model loaded (fallback)!")
|
167 |
+
return model
|
168 |
+
except Exception as e2:
|
169 |
+
st.error(f"β Cross-Encoder fallback also failed: {str(e2)}")
|
170 |
+
return None
|
171 |
|
172 |
def generate_qwen3_response(prompt, tokenizer, model, max_new_tokens=200):
|
173 |
messages = [{"role": "user", "content": prompt}]
|
requirements.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
streamlit==1.31.0
|
2 |
transformers>=4.51.0
|
3 |
-
torch
|
4 |
pdfplumber==0.10.1
|
5 |
PyPDF2==3.0.1
|
6 |
python-docx==1.0.1
|
|
|
1 |
streamlit==1.31.0
|
2 |
transformers>=4.51.0
|
3 |
+
torch>=2.1.0
|
4 |
pdfplumber==0.10.1
|
5 |
PyPDF2==3.0.1
|
6 |
python-docx==1.0.1
|