Token Classification
Transformers
Safetensors
Thai
camembert
ner
thai
phayathaibert
job-posting
apple-silicon
Eval Results (legacy)
Instructions to use chayuto/thai-job-ner-phayathaibert with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use chayuto/thai-job-ner-phayathaibert with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="chayuto/thai-job-ner-phayathaibert")# Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("chayuto/thai-job-ner-phayathaibert") model = AutoModelForTokenClassification.from_pretrained("chayuto/thai-job-ner-phayathaibert", device_map="auto") - Notebooks
- Google Colab
- Kaggle
docs: update model card for Sprint 7.2 (real-world F1=0.975)
Browse files
README.md
CHANGED
|
@@ -24,15 +24,18 @@ model-index:
|
|
| 24 |
type: token-classification
|
| 25 |
name: Named Entity Recognition
|
| 26 |
metrics:
|
| 27 |
-
- name: F1
|
| 28 |
type: f1
|
| 29 |
-
value: 0.
|
| 30 |
-
- name:
|
|
|
|
|
|
|
|
|
|
| 31 |
type: precision
|
| 32 |
-
value: 0.
|
| 33 |
-
- name: Recall
|
| 34 |
type: recall
|
| 35 |
-
value: 0.
|
| 36 |
---
|
| 37 |
|
| 38 |
# Thai Job NER — Fine-tuned PhayaThaiBERT
|
|
@@ -69,74 +72,83 @@ for entity in results:
|
|
| 69 |
|
| 70 |
## Training
|
| 71 |
|
| 72 |
-
- **Base model:** `clicknext/phayathaibert` (CamemBERT architecture, ~122M params
|
| 73 |
-
- **Training data:**
|
|
|
|
| 74 |
- **Hardware:** Apple Silicon MPS backend, FP32
|
| 75 |
-
- **Hyperparameters:** LR=3e-5, warmup=0.1, batch=2, grad_accum=
|
| 76 |
-
- **Training time:** ~
|
| 77 |
|
| 78 |
### Data Pipeline
|
| 79 |
|
| 80 |
-
Raw Thai text +
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
## Evaluation
|
| 83 |
|
| 84 |
-
###
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
| Metric | Score |
|
| 87 |
|--------|-------|
|
| 88 |
-
| **F1** | **0.
|
| 89 |
-
| Precision | 0.
|
| 90 |
-
| Recall | 0.
|
| 91 |
-
|
| 92 |
-
### Per-Entity F1
|
| 93 |
-
|
| 94 |
-
| Entity | F1 | Precision | Recall |
|
| 95 |
-
|--------|-----|-----------|--------|
|
| 96 |
-
| CONTACT | 0.987 | 0.983 | 0.991 |
|
| 97 |
-
| PERSON | 0.979 | 0.972 | 0.986 |
|
| 98 |
-
| LOCATION | 0.966 | 0.950 | 0.983 |
|
| 99 |
-
| EMPLOYMENT_TERMS | 0.966 | 0.943 | 0.990 |
|
| 100 |
-
| COMPENSATION | 0.965 | 0.956 | 0.973 |
|
| 101 |
-
| HARD_SKILL | 0.946 | 0.919 | 0.974 |
|
| 102 |
-
| DEMOGRAPHIC | 0.915 | 0.897 | 0.935 |
|
| 103 |
-
|
| 104 |
-
### Comparison vs WangchanBERTa
|
| 105 |
-
|
| 106 |
-
| Entity | WangchanBERTa | PhayaThaiBERT | Delta |
|
| 107 |
-
|--------|---------------|---------------|-------|
|
| 108 |
-
| **Overall F1** | 0.897 | **0.956** | **+0.059** |
|
| 109 |
-
| COMPENSATION | 0.764 | **0.965** | **+0.200** |
|
| 110 |
-
| PERSON | 0.907 | **0.979** | **+0.072** |
|
| 111 |
-
| HARD_SKILL | 0.903 | **0.946** | **+0.043** |
|
| 112 |
-
| EMPLOYMENT_TERMS | 0.926 | **0.966** | +0.040 |
|
| 113 |
-
| DEMOGRAPHIC | 0.875 | **0.915** | +0.041 |
|
| 114 |
-
| CONTACT | 0.962 | **0.987** | +0.025 |
|
| 115 |
-
| LOCATION | 0.959 | **0.966** | +0.008 |
|
| 116 |
-
|
| 117 |
-
PhayaThaiBERT improves on every entity type, with the most dramatic gain on COMPENSATION (+0.200 F1).
|
| 118 |
-
|
| 119 |
-
## Links
|
| 120 |
-
|
| 121 |
-
- **Model:** [chayuto/thai-job-ner-phayathaibert](https://huggingface.co/chayuto/thai-job-ner-phayathaibert)
|
| 122 |
-
- **WangchanBERTa variant:** [chayuto/thai-job-ner-wangchanberta](https://huggingface.co/chayuto/thai-job-ner-wangchanberta)
|
| 123 |
-
- **Dataset:** [chayuto/thai-job-ner-dataset](https://huggingface.co/datasets/chayuto/thai-job-ner-dataset)
|
| 124 |
-
- **Source Code:** [github.com/chayuto/thai-job-nlp-ner](https://github.com/chayuto/thai-job-nlp-ner)
|
| 125 |
|
| 126 |
-
##
|
| 127 |
|
| 128 |
-
|
| 129 |
-
-
|
| 130 |
-
|
| 131 |
-
|
|
|
|
| 132 |
|
| 133 |
-
|
|
|
|
|
|
|
| 134 |
|
| 135 |
-
-
|
| 136 |
-
-
|
| 137 |
-
-
|
| 138 |
-
-
|
| 139 |
|
| 140 |
-
##
|
| 141 |
|
| 142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
type: token-classification
|
| 25 |
name: Named Entity Recognition
|
| 26 |
metrics:
|
| 27 |
+
- name: F1 (real-world)
|
| 28 |
type: f1
|
| 29 |
+
value: 0.975
|
| 30 |
+
- name: F1 (mixed test)
|
| 31 |
+
type: f1
|
| 32 |
+
value: 0.929
|
| 33 |
+
- name: Precision (real-world)
|
| 34 |
type: precision
|
| 35 |
+
value: 0.960
|
| 36 |
+
- name: Recall (real-world)
|
| 37 |
type: recall
|
| 38 |
+
value: 0.990
|
| 39 |
---
|
| 40 |
|
| 41 |
# Thai Job NER — Fine-tuned PhayaThaiBERT
|
|
|
|
| 72 |
|
| 73 |
## Training
|
| 74 |
|
| 75 |
+
- **Base model:** `clicknext/phayathaibert` (CamemBERT architecture, ~122M params)
|
| 76 |
+
- **Training data:** 510 style-matched synthetic + 270 real posts (54 real upsampled 5x)
|
| 77 |
+
- **Training strategy:** Mixed synthetic + real with real data upsampling to ensure 34.6% real data proportion
|
| 78 |
- **Hardware:** Apple Silicon MPS backend, FP32
|
| 79 |
+
- **Hyperparameters:** LR=3e-5, warmup=0.1, batch=2, grad_accum=4, 10 epochs, gradient checkpointing, frozen embeddings
|
| 80 |
+
- **Training time:** ~35 min on Apple Silicon
|
| 81 |
|
| 82 |
### Data Pipeline
|
| 83 |
|
| 84 |
+
Raw Thai text + entity annotations -> fuzzy alignment with rapidfuzz + pythainlp TCC boundary snapping -> subword token mapping via offset_mapping -> IOB2-formatted HuggingFace Dataset.
|
| 85 |
+
|
| 86 |
+
### Key Training Insight
|
| 87 |
+
|
| 88 |
+
Real data proportion is the dominant factor for real-world performance. Our experiments showed:
|
| 89 |
+
|
| 90 |
+
| Real Data % | Real-World F1 |
|
| 91 |
+
|------------|---------------|
|
| 92 |
+
| 2.9% | 0.771 |
|
| 93 |
+
| 4.1% | 0.935 |
|
| 94 |
+
| 9.6% | 0.714* |
|
| 95 |
+
| 23.3% | 0.975 |
|
| 96 |
+
| **34.6%** | **0.975** |
|
| 97 |
+
|
| 98 |
+
(*small dataset, underfitting)
|
| 99 |
+
|
| 100 |
+
Style-matched synthetic data (matching real-world formatting patterns) is 3x more data-efficient than generic synthetic data.
|
| 101 |
|
| 102 |
## Evaluation
|
| 103 |
|
| 104 |
+
### Real-World Performance (8 held-out real posts, 98 entities)
|
| 105 |
+
|
| 106 |
+
| Entity | Precision | Recall | F1 |
|
| 107 |
+
|--------|-----------|--------|-----|
|
| 108 |
+
| COMPENSATION | 1.000 | 1.000 | **1.000** |
|
| 109 |
+
| CONTACT | 1.000 | 1.000 | **1.000** |
|
| 110 |
+
| DEMOGRAPHIC | 1.000 | 1.000 | **1.000** |
|
| 111 |
+
| LOCATION | 1.000 | 1.000 | **1.000** |
|
| 112 |
+
| PERSON | 1.000 | 1.000 | **1.000** |
|
| 113 |
+
| HARD_SKILL | 0.947 | 1.000 | **0.973** |
|
| 114 |
+
| EMPLOYMENT_TERMS | 0.846 | 0.917 | **0.880** |
|
| 115 |
+
| **Overall** | **0.960** | **0.990** | **0.975** |
|
| 116 |
+
|
| 117 |
+
### Mixed Test Performance (78 examples)
|
| 118 |
|
| 119 |
| Metric | Score |
|
| 120 |
|--------|-------|
|
| 121 |
+
| **F1** | **0.929** |
|
| 122 |
+
| Precision | 0.915 |
|
| 123 |
+
| Recall | 0.944 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
+
### Model Evolution
|
| 126 |
|
| 127 |
+
| Version | Data | Real-World F1 |
|
| 128 |
+
|---------|------|---------------|
|
| 129 |
+
| v1 (Sprint 5) | 1,253 synthetic only | 0.143 |
|
| 130 |
+
| v2 (Sprint 6) | 1,057 synthetic + real | 0.935 |
|
| 131 |
+
| **v3 (Sprint 7)** | **510 v3 synthetic + real (5x)** | **0.975** |
|
| 132 |
|
| 133 |
+
**Note:** Real-world test set is small (8 posts, 98 entities). Confidence intervals are wide. More real data is needed for robust evaluation.
|
| 134 |
+
|
| 135 |
+
## Limitations
|
| 136 |
|
| 137 |
+
- Trained primarily on caregiving/elderly care job posts (~70% of training data). Performance on other domains (tech, office, etc.) may be lower.
|
| 138 |
+
- Real-world evaluation is based on only 8 held-out posts — results should be interpreted with caution.
|
| 139 |
+
- Entity annotations are silver labels (Claude-annotated), not human gold labels.
|
| 140 |
+
- max_length=256 tokens — longer posts may have entities truncated.
|
| 141 |
|
| 142 |
+
## Citation
|
| 143 |
|
| 144 |
+
If you use this model, please cite:
|
| 145 |
+
|
| 146 |
+
```
|
| 147 |
+
@misc{thai-job-ner-phayathaibert,
|
| 148 |
+
title={Thai Job NER: Fine-tuned PhayaThaiBERT for Job Post Entity Extraction},
|
| 149 |
+
author={Chayut O.},
|
| 150 |
+
year={2026},
|
| 151 |
+
publisher={HuggingFace},
|
| 152 |
+
url={https://huggingface.co/chayuto/thai-job-ner-phayathaibert}
|
| 153 |
+
}
|
| 154 |
+
```
|