FLAN-T5-small Resume Extractor (V2)
A learning / portfolio project: google/flan-t5-small fine-tuned to extract structured
fields from resume text. Trained only on synthetic, template-generated resumes. Not a
production recruitment tool.
Tasks (prompt = Task: <instruction>\n\nResume:\n<resume text>)
| Task | Instruction | Output format |
|---|---|---|
| skills | Extract all technical and professional skills listed in the resume. Separate them with semicolons. | A; B; C |
| education | Extract the candidate's highest educational qualification in the format: degree - institution. | degree - institution |
| projects | List the titles of all projects in the resume. Separate them with semicolons. | A; B |
| certifications | List all certifications in the resume, without the issuer. Separate them with semicolons. If there are none, answer None. | A; B or None |
| role | Identify the target job role the candidate is seeking. | role name |
Data
- 500 synthetic candidates, 6 roles, 5 tasks each = 2,500 examples
- Split by candidate (400 / 50 / 50) so no resume appears in more than one split
- Varied layouts, shuffled section order, and distractor tool names in project bullets
Training
Max input 1024 tokens, max target 256, LR 3e-4, batch 8, 10 epochs (best: epoch 9, val loss 0.0785), T4 GPU, fp32.
Results — synthetic test set (50 unseen candidates)
| Task | Zero-shot base model | Fine-tuned V2 |
|---|---|---|
| Skills (item F1) | 0.00 | 1.000 |
| Education (exact match) | 0.00 | 0.900 |
| Projects (item F1) | 0.00 | 0.996 |
| Certifications (item F1) | 0.04 | 0.976 |
| Role (exact match) | 0.00 | 1.000 |
These scores mainly show the model learned the synthetic format; they are not real-world accuracy.
Results — one held-out real resume (1,348 tokens)
| Task | 512 tokens | 1024 tokens | Full length |
|---|---|---|---|
| Skills (item F1) | 0.21 | 0.33 | 1.00 |
| Education | wrong | correct | correct |
| Projects (item F1) | 0.67 | 1.00 | 1.00 |
| Certifications (item F1) | 0.00 | 0.00 | 0.62 |
| Role | correct | correct | correct |
A V1 model (mixed tasks, 512-token input) failed every task on the same resume. Most of that failure was input truncation. Caveats: n = 1, and this resume's layout informed the design of the synthetic generator, so it is not a fully independent test.
Known limitations
- Use full-length input (no truncation) for long resumes; T5 uses relative positions.
- Certification lines formatted as
Name - Issuer, with commaare split incorrectly. - When a section is missing or cut off, the model may invent a plausible answer instead of saying it is absent.
- English only; synthetic template data; not evaluated for fairness. Do not use for hiring decisions.
Usage
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
tok = AutoTokenizer.from_pretrained("leeshal/flan-t5-small-resume-extractor-v2")
model = AutoModelForSeq2SeqLM.from_pretrained("leeshal/flan-t5-small-resume-extractor-v2")
prompt = "Task: Identify the target job role the candidate is seeking.\n\nResume:\n" + resume_text
ids = tok(prompt, return_tensors="pt") # no truncation for long resumes
print(tok.decode(model.generate(**ids, max_new_tokens=256, num_beams=4)[0], skip_special_tokens=True))