grgngl commited on
Commit
1fa189d
·
verified ·
1 Parent(s): e07e5f6

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +186 -0
README.md ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ pipeline_tag: image-segmentation
4
+ tags:
5
+ - vesuvius
6
+ - herculaneum
7
+ - fibers
8
+ - computed-tomography
9
+ - 3d-segmentation
10
+ - dino-guided
11
+ - self-distillation
12
+ - self-supervised
13
+ - volumetric-imaging
14
+ ---
15
+
16
+ # PHerc. Paris 4 — 2-class fiber segmentation, DINO-embedding-guided self-training (step 10000)
17
+
18
+ Segments **fiber vs. background** (2 classes — not an orientation split, see
19
+ below) in 3D, directly in micro-CT of **PHerc. Paris 4**, trained with **no
20
+ fixed ground truth**: a pseudo-label is regenerated every step from a frozen
21
+ teacher UNet's own predictions, adaptively thresholded and refined against a
22
+ DINO-embedding similarity map.
23
+
24
+ **This is a precursor / component checkpoint, not villa's flagship 4-class
25
+ fiber/ink model.** It is published because it is real, verified lineage: per
26
+ villa's own [`scripts/fiber_5class/train.py`](https://github.com/ScrollPrize/villa/blob/main/scripts/fiber_5class/train.py)
27
+ (PR [#985](https://github.com/ScrollPrize/villa/pull/985)) module docstring,
28
+ *this exact checkpoint* — referred to there by its W&B run ID, "ihoo3tpl ckpt"
29
+ — is loaded as the frozen **fiber teacher** input to villa's separate, later,
30
+ 4-class (background / vertical fiber / horizontal-angular fiber / ink)
31
+ self-distillation trainer. See **Relationship to the 4-class model** below;
32
+ we do not currently have that 4-class model's weights to publish.
33
+
34
+ ## Model details
35
+
36
+ | | |
37
+ |---|---|
38
+ | Architecture | `vesuvius` `NetworkFromConfig` 3D UNet (`shared_encoder` / `shared_decoder` / `task_heads`, the same family used across villa's segmentation models), single `fibers` head |
39
+ | Output | **2 channels**, softmax. Channel 0 = background, channel 1 = fiber foreground — confirmed via villa's own `label_generator.py::_to_fg_prob`, the function that loads this exact checkpoint as a frozen teacher (2-channel case: `softmax(logits, dim=1)[:, 1:2]`) |
40
+ | Input | 1-channel CT, 256³ patches |
41
+ | This checkpoint | step **10000** · W&B run [`ps256_fiber_dinoguided__dino362500__cls3__embbackbone__ddp8__20260522`](https://wandb.ai/vesuvius-challenge/vesuvius_fibers_3d/runs/ihoo3tpl) (`ihoo3tpl`, project `vesuvius_fibers_3d`, state **finished**) |
42
+ | Weights | `model` (raw) and `ema` (**EMA — recommended for inference**, decay 0.9995) |
43
+ | Optimisation | SGD + Nesterov (lr 0.005, momentum 0.99, weight_decay 3e-5), cosine LR, 1500-step warmup, bf16 mixed precision, BCE + soft Dice (0.1 label smoothing each), batch size 2 × 8 GPUs (`ddp8`), 12000 total iterations |
44
+ | Trained on | PHerc. Paris 4, 2.4 µm scan (`s3://vesuvius-challenge-open-data/PHercParis4/volumes/20260411134726-2.400um-0.2m-78keV-masked.zarr/`) |
45
+
46
+ ## Training procedure: DINO-embedding-guided dynamic pseudo-labeling
47
+
48
+ Unlike a conventional teacher→student distillation with a fixed label set,
49
+ this run generates a **new pseudo-label every step** from:
50
+
51
+ 1. A frozen self-trained fiber UNet's own probability map —
52
+ [`scrollprize/fiber_selftrain_teacher_epoch30`](https://huggingface.co/scrollprize/fiber_selftrain_teacher_epoch30)
53
+ (the same checkpoint also **warm-starts** this model's own weights, i.e.
54
+ this is continued self-training, not distillation from an unrelated
55
+ architecture).
56
+ 2. An Otsu-adaptive light/dark voxel threshold (`otsu_light_threshold=70`,
57
+ plus `otsu_min_light_voxels`, `otsu_fallback_threshold`,
58
+ `otsu_tail_floor_percentile`, `otsu_min_tail_voxels`).
59
+ 3. A similarity map between the
60
+ [supcon-fine-tuned DINO backbone, step 362500](https://huggingface.co/scrollprize/dinovol_v2_ps8_supcon3class_step362500)'s
61
+ dense patch embeddings and a single reference "fiber" prototype embedding
62
+ (`avg_fiber_embedding__864d_backbone.npz`, bundled in that backbone's repo),
63
+ computed at stride 128 and blended in with `dino_blend_sigma=4.0`.
64
+
65
+ We reconstructed this description from the run's own config field names
66
+ (`dynamic_label.*`); the specific script implementing this exact blend was not
67
+ found in the available `villa` repository snapshot (unlike the 4-class
68
+ pipeline discussed below, whose source we did read directly), so treat the
69
+ precise algorithmic combination as a well-supported inference, not a verbatim
70
+ account of the code.
71
+
72
+ ### Checkpoint provenance: a mid-run bugfix
73
+
74
+ This run's own config records `resume_from_ckpt` pointing at its own
75
+ `ckpt_002000.pth`, under the *same* W&B run ID (`ihoo3tpl`) — confirming
76
+ training paused at step 2000 and resumed later in the same run (verified both
77
+ via the W&B API and by loading this checkpoint's own embedded config directly,
78
+ which lists `wandb_run_id: ihoo3tpl` and the matching `resume_from_ckpt`
79
+ path). This lines up exactly with the two checkpoints produced:
80
+
81
+ - `step_002000__resume_point__pre_dark_mask_fix.pth` — **not published here**
82
+ (superseded).
83
+ - `step_010000__post_dark_mask_fix__latest.pth` — **this repo.**
84
+
85
+ The filenames describe this as a fix to "dark voxel masking." We can confirm
86
+ the resume-at-step-2000 mechanics precisely (embedded config + matching
87
+ filenames + same run ID) but **cannot independently confirm the exact nature
88
+ of the underlying bug/fix** — plausible candidate parameters visible in the
89
+ (post-fix) config relate to dark/light voxel handling (`input_mask_threshold`,
90
+ `otsu_light_threshold`, the dataset's `dark_threshold`), but we only have the
91
+ post-fix config, not a diff against the pre-fix run.
92
+
93
+ ## Metrics
94
+
95
+ **This run has no held-out validation metric** — its W&B summary contains no
96
+ `val_*` key at all, because the entire pipeline is label-free self-training
97
+ (there is no independent ground truth to validate against). Final logged
98
+ values at step 11999 (of a 12000-step schedule; run marked **finished**):
99
+
100
+ | metric | value |
101
+ |---|---|
102
+ | `loss` (bce + dice) | 0.7824 |
103
+ | `loss_bce` | 0.3318 |
104
+ | `loss_dice` | 0.4506 |
105
+ | `pseudo_fg_frac` (dynamic label's foreground fraction) | 0.132 |
106
+ | `sim_mean` (mean DINO-embedding similarity to the reference) | 0.432 |
107
+ | `otsu_threshold` (final adaptive cut) | 0.503 |
108
+ | `lr` | ≈1.1×10⁻¹⁰ (cosine-annealed to ~0) |
109
+
110
+ These are training-loop / pseudo-label-consistency statistics, not accuracy
111
+ against independently verified ground truth.
112
+
113
+ ## Relationship to the 4-class fiber/ink model — please read before assuming this is that model
114
+
115
+ Villa's actual finished 4-class (background / vertical fiber / horizontal-angular
116
+ fiber / ink) self-distillation model — matching
117
+ [`scripts/fiber_5class`](https://github.com/ScrollPrize/villa/tree/main/scripts/fiber_5class)
118
+ exactly (watershed-from-minima + per-instance PCA orientation split + ink-teacher
119
+ override + dark-voxel guard) — is a **separate** checkpoint: W&B run
120
+ [`p4_4class_ddp8_20260526`](https://wandb.ai/vesuvius-challenge/paris4-full-features/runs/36pykwky)
121
+ (`36pykwky`, project `paris4-full-features`, state finished, created
122
+ 2026-05-26 — four days after this run). Its config confirms it uses this
123
+ checkpoint's lineage as its frozen fiber teacher, plus a separate frozen ink
124
+ teacher that we do not have. **We do not currently have that 4-class model's
125
+ weight files**: its training `out_dir` was an ephemeral cloud-instance scratch
126
+ path (`/ephemeral/fiber_5class_ckpts/p4_4class_ddp8_20260526`), not S3, and a
127
+ scoped search of `s3://philodemos/giorgio/PHercParis4/` turned up only
128
+ DINO-backbone checkpoints and what appears to be stitched inference *output*
129
+ (not model weights). **It is not published on HuggingFace at this time.**
130
+
131
+ For reference, that run's self-consistency metrics (student vs. its own
132
+ pseudo-label on the training crop — again, not held-out validation):
133
+ `dice_0_bg`=0.961, `dice_1_vert_fiber`=0.673, `dice_2_horiz_fiber`=0.705,
134
+ `dice_3_ink`=0.791, `dice_fg_mean`=0.723.
135
+
136
+ ## Prior / sibling work
137
+
138
+ An earlier, independently-trained, **supervised** 2-class horizontal/vertical
139
+ fiber model (traced from WebKnossos skeleton annotations via cross-frame affine
140
+ registration, villa PR [#825](https://github.com/ScrollPrize/villa/pull/825))
141
+ is already published as [`scrollprize/fiber_hz_vt`](https://huggingface.co/scrollprize/fiber_hz_vt)
142
+ (W&B run `xnjpitfg`, project `fibers`, `val_hzvt_mean_dice`=0.60,
143
+ `val_hzvt_mean_iou`=0.52). That model predicts horizontal-vs-vertical
144
+ orientation from real annotations; this model predicts fiber-vs-background
145
+ from self-generated pseudo-labels. They are not directly comparable.
146
+
147
+ ## Files
148
+
149
+ | File | Size | Role |
150
+ |---|---|---|
151
+ | `step_010000__post_dark_mask_fix__latest.pth` | ~2.1 GB | `model` (raw) + `ema.model_state` (recommended for inference) + `optimizer` + embedded `config`. |
152
+ | `config.json` | — | The same training config embedded in the checkpoint, for quick inspection without loading the full file. |
153
+
154
+ ## Usage
155
+
156
+ ```python
157
+ import torch
158
+ from huggingface_hub import hf_hub_download
159
+
160
+ path = hf_hub_download(
161
+ "scrollprize/fiber_dinoguided_2class_step010000",
162
+ "step_010000__post_dark_mask_fix__latest.pth",
163
+ )
164
+ ckpt = torch.load(path, map_location="cpu", weights_only=False)
165
+ state = ckpt["ema"]["model_state"] # recommended over ckpt["model"]
166
+ # Build with vesuvius' NetworkFromConfig (target "fibers", out_channels=2,
167
+ # in_channels=1, patch_size 256^3) then load_state_dict(state).
168
+ ```
169
+ The `vesuvius` package is in <https://github.com/ScrollPrize/villa>.
170
+
171
+ ## Related models
172
+
173
+ - **Frozen fiber teacher / weight init for this run:** [`scrollprize/fiber_selftrain_teacher_epoch30`](https://huggingface.co/scrollprize/fiber_selftrain_teacher_epoch30)
174
+ - **Frozen DINO backbone used for guidance:** [`scrollprize/dinovol_v2_ps8_supcon3class_step362500`](https://huggingface.co/scrollprize/dinovol_v2_ps8_supcon3class_step362500)
175
+ - **Prior supervised hz/vt model:** [`scrollprize/fiber_hz_vt`](https://huggingface.co/scrollprize/fiber_hz_vt)
176
+
177
+ ## Links
178
+
179
+ - **Code:** <https://github.com/ScrollPrize/villa> — PR [#825](https://github.com/ScrollPrize/villa/pull/825) (cross-frame affine infra), PR [#985](https://github.com/ScrollPrize/villa/pull/985) (`scripts/fiber_5class`, the downstream 4-class trainer that consumes this checkpoint)
180
+ - **W&B run:** <https://wandb.ai/vesuvius-challenge/vesuvius_fibers_3d/runs/ihoo3tpl>
181
+ - **Data:** <https://scrollprize.org/data_browser>
182
+ - **Vesuvius Challenge:** <https://scrollprize.org>
183
+
184
+ ## License
185
+
186
+ MIT.