researchsubmissions66/PGVL-Gym

0

stars

29

commits

Python

primary language

Sep 6, 2026

updated

researchsubmissions66.github.io/PGVL-Gym/project/

README

PGVL-Gym

A generalized framework for fair, reproducible evaluation of
whole-slide pathology vision-language models.

Project website Documentation Source


🔭 Overview

PGVL-Gym is a registry-based benchmark that runs recent few-shot and zero-shot whole-slide-image (WSI) vision-language methods through one explicit experiment contract. It preserves each paper's model-specific architecture while standardizing protocols, feature provenance, folds, shots, seeds, and reporting.

Systematic protocols cover TCGA NSCLC, BRCA and RCC plus UBC-OCEAN and CAMELYON16. A separate combined CAMELYON16+17 matrix registers the native FOCUS/MUSE cohort without mixing it into CAMELYON16-only results.

📁 Benchmark layout

Each cohort owns one benchmark directory under benchmarks/, holding its protocol.yaml and everything generated from it (manifests, splits, configs, run_matrix.csv, readiness reports). Cohorts are kept separate so one whose data is not ready cannot hold back the ones that are:

BenchmarkTask
benchmarks/tcga_nsclcLUAD vs LUSC
benchmarks/tcga_brcaIDC vs ILC
benchmarks/tcga_rccRCC subtyping
benchmarks/ubc_oceanfive-class ovarian carcinoma subtyping
benchmarks/camelyon16lymph-node metastasis detection
benchmarks/camelyon_combinedcombined CAMELYON16+17 metastasis detection for FOCUS/MUSE

📚 Documentation website

The documentation site combines curated guides with API reference generated directly from the stable Python docstrings:

python -m pip install -r requirements-docs.txt
python scripts/check_docstrings.py
python -m mkdocs build --strict

PGVL-Gym is a reproducible benchmark for few-shot and zero-shot whole-slide pathology vision-language methods. It standardizes datasets, feature provenance, patient-disjoint folds, training, and reporting while explicitly recording whether each adapter is vendored, mixed, or a partial local reimplementation.

The normal workflow is:

configure local paths → generate run YAMLs → preflight → train → aggregate → explain

📦 1. Install the environment

The supported Python range is 3.10–3.11. Create the base environment with Conda:

conda env create -f environment.yml
conda activate pgvl-gym
pip install -e .

Install only the optional dependencies needed by your method:

pip install -e '.[cod-mil]'
pip install -e '.[pathpt-musk]'
pip install -e '.[convlm]'
pip install -e '.[hive-mil]'

Available extras are listed in pyproject.toml. Foundation-model checkpoints are not downloaded automatically; benchmark runs are designed for local or offline model caches.

⚙️ 2. Configure machine-local paths

Copy the environment template and edit the ignored local file:

cp .env.example .env
PGVL_REPO_ROOT=/path/to/PGVL-Gym
PGVL_USER_ROOT=/path/to/user-root
PGVL_STORAGE_ROOT=/path/to/storage-root
PGVL_CONDA_ENV=/path/to/project/envs/pgvl-gym

Committed protocols, manifests, splits, and configs use references such as ${PGVL_REPO_ROOT} and ${PGVL_STORAGE_ROOT}. Python commands load .env automatically. The launch shell scripts source it as well. Existing process environment variables take precedence, which is useful on a cluster.

Do not commit .env; it is intentionally ignored.

🧬 3. Generate experiment YAMLs

Each cohort has one source-of-truth protocol:

benchmarks/<cohort>/protocol.yaml

Edit its cohort metadata, feature registry, checkpoints, methods, folds, and shot counts, then generate manifests, splits, method configs, and the run matrix:

python scripts/tcga_benchmark.py all \
  --protocol benchmarks/tcga_brca/protocol.yaml

Useful stages are inventory, prepare, configs, validate, aggregate, and all. Generated configs appear under benchmarks/<cohort>/configs/<experiment>/; runnable rows are indexed in benchmarks/<cohort>/run_matrix.csv.

Shot schedules are cohort-capacity-aware while retaining identical nested, patient-disjoint splits across methods: CAMELYON16, combined CAMELYON16+17, TCGA-BRCA, and TCGA-NSCLC provide 4/8/16/32/64-shot configs; TCGA-RCC provides 4/8/16/32; UBC-OCEAN provides 4/8/16. The combined cohort's 32/64-shot rows are explicit benchmark extensions beyond the upstream 4/8/16 comparison. Higher RCC and UBC-OCEAN levels are deliberately absent because the rarest classes cannot supply equal-sized training and validation sets without leakage or patient reuse.

Feature extraction may finish after those artifacts are generated. Campaign planning refreshes feature_coverage.csv, missing_feature_files, and the feature-derived ready state directly from the existing manifests before every plan. It does not rebuild prompts, manifests, splits, or configs. Thus a pending feature set remains a clean skip, then becomes runnable automatically once all of its referenced files arrive. Use --no-refresh-readiness only when you deliberately need to inspect the frozen matrix cells.

Check one generated run before allocating a GPU:

python scripts/preflight.py \
  benchmarks/tcga_brca/configs/focus/brca_4shot.yaml

python scripts/preflight.py run.yaml --features
python scripts/preflight.py run.yaml --features --deep
python scripts/preflight.py run.yaml --prompts --encoders
python scripts/preflight.py run.yaml --quick
python scripts/preflight.py --system
python scripts/preflight.py run.yaml --strict --json

The preflight command is a read-only doctor. Failures include suggested fixes. Normal mode does not construct a model or load a feature tensor.

Key Checks:

  • Feature Payloads (via --deep): Verifies keys, shapes, widths, and finite values.
  • Data Integrity: Checks shared pickle stores for key/ID alignment, duplicate IDs, and coverage.
  • Asset Validation: Scans for missing, empty, unreadable, or wrong-type paths.
  • Safety: Verifies that the results directory is safe and writable.
  • Leakage Prevention: Detects slide or patient leakage between train, validation, and test partitions.
  • Method-Specific Schemas: Validates prompt banks across all methods (FOCUS, ViLa-MIL, MAPLE, MSCPT, HiVE-MIL, MI-VisionShot, Libra-MIL, DyKo, MGPATH, HIPSS, PathPT, TOP, SLIP, CoD-MIL, WSI-FiVE, MUSE, ConVLM, SLDPC).
  • Configuration & Runtime: Rejects non-unit batches for variable-length methods, unscoped phase tables, and invalid staged-training values. Validates CoD-MIL map shapes and bounds.

Useful doctor modes are:

OptionPurpose
--systemCheck Python 3.10–3.11, all core packages (including the supported and mutually compatible Torch/torchvision releases), .env, and all PGVL root directories; a run YAML is optional.
--quickCheck feature roots without statting every manifest row; equivalent to --no-feature-scan.
--deepOpen every available referenced feature and validate its payload; incompatible with --quick.
--min-feature-coverage NTemporarily override the configured coverage threshold with a fraction from 0 through 1.
--strictTurn warnings, including explicitly allowed partial coverage, into a failing readiness gate.
--jsonEmit schema-versioned JSON with summaries, timings, host diagnostics, and per-config results.
--verboseInclude successful resolved paths, asset types, and file sizes.
--quietPrint only findings and the final diagnosis.
--no-colorDisable ANSI color explicitly; redirected output disables it automatically.

Selectors --assets, --features, --prompts, --encoders, and --splits can be combined; --all or omitting selectors runs every check. Multiple YAMLs or shell globs are accepted. A healthy diagnosis exits zero, diagnosed failures exit one, and invalid command arguments exit two. See Commands and run lifecycle for the full interface and JSON contract.

📝 Prompt Provenance

Prompt provenance is tracked by method and by role in text_prompts/PROVENANCE.json. Every method summary records an exact disclosed generator, an explicit not_disclosed_by_upstream/legacy_local_generator_not_recorded marker, or a precise not_applicable_* reason. scripts/audit_prompt_provenance.py --check fails when a generated asset or method summary omits that identity.

  • TOP: Standard NSCLC and CAMELYON16 use the released 26-instance code bank and their task-specific active bag initializers. Initialized descriptions remain frozen and only their ten released * slots are trainable (all_ctx_trainable: false); external CLIP-RN50 patch rows are unit-normalized before the paper's cosine-similarity operations. CAMELYON also preserves the upstream space before instance prompt slots and its 500-epoch launcher recipe. Unwired alternatives are explicitly labeled. The doctor validates prompt structure, ordered labels, hashes, and the frozen-description boundary.
  • SLIP: TCGA-NSCLC uses the complete released bank. Its RN50 run is a local protocol extension because upstream's referenced TCGA dataset module is absent and the paper reports other cohorts with ViT-B/16. A separately named PLIP run uses paired PLIP features/text prompts and restores cached preprojection features through PLIP's frozen native visual head. Missing cohort banks are clearly labeled as generated task extensions.
  • MAPLE: Lung, RCC, and BRCA use byte-exact upstream copies. TCGA-NSCLC exposes PLIP 10x/20x and 5x/20x release-code runs plus a distinct 5x/10x paper-text reproduction condition (AdamW, 1e-4, 80 epochs); the local runtime restores cached 768-wide PLIP vision features with PLIP's frozen native projection and corrects a released reshape mismatch.
  • MUSE: CAMELYON16, the separate combined CAMELYON16+17 matrix, TCGA-NSCLC, and TCGA-BRCA use byte-exact description CSVs. Native prompt-path runs execute the released shared 16-token CONCH learner, noisy top-2/8-expert SFSE routing, and training-only class-scoped top-20 SMMO view; RCC and UBC-OCEAN remain labeled generated MUSE-schema extensions. The combined row uses the fully covered 20x/256px store and patient-disjoint folds, so it is explicitly partial. Opt-in text-tower swaps use a separately disclosed feature-space context path and never replace the native row.
  • ConVLM: Upstream omits att_splits.mat and a usable attribute builder. NSCLC deliberately enables a partial local reconstruction using complete QuiltNet-B-16 20x bags, the pinned B16 text checkpoint, and an audited generated bank; the other banks remain unwired. It must not be reported as an upstream reproduction.
  • HiVE-MIL: BRCA, NSCLC, and RCC use every released GPT-4o prompt string in its exact within-class order; only insignificant JSON whitespace is normalized, so the assets are marked derived. Runs pair CONCH v1 5x/20x bags and build each [N,16,D] child hierarchy from audited Trident coordinates. Parent spans are derived per slide and strictly checked against the shared coordinate frame, supporting mixed 20x/40x/60x/80x source scans without a scanner-specific constant; this local feature-preparation boundary is disclosed as partial.
  • MI-VisionShot: RCC uses the exact three PLIP class prompts hardcoded upstream; the local keyed JSON container is marked derived. Two explicit rows resolve a paper/code conflict: mi_visionshot preserves the released executable's unnormalized projected patch rows, while mi_visionshot_paper_l2 applies the per-patch L2 normalization required by paper Eq. 2.2 before support top-200 selection and inference BGAP. Both restore cached 768D PLIP features through PLIP's frozen native visual projection and keep labels support-only. The current 939-slide, patient-level, 224px protocol remains partial relative to the paper's 923-slide, random-repeat, 256px experiment.
  • Libra-MIL: RCC uses the released 46-entry instance bank and six-row scale/class bank with the native 20x/512px CONCH feature space. Ten learned visual prototypes and learned text prototypes are fused by Sinkhorn optimal transport before the high-resolution class prompts query the reweighted bag. The paper's 80-epoch/patience-15 protocol is combined with the released cosine-per-update AdamW schedule; current 939-slide patient folds remain explicitly partial relative to the paper's 925-slide cohort.
  • DyKo: NSCLC and RCC use the released Claude-3.5-Sonnet task descriptions and byte-exact 1,000×768 TITAN concept tensors. The runtime keeps CONCH-v1.5 vision-preprojection bags and the TITAN prompt tower as separately validated paired identities. The available 20x/512px bags extend the paper's 20x/448px geometry, and RCC remains feature-gated at 935/939 slides.
  • MGPATH: BRCA and NSCLC preserve all four released low/high PLIP descriptions and their positional order. The executable PLIP-only condition follows the final TMLR recipe (5x/10x, Adam 9e-6, 200 epochs), correcting the conflicting release command example (5x/20x, 9e-4, 50 epochs). It remains partial because cached tiles are 224px rather than 256px, augmented bags are unavailable, and it is not the primary PLIP-G/Prov-GigaPath condition. Upstream does not disclose a generator LLM.
  • HIPSS: CAMELYON16, NSCLC, and UBC-OCEAN use complete GPT-5.6 replacement banks because the public release contains empty prompt literals and only two prompt slots. The clean runtime concatenates WSI/region token sequences and applies SSF at all four internal sites in the last 2 or 8 frozen CONCH text blocks, exactly matching the paper's 284,419/348,931 trainable-parameter budgets. Results remain partial because the original ChatGPT-4o strings are unavailable and cached patch geometry differs from the paper's dense tiling.

Paired-VLM encoder ports are available as opt-in extensions for FOCUS, ViLa-MIL, TOP, MGPATH, Libra-MIL, DyKo, and HIPSS. Native rows are unchanged. Each extension requires one exact CONCH, KEEP, MUSK, PLIP, or QuiltNet-B-16 image/text checkpoint, encoder_extension: true, and a method-specific strategy recorded in the resolved config and result provenance. Most ports replace inaccessible token-level prompting with zero-initialized final-feature context; Libra-MIL only re-encodes its prompt roles, DyKo also learns a bridge from its fixed TITAN concept bank, and HIPSS replaces CONCH-block SSF with final-feature affine SSF. PLIP's cached 768-wide vision-preprojection rows are restored with the matching frozen native 768-to-512 visual projection; QuiltNet-B-16 caches are already in its 512-wide shared image/text space. These rows are partial architecture extensions, not upstream reproductions. Inspect the legal combinations with:

The generated matrices now enumerate every exact on-disk encoder condition for each already registered method/cohort pair. PathPT uses its method-owned CONCH/KEEP/MUSK implementations; its PLIP path remains unregistered because the available bags are 768-wide vision-preprojection rather than the required 512-wide shared features. MUSE separately identifies native CONCH, cross-space CONCH-text, and paired-tower conditions; SLDPC's CLIP-RN50 text tower uses an explicit learned slide projection. Dual-scale methods are emitted only when both required scales exist for one checkpoint, so a missing 5x or 10x store is never replaced with a different magnification.

python scripts/list_encoder_swaps.py
python scripts/list_encoder_swaps.py --method hipss --json

🚀 4. Run a configuration

python train.py \
  --method focus \
  --config benchmarks/tcga_brca/configs/focus/brca_4shot.yaml \
  --device cuda:0

🔬 Checkpoint-bound interpretability

Generate an audited patch-evidence artifact set (lossless CSV, rendered PNG, and provenance manifest) for an eligible method:

python scripts/generate_heatmap.py \
  --method pathpt --config run.yaml --ckpt-dir /path/to/results \
  --fold 0 --split test --slide-id SLIDE_ID

The command validates the run/checkpoint identity, uses exact HDF5 level-0 coordinates, and defaults to the predicted class on a coordinate-only canvas. Pass --target-class LABEL for another class or --wsi /path/to/slide.svs for an overlay whose dimensions are checked against the feature geometry. FOCUS, ViLa-MIL, CoD-MIL, native PathPT, TOP, SLIP, MUSE, Libra-MIL, DyKo, MGPATH, and HIPSS expose audited providers.

Their quantities are intentionally not conflated: outputs retain names such as class-query attention, prompt evidence, patch-class probability, transport attention, and hierarchical contribution. Methods without an audited patch-aligned quantity refuse generation. See the full interpretability workflow and compact method support matrix.

📊 Uncertainty and efficiency reports

Completed prediction files can be analyzed without retraining:

python scripts/statistical_report.py \
  --matrix benchmarks/tcga_nsclc/run_matrix.csv \
  --output-dir "${PGVL_STORAGE_ROOT}/PGVL-Gym-results/analysis/statistics/nsclc"

python scripts/efficiency_report.py \
  --output-dir "${PGVL_STORAGE_ROOT}/PGVL-Gym-results/analysis/efficiency/current"

The statistical report adds patient-stratified bootstrap confidence intervals, strict paired differences, AUPRC/Brier/calibration outputs, and collapse diagnostics. It also writes patient-level reliability curves and confidence histograms as PNG/PDF figures with hashed run provenance (--no-plots keeps tables only). This assesses calibration without changing predictions. The efficiency report joins current run fingerprints with Slurm GPU hours and memory, trainer parameter records, checkpoint sizes, and optional profiled throughput, then emits broad and encoder-controlled Pareto fronts. Unavailable measurements stay blank. See statistical analysis and efficiency reporting for the exact contracts.

For a campaign:

./launch_pgvl.sh --dry-run
./launch_pgvl.sh --cohort brca --shots 4 --limit 3
./launch_pgvl.sh

For a convergence and launch-blocker audit, run one full-recipe fold without touching the five-fold outputs:

./launch_pgvl.sh --one-fold --shots 4 --dry-run \
  --report benchmarks/launch_report_one_fold_4shot_dry_run.csv
./launch_pgvl.sh --one-fold --shots 4 \
  --report benchmarks/launch_report_one_fold_4shot.csv

--one-fold preserves every method's configured epochs and staged-training recipe, writes to results/one_fold/, and resumes by skipping valid completed rows. It is not the same as the one-epoch --smoke mode and is not a final five-fold paper result. Check the quota of the filesystem containing results/ before a large matrix launch because model checkpoints can dominate storage.

📋 Campaign Planning & Execution

Dry-run planning inspects the campaign directly from a bootstrap Python without importing heavy libraries. Real submissions require PGVL_CONDA_ENV.

Launcher & Trainer Features:

  • Smart Resumption: Skips unavailable assets, avoids queued runs, and resumes only on exact config fingerprint matches.
  • State Validation: Requires finite validation loss and valid test results for each fold. Corrupt or out-of-range states are rejected.
  • Safety First: Proves log destinations are writable, locks results directories, and replaces checkpoints atomically to prevent partial writes.
  • Isolation: Each fold receives a fresh adapter and private config copy, preventing state leakage.
  • Strict Checks: Rejects mismatched adapters, invalid devices, duplicate job names, and contradictory readiness headers.

Use --rerun for a clean slate run (archives existing state) and --best-effort for explicit automation override.

Generated results also carry implementation_provenance and upstream_fidelity. These are independent of encoder_provenance: a backbone can be natively supported while the local objective remains partial. Set require_upstream_fidelity: true to make the doctor reject partial adapters.

🧩 Method Details & Upstream Fidelity

  • FOCUS: Uses byte-exact upstream CSVs for CAMELYON16, the separate combined CAMELYON16+17 matrix, TCGA-NSCLC, and UBC-OCEAN. The combined row discloses its 898-slide operational universe, 20x/256px geometry, and patient-disjoint split extension. Enforces file-class binding and provenance checks.
  • ViLa-MIL: Uses exact headerless upstream Lung and RCC CSVs; missing cohorts are generated task extensions matching the native layout. Every run is pinned to the paper's CLIP-RN50 5x/10x scale pair. The released code's unshifted end-of-text lookup after inserting 16 learned context embeddings is corrected and disclosed as partial implementation fidelity.
  • MSCPT: Uses both byte-exact upstream multiscale description banks and the distinct 50-set patch-selector banks for NSCLC, RCC, and UBC-OCEAN. Feature-only rows use the selector ensemble for low-magnification top-k ranking and remain partial. The separately named UBC mscpt_raw_rgb row restores the trainable deep visual-prompt branch from 50 ordered selector-ranked RGB crops per slide, deterministically compiled from transferred PNG slides and aligned 5x CONCH coordinates; this local cache boundary remains disclosed.
  • HiVE-MIL: Vendors the released CONCH heterogeneous graph, hierarchical prompt learner, filtering, and contrastive objective. It validates four 5x plus twelve 20x descriptions per class, pins the upstream commit and prompt hash, and reorders RCC's keyed class blocks to the benchmark label indices without changing their text.
  • MI-VisionShot: Cleanly reimplements the training-free method because upstream declares no software license. Separately named released-code and paper-Eq.-2.2 normalization rows pin the source commit, DOI, prompt hash, PLIP feature boundary, top-K value, support-only label usage, and label-free inference contract.
  • Libra-MIL: Cleanly reimplements the published dual-prototype SOT equations because upstream declares no software license. It pins the source commit, arXiv version, both prompt hashes, CONCH feature boundary, prototype counts, OT recipe, and paper/code training boundary.
  • DyKo: Cleanly reimplements dynamic prototype/concept retrieval and structural consistency around the released TITAN prompt/concept assets. Its contract validates cached CONCH-v1.5 patch provenance separately from the exact TITAN runtime text checkpoint.
  • MGPATH: Cleanly implements the released PLIP-only dual-scale prompt, graph-attention, clustering, and Sinkhorn path. Cached 768D PLIP bags are restored through PLIP's frozen native visual projection; the missing primary PLIP-G augmentation path is not implied.
  • HIPSS: Cleanly implements concatenated hierarchical prompts, layerwise CONCH text SSF, and region- then WSI-level text-refined gated attention over coordinate-grouped cached CONCH bags. Generated prompt banks, cached geometry, and paper/code attention-guidance differences remain explicit partial-fidelity boundaries.
  • PathPT: Uses the published 20x upstream_patch_ssl subtyping recipe, the released zero-start two-epoch warm-up, exact prompt-ranking behavior, and the family-specific pseudo-loss policy (CONCH/KEEP on; PLIP/MUSK off). CAMELYON16 is explicitly a local WSI-detection adaptation—the paper evaluates region segmentation there—and uses validation-only top-1% tumour-evidence calibration rather than majority patch voting. Report balanced accuracy first on imbalanced cohorts.
  • SLIP: Preserves prompt-bank structure natively (averaging separate texts), diverging from older flattened conversions.
  • MAPLE: Preserves entity-major order and validates prompt dictionary against classifier order.
  • CoD-MIL: Uses the RCC CSV as the canonical ordered bank, avoiding arbitrary feature tensors. It preserves the released encoder-specific text scales (native projected CLIP-RN50; unit-normalized PLIP/QuiltNet), includes all normal-tissue rows instead of the release's accidental [2C:-1] omission, and matches the release's inert scheduler behavior. These disclosed corrections make implementation fidelity partial. The extension name quiltnet is locked to wisdomik/QuiltNet-B-16; the upstream B-32 tensor remains audit-only and is never relabelled as B-16.
  • WSI-FiVE: Preserves distinct question, answer, and evaluation roles and avoids per-slide answers at inference. NSCLC records its 82 GPT-5.6 conservative extensions separately from 912 upstream answers and 27 blank-cell completions. Because answer-only 4-shot runs left the LUAD/LUSC boundary unconstrained and collapsed to one class, registered NSCLC configs retain that loss and add a disclosed weight-1 class loss using training-fold labels only (few_shot_class_anchor_weight; set it to 0 for the pure-objective ablation). CAMELYON16 runs the released DSMIL/classname transfer condition: exact normal/tumor text, the restored 50%-then-22,528 interval sampler, upstream question dropout, layer-1/layer-2/last soft-prompt pooling, and the SHA-256-pinned TCGA image-report pretrained FiVE checkpoint required by the paper's downstream protocol. Its two unused 16,384-position MIT parameters are reinitialized at the CAMELYON length; the released forward path ignores them and computes position encodings from patch indices. The authors' lung-specific questions in fix_pth_cam.yaml are preserved and disclosed. CAMELYON also has separately named CONCH, CLIP-RN50, and KEEP patch-feature swaps that retain BioClinicalBERT and the released transfer initialization; paired CAMELYON towers are excluded because that checkpoint is BioClinicalBERT-specific. Separate NSCLC VLM-feature rows remain partial BioClinicalBERT extensions; six additional paired-space ablations freeze the exact CONCH v1, QuiltNet-B-16, CLIP-RN50, PLIP, KEEP, or MUSK tower while training native soft prompts and WSI-FiVE fusion. The paired CLIP-RN50 row alone applies CLIP's native EOT-preserving truncation at its immutable 77-token boundary (clip_eot_truncate_77_v1); BioClinicalBERT and the other paired towers are unchanged.

The TCGA-NSCLC protocol also maintains a complete 23-source feature inventory for the requested encoder families and magnifications. See benchmarks/tcga_nsclc/README.md for exact coverage. WSI-FiVE's downloaded DSMIL CSV release is imported into audited HDF5 bags by scripts/import_wsi_five_dsmil_features.py; the same importer handles CAMELYON16. Inventory registration is intentionally separate from method/runtime encoder support.

📄 Example run YAML

Generated YAMLs are preferred, but this shows the core contract:

method: focus
backbone: conch
backbone_weights: ${PGVL_STORAGE_ROOT}/models/conch.bin
feature_space_id: hf:MahmoodLab/conch
feature_dim: 512
implementation_provenance: vendored
upstream_fidelity: upstream

dataset_csv: ${PGVL_REPO_ROOT}/benchmarks/tcga_brca/data/brca/manifest.csv
split_dir: ${PGVL_REPO_ROOT}/benchmarks/tcga_brca/splits/brca/4shot
feature_path_column: feature__conch_v1_20x
feature_path_column_l: feature__conch_v1_20x
feature_key: features
min_feature_coverage: 1.0

n_classes: 2
classnames:
  - invasive ductal carcinoma
  - invasive lobular carcinoma
label_dict:
  IDC: 0
  ILC: 1
text_prompt_path: ${PGVL_REPO_ROOT}/text_prompts/focus/TCGA_BRCA_two_scale_text_prompt.csv

shots: 4
k: 5
k_start: 0
k_end: 5
seed: 1
epochs: 200
batch_size: 1
lr: 0.0001
weight_decay: 0.00001
early_stopping: true
results_dir: ${PGVL_REPO_ROOT}/results/focus/brca/4shot

Feature provenance and dimensions are part of the experiment identity. Do not change a generated YAML in place and reuse its results directory.

🔗 Register a backbone

A backbone registration declares its real capabilities and returns an EncoderBundle. Registration does not automatically make every method compatible; each method's MethodBackboneContract still decides whether the combination is native, adaptable, or blocked.

import torch
from common.backbones import (
    BackboneCapability,
    BackboneSpec,
    EncoderBundle,
    register_backbone,
)

SPEC = BackboneSpec(
    name="my-backbone",
    family="my-family",
    feature_space_id="org/my-backbone@revision",
    capabilities=frozenset({BackboneCapability.TILE_ENCODE}),
    tile_dim=768,
    revision="commit-or-checksum",
)

def build_my_backbone(*, weights_path=None, device="cpu", **kwargs):
    model = load_my_model(weights_path).to(device)  # your implementation
    tile_encoder = MyTileEncoder(model)              # implements encode_tiles
    return EncoderBundle(
        raw_model=model,
        spec=SPEC,
        tile=tile_encoder,
        metadata={"weights_path": weights_path},
    )

register_backbone(SPEC, build_my_backbone)

For a permanent built-in registration, place the spec and loader in common/backbones/factory.py, export any wrapper from common/backbones/, and add interface tests. Inspect compatibility without loading weights:

python scripts/list_backbone_compatibility.py
python scripts/list_backbone_compatibility.py --method pathpt --json
python scripts/list_encoder_swaps.py
python scripts/list_encoder_swaps.py --method muse --json

See docs/BACKBONE_INTERFACES.md for capability definitions and method swap boundaries.

🗺️ Repository map

train.py                  unified training and reporting
common/                   datasets, backbone contracts, shared model blocks
common/interpretability.py validated patch-evidence and rendering contract
common/statistical_analysis.py patient-bootstrap and calibration contracts
common/efficiency_analysis.py Slurm parsing and Pareto contracts
methods/<name>/           paper-specific model plus BaseMethod adapter
benchmarks/<cohort>/      protocol and generated experiment artifacts
scripts/tcga_benchmark.py protocol compiler
scripts/preflight.py      filesystem and feature health check
scripts/generate_heatmap.py checkpoint-bound heatmap artifact generator
scripts/statistical_report.py current-run uncertainty and diagnostic reports
scripts/efficiency_report.py resource, artifact-size, and Pareto reports
configs/                  small hand-authored examples
docs/                     detailed design and method documentation

Run tests with pytest -q. Contribution and extension guidance lives in CONTRIBUTING.md and docs/extending.md.

🙏 Acknowledgments

This codebase consolidates code from the following repositories. All copyright remains with the original authors.

RepositoryMethod/RoleLicense
dddavid4real/FOCUSFOCUS🔒 Apache-2.0
Jiangbo-Shi/ViLa-MILViLa-MIL🔒 CC-BY-NC-ND-4.0 *
Jiangbo-Shi/CoD-MILCoD-MIL🔒 CC-BY-NC-ND-4.0 *
JJ-ZHOU-Code/MAPLEMAPLE🔒 CC-BY-NC-ND-4.0 *
Hanminghao/MSCPTMSCPT🔒 CC-BY-NC-ND-4.0 *
MAGIC-AI4Med/PathPTPathPT🔒 MIT
miccaiif/TOPTOP🔒 CC-BY-NC-ND-4.0 *
LTS5/SLIPSLIP🔒 CC-BY-NC-ND-4.0 *
ls1rius/WSI_FiVEWSI-FiVE🔒 CC-BY-NC-ND-4.0 *
JiahaoXu-god/CVPR2026_MUSEMUSE🔒 CC-BY-NC-ND-4.0 *
BasitAlawode/ConVLMConVLM🔒 MIT
linlu2022/SLDPCSLDPC🔒 Apache-2.0
bryanwong17/HiVE-MILHiVE-MIL🔒 MIT
cvblab/MIVisionShotMI-VisionShot⚠️ No license declared; equations cleanly reimplemented, no source vendored
zfy07/Libra-MILLibra-MIL⚠️ No license declared; equations cleanly reimplemented, no source vendored
junjianli106/DyKoDyKo⚠️ No license declared; equations cleanly reimplemented, no source vendored
HauschildLab/MGPATHMGPATH⚠️ No license declared; equations cleanly reimplemented, no source vendored
Jayanie/HIPSSHIPSS⚠️ No license declared; equations cleanly reimplemented, no source vendored
RepositoryMethod/RoleLicense
mahmoodlab/CLAMCLAM Scaffold🔒 GPL-3.0
KaiyangZhou/CoOpCoOp Blocks🔒 MIT
  • Assumed license based on the repository contents or context.

Contributors

byAutumn

8 commits

researchsubmissions66/PGVL-Gym

0

stars

29

commits

Python

primary language

Sep 6, 2026

updated

researchsubmissions66.github.io/PGVL-Gym/project/

README

PGVL-Gym

A generalized framework for fair, reproducible evaluation of
whole-slide pathology vision-language models.

Project website Documentation Source


🔭 Overview

PGVL-Gym is a registry-based benchmark that runs recent few-shot and zero-shot whole-slide-image (WSI) vision-language methods through one explicit experiment contract. It preserves each paper's model-specific architecture while standardizing protocols, feature provenance, folds, shots, seeds, and reporting.

Systematic protocols cover TCGA NSCLC, BRCA and RCC plus UBC-OCEAN and CAMELYON16. A separate combined CAMELYON16+17 matrix registers the native FOCUS/MUSE cohort without mixing it into CAMELYON16-only results.

📁 Benchmark layout

Each cohort owns one benchmark directory under benchmarks/, holding its protocol.yaml and everything generated from it (manifests, splits, configs, run_matrix.csv, readiness reports). Cohorts are kept separate so one whose data is not ready cannot hold back the ones that are:

BenchmarkTask
benchmarks/tcga_nsclcLUAD vs LUSC
benchmarks/tcga_brcaIDC vs ILC
benchmarks/tcga_rccRCC subtyping
benchmarks/ubc_oceanfive-class ovarian carcinoma subtyping
benchmarks/camelyon16lymph-node metastasis detection
benchmarks/camelyon_combinedcombined CAMELYON16+17 metastasis detection for FOCUS/MUSE

📚 Documentation website

The documentation site combines curated guides with API reference generated directly from the stable Python docstrings:

python -m pip install -r requirements-docs.txt
python scripts/check_docstrings.py
python -m mkdocs build --strict

PGVL-Gym is a reproducible benchmark for few-shot and zero-shot whole-slide pathology vision-language methods. It standardizes datasets, feature provenance, patient-disjoint folds, training, and reporting while explicitly recording whether each adapter is vendored, mixed, or a partial local reimplementation.

The normal workflow is:

configure local paths → generate run YAMLs → preflight → train → aggregate → explain

📦 1. Install the environment

The supported Python range is 3.10–3.11. Create the base environment with Conda:

conda env create -f environment.yml
conda activate pgvl-gym
pip install -e .

Install only the optional dependencies needed by your method:

pip install -e '.[cod-mil]'
pip install -e '.[pathpt-musk]'
pip install -e '.[convlm]'
pip install -e '.[hive-mil]'

Available extras are listed in pyproject.toml. Foundation-model checkpoints are not downloaded automatically; benchmark runs are designed for local or offline model caches.

⚙️ 2. Configure machine-local paths

Copy the environment template and edit the ignored local file:

cp .env.example .env
PGVL_REPO_ROOT=/path/to/PGVL-Gym
PGVL_USER_ROOT=/path/to/user-root
PGVL_STORAGE_ROOT=/path/to/storage-root
PGVL_CONDA_ENV=/path/to/project/envs/pgvl-gym

Committed protocols, manifests, splits, and configs use references such as ${PGVL_REPO_ROOT} and ${PGVL_STORAGE_ROOT}. Python commands load .env automatically. The launch shell scripts source it as well. Existing process environment variables take precedence, which is useful on a cluster.

Do not commit .env; it is intentionally ignored.

🧬 3. Generate experiment YAMLs

Each cohort has one source-of-truth protocol:

benchmarks/<cohort>/protocol.yaml

Edit its cohort metadata, feature registry, checkpoints, methods, folds, and shot counts, then generate manifests, splits, method configs, and the run matrix:

python scripts/tcga_benchmark.py all \
  --protocol benchmarks/tcga_brca/protocol.yaml

Useful stages are inventory, prepare, configs, validate, aggregate, and all. Generated configs appear under benchmarks/<cohort>/configs/<experiment>/; runnable rows are indexed in benchmarks/<cohort>/run_matrix.csv.

Shot schedules are cohort-capacity-aware while retaining identical nested, patient-disjoint splits across methods: CAMELYON16, combined CAMELYON16+17, TCGA-BRCA, and TCGA-NSCLC provide 4/8/16/32/64-shot configs; TCGA-RCC provides 4/8/16/32; UBC-OCEAN provides 4/8/16. The combined cohort's 32/64-shot rows are explicit benchmark extensions beyond the upstream 4/8/16 comparison. Higher RCC and UBC-OCEAN levels are deliberately absent because the rarest classes cannot supply equal-sized training and validation sets without leakage or patient reuse.

Feature extraction may finish after those artifacts are generated. Campaign planning refreshes feature_coverage.csv, missing_feature_files, and the feature-derived ready state directly from the existing manifests before every plan. It does not rebuild prompts, manifests, splits, or configs. Thus a pending feature set remains a clean skip, then becomes runnable automatically once all of its referenced files arrive. Use --no-refresh-readiness only when you deliberately need to inspect the frozen matrix cells.

Check one generated run before allocating a GPU:

python scripts/preflight.py \
  benchmarks/tcga_brca/configs/focus/brca_4shot.yaml

python scripts/preflight.py run.yaml --features
python scripts/preflight.py run.yaml --features --deep
python scripts/preflight.py run.yaml --prompts --encoders
python scripts/preflight.py run.yaml --quick
python scripts/preflight.py --system
python scripts/preflight.py run.yaml --strict --json

The preflight command is a read-only doctor. Failures include suggested fixes. Normal mode does not construct a model or load a feature tensor.

Key Checks:

  • Feature Payloads (via --deep): Verifies keys, shapes, widths, and finite values.
  • Data Integrity: Checks shared pickle stores for key/ID alignment, duplicate IDs, and coverage.
  • Asset Validation: Scans for missing, empty, unreadable, or wrong-type paths.
  • Safety: Verifies that the results directory is safe and writable.
  • Leakage Prevention: Detects slide or patient leakage between train, validation, and test partitions.
  • Method-Specific Schemas: Validates prompt banks across all methods (FOCUS, ViLa-MIL, MAPLE, MSCPT, HiVE-MIL, MI-VisionShot, Libra-MIL, DyKo, MGPATH, HIPSS, PathPT, TOP, SLIP, CoD-MIL, WSI-FiVE, MUSE, ConVLM, SLDPC).
  • Configuration & Runtime: Rejects non-unit batches for variable-length methods, unscoped phase tables, and invalid staged-training values. Validates CoD-MIL map shapes and bounds.

Useful doctor modes are:

OptionPurpose
--systemCheck Python 3.10–3.11, all core packages (including the supported and mutually compatible Torch/torchvision releases), .env, and all PGVL root directories; a run YAML is optional.
--quickCheck feature roots without statting every manifest row; equivalent to --no-feature-scan.
--deepOpen every available referenced feature and validate its payload; incompatible with --quick.
--min-feature-coverage NTemporarily override the configured coverage threshold with a fraction from 0 through 1.
--strictTurn warnings, including explicitly allowed partial coverage, into a failing readiness gate.
--jsonEmit schema-versioned JSON with summaries, timings, host diagnostics, and per-config results.
--verboseInclude successful resolved paths, asset types, and file sizes.
--quietPrint only findings and the final diagnosis.
--no-colorDisable ANSI color explicitly; redirected output disables it automatically.

Selectors --assets, --features, --prompts, --encoders, and --splits can be combined; --all or omitting selectors runs every check. Multiple YAMLs or shell globs are accepted. A healthy diagnosis exits zero, diagnosed failures exit one, and invalid command arguments exit two. See Commands and run lifecycle for the full interface and JSON contract.

📝 Prompt Provenance

Prompt provenance is tracked by method and by role in text_prompts/PROVENANCE.json. Every method summary records an exact disclosed generator, an explicit not_disclosed_by_upstream/legacy_local_generator_not_recorded marker, or a precise not_applicable_* reason. scripts/audit_prompt_provenance.py --check fails when a generated asset or method summary omits that identity.

  • TOP: Standard NSCLC and CAMELYON16 use the released 26-instance code bank and their task-specific active bag initializers. Initialized descriptions remain frozen and only their ten released * slots are trainable (all_ctx_trainable: false); external CLIP-RN50 patch rows are unit-normalized before the paper's cosine-similarity operations. CAMELYON also preserves the upstream space before instance prompt slots and its 500-epoch launcher recipe. Unwired alternatives are explicitly labeled. The doctor validates prompt structure, ordered labels, hashes, and the frozen-description boundary.
  • SLIP: TCGA-NSCLC uses the complete released bank. Its RN50 run is a local protocol extension because upstream's referenced TCGA dataset module is absent and the paper reports other cohorts with ViT-B/16. A separately named PLIP run uses paired PLIP features/text prompts and restores cached preprojection features through PLIP's frozen native visual head. Missing cohort banks are clearly labeled as generated task extensions.
  • MAPLE: Lung, RCC, and BRCA use byte-exact upstream copies. TCGA-NSCLC exposes PLIP 10x/20x and 5x/20x release-code runs plus a distinct 5x/10x paper-text reproduction condition (AdamW, 1e-4, 80 epochs); the local runtime restores cached 768-wide PLIP vision features with PLIP's frozen native projection and corrects a released reshape mismatch.
  • MUSE: CAMELYON16, the separate combined CAMELYON16+17 matrix, TCGA-NSCLC, and TCGA-BRCA use byte-exact description CSVs. Native prompt-path runs execute the released shared 16-token CONCH learner, noisy top-2/8-expert SFSE routing, and training-only class-scoped top-20 SMMO view; RCC and UBC-OCEAN remain labeled generated MUSE-schema extensions. The combined row uses the fully covered 20x/256px store and patient-disjoint folds, so it is explicitly partial. Opt-in text-tower swaps use a separately disclosed feature-space context path and never replace the native row.
  • ConVLM: Upstream omits att_splits.mat and a usable attribute builder. NSCLC deliberately enables a partial local reconstruction using complete QuiltNet-B-16 20x bags, the pinned B16 text checkpoint, and an audited generated bank; the other banks remain unwired. It must not be reported as an upstream reproduction.
  • HiVE-MIL: BRCA, NSCLC, and RCC use every released GPT-4o prompt string in its exact within-class order; only insignificant JSON whitespace is normalized, so the assets are marked derived. Runs pair CONCH v1 5x/20x bags and build each [N,16,D] child hierarchy from audited Trident coordinates. Parent spans are derived per slide and strictly checked against the shared coordinate frame, supporting mixed 20x/40x/60x/80x source scans without a scanner-specific constant; this local feature-preparation boundary is disclosed as partial.
  • MI-VisionShot: RCC uses the exact three PLIP class prompts hardcoded upstream; the local keyed JSON container is marked derived. Two explicit rows resolve a paper/code conflict: mi_visionshot preserves the released executable's unnormalized projected patch rows, while mi_visionshot_paper_l2 applies the per-patch L2 normalization required by paper Eq. 2.2 before support top-200 selection and inference BGAP. Both restore cached 768D PLIP features through PLIP's frozen native visual projection and keep labels support-only. The current 939-slide, patient-level, 224px protocol remains partial relative to the paper's 923-slide, random-repeat, 256px experiment.
  • Libra-MIL: RCC uses the released 46-entry instance bank and six-row scale/class bank with the native 20x/512px CONCH feature space. Ten learned visual prototypes and learned text prototypes are fused by Sinkhorn optimal transport before the high-resolution class prompts query the reweighted bag. The paper's 80-epoch/patience-15 protocol is combined with the released cosine-per-update AdamW schedule; current 939-slide patient folds remain explicitly partial relative to the paper's 925-slide cohort.
  • DyKo: NSCLC and RCC use the released Claude-3.5-Sonnet task descriptions and byte-exact 1,000×768 TITAN concept tensors. The runtime keeps CONCH-v1.5 vision-preprojection bags and the TITAN prompt tower as separately validated paired identities. The available 20x/512px bags extend the paper's 20x/448px geometry, and RCC remains feature-gated at 935/939 slides.
  • MGPATH: BRCA and NSCLC preserve all four released low/high PLIP descriptions and their positional order. The executable PLIP-only condition follows the final TMLR recipe (5x/10x, Adam 9e-6, 200 epochs), correcting the conflicting release command example (5x/20x, 9e-4, 50 epochs). It remains partial because cached tiles are 224px rather than 256px, augmented bags are unavailable, and it is not the primary PLIP-G/Prov-GigaPath condition. Upstream does not disclose a generator LLM.
  • HIPSS: CAMELYON16, NSCLC, and UBC-OCEAN use complete GPT-5.6 replacement banks because the public release contains empty prompt literals and only two prompt slots. The clean runtime concatenates WSI/region token sequences and applies SSF at all four internal sites in the last 2 or 8 frozen CONCH text blocks, exactly matching the paper's 284,419/348,931 trainable-parameter budgets. Results remain partial because the original ChatGPT-4o strings are unavailable and cached patch geometry differs from the paper's dense tiling.

Paired-VLM encoder ports are available as opt-in extensions for FOCUS, ViLa-MIL, TOP, MGPATH, Libra-MIL, DyKo, and HIPSS. Native rows are unchanged. Each extension requires one exact CONCH, KEEP, MUSK, PLIP, or QuiltNet-B-16 image/text checkpoint, encoder_extension: true, and a method-specific strategy recorded in the resolved config and result provenance. Most ports replace inaccessible token-level prompting with zero-initialized final-feature context; Libra-MIL only re-encodes its prompt roles, DyKo also learns a bridge from its fixed TITAN concept bank, and HIPSS replaces CONCH-block SSF with final-feature affine SSF. PLIP's cached 768-wide vision-preprojection rows are restored with the matching frozen native 768-to-512 visual projection; QuiltNet-B-16 caches are already in its 512-wide shared image/text space. These rows are partial architecture extensions, not upstream reproductions. Inspect the legal combinations with:

The generated matrices now enumerate every exact on-disk encoder condition for each already registered method/cohort pair. PathPT uses its method-owned CONCH/KEEP/MUSK implementations; its PLIP path remains unregistered because the available bags are 768-wide vision-preprojection rather than the required 512-wide shared features. MUSE separately identifies native CONCH, cross-space CONCH-text, and paired-tower conditions; SLDPC's CLIP-RN50 text tower uses an explicit learned slide projection. Dual-scale methods are emitted only when both required scales exist for one checkpoint, so a missing 5x or 10x store is never replaced with a different magnification.

python scripts/list_encoder_swaps.py
python scripts/list_encoder_swaps.py --method hipss --json

🚀 4. Run a configuration

python train.py \
  --method focus \
  --config benchmarks/tcga_brca/configs/focus/brca_4shot.yaml \
  --device cuda:0

🔬 Checkpoint-bound interpretability

Generate an audited patch-evidence artifact set (lossless CSV, rendered PNG, and provenance manifest) for an eligible method:

python scripts/generate_heatmap.py \
  --method pathpt --config run.yaml --ckpt-dir /path/to/results \
  --fold 0 --split test --slide-id SLIDE_ID

The command validates the run/checkpoint identity, uses exact HDF5 level-0 coordinates, and defaults to the predicted class on a coordinate-only canvas. Pass --target-class LABEL for another class or --wsi /path/to/slide.svs for an overlay whose dimensions are checked against the feature geometry. FOCUS, ViLa-MIL, CoD-MIL, native PathPT, TOP, SLIP, MUSE, Libra-MIL, DyKo, MGPATH, and HIPSS expose audited providers.

Their quantities are intentionally not conflated: outputs retain names such as class-query attention, prompt evidence, patch-class probability, transport attention, and hierarchical contribution. Methods without an audited patch-aligned quantity refuse generation. See the full interpretability workflow and compact method support matrix.

📊 Uncertainty and efficiency reports

Completed prediction files can be analyzed without retraining:

python scripts/statistical_report.py \
  --matrix benchmarks/tcga_nsclc/run_matrix.csv \
  --output-dir "${PGVL_STORAGE_ROOT}/PGVL-Gym-results/analysis/statistics/nsclc"

python scripts/efficiency_report.py \
  --output-dir "${PGVL_STORAGE_ROOT}/PGVL-Gym-results/analysis/efficiency/current"

The statistical report adds patient-stratified bootstrap confidence intervals, strict paired differences, AUPRC/Brier/calibration outputs, and collapse diagnostics. It also writes patient-level reliability curves and confidence histograms as PNG/PDF figures with hashed run provenance (--no-plots keeps tables only). This assesses calibration without changing predictions. The efficiency report joins current run fingerprints with Slurm GPU hours and memory, trainer parameter records, checkpoint sizes, and optional profiled throughput, then emits broad and encoder-controlled Pareto fronts. Unavailable measurements stay blank. See statistical analysis and efficiency reporting for the exact contracts.

For a campaign:

./launch_pgvl.sh --dry-run
./launch_pgvl.sh --cohort brca --shots 4 --limit 3
./launch_pgvl.sh

For a convergence and launch-blocker audit, run one full-recipe fold without touching the five-fold outputs:

./launch_pgvl.sh --one-fold --shots 4 --dry-run \
  --report benchmarks/launch_report_one_fold_4shot_dry_run.csv
./launch_pgvl.sh --one-fold --shots 4 \
  --report benchmarks/launch_report_one_fold_4shot.csv

--one-fold preserves every method's configured epochs and staged-training recipe, writes to results/one_fold/, and resumes by skipping valid completed rows. It is not the same as the one-epoch --smoke mode and is not a final five-fold paper result. Check the quota of the filesystem containing results/ before a large matrix launch because model checkpoints can dominate storage.

📋 Campaign Planning & Execution

Dry-run planning inspects the campaign directly from a bootstrap Python without importing heavy libraries. Real submissions require PGVL_CONDA_ENV.

Launcher & Trainer Features:

  • Smart Resumption: Skips unavailable assets, avoids queued runs, and resumes only on exact config fingerprint matches.
  • State Validation: Requires finite validation loss and valid test results for each fold. Corrupt or out-of-range states are rejected.
  • Safety First: Proves log destinations are writable, locks results directories, and replaces checkpoints atomically to prevent partial writes.
  • Isolation: Each fold receives a fresh adapter and private config copy, preventing state leakage.
  • Strict Checks: Rejects mismatched adapters, invalid devices, duplicate job names, and contradictory readiness headers.

Use --rerun for a clean slate run (archives existing state) and --best-effort for explicit automation override.

Generated results also carry implementation_provenance and upstream_fidelity. These are independent of encoder_provenance: a backbone can be natively supported while the local objective remains partial. Set require_upstream_fidelity: true to make the doctor reject partial adapters.

🧩 Method Details & Upstream Fidelity

  • FOCUS: Uses byte-exact upstream CSVs for CAMELYON16, the separate combined CAMELYON16+17 matrix, TCGA-NSCLC, and UBC-OCEAN. The combined row discloses its 898-slide operational universe, 20x/256px geometry, and patient-disjoint split extension. Enforces file-class binding and provenance checks.
  • ViLa-MIL: Uses exact headerless upstream Lung and RCC CSVs; missing cohorts are generated task extensions matching the native layout. Every run is pinned to the paper's CLIP-RN50 5x/10x scale pair. The released code's unshifted end-of-text lookup after inserting 16 learned context embeddings is corrected and disclosed as partial implementation fidelity.
  • MSCPT: Uses both byte-exact upstream multiscale description banks and the distinct 50-set patch-selector banks for NSCLC, RCC, and UBC-OCEAN. Feature-only rows use the selector ensemble for low-magnification top-k ranking and remain partial. The separately named UBC mscpt_raw_rgb row restores the trainable deep visual-prompt branch from 50 ordered selector-ranked RGB crops per slide, deterministically compiled from transferred PNG slides and aligned 5x CONCH coordinates; this local cache boundary remains disclosed.
  • HiVE-MIL: Vendors the released CONCH heterogeneous graph, hierarchical prompt learner, filtering, and contrastive objective. It validates four 5x plus twelve 20x descriptions per class, pins the upstream commit and prompt hash, and reorders RCC's keyed class blocks to the benchmark label indices without changing their text.
  • MI-VisionShot: Cleanly reimplements the training-free method because upstream declares no software license. Separately named released-code and paper-Eq.-2.2 normalization rows pin the source commit, DOI, prompt hash, PLIP feature boundary, top-K value, support-only label usage, and label-free inference contract.
  • Libra-MIL: Cleanly reimplements the published dual-prototype SOT equations because upstream declares no software license. It pins the source commit, arXiv version, both prompt hashes, CONCH feature boundary, prototype counts, OT recipe, and paper/code training boundary.
  • DyKo: Cleanly reimplements dynamic prototype/concept retrieval and structural consistency around the released TITAN prompt/concept assets. Its contract validates cached CONCH-v1.5 patch provenance separately from the exact TITAN runtime text checkpoint.
  • MGPATH: Cleanly implements the released PLIP-only dual-scale prompt, graph-attention, clustering, and Sinkhorn path. Cached 768D PLIP bags are restored through PLIP's frozen native visual projection; the missing primary PLIP-G augmentation path is not implied.
  • HIPSS: Cleanly implements concatenated hierarchical prompts, layerwise CONCH text SSF, and region- then WSI-level text-refined gated attention over coordinate-grouped cached CONCH bags. Generated prompt banks, cached geometry, and paper/code attention-guidance differences remain explicit partial-fidelity boundaries.
  • PathPT: Uses the published 20x upstream_patch_ssl subtyping recipe, the released zero-start two-epoch warm-up, exact prompt-ranking behavior, and the family-specific pseudo-loss policy (CONCH/KEEP on; PLIP/MUSK off). CAMELYON16 is explicitly a local WSI-detection adaptation—the paper evaluates region segmentation there—and uses validation-only top-1% tumour-evidence calibration rather than majority patch voting. Report balanced accuracy first on imbalanced cohorts.
  • SLIP: Preserves prompt-bank structure natively (averaging separate texts), diverging from older flattened conversions.
  • MAPLE: Preserves entity-major order and validates prompt dictionary against classifier order.
  • CoD-MIL: Uses the RCC CSV as the canonical ordered bank, avoiding arbitrary feature tensors. It preserves the released encoder-specific text scales (native projected CLIP-RN50; unit-normalized PLIP/QuiltNet), includes all normal-tissue rows instead of the release's accidental [2C:-1] omission, and matches the release's inert scheduler behavior. These disclosed corrections make implementation fidelity partial. The extension name quiltnet is locked to wisdomik/QuiltNet-B-16; the upstream B-32 tensor remains audit-only and is never relabelled as B-16.
  • WSI-FiVE: Preserves distinct question, answer, and evaluation roles and avoids per-slide answers at inference. NSCLC records its 82 GPT-5.6 conservative extensions separately from 912 upstream answers and 27 blank-cell completions. Because answer-only 4-shot runs left the LUAD/LUSC boundary unconstrained and collapsed to one class, registered NSCLC configs retain that loss and add a disclosed weight-1 class loss using training-fold labels only (few_shot_class_anchor_weight; set it to 0 for the pure-objective ablation). CAMELYON16 runs the released DSMIL/classname transfer condition: exact normal/tumor text, the restored 50%-then-22,528 interval sampler, upstream question dropout, layer-1/layer-2/last soft-prompt pooling, and the SHA-256-pinned TCGA image-report pretrained FiVE checkpoint required by the paper's downstream protocol. Its two unused 16,384-position MIT parameters are reinitialized at the CAMELYON length; the released forward path ignores them and computes position encodings from patch indices. The authors' lung-specific questions in fix_pth_cam.yaml are preserved and disclosed. CAMELYON also has separately named CONCH, CLIP-RN50, and KEEP patch-feature swaps that retain BioClinicalBERT and the released transfer initialization; paired CAMELYON towers are excluded because that checkpoint is BioClinicalBERT-specific. Separate NSCLC VLM-feature rows remain partial BioClinicalBERT extensions; six additional paired-space ablations freeze the exact CONCH v1, QuiltNet-B-16, CLIP-RN50, PLIP, KEEP, or MUSK tower while training native soft prompts and WSI-FiVE fusion. The paired CLIP-RN50 row alone applies CLIP's native EOT-preserving truncation at its immutable 77-token boundary (clip_eot_truncate_77_v1); BioClinicalBERT and the other paired towers are unchanged.

The TCGA-NSCLC protocol also maintains a complete 23-source feature inventory for the requested encoder families and magnifications. See benchmarks/tcga_nsclc/README.md for exact coverage. WSI-FiVE's downloaded DSMIL CSV release is imported into audited HDF5 bags by scripts/import_wsi_five_dsmil_features.py; the same importer handles CAMELYON16. Inventory registration is intentionally separate from method/runtime encoder support.

📄 Example run YAML

Generated YAMLs are preferred, but this shows the core contract:

method: focus
backbone: conch
backbone_weights: ${PGVL_STORAGE_ROOT}/models/conch.bin
feature_space_id: hf:MahmoodLab/conch
feature_dim: 512
implementation_provenance: vendored
upstream_fidelity: upstream

dataset_csv: ${PGVL_REPO_ROOT}/benchmarks/tcga_brca/data/brca/manifest.csv
split_dir: ${PGVL_REPO_ROOT}/benchmarks/tcga_brca/splits/brca/4shot
feature_path_column: feature__conch_v1_20x
feature_path_column_l: feature__conch_v1_20x
feature_key: features
min_feature_coverage: 1.0

n_classes: 2
classnames:
  - invasive ductal carcinoma
  - invasive lobular carcinoma
label_dict:
  IDC: 0
  ILC: 1
text_prompt_path: ${PGVL_REPO_ROOT}/text_prompts/focus/TCGA_BRCA_two_scale_text_prompt.csv

shots: 4
k: 5
k_start: 0
k_end: 5
seed: 1
epochs: 200
batch_size: 1
lr: 0.0001
weight_decay: 0.00001
early_stopping: true
results_dir: ${PGVL_REPO_ROOT}/results/focus/brca/4shot

Feature provenance and dimensions are part of the experiment identity. Do not change a generated YAML in place and reuse its results directory.

🔗 Register a backbone

A backbone registration declares its real capabilities and returns an EncoderBundle. Registration does not automatically make every method compatible; each method's MethodBackboneContract still decides whether the combination is native, adaptable, or blocked.

import torch
from common.backbones import (
    BackboneCapability,
    BackboneSpec,
    EncoderBundle,
    register_backbone,
)

SPEC = BackboneSpec(
    name="my-backbone",
    family="my-family",
    feature_space_id="org/my-backbone@revision",
    capabilities=frozenset({BackboneCapability.TILE_ENCODE}),
    tile_dim=768,
    revision="commit-or-checksum",
)

def build_my_backbone(*, weights_path=None, device="cpu", **kwargs):
    model = load_my_model(weights_path).to(device)  # your implementation
    tile_encoder = MyTileEncoder(model)              # implements encode_tiles
    return EncoderBundle(
        raw_model=model,
        spec=SPEC,
        tile=tile_encoder,
        metadata={"weights_path": weights_path},
    )

register_backbone(SPEC, build_my_backbone)

For a permanent built-in registration, place the spec and loader in common/backbones/factory.py, export any wrapper from common/backbones/, and add interface tests. Inspect compatibility without loading weights:

python scripts/list_backbone_compatibility.py
python scripts/list_backbone_compatibility.py --method pathpt --json
python scripts/list_encoder_swaps.py
python scripts/list_encoder_swaps.py --method muse --json

See docs/BACKBONE_INTERFACES.md for capability definitions and method swap boundaries.

🗺️ Repository map

train.py                  unified training and reporting
common/                   datasets, backbone contracts, shared model blocks
common/interpretability.py validated patch-evidence and rendering contract
common/statistical_analysis.py patient-bootstrap and calibration contracts
common/efficiency_analysis.py Slurm parsing and Pareto contracts
methods/<name>/           paper-specific model plus BaseMethod adapter
benchmarks/<cohort>/      protocol and generated experiment artifacts
scripts/tcga_benchmark.py protocol compiler
scripts/preflight.py      filesystem and feature health check
scripts/generate_heatmap.py checkpoint-bound heatmap artifact generator
scripts/statistical_report.py current-run uncertainty and diagnostic reports
scripts/efficiency_report.py resource, artifact-size, and Pareto reports
configs/                  small hand-authored examples
docs/                     detailed design and method documentation

Run tests with pytest -q. Contribution and extension guidance lives in CONTRIBUTING.md and docs/extending.md.

🙏 Acknowledgments

This codebase consolidates code from the following repositories. All copyright remains with the original authors.

RepositoryMethod/RoleLicense
dddavid4real/FOCUSFOCUS🔒 Apache-2.0
Jiangbo-Shi/ViLa-MILViLa-MIL🔒 CC-BY-NC-ND-4.0 *
Jiangbo-Shi/CoD-MILCoD-MIL🔒 CC-BY-NC-ND-4.0 *
JJ-ZHOU-Code/MAPLEMAPLE🔒 CC-BY-NC-ND-4.0 *
Hanminghao/MSCPTMSCPT🔒 CC-BY-NC-ND-4.0 *
MAGIC-AI4Med/PathPTPathPT🔒 MIT
miccaiif/TOPTOP🔒 CC-BY-NC-ND-4.0 *
LTS5/SLIPSLIP🔒 CC-BY-NC-ND-4.0 *
ls1rius/WSI_FiVEWSI-FiVE🔒 CC-BY-NC-ND-4.0 *
JiahaoXu-god/CVPR2026_MUSEMUSE🔒 CC-BY-NC-ND-4.0 *
BasitAlawode/ConVLMConVLM🔒 MIT
linlu2022/SLDPCSLDPC🔒 Apache-2.0
bryanwong17/HiVE-MILHiVE-MIL🔒 MIT
cvblab/MIVisionShotMI-VisionShot⚠️ No license declared; equations cleanly reimplemented, no source vendored
zfy07/Libra-MILLibra-MIL⚠️ No license declared; equations cleanly reimplemented, no source vendored
junjianli106/DyKoDyKo⚠️ No license declared; equations cleanly reimplemented, no source vendored
HauschildLab/MGPATHMGPATH⚠️ No license declared; equations cleanly reimplemented, no source vendored
Jayanie/HIPSSHIPSS⚠️ No license declared; equations cleanly reimplemented, no source vendored
RepositoryMethod/RoleLicense
mahmoodlab/CLAMCLAM Scaffold🔒 GPL-3.0
KaiyangZhou/CoOpCoOp Blocks🔒 MIT
  • Assumed license based on the repository contents or context.

Contributors

byAutumn

8 commits

Languages

Python

97.1%