Independent Research · 2025 – 2026MiniLM v2 · Inference V2

Parselex

Previously known as Resume-TLM

High-fidelity resume parsing without the LLM tax. A modular MiniLM pipeline: hybrid heading detection → section classification → domain-specific boundary, segmentation, and field cascades — deployed as 3 INT8 ONNX bundles, plus a server-side Inference V2 runner with selectable FP32/INT8 precision. Zero API calls at inference.

Working demo
parselex · pipeline
Architecture
MiniLM-L6-v2 + GLU
Parameters
~22M per encoder
Deployment
3 INT8 bundles
Pipeline INT8
~3.9 s
01 — Engineering Thesis

Efficiency as a feature.

The “LLM Tax”: the unnecessary cost, latency, and hallucination risk of routing a structured extraction task through a general-purpose language model.

MetricGPT-4o / Claude 3.5Parselex ✓
Parameters∼175B+ (GPT-4o / Claude)~22M (MiniLM-L6-v2 per encoder)
Inference3–8s (API round-trip)~3.9 s INT8 · ~7.4 s FP32 (Inference V2, server, warm cache)
Model disk sizeN/A (cloud)~157 MB INT8 (3 bundles)
Overall GT (INT8)Unstructured JSON86.0% (sample resume; education head drives −3.5 pp vs FP32)
Section label accuracy~85–95% (hallucination risk)97.6% val chunk accuracy
Experience field F1Unstructured JSON90.9% val pooled macro F1
Token-level confidenceNoYes — per-token / per-block logits
Runs in browserNo (API-only)Planned — on hold
Data privacySent to external APILocal inference — no data leaves device
02 — The Data Factory

High-quality parsing needs high-quality ground truth.

Instead of downloading a dataset, I built the machinery to create one — a custom Human-in-the-Loop Labeling Workbench.

01
Raw PDF
203 resumes
02
Local LLM Pre-label
Gemma 4 via Ollama
03
Human Review UI
Next.js annotator
04
Gold Dataset
MongoDB Atlas
🏷️

LLM Pre-annotation

Gemma 4 generates "silver standard" labels for every token before a human sees the resume. Batch runs process 12 resumes per Ollama cooldown window with smart skip logic for already-labeled docs.

70% less manual effort
👁️

Visual Labeling UI

Custom Next.js app renders token bounding boxes, section clusters, and BIO tag assignments in a 3-stage interface (Live → Heuristic → AI) across Personal, Skills, Experience, Education, and Projects sections. Experience Phase 3 eval filters to 108 train / 18 val resumes with confirmed job blocks.

3-stage review pipeline
🛡️

Data Integrity

The UI enforces 8D/24D spatial feature constraints during labeling. BIO violation audit scripts catch illegal tag transitions before training. Per-document loss scores surface high-loss outliers for re-review.

savedBy: 'user' | 'model'
203
Total in corpus
134 / 24
Train / val (section)
~189
Fully labeled
5
Label stages
03 — The Laboratory

Architecture deep dive.

GLU Spatial Fusion

Resumes are spatial documents — a header's position is as informative as its text. A Gated Linear Unit selectively blends token semantics with layout features at inference time, without hardcoding layout rules:

# GLUSpatialFusion forward pass
gate = sigmoid(W_g · [f_text ; f_spatial])
output = gate × f_text + (1 − gate) × f_spatial
 
# Spatial dims vary by stage (MiniLM backbone):
# Section P1 line hybrid → 10D (bbox + page + line_idx)
# Domain token heads → 8–20D (bbox + page-relative position)
# Education phrase seg → 28D (extended: line context + font size)
# Block classifiers → 4–20D (chunk spatial, varies by track)
# Personal segment → 24D (segment-level spatial GLU)

Training Configuration

Backbone
all-MiniLM-L6-v2
Optimizer
AdamW · lr=2e-5
LR Schedule
Cosine decay + 10% warmup
Gradient clip
max_norm=1.0
Early stopping
Patience = 4 epochs
Entry points
Per-track run.py
Class weights
sqrt-inverse-freq [0.5, 5.0]
Batch size
8 (token) · 16 (chunk)

Modular Track Pipeline

Stage 1Section P1 hybrid
Heading boundary detection

Hybrid rules + MiniLM line classifier (standalone line_minilm_int8.onnx). Detects B-HEADING / I-HEADING tokens on uncertain lines. Val FHA: 94.7% · recall: 95.9%. Not inside the 10-head graph — line-level prev/next context requires standalone ONNX.

Stage 2Section P2 chunk classifier
Section label per heading block

Autoregressive chunk classifier maps each block to EDUCATION · EXPERIENCE · PROJECTS · SKILLS · PERSONAL. Virtual PERSONAL chunk handles headless resumes. Val chunk accuracy: 97.6%.

Stage 3aDomain cascade (×3 sections)
Entry boundaries → phrase seg → field labels

Combined 10-head MiniLM (combined_ten_head_int8.onnx). Per section: P2 entry boundaries → P1 phrase segmentation (B-SEG / I-SEG) → P3 block classification. Experience fields: ROLE · COMP · DATE · DESC. Exp val: 100% FBA · 97.5% seg · 90.9% F1. Edu: 69.4% FBA · 94.1% seg · 87.8% F1. Proj: 90.9% FBA · 90.2% F1.

Stage 3bPersonal + Skills combined
Personal segments + skills BIO

personal_skills_combined_int8.onnx (~63 MB INT8). Personal: segment-level entities (NAME, EMAIL, PHONE, …) with 24D spatial GLU — B-NAME 99.4% · B-EMAIL 98.1% · B-PHONE 96.3% F1. Skills: per-token BIO. Val macro F1: 91.7% personal · 65.4% skills.

04 — Benchmarks

Measured. Not estimated.

Locked validation metrics from PyTorch eval reports, plus ONNX INT8 parity gates (combined/reports/comparison.md, 2026-07-01). Inference V2 (server-side PyTorch, July 2026): full pipeline INT8 ~3.9 s vs FP32 ~7.4 s on a gold-labeled sample resume — Skills, Experience, and Projects within 1 pp of FP32; Education shows known INT8 drift.

97.6%
Section labels
Val chunk accuracy Section P2 classifier
100%
Exp boundaries
Val aggregate FBA Experience Phase 2
~3.9s
INT8 pipeline
Inference V2 · server ~1.9× vs FP32 (warm cache)
ONNX INT8 deployment gate — PyTorch baseline vs INT8 export
BundleMetricPyTorchONNX INT8DeltaStatus
Section P1Val FHA94.68%94.09%−0.59ppPASS
Section P1Val recall95.87%95.28%−0.59ppPASS
Section P2Val accuracy97.55%97.55%0.00ppPASS
PersonalVal macro F191.71%90.26%−1.45ppPASS
SkillsVal macro F165.38%65.46%+0.08ppPASS
Production deployment — 3 INT8 ONNX bundles (~157 MB total)
ArtifactRoleGraphDisk
line_minilm_int8.onnx
Section P1 hybridStandalone~63 MB
combined_ten_head_int8.onnxCore cascade
Section P2 + 9 domain headsCombined graph~94 MB
personal_skills_combined_int8.onnx
Personal segment + Skills BIOCombined graph~63 MB
Per-stage locked validation metrics (val split)
94.7%
Section P1 FHA
Val strict heading accuracy
97.6%
Section Labels
Val chunk accuracy
100%
Exp Boundaries
Val aggregate FBA
90.9%
Exp Field F1
Val pooled macro F1
90.9%
Proj Boundaries
Val aggregate FBA
90.2%
Proj Field F1
Val macro F1
94.1%
Edu Phrase Seg
Val token accuracy
65.4%
Skills F1
Val macro F1 (labeling granularity)

Inference V2 timings are server-side PyTorch INT8 (warm cache), not browser ONNX. Legacy DistilRoBERTa 13-model benchmarks (2.96s / 40 MB / 280 MB) are from the pre-MiniLM architecture and are no longer representative of the current 3-bundle deployment.

05 — JSON Sandbox

Show, don't tell.

Illustrative structured output showing the JSON the model produces — with per-field confidence scores. Representative examples, not from a live run.

Raw Resume Text
John Doe
[email protected] | +1 555 010 2345
github.com/johndoe | Austin, TX

EXPERIENCE
Software Engineer — Acme Corp (2022–2024)
Built microservices in Go, reduced p99 latency by 40%

SKILLS
Go, Python, Kubernetes, PostgreSQL, gRPC

EDUCATION
B.S. Computer Science — State University (2018–2022)
Extracted JSON✓ Structured
{
"personal": {
"name":"John Doe"conf: 0.994
"email":"[email protected]"conf: 0.971
"phone":"+1 555 010 2345"conf: 0.958
"github":"github.com/johndoe"conf: 0.933
"location":"Austin, TX"conf: 0.912
},
"sections_detected": [
"EXPERIENCE"
"SKILLS"
"EDUCATION"
],
"experience": [
{
"role": "Software Engineer"
"company": "Acme Corp"
"start_date": "2022"
"end_date": "2024"
"confidence": 0.967
}
]
}
06 — System Architecture

Full stack, production-ready.

// production inference flow — 3 INT8 bundles
PDF Upload ──▶ pdfplumber / PDF.js ──▶ Word tokens + bounding boxes per page
↓ (spatial feature vectors: 4D–28D per token, varies by stage)
line_minilm_int8.onnx ──▶ Section P1 hybrid (rules + MiniLM line classifier)
↓ (heading keys per page, lineIndex)
combined_ten_head_int8.onnx ──▶ Section P2 + domain cascade (edu / exp / proj)
↓ (boundaries → phrase seg → field labels per section)
personal_skills_combined_int8.onnx ──▶ Personal segments + Skills BIO
↓ (fully-classified token stream)
structured_output.json ──▶ Structured JSON
// labeling stack
Next.js labeling UI ──▶ Ollama (Gemma 4 pre-label) ──▶ FastAPI Training Engine
↓ (PyTorch · MiniLM-L6-v2 · AdamW · per-track run.py)
MongoDB (gold labels) ──▶ DataLoader ──▶ Model Checkpoints (.pt)
// deployment target
PyTorch .pt ──▶ ONNX opset 17 (torch.onnx.export) ──▶ INT8 QUInt8 (onnxruntime.quantization)
↓ (~157 MB INT8 · Cloudflare R2 staging · parity gates PASS)
// server path
training-engine/inference_v2 ──▶ FP32 or INT8 (~7.4s / ~3.9s sample resume)
// browser path: 3-bundle ONNX — on hold (parity work incomplete)
all-MiniLM-L6-v2PyTorch 2.xHuggingFace TransformersGLU Spatial FusionAdamW · Cosine LRFocal Loss γ=2.0ONNX opset 17onnxruntime v1.24.3INT8 QUInt8 dynamicpdfplumberPyMuPDFMongoDB AtlasFastAPIOllama / Gemma 4Next.js (labeling UI)Cloudflare R2
07 — Failure Log & Edge Cases

Where it fails — and how it's being fixed.

Honesty as an engineering signal. Real edge cases, their root causes, and the current mitigation status.

08 — Limitations

Honest constraints.

Systemic limits of the current corpus, architecture, and deployment state — separate from specific edge-case bugs in the failure log above.

Limited training data

~203 resumes in the MongoDB corpus; ~134 train / 24 val for the section gate. Domain tracks (experience, education, project) filter further by section presence and confirmed entry heads — effective sample sizes are smaller per stage.

Education boundaries

69.4% val FBA — the weakest stage in the pipeline. Education INT8 quantization shows the largest GT regression on a sample resume (−19.7 pp); val FBA still the primary bottleneck. Active improvement work.

Skills extraction

65.4% val macro F1. Dense run-on skill strings (e.g. "Python OOPs Data Analysis ML Streamlit") are a labeling granularity issue, not section misclassification.

Layout coverage

Multi-column resumes are excluded from training. Reading-order errors in the PDF extraction layer propagate to spatial features and boundary detection.

Resume diversity

Corpus skews toward Indian and tech-heavy formats. Generalization to creative layouts, non-English resumes, or industry-specific templates is unproven.

Browser inference

ONNX bundles pass locked parity gates; browser runner is on hold. Server-side Inference V2 (selectable FP32/INT8) is available for benchmarking — ~3.9 s INT8 full pipeline on a sample resume.

09 — Milestones

Build log.

Labeling app + human-verified gold dataset (~203 resumes)✓ Done
Training engine (FastAPI + PyTorch)✓ Done
MiniLM-L6-v2 migration — retired DistilRoBERTa (June 2026)✓ Done
Combined 10-head + Personal/Skills 2-head ONNX export✓ Done
ONNX INT8 dynamic quantization — 3 bundles (~157 MB total)✓ Done
ONNX INT8 parity gates — all bundles PASS (2026-07-01)✓ Done
Locked validation reports per track (reports/minilm/overall/)✓ Done
Inference V2 — selectable FP32/INT8 server pipeline (2026-07-08)✓ Done
Education boundary val improvement (69% → target 85%+ FBA)
Static calibration INT8 for edge-case domain heads (education phrase seg/classify; sample resume −19.7 pp INT8 drift)
Train on full 203-resume split (assign trainingMeta.split to all)
Active-learning /infer endpoint + high-loss re-review loop
Live browser demo — ONNX Runtime Web (on hold)
What's next

Built for production NLP —
not just a demo.

Three INT8 ONNX bundles, locked validation metrics, and Inference V2 server benchmarks (~3.9 s INT8 full pipeline). Happy to discuss architecture, quantization trade-offs (including where INT8 is not lossless), dataset design, or production NLP.