ProfRom commited on
Commit
d6abe23
·
verified ·
1 Parent(s): 9216aa1

Eckley - Final submission

Browse files
Files changed (1) hide show
  1. app.py +23 -129
app.py CHANGED
@@ -1,142 +1,36 @@
1
  import gradio as gr
2
- from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
3
- import torch
4
- import pypdf
5
- import re
6
 
7
- # NER Model: Standard setup with aggregation
8
- skill_pipe = pipeline(
9
- "token-classification",
10
- model="ihk/skillner",
11
- aggregation_strategy="simple"
12
- )
13
-
14
- # LLM: Flan-T5-Large
15
- model_id = "google/flan-t5-large"
16
- tokenizer = AutoTokenizer.from_pretrained(model_id)
17
- model = AutoModelForSeq2SeqLM.from_pretrained(model_id)
18
-
19
- def extract_text_from_pdf(file_path):
20
- text = ""
21
- try:
22
- with open(file_path, "rb") as f:
23
- reader = pypdf.PdfReader(f)
24
- for page in reader.pages:
25
- content = page.extract_text()
26
- if content:
27
- text += content + "\n"
28
- except Exception:
29
- return ""
30
- return text
31
-
32
- def analyze_profile(file_obj, text_input):
33
- resume_text = ""
34
- if file_obj is not None:
35
- if file_obj.name.endswith('.pdf'):
36
- resume_text = extract_text_from_pdf(file_obj.name)
37
- else:
38
- with open(file_obj.name, "r", encoding="utf-8") as f:
39
- resume_text = f.read()
40
- else:
41
- resume_text = text_input
42
-
43
- if not resume_text.strip():
44
- return "Please provide a resume.", "N/A"
45
-
46
- # Step 1: Skill Extraction & Cleaning
47
- try:
48
- results = skill_pipe(resume_text[:2000])
49
- raw_skills = [res['word'].strip() for res in results if 'SKILL' in res['entity_group']]
50
-
51
- clean_skills = []
52
- for s in raw_skills:
53
- s = s.replace("##", "")
54
- # Removing non-alphabetic noise
55
- s = re.sub(r'^[^a-zA-Z]+|[^a-zA-Z]+$', '', s)
56
- if len(s) > 2:
57
- clean_skills.append(s)
58
-
59
- skills = sorted(list(set(clean_skills)))
60
- except Exception:
61
- return "Extraction failed.", "N/A"
62
 
63
- if not skills:
64
- return "No skills detected.", "Try a more detailed resume."
65
 
66
- skills_str = ", ".join(skills)
 
 
67
 
68
- # Step 2: Few-Shot Prompting
 
69
 
70
- few_shot_prompt = (
71
- "Example:\n"
72
- "Skills: Python, SQL, AWS, Spark\n"
73
- "Certifications:\n"
74
- "1. AWS Certified Solutions Architect - Professional\n"
75
- "2. Databricks Certified Data Engineer Professional\n"
76
- "3. Google Professional Data Engineer\n\n"
77
- f"Actual Task:\n"
78
- f"Skills: {skills_str}\n"
79
- "Certifications:\n"
80
- "1."
81
- )
82
-
83
- inputs = tokenizer(few_shot_prompt, return_tensors="pt", truncation=True, max_length=512)
84
-
85
 
86
- outputs = model.generate(
87
- **inputs,
88
- max_new_tokens=80,
89
- num_beams=4, # Beam search is logical/less random
90
- repetition_penalty=1.2, # Lower penalty avoids hallucinations
91
- no_repeat_ngram_size=2, # Prevents word-looping
92
- early_stopping=True
93
  )
94
-
95
- roadmap = tokenizer.decode(outputs[0], skip_special_tokens=True)
96
-
97
- # Cleaning the output to ensure it starts with our '1.'
98
- if not roadmap.startswith("1."):
99
- roadmap = "1. " + roadmap
100
-
101
- return skills_str, roadmap
102
-
103
- # Documentation
104
- arch_doc = """
105
- ### System Architecture
106
- This system utilizes a three-stage pipeline for document intelligence. I integrated pypdf for raw document ingestion, followed by a JobBERT model fine-tuned for professional skill extraction. For the final reasoning layer, I used Flan-T5-Large to perform a gap analysis and generate an upskilling roadmap.
107
- """
108
 
109
- eval_doc = """
110
- ### Challenges & Solutions
111
- Fragmentation: To fix sub-word tokenization (e.g., "Py" + "##spark"), I implemented an Aggregation Strategy and custom Regex cleaning.
112
- Hallucinations: Early testing showed model "parrotting." I solved this using Few-Shot In-Context Learning and Beam Search (num_beams = 4‬) to ensure factual certification names.
113
- """
114
 
115
- ethics_doc = """
116
- ### Responsible AI & Ethics
117
- Bias Mitigation: The model is "feature-restricted"—the LLM only sees technical skills, blinding it to demographic data like names or gender.
118
- Data Privacy: This application uses transient processing; all document data exists only in volatile memory and is discarded immediately after the session ends.
119
- """
120
-
121
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
122
- gr.Markdown("# Advanced Resume Intelligence")
123
-
124
- with gr.Row():
125
- with gr.Column():
126
- file_in = gr.File(label="Upload Resume (PDF/TXT)", file_types=[".pdf", ".txt"])
127
- txt_in = gr.Textbox(label="Or Paste Text", lines=5)
128
- btn = gr.Button("Analyze Profile", variant="primary")
129
-
130
- with gr.Column():
131
- skill_out = gr.Textbox(label="Identified Skills")
132
- advice_out = gr.Textbox(label="AI Training Roadmap")
133
-
134
- btn.click(fn=analyze_profile, inputs=[file_in, txt_in], outputs=[skill_out, advice_out])
135
-
136
- with gr.Accordion("Project Documentation", open=False):
137
- gr.Markdown(arch_doc)
138
- gr.Markdown(eval_doc)
139
- gr.Markdown(ethics_doc)
140
 
141
  if __name__ == "__main__":
142
  demo.launch()
 
1
  import gradio as gr
2
+ from PIL import Image
3
+ from transformers import BlipProcessor, BlipForConditionalGeneration
 
 
4
 
5
+ MODEL_NAME = "Salesforce/blip-image-captioning-base"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ processor = BlipProcessor.from_pretrained(MODEL_NAME)
8
+ model = BlipForConditionalGeneration.from_pretrained(MODEL_NAME)
9
 
10
+ def generate_caption(image):
11
+ if image is None:
12
+ return "Please upload an image."
13
 
14
+ if image.mode != "RGB":
15
+ image = image.convert("RGB")
16
 
17
+ inputs = processor(image, return_tensors="pt")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ output = model.generate(
20
+ **inputs,
21
+ max_new_tokens=30
 
 
 
 
22
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ caption = processor.decode(output[0], skip_special_tokens=True)
25
+ return caption
 
 
 
26
 
27
+ demo = gr.Interface(
28
+ fn=generate_caption,
29
+ inputs=gr.Image(type="pil", label="Upload an Image"),
30
+ outputs=gr.Textbox(label="Generated Caption"),
31
+ title="AI Image Captioning System",
32
+ description="Upload an image and generate a caption using Salesforce/blip-image-captioning-base."
33
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  if __name__ == "__main__":
36
  demo.launch()