Skip to content

Releases: xtmtd/OTU-Former

v0.11.1

Choose a tag to compare

@xtmtd xtmtd released this 27 Oct 03:05

v0.11.1

Fixed

  • Parameters: now records the requested keyword for auto/none defaults: --global-crop-size auto, --extract-size auto, and --register-tokens none read "auto" / "none" instead of the internal null placeholder (pretrain, finetune). null is now reserved for an option the user did not supply.
  • Command: replays --disable-embedding-metrics as the CLI switch instead of its derived compute_embedding_metrics argument, and finetune keeps an explicitly typed --extract-size auto.
  • Replayed values are POSIX-shell quoted, so a path containing spaces can be copied and rerun.
  • Every run records the resolved compute device once (Resolved device: mps), including the ONNX extraction path, which records its CPUExecutionProvider.
  • The normalized argument object handed to the core layer and the saved checkpoint arguments are unchanged.

Docs

  • The master design spec gains a run log contract (Section 2.3): what Command: and Parameters: each mean, why resolved values are recorded after resolution rather than substituted back, and which null meanings belong to the Patch config: block.

Compatibility

  • Log output only: no analysis default, algorithm, argument name, or checkpoint field changed. Existing run logs keep their previous null spelling and remain readable.

v0.11.0

Choose a tag to compare

@xtmtd xtmtd released this 01 Oct 04:26

v0.11.0

Added

  • Portable otuformer-workflow Skill (skills/otuformer-workflow/) that reviews every runtime-derived CLI parameter, presents a complete parameter card, and asks for one approval per analysis step.
  • Read-only runtime schema export (src/otuformer/cli_schema.py) with omission-preserving argv generation and pre-execution output-safety checks (source/examples/asset protection, symlink-aware resolution, explicit overwrite consent).
  • Shared, import-light CLI restrictions (src/otuformer/cli/constraints.py) reused by the CLI, core, and schema path without changing option declarations, defaults, or error boundaries.
  • Full 230-image teaching recipes backed by the real example assets and extraction ID resolution.

Changed

  • Both READMEs document Skill installation, agent registration, trust/collision behavior, and conversational Q&A (English and Chinese).

License

  • From v0.11.0 this project is distributed under the OTU-Former Research and Commercial Use License Notice: academic, educational, and non-commercial research use is permitted with the notice retained; commercial use requires prior written permission from the copyright holder. This is source-available software, not OSI-approved open source.
  • Versions published before v0.11.0 remain available under the MIT License.

v0.10.1

Choose a tag to compare

@xtmtd xtmtd released this 30 Sep 08:39

Documentation-only patch (no functional change).

  • Split the per-command reference out of both READMEs into docs/commands/<command>.md with .cn.md twins (8 command documents plus the shared training-augmentation and embedding-metrics documents).
  • READMEs are now a front page plus the inline doctor / update operational surface, and link their own language's command documents.
  • CLI --help now points at the published GitHub documentation URLs.
  • Documentation conventions (layer model, bilingual .cn.md pairing, command document skeleton, --help boundary, test corpus contract) are established as standing rules, with corpus-driven structure, pairing, option-coverage, and link tests.

v0.10.0

Choose a tag to compare

@xtmtd xtmtd released this 28 Sep 15:19

Optional register tokens for eligible single-CLS ViTs, with register-aware checkpoint layouts and patch consumers.

Added

  • --register-tokens none|0|4 (default none) on pretrain: 4 adds four trainable registers and migrates the one-CLS pretrained backbone (the register token keeps its native initialization while every CLS/patch/block weight and position is preserved); none keeps the backbone's own architecture, i.e. no registers on a plain ViT or a native-register model's own count.
  • A shared read-only checkpoint loader with a register-layout decision table, rejection of non-canonical reg_token keys, and RNG-isolated pretrained=False probes; extract, cam and export all load through it.
  • Registered pretraining resume and registered fine-tune sources, including student/teacher synchronization of the newly initialized registers and explicit layout validation before any optimizer state is restored.
  • An attention-pool patch policy (num_prefix_tokens, register_tokens, prefix_excluded, attention_pooling_type) recorded in new pool checkpoints and saved to a policy-tagged sibling whose contents are validated even when the filename matches.
  • CPU FP32 PyTorch versus CPU ONNX Runtime numeric validation of exports (atol=1e-4, rtol=1e-3), recorded as validation_status, max_abs_diff, atol and rtol.
  • A design document and implementation plan under docs/superpowers/.

Changed

  • Every patch consumer (patch-topk, attention-query training, attention-pool extraction and the ViT CAM reshape) now drops all prefix tokens via backbone.num_prefix_tokens, so a CLS-free backbone keeps its first patch.
  • New checkpoints record config.register_tokens (the actual count) and args.register_tokens (the invocation value); fine-tuning re-saves the inherited layout and includes it in the v0.9.0 pseudo-label experiment identity.
  • vit_reshape_transform gained an optional prefix_tokens argument; the default is unchanged for direct callers.
  • README and README.cn.md document the option, the patch policy and the export validation.

Fixed

  • A failed or numerically mismatched export no longer publishes a model and can no longer leave a stale validated: true report behind; only this attempt's temporary files are cleaned up.
  • An incompatible attention-pool checkpoint at the policy-tagged path now fails naming its path instead of being masked by another fallback artifact.
  • config.register_tokens is validated as a non-negative integer at every checkpoint entry point, so a malformed value is rejected rather than treated as a legacy zero.

Upgrade notes

  • none is the default and preserves the previous construction, so existing zero-register workflows are unchanged; the 272 existing checkpoints were verified end to end (extract, CAM, ONNX export) with the corrected patch boundaries.
  • ONNX export now fails, instead of publishing a shape-only validated model, when ONNX Runtime is installed but the graph fails to run or disagrees numerically beyond the approved tolerances.
  • Patch-consumer outputs change for CLS-free/no-register checkpoints (the first patch is now included) and for CLS-bearing native-register checkpoints (registers are no longer treated as patches): regenerate affected patch-topk embeddings and attention pools.
  • Fine-tuning has no new switch; it inherits the source architecture and its register layout.

v0.9.0

Choose a tag to compare

@xtmtd xtmtd released this 27 Sep 14:47

Opt-in sparse-label fine-tuning: one CB-DRW long-tail strategy and one automatic known-class pseudo-label round.

Added

  • --long-tail none|cb-drw (Class-Balanced Deferred Reweighting) for the class-level cross-entropy term of the ArcFace-family losses.
  • --pseudo-label-from FINETUNE1.pth plus five feature-rule options: --pseudo-similarity-floor (0.75), --pseudo-min-gap (0.10), --pseudo-neighbors (15), --pseudo-cap-multiplier (3), --pseudo-absolute-cap (50).
  • Automatic candidate discovery under the image root minus expert references, with recursive traversal, path-identity subtraction, duplicate-alias rejection, and output-subtree skipping.
  • Raw-CLS scoring, an asymmetric own-class-excluded mutual-kNN filter, per-class acceptance caps, and pseudo_labels.csv / pseudo_summary.json diagnostics.
  • Finetune#2 preflight provenance: expert manifest, SSL file SHA-256, pseudo-source SHA-256, experiment identity, class order, and preprocessing are hard gates; root moves, non-accepted candidate changes, and a missing or edited pseudo_labels.csv warn only.
  • Additive finetune#2 checkpoint metadata: pseudo round, accepted rows and hashes, rule constants, candidate-pool and diagnostics hashes, and a training summary.
  • A design document and implementation plan under docs/superpowers/.

Changed

  • New fine-tune checkpoints record the resolved image root and a top-level class_order alongside the historical sorted-string class_labels.
  • README and README.cn.md document the two-command sparse-label workflow.

Fixed

  • Invalid source checkpoints, unreadable candidate images, and extraction failures raise one PseudoLabelError.
  • Empty-acceptance diagnostics now report candidate count, acceptance rate, per-seed-count-bin acceptance, and the design-specified counterfactual pass counts.
  • Deterministic similarity tie-breaking uses canonical references across candidates and expert seeds, including seed index 0.

Ordinary fine-tuning behavior and all defaults remain unchanged.

v0.8.0

Choose a tag to compare

@xtmtd xtmtd released this 26 Sep 05:29

Supervised metric-loss extension for otuformer finetune.

Added

  • Four explicit --loss modes: arcface (default), supcon, subcenter-arcface, subcenter-arcface-compact.
  • Loss-aware CLI preflight: unknown or inapplicable flags fail before any output directory or log file is created.
  • New options: --subcenters (K, 2-8, both Sub-center modes), --compact-weight (cap fixed at 0.5), --supcon-temperature, --trace-batch-ids.
  • Per-epoch logs/loss_diagnostics.finetune.csv and optional logs/batch_ids.finetune.jsonl.
  • Checkpoint provenance: seed, source/SSL checkpoint SHA-256, canonical training-manifest SHA-256, optimizer layout, and prototype weight-decay rule.

Changed

  • New v0.8.0 ArcFace runs give L2-normalized prototypes zero weight decay. At the default learning rate and weight decay the results are numerically identical to v0.7.x, because the old decay only rescaled the prototype norm.
  • Every run log starts with the package version and a best-effort commit of the checkout.
  • One shared CLI command formatter renders boolean flags without a value.

Fixed

  • Legacy --resume keeps its saved optimizer semantics and rejects conflicting loss/K/weight/temperature settings before creating output.
  • SupCon skips unusable batches and fails an epoch with no usable signal instead of saving a checkpoint trained on an empty signal.

v0.7.1

Choose a tag to compare

@xtmtd xtmtd released this 22 Sep 02:45

Breaking changes

Embedding metrics are not numerically comparable with pre-v0.7.1 values. Four evaluator changes cause this:

  • Cross-validated kNN and linear-probe scores now share one explicit shuffled StratifiedKFold(shuffle=True, random_state=42) whose fold count is min(5, smallest class count). A two-class dataset previously used only 2 folds; it now uses 5, so each fold trains on more data and the reported kNN/linear-probe values are systematically higher for the same model.
  • Trainer and extract now apply the same sorted subsample order, so fold assignment, KMeans initialization, and tie-breaking agree between the two paths.
  • mAP no longer counts the query itself as a relevant result.
  • Metrics that cannot be computed are written as empty CSV fields instead of a fabricated 0.0 or a single-cluster KMeans fallback, and cross-validated metrics can no longer be written as NaN.

Existing field names are unchanged, and kNN_Acc_k1, kNN_Acc_k5, and kNN_Acc_k20 are retained. A requested k the data cannot support (for example kNN_Acc_k20 when the smallest training fold has fewer than 20 samples, or Recall@k with k > n_samples - 1) is now empty rather than silently renamed.

Highlights

  • New Linear_Probing_Balanced_Acc field: class-balanced linear-probe accuracy taken from the same cross-validation pass as Linear_Probing_Acc, so it costs no extra fits. It appears in metrics.pretrain.csv, metrics.finetune.csv, extract's metrics.csv, and the Retrieval/Probe training plot.
  • Correct retrieval and clustering edge cases: mAP ranks only non-query samples and drops queries with no non-self relevant item; clustering metrics are unavailable when there are fewer distinct normalized embeddings than clusters instead of fabricating a single cluster; Silhouette_Score is unavailable when silhouette is undefined.
  • CLI no longer couples to external Click. Parameter-source checks compare by enum name, and cam/extract validate their enumerated options with native typer.BadParameter before any output directory is created, so commands keep working when typer>=0.26 vendors Click. --arch, --fig-format, and --device now list their accepted values in --help.
  • extract rejects duplicate image rows in --label-csv before metric computation, instead of silently desynchronizing labels from embeddings.
  • Metric contract documented in docs/superpowers/specs/2026-09-21-otuformer-v071-cli-metrics-corrections.md, with evaluator-vintage notes added to the historical comparison reports.

Compatibility

  • Resuming a v0.7.0 logs/metrics.pretrain.csv or logs/metrics.finetune.csv migrates the recognized header atomically: an empty Linear_Probing_Balanced_Acc column is added and every existing row is preserved. A header that already matches the current schema is appended without rewriting; duplicate-column, malformed, and unrecognized headers fail before any append.
  • Old rows leave the new field empty, and plots treat empty fields as gaps rather than zeros.
  • extract writes metrics.csv only when --label-csv provides at least two classes; unlabelled extraction, and labelled extraction with a single class, still write embeddings.csv (and UMAP when eligible).
  • No new dependency, and no change to training, checkpoint contents, or the embedding extraction path.

Notes

  • Values recorded before v0.7.1 (for example the epoch-50 tables in docs/superpowers/specs/2026-03-30-*) keep their recorded numbers but are not comparable with v0.7.1 outputs.
  • Training itself is unchanged: a controlled old-code vs new-code run with the same seed produced bit-identical weights, optimizer state, and RNG state. On the same checkpoint, only the four evaluator changes above move the numbers.
  • Comparing two separate training invocations is not apples-to-apples on this pipeline: with --num-workers > 0 the augmentation RNG is per worker and batch-to-worker assignment is dynamic, so runs with identical arguments can diverge. Use --num-workers 0 when run-to-run reproducibility matters.

v0.7.0

Choose a tag to compare

@xtmtd xtmtd released this 20 Sep 14:35

Breaking changes

--mask-ratio now defaults to auto, which resolves to 0.30 for a new run; v0.6.x used a float default of 0.50. Explicitly passing an option that the selected patch mode does not use is now rejected instead of silently ignored.

Migration:

  • A new run that relied on the old 0.50 default gets 0.30. Pass --mask-ratio 0.5 explicitly to keep the previous behavior.
  • Resuming a legacy checkpoint keeps its recorded ratio (0.50 when absent) and stays on consistency. Legacy checkpoints cannot resume as masked-feature or ibot.
  • --patch-loss consistency with --masking-strategy or --ibot-prototypes now fails instead of ignoring the option.

Highlights

  • Four patch-loss modes, mutually exclusive: none, consistency (default), masked-feature, and ibot (experimental).
    • consistency selects fully visible same-position patches for normalized cosine regression. It is masked-position patch consistency, not masked image modeling: the student still sees every pixel.
    • masked-feature (continuous masked feature prediction) replaces the selected student patch embeddings with a learnable mask token before positional encoding, so the student never sees the selected content while the position is preserved, and regresses them onto the L2-normalized mean of the teacher's final four block outputs.
    • ibot predicts the teacher's centered prototype distribution at masked positions with moving-average centering.
  • Three real-masking strategies via --masking-strategy random|blockwise|hybrid, with exact mask counts, per-grid rectangle feasibility checks, and fail-fast on infeasible grids such as 4 x 4.
  • --ibot-prototypes accepts any integer >= 2 (default 512) instead of a fixed 256/512/1024 list, so larger datasets can use larger dictionaries.
  • --lambda-mask documents that ibot usually needs a lower weight (for example 0.25-0.5).

Compatibility

  • Extraction, fine-tuning, CAM, and export are unchanged: the default path is still the raw CLS token, and they never load or invoke the training-only patch state.
  • Pretraining and pretraining resume support standard timm ViT backbones only. EVA, Swin, and CNN backbones fail with an actionable error before the training loop.
  • v0.7.0 resume is strict: patch mode, resolved ratio, masking strategy, prototype count, and the fixed target/center settings must match the checkpoint, and masked-feature/ibot checkpoints must carry their patch_objective state. Python, NumPy, PyTorch CPU, and CUDA RNG state round-trip.
  • Existing instant-metrics CSVs with the recognized legacy pretrain header are migrated atomically to the new schema; unknown, duplicate-column, or malformed schemas fail without touching the file.

Notes

  • masked-feature and ibot add one masked student forward per global view. On a CPU benchmark with vit_tiny_patch16_224, 2x224 global + 6x96 local crops, batch 16, they cost roughly 1.25x-1.42x the consistency step time, consistent with the design's ~1.39x forward-work proxy. This is a reported cost comparison, not a performance gate.
  • These objectives are self-supervised contextual feature prediction. They do not by themselves establish anatomical part semantics or dense morphology supervision, and v0.7.0 makes no dense-representation claim.
  • Loss values are not comparable across patch modes. The iBOT cross-entropy is not divided by log(K).

v0.6.0

Choose a tag to compare

@xtmtd xtmtd released this 15 Sep 15:41

Breaking changes

--save-npy now takes an explicit value from none, raw, or normalized (default none). The bare flag is rejected.

  • --save-npy raw writes the positive unnormalized CAM (after ReLU, resized to model resolution, before per-image min-max normalization).
  • --save-npy normalized writes the per-image min-max [0, 1] copy — the same semantics the flag had before.
  • --save-npy none (default) writes no array and creates no arrays/ directory.

Migration: scripts using the bare flag fail immediately with Option '--save-npy' requires an argument. Use --save-npy raw for arrays (magnitudes changed) or --save-npy normalized to keep the previous values.

Notes

  • Raw magnitudes are comparable only within the same model, target layer, and preprocessing configuration. eigencam raw values come from an SVD projection with arbitrary sign — exported for completeness, not suitable for response-strength statistics.

v0.5.0

Choose a tag to compare

@xtmtd xtmtd released this 10 Sep 10:17

What's new since v0.4.0

  • ArcFace fine-tuning: new runs use a compact unnormalized embedding head (backbone_dim -> 512 -> metric_embed_dim) matching the reference script. --metric-embed-dim now actually resizes the head.
  • New options: --metric-head-lr, --weight-decay (default 1e-4; pass 0.05 for the legacy script). SFT gradient clipping removed.
  • Resume safety: checkpoints record embedding_head and freeze_ratio; --resume validates them and rejects a changed embedding dimension.
  • Checkpoint compatibility: extract/export/cam share one resolver, can read ref-script checkpoints, and gained --model-name where needed. A wrong backbone now fails with a clear message.
  • Breaking: --weight-decay default changed from 0.01 to 1e-4; 0.4.0 fine-tune checkpoints load as projection_mlp_2048; finetune cannot resume ref-script checkpoints.

441 tests pass.