PHerc. Paris 4 — 4-class fiber/ink segmentation, self-distilled (step 29000)
Segments background / vertical fiber / horizontal-angular fiber / ink — 4
classes, in 3D, directly in micro-CT of PHerc. Paris 4 — trained with no
fixed ground truth via self-distillation from two frozen teacher UNets. This
is villa's scripts/fiber_5class
pipeline (PR #985), and this
checkpoint is confirmed (via direct inspection of its embedded training config,
which matches its W&B run exactly) to be the real, finished model that
pipeline produced.
This model's own training pipeline does not use DINO at all — it is pure
two-teacher self-distillation (see below). DINO only appears earlier/elsewhere
in this broader fiber-modeling effort, in a separate checkpoint that may feed
this run's fiber teacher input — see Related models.
debug figure
Training-time debug visualization from this run at step 29899 (image slice,
teacher probability maps, watershed instances, student prediction). Logged to
W&B, not an independent evaluation.
Model details
Architecture
vesuviusNetworkFromConfig 3D UNet (shared_encoder/shared_decoder/task_heads) — verified directly from the checkpoint: 544 encoder tensors, 60 decoder tensors, single head
Output
4 channels, softmax, head named task_heads.labels — verified shape (4, 32, 1, 1, 1)
PHerc. Paris 4, 2.4 µm scan (s3://vesuvius-challenge-open-data/PHercParis4/volumes/20260411134726-2.400um-0.2m-78keV-masked.zarr/)
We verified this checkpoint directly (torch.load(..., weights_only=False)):
its embedded config.wandb_run_name is p4_4class_ddp8_20260526, its
config.out_dir is /ephemeral/fiber_5class_ckpts/p4_4class_ddp8_20260526 —
both matching the W&B run's own recorded config exactly, and step=29000
matches the file's provenance exactly. save_every=1000 with
num_iterations=30000 means step 29000 is mathematically the last
checkpoint this run could have saved (the loop exits at step 30000 before
another save triggers) — this is the final checkpoint of a finished run, not
an arbitrary snapshot.
This run was reached after two earlier attempts under the same name failed
(5ga68dxv) or crashed (q8jmzbiv), and after an even earlier, broader
experiment line tagged 5class/fiber-ink-papyrus (out_channels=5, adding a
"papyrus" class) was simplified down to the 4-class scheme published here.
Training procedure: two-teacher self-distillation (verified against source)
Read directly from label_generator.py (FiveClassLabelGenerator) and
train.py in PR #985 — this is a from-source description, not an inference
from config field names:
GPU watershed-from-minima (cuws) on the distance transform of fiber_mask (ws_image_mode="distance", ws_h_merge=14000) → per-instance fiber segmentation.
Per-instance PCA on each instance's ZYX voxel coordinates: |principal_axis · ẑ| > pca_cos_threshold (0.819 = cos 35°) → class 1 (vertical), else class 2 (horizontal/angular). Instances below ws_min_voxels (400) default to class 2 rather than being dropped.
Ink overrides fiber:label[ink_prob > ink_thr] = 3 (ink_thr=0.1) — applied after the fiber/orientation assignment, so ink always wins where the ink teacher is confident.
Dark-voxel guard (final step):label[raw < dark_voxel_thr] = 0 (dark_voxel_thr=90) — forces very dark/air voxels to background regardless of any earlier assignment.
Loss = cross-entropy (label smoothing 0.1) + multiclass soft Dice (smoothing
0.1, foreground classes only). A fresh pseudo-label is generated from the two
frozen teachers every step — there is no fixed/static label set at any
point in training.
The two teacher checkpoints for this run were configured as
/ephemeral/fiber_5class_inputs/fiber_teacher.pth and ink_teacher.pth —
generic on-disk names that don't self-identify their origin. Per the identical
scripts/fiber_5class/train.py module docstring, the fiber teacher is
documented as "ihoo3tpl ckpt", i.e. very likely
scrollprize/fiber_dinoguided_2class_step010000
(not proven byte-identical — it was copied/renamed on the training box). The
ink teacher is a separate checkpoint we never had; it no longer exists on the
original training instance and was not found anywhere else we checked, so we
are treating it as unrecoverable and are not able to publish it.
Metrics
Final logged values at step 29999 (run marked finished; checkpoint
published here is step 29000, the last one actually saved):
Important: the per-class Dice above is student-vs-its-own-pseudo-label
self-consistency, recomputed each val_every steps by re-forwarding the
student on a clean (non-augmented) training crop and comparing to that crop's
pseudo-label — confirmed directly from train.py's logging code. It is not
accuracy against independent, human-verified ground truth (none exists for
this pipeline). Treat these numbers as a training-health signal, not a
benchmark score.
debug mask
Categorical mask visualization (pseudo-label vs. student prediction) from the
same step, with the fixed class palette used throughout this pipeline.
Relationship to other fiber-effort models — please read before conflating pipelines
This is the only one of the four related repos published so far whose own
training loop is DINO-free. The others are separate, earlier, or upstream
components of the same broader effort:
scrollprize/fiber_dinoguided_2class_step010000 — 2-class (background/fiber) DINO-embedding-guided self-training checkpoint, very likely (not proven byte-identical) the fiber_teacher input consumed by this run. Trains completely differently (Otsu + DINO-similarity dynamic pseudo-labels, no watershed, no PCA, no ink).
scrollprize/fiber_hz_vt — an independent, supervised, real-annotation-trained 2-class horizontal/vertical model (villa PR #825). Different pipeline, different training data (WebKnossos skeleton traces vs. self-distillation), not directly comparable.
Files
File
Size
Role
p4_4class_ddp8_20260526_step029000.pth
~2.1 GB
model (raw) + ema.model_state (recommended for inference) + optimizer + embedded config.
Metrics are self-consistency (student vs. its own pseudo-label), not
held-out validation against independent ground truth — there is none in
this pipeline.
The ink teacher checkpoint used to train this model is not published here
and is believed unrecoverable (no longer present on the original training
instance; not found elsewhere in our search).
The fiber teacher checkpoint used to train this model is very likely
scrollprize/fiber_dinoguided_2class_step010000
based on matching documentation in the training source, but this was not
proven byte-identical (it was renamed to a generic filename on the training
box before this run consumed it).
Trained on a single scroll (PHerc. Paris 4); generalization to other scrolls
is untested by us.