Skip to content

About

Korean procurement NLP with weak supervision, RoBERTa and LoRA, static INT8 ONNX, and FastAPI CPU serving.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Procurement NLP

English | 한국어

Korean public-procurement notice classification from titles alone, deployed as an INT8 ONNX CPU batch API.

License: MIT Python 3.10+

Why

New notices had to be routed as soon as they arrived. The service needed to decide whether a notice was eligible for bidding and which team should handle it without opening and analyzing the full document. Fine-grained labels for domains such as river engineering, fire protection, and telecommunications were limited, and the production server had no inference GPU.

How

A RoBERTa-large model fine-tuned with LoRA first learned bid eligibility and domain-specific language. Historical notice titles from each team were then clustered with UMAP and HDBSCAN to construct a domain ontology. The binary teacher's domain representation was combined with SBERT-RoBERTa weak labeling to create training labels for a multiclass student. Both classifiers were exported to static INT8 ONNX and served through a FastAPI batch path on CPU.

Result

Task Result
Bid-eligibility classification Macro-F1 0.9639, Accuracy 96.4%
Detailed-domain classification F1 0.90
CPU inference About 50 ms per notice
INT8 ONNX model About 330 MB

Pipeline

Notice titles
  -> RoBERTa-large + LoRA bid-eligibility teacher
  -> UMAP/HDBSCAN domain ontology
  -> SBERT + RoBERTa weak labeling
  -> Multiclass student
  -> Static INT8 ONNX
  -> FastAPI batch serving on CPU

Script map

01_preprocess.py            # Build the balanced binary dataset
02_train_binary.py          # Train RoBERTa-large + LoRA
03_vector_db.py             # Build an optional SBERT/FAISS index
04_cluster.py               # Cluster domain representations with UMAP/HDBSCAN
05_ontology.py              # Extract representative terms per cluster
06_weak_label.py            # Produce hybrid SBERT/RoBERTa weak labels
06_weak_label_llm.py        # Optional LLM-assisted review
07_optimization_compare.py  # Compare optimization and quantization paths
08_train_multiclass.py      # Train the detailed-domain classifier
09_quantize.py              # Export and statically quantize ONNX models
10_serve.py                 # Serve /classify_batch with FastAPI

Quick start

pip install -r requirements.txt

# Train bid eligibility
python 02_train_binary.py

# Build the domain ontology and weak labels
python 04_cluster.py
python 05_ontology.py
python 06_weak_label.py

# Train the detailed-domain model
python 08_train_multiclass.py

# Quantize and serve
python 09_quantize.py
python 10_serve.py

Implementation notes

  • UltimateTrainer combines focal loss, R-Drop, and FGM with LoRA fine-tuning.
  • Weak labeling uses per-label maximum similarity from a general Korean SBERT model and a procurement-domain RoBERTa teacher, with deterministic overrides for frequent categories.
  • Static INT8 quantization exports ONNX models and calibrates them on 200 samples for AVX512-VNNI CPU inference.

Public repository scope

This repository contains the training, weak-labeling, quantization, and serving code. Procurement data and trained weights are not included because they contain domain-specific labels and operational data.

License

MIT.

About

Korean procurement NLP with weak supervision, RoBERTa and LoRA, static INT8 ONNX, and FastAPI CPU serving.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages