Skip to content

Commit 1a78099

Browse files
Sid Mohanclaude
andcommitted
Add v1.2 backbone freezing experiment
- Versioned Colab notebook: v1.2_freeze_backbone.ipynb - Local training script: scripts/train_v1.2_local.py (RTX 3090) - FreezeBackboneCallback: freezes DeBERTa after epoch 4 - Updated training chronicle with v1.1 results and v1.2 hypothesis Hypothesis: backbone destabilizes under amplified tier-weighted gradients (~9x signal). Freezing after empirical peak (epoch 4) lets head components continue learning safely. Prior art: ULMFiT, LP-FT. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 0c854d5 commit 1a78099

3 files changed

Lines changed: 1045 additions & 6 deletions

File tree

pii-ner-v1/docs/training_chronicle.md

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,84 @@ Supports HuggingFace Hub loading, character-level offsets, BIO→span decoding,
216216

217217
---
218218

219+
## Phase 6: V1.1 Training Results
220+
221+
**Commit:** `0c854d5`
222+
**Trained on:** A100 (Colab), BF16, 15 epochs, effective batch 32
223+
224+
### Training Curve
225+
226+
| Epoch | Train Loss | Val Loss | F1 | Tier 1 Recall | Notes |
227+
|-------|-----------|---------|------|--------------|-------|
228+
| 1 | 4.26 | 4.13 | 0.876 | 0.759 | Strong start |
229+
| 2 | 3.03 | 3.23 | 0.891 | 0.796 | Steady improvement |
230+
| 3 | 2.68 | 2.93 | 0.900 | 0.776 | Near peak |
231+
| 4 | 2.68 | 2.88 | **0.899** | **0.806** | **Best checkpoint** |
232+
| 5 | **8.40** | 7.90 | 0.841 | 0.749 | **Train loss spike — backbone destabilized** |
233+
| 6 | 6.80 | 7.42 | 0.827 | 0.735 | Partial recovery |
234+
| 7 | 6.48 | 6.34 | 0.851 | 0.747 | Still below peak |
235+
236+
Best model restored from epoch 4 via `load_best_model_at_end=True`.
237+
238+
### V1.1 vs V1 Comparison (Best Checkpoints)
239+
240+
| Metric | V1.1 (Ep 4) | V1 (Ep 5) | Change |
241+
|--------|------------|-----------|--------|
242+
| Overall F1 | 0.899 | 0.903 | -0.004 |
243+
| Tier 1 Recall | **0.806** | 0.722 | **+0.084** |
244+
| Tier 2 Recall | 0.940 | 0.934 | +0.006 |
245+
| Tier 3 Recall | 0.929 | 0.919 | +0.010 |
246+
| Tier 4 Recall | 0.870 | 0.866 | +0.004 |
247+
248+
### What We Learned
249+
250+
**The tier-weighted loss and oversampling worked for their intended purpose.** Tier 1 recall improved +8.4 points. Standout entities at epoch 4: SSN recall 0.949, Credit Card 0.883, Drivers License 0.961. Passport number (0.426) remained the main drag — only 526 training examples, and 3x oversampling can only do so much.
251+
252+
**The backbone destabilization pattern recurred, earlier and worse.** V1 spiked at epoch 6 (train loss 2.96→5.81). V1.1 spiked at epoch 5 (train loss 2.68→8.40). The tier-weighted loss (3x weight) + oversampling (3x duplication) = ~9x effective gradient signal for Tier 1 sequences hitting the backbone. We reduced backbone LR by 2x (2e-5→1e-5) but amplified gradients by ~9x. Net effect: worse instability, one epoch earlier.
253+
254+
**The cosine schedule didn't prevent the spike.** By epoch 5 the backbone LR had only decayed to ~0.65 of its initial value (cosine at 5/15 of total). The recovery in epochs 6-7 was partial at best — once the backbone representations are disrupted, they don't fully recover within the same run.
255+
256+
---
257+
258+
## Phase 7: V1.2 — Backbone Freezing Schedule
259+
260+
**Hypothesis:** The backbone (DeBERTa-v3-xsmall) adapts well for ~4 epochs, then continued updates under amplified tier-weighted gradients cause catastrophic destabilization. Freezing the backbone after epoch 4 lets the head components (CharCNN, GatingFusion, CRF) continue learning without risking backbone collapse.
261+
262+
**Prior art:**
263+
- ULMFiT (Howard & Ruder, 2018): gradual unfreezing for transfer learning
264+
- LP-FT (Kumar et al., 2022): fine-tuning can distort pretrained features
265+
266+
### Changes from V1.1
267+
268+
| Parameter | V1.1 | V1.2 | Rationale |
269+
|-----------|------|------|-----------|
270+
| Backbone freeze | Never | After epoch 4 | Prevent destabilization |
271+
| Total epochs | 15 | 10 | 4 full + 6 head-only |
272+
| All other params || Identical | Isolate the freeze variable |
273+
274+
### Implementation
275+
276+
A `FreezeBackboneCallback` (HF `TrainerCallback`) fires at the end of epoch 4 and sets `requires_grad=False` on all parameters with `"deberta"` in the name. ~10 lines of code. The optimizer still holds backbone params but computes zero gradients, so no updates occur. Head components continue with the cosine-decaying LR.
277+
278+
### Expected Outcome
279+
280+
If the hypothesis is correct:
281+
- Epochs 1-4 should match v1.1 exactly (same hyperparameters)
282+
- Epochs 5-10 should maintain or improve upon epoch 4 quality (no spike)
283+
- Overall F1 ≥ 0.899 with Tier 1 recall ≥ 0.806
284+
285+
If the hypothesis is wrong and the spike comes from head components (not backbone drift), we'd still see destabilization after epoch 4. This would point toward gradient clipping or lower tier weights as the next intervention.
286+
287+
### Notebooks
288+
289+
Versioned experiment notebooks:
290+
- `notebooks/smoke_test.ipynb` — Phase 1: overfit validation
291+
- `notebooks/full_training.ipynb` — Phase 3-6: v1 and v1.1 full training
292+
- `notebooks/v1.2_freeze_backbone.ipynb` — Phase 7: backbone freezing experiment
293+
- `scripts/train_v1.2_local.py` — Local RTX 3090 runner for v1.2
294+
295+
---
296+
219297
## Commit Log Summary
220298

221299
| Phase | Commits | Key Outcome |
@@ -226,16 +304,22 @@ Supports HuggingFace Hub loading, character-level offsets, BIO→span decoding,
226304
| Precision Strategy | 3 | Auto-select BF16→FP32 fallback |
227305
| V1 Full Training | 1 | F1=0.904 on 360K examples, model on HuggingFace |
228306
| V1.1 Improvements | 3 | Tier-weighted loss, oversampling, inference pipeline |
229-
| **Total** | **32** | |
307+
| V1.1 Training | 1 | Tier 1 recall +8.4pts but backbone spike at epoch 5 |
308+
| V1.2 Setup | 1+ | Backbone freezing notebook + local training script |
309+
| **Total** | **34+** | |
230310

231311
---
232312

233-
## Open Questions for V1.1+
313+
## Open Questions
314+
315+
1. **Will backbone freezing eliminate the training spike?** V1.2 is the direct test. If it works, the model achieves v1.1 epoch 4 quality without regression.
316+
317+
2. **Can head-only training improve beyond epoch 4?** With 6 epochs of head-only training, CharCNN and CRF may learn better entity patterns using the frozen backbone representations as stable features.
234318

235-
1. **Will tier-weighted loss + oversampling close the Tier 1 gap?** The 323x imbalance is severe. Oversampling helps but doesn't create genuinely new examples. If Tier 1 recall stays below 0.90, we may need synthetic data augmentation.
319+
3. **Passport number recall (0.426)** — Only 526 training examples. Even with 3x oversampling and 3x tier weight, this may require synthetic data generation to approach the 0.98 target.
236320

237-
2. **16 zero-occurrence entity types** — NATIONALITY, ETHNICITY, RELIGION, MARITAL_STATUS, MEDICAL_RECORD, STUDENT_ID, DEVICE_ID, CRYPTO_WALLET, INSURANCE_NUMBER, SALARY, CRIMINAL_RECORD, POLITICAL_AFFILIATION, SEXUAL_ORIENTATION, HEALTH_CONDITION, GENETIC_DATA, TRADE_UNION. These can't be learned without new data sources. Should we drop them from the taxonomy or find additional datasets?
321+
4. **16 zero-occurrence entity types** — NATIONALITY, ETHNICITY, RELIGION, MARITAL_STATUS, MEDICAL_RECORD, STUDENT_ID, DEVICE_ID, CRYPTO_WALLET, INSURANCE_NUMBER, SALARY, CRIMINAL_RECORD, POLITICAL_AFFILIATION, SEXUAL_ORIENTATION, HEALTH_CONDITION, GENETIC_DATA, TRADE_UNION. These can't be learned without new data sources.
238322

239-
3. **ONNX export** — The CRF Viterbi decode doesn't export cleanly from pytorch-crf. May need a pure-PyTorch reimplementation (~50 lines) for the ONNX path.
323+
5. **ONNX export** — The CRF Viterbi decode doesn't export cleanly from pytorch-crf. May need a pure-PyTorch reimplementation (~50 lines) for the ONNX path.
240324

241-
4. **Backbone scaling** — DeBERTa-v3-xsmall (22M) was chosen for latency. If we need more capacity for Tier 1, DeBERTa-v3-small (44M) or DeBERTa-v3-base (86M) are the next steps, with corresponding latency trade-offs.
325+
6. **Backbone scaling** — DeBERTa-v3-xsmall (22M) was chosen for latency. If we need more capacity for Tier 1, DeBERTa-v3-small (44M) or DeBERTa-v3-base (86M) are the next steps.

0 commit comments

Comments
 (0)