taejoon89 commited on
Commit
1ca3ad9
·
verified ·
1 Parent(s): d852fa4

Upload folder using huggingface_hub

Browse files
OpenPath/README.md CHANGED
@@ -6,7 +6,7 @@ Kaiko.AI's *Midnight*), with substantial modifications:
6
 
7
  - **Corpus:** trains on the public **OpenPath corpus** (native 40× tiles) via a WebDataset
8
  loader (`dinov2/data/openpath_wds.py`) instead of the upstream TCGA-12K Parquet stream.
9
- - **Gram anchoring** (ported from DINOv3): `dinov2/loss/gram_loss.py` + a frozen anchor
10
  teacher in `dinov2/train/ssl_meta_arch.py`, to dampen dense-feature degradation.
11
  - **Schedule:** flat (near-constant) LR, `early_stop` at ~1 native epoch (345k iters).
12
  - Multi-node FSDP launcher / crash-tolerant auto-resume / online HEST probing under `../scripts/`.
 
6
 
7
  - **Corpus:** trains on the public **OpenPath corpus** (native 40× tiles) via a WebDataset
8
  loader (`dinov2/data/openpath_wds.py`) instead of the upstream TCGA-12K Parquet stream.
9
+ - **Gram anchoring** (technique from DINOv3; loss re-implemented clean-room, Apache-2.0): `dinov2/loss/gram_loss.py` + a frozen anchor
10
  teacher in `dinov2/train/ssl_meta_arch.py`, to dampen dense-feature degradation.
11
  - **Schedule:** flat (near-constant) LR, `early_stop` at ~1 native epoch (345k iters).
12
  - Multi-node FSDP launcher / crash-tolerant auto-resume / online HEST probing under `../scripts/`.
OpenPath/dinov2/configs/train/openpath_vitg14.yaml CHANGED
@@ -82,7 +82,7 @@ evaluation:
82
  breakhis_root: ""
83
  pcam_root: ""
84
 
85
- # Gram anchoring (ported from DINOv3): MSE between L2-normalized patch-token Gram matrices of
86
  # student vs a frozen anchor. Dampens dense-feature degradation during long training.
87
  gram:
88
  use_loss: true
 
82
  breakhis_root: ""
83
  pcam_root: ""
84
 
85
+ # Gram anchoring (technique from DINOv3; clean-room re-implementation): MSE between L2-normalized patch-token Gram matrices of
86
  # student vs a frozen anchor. Dampens dense-feature degradation during long training.
87
  gram:
88
  use_loss: true
README.md CHANGED
@@ -24,8 +24,8 @@ The corpus and checkpoints are hosted separately (see below).
24
  > **Headline result.** On **AMC-HCC-ST** — a contamination-free in-house Asan Medical Center
25
  > hepatocellular-carcinoma spatial-transcriptomics cohort, the least leakage-prone benchmark since no
26
  > public foundation model was trained on it — OpenPath **ranks #1 among seven foundation models** (mean
27
- > Pearson: OpenPath **0.323** > UNI2-h 0.301 > OpenMidnight 0.300 > Virchow2 0.292 > prov-gigapath 0.286
28
- > > Phikon-v2 0.274 > UNI 0.257). Released checkpoint: **`training_316250`** (in `openpath-checkpoints`).
29
  > See [Evaluation](#evaluation).
30
 
31
  - **Encoder:** ViT-g/14 (reg4), 1536-dim CLS embedding
@@ -40,7 +40,7 @@ The corpus and checkpoints are hosted separately (see below).
40
  OpenPath/ # DINOv2 training fork (derived from OpenMidnight)
41
  dinov2/train/train.py # training loop (+ gram-weight schedule)
42
  dinov2/train/ssl_meta_arch.py # SSL arch (+ frozen gram-anchor teacher)
43
- dinov2/loss/gram_loss.py # gram anchoring loss (ported from DINOv3)
44
  dinov2/data/openpath_wds.py # WebDataset loader for the OpenPath corpus
45
  dinov2/configs/train/openpath_vitg14.yaml # training config
46
  scripts/
@@ -52,6 +52,7 @@ eval/ # downstream benchmark / referenc
52
  openpath_eva_backbone.py # backbone factories: OpenPath + Phikon / OpenMidnight / UNI / UNI2-h / gigapath / Virchow2
53
  st_bench.py # AMC-HCC-ST benchmark (LOPO ridge, headline)
54
  run_patch_eval.sh # PCam / CRC / BACH patch probing via kaiko-eva
 
55
  eva_configs/ # eva YAML configs (crc / bach / patch_camelyon)
56
  requirements.txt
57
  ```
 
24
  > **Headline result.** On **AMC-HCC-ST** — a contamination-free in-house Asan Medical Center
25
  > hepatocellular-carcinoma spatial-transcriptomics cohort, the least leakage-prone benchmark since no
26
  > public foundation model was trained on it — OpenPath **ranks #1 among seven foundation models** (mean
27
+ > Pearson: OpenPath **0.323** > UNI2-h 0.301 > OpenMidnight 0.300 > Virchow2 0.292 > prov-gigapath 0.286 >
28
+ > Phikon-v2 0.274 > UNI 0.257). Released checkpoint: **`training_316250`** (in `openpath-checkpoints`).
29
  > See [Evaluation](#evaluation).
30
 
31
  - **Encoder:** ViT-g/14 (reg4), 1536-dim CLS embedding
 
40
  OpenPath/ # DINOv2 training fork (derived from OpenMidnight)
41
  dinov2/train/train.py # training loop (+ gram-weight schedule)
42
  dinov2/train/ssl_meta_arch.py # SSL arch (+ frozen gram-anchor teacher)
43
+ dinov2/loss/gram_loss.py # gram anchoring loss (clean-room re-impl, Apache-2.0)
44
  dinov2/data/openpath_wds.py # WebDataset loader for the OpenPath corpus
45
  dinov2/configs/train/openpath_vitg14.yaml # training config
46
  scripts/
 
52
  openpath_eva_backbone.py # backbone factories: OpenPath + Phikon / OpenMidnight / UNI / UNI2-h / gigapath / Virchow2
53
  st_bench.py # AMC-HCC-ST benchmark (LOPO ridge, headline)
54
  run_patch_eval.sh # PCam / CRC / BACH patch probing via kaiko-eva
55
+ run_hest_ref.py # HEST-1K for reference FMs (UNI / UNI2-h / gigapath / Virchow2)
56
  eva_configs/ # eva YAML configs (crc / bach / patch_camelyon)
57
  requirements.txt
58
  ```
eval/run_hest_ref.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """HEST-1K for reference timm pathology FMs (UNI/UNI2/gigapath/Virchow2).
3
+ run_hest_3way와 동일 프로토콜: 224px, ImageNet norm, CLS 임베딩, PCA256+ridge, 9 task 평균 Pearson.
4
+ (참조모델 CRC/BACH/HCC와 동일하게 CLS만 사용 — Virchow2도 CLS 1280.)
5
+ """
6
+ import argparse, os, sys
7
+ import torch
8
+ from torchvision import transforms
9
+
10
+ ROOT = os.environ.get("OPENPATH_ROOT", os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
11
+ BENCH = os.environ.get("HEST_BENCH_ROOT", f"{ROOT}/data/eva/hest_bench")
12
+ ALL = ["IDC", "PRAD", "PAAD", "SKCM", "COAD", "READ", "CCRCC", "LUNG", "LYMPH_IDC"]
13
+ eval_tf = transforms.Compose([
14
+ transforms.Resize(224), transforms.CenterCrop(224), transforms.ToTensor(),
15
+ transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
16
+ ])
17
+
18
+
19
+ def main():
20
+ ap = argparse.ArgumentParser()
21
+ ap.add_argument("--backbone", required=True, choices=["uni", "uni2", "gigapath", "virchow2"])
22
+ ap.add_argument("--exp-code", required=True)
23
+ ap.add_argument("tasks", nargs="*")
24
+ args = ap.parse_args()
25
+
26
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
27
+ import openpath_eva_backbone as B
28
+ fn = {"uni": B.build_uni, "uni2": B.build_uni2,
29
+ "gigapath": B.build_gigapath, "virchow2": B.build_virchow2}[args.backbone]
30
+ model = fn().cuda().eval()
31
+
32
+ from hest.bench import benchmark
33
+ tasks = args.tasks or ALL
34
+ print(f"[hest-ref] backbone={args.backbone} exp={args.exp_code} tasks={tasks}", flush=True)
35
+ dataset_perfs, perf_per_enc = benchmark(
36
+ model, eval_tf, torch.float32,
37
+ exp_code=args.exp_code, datasets=tasks, bench_data_root=BENCH,
38
+ embed_dataroot=os.environ.get("HEST_EMBED_ROOT", f"eval/ST_data_emb_{args.exp_code}"),
39
+ dimreduce="PCA", latent_dim=256, method="ridge", normalize=True,
40
+ )
41
+ print(f"=== HEST per-encoder avg Pearson [{args.exp_code}] ===", perf_per_enc, flush=True)
42
+
43
+
44
+ if __name__ == "__main__":
45
+ main()
scripts/run_hest_3way.py CHANGED
@@ -17,7 +17,7 @@ import torch
17
  import torch.nn as nn
18
  from torchvision import transforms
19
 
20
- ROOT = "/NHNHOME/WORKSPACE/0526040027_A/OpenPath"
21
  BENCH = os.environ.get("HEST_BENCH_ROOT", f"{ROOT}/data/eva/hest_bench")
22
  ALL = ["IDC", "PRAD", "PAAD", "SKCM", "COAD", "READ", "CCRCC", "LUNG", "LYMPH_IDC"]
23
 
 
17
  import torch.nn as nn
18
  from torchvision import transforms
19
 
20
+ ROOT = os.environ.get("OPENPATH_ROOT", os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
21
  BENCH = os.environ.get("HEST_BENCH_ROOT", f"{ROOT}/data/eva/hest_bench")
22
  ALL = ["IDC", "PRAD", "PAAD", "SKCM", "COAD", "READ", "CCRCC", "LUNG", "LYMPH_IDC"]
23