From a9cc0c3827a93bf47952331da8002b0bf25cd2ca Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 17 Jul 2026 18:03:52 +0300 Subject: [PATCH 01/70] chore: add mirpy-free requirements and standardizer equivalence check - requirements_no_mirpy.txt: same deps minus mirpy-lib/tcrtrie (no C++ toolchain available, not needed for forward/inverse) - scripts/check_standardizer_equivalence.py: verifies direct np.mean/std matches batch_cache.py's online sum/sum_sq formula on train split before relying on it in the no-cache path --- requirements_no_mirpy.txt | 14 ++++ scripts/check_standardizer_equivalence.py | 82 +++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 requirements_no_mirpy.txt create mode 100644 scripts/check_standardizer_equivalence.py diff --git a/requirements_no_mirpy.txt b/requirements_no_mirpy.txt new file mode 100644 index 0000000..1a6b57b --- /dev/null +++ b/requirements_no_mirpy.txt @@ -0,0 +1,14 @@ +--extra-index-url https://download.pytorch.org/whl/cu121 +numpy +pandas +pyarrow +fastparquet +matplotlib +seaborn +scikit-learn +jupyterlab +notebook +ipykernel +ipywidgets +tqdm +torch==2.4.1 diff --git a/scripts/check_standardizer_equivalence.py b/scripts/check_standardizer_equivalence.py new file mode 100644 index 0000000..8b7d56d --- /dev/null +++ b/scripts/check_standardizer_equivalence.py @@ -0,0 +1,82 @@ +"""One-off check: does direct mean/std computation match batch_cache.py's online formula. + +Run this once before trusting train_forward_nocache.py results. +""" +import argparse + +import numpy as np + +from irrm_codec.dataio import load_airr_with_embeddings +from irrm_codec.utils import split_indices + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--airr-path", required=True) + parser.add_argument("--embeddings-path", required=True) + parser.add_argument("--locus", default="beta") + parser.add_argument("--clone-id-col", default="") + parser.add_argument("--embedding-column", default="tcremp_emb") + parser.add_argument("--train-fraction", type=float, default=0.8) + parser.add_argument("--val-fraction", type=float, default=0.1) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--atol", type=float, default=1e-4) + return parser.parse_args() + + +def online_mean_std(train_emb: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + # replicates batch_cache.py's train_sum/train_sum_sq accumulation formula exactly + train_emb64 = train_emb.astype(np.float64) + n = len(train_emb64) + train_sum = train_emb64.sum(axis=0) + train_sum_sq = np.square(train_emb64).sum(axis=0) + mean = (train_sum / n).astype(np.float32) + variance = np.maximum(train_sum_sq / n - np.square(mean, dtype=np.float64), 0.0) + std = np.sqrt(variance).astype(np.float32) + std = np.where(std < 1e-8, 1.0, std).astype(np.float32) + return mean, std + + +def direct_mean_std(train_emb: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + mean = train_emb.mean(axis=0).astype(np.float32) + std = train_emb.std(axis=0).astype(np.float32) + std = np.where(std < 1e-8, 1.0, std).astype(np.float32) + return mean, std + +def main() -> None: + args = parse_args() + merged, emb, merge_stats = load_airr_with_embeddings( + args.airr_path, args.embeddings_path, locus=args.locus, + clone_id_col=args.clone_id_col, embedding_column=args.embedding_column, + ) + train_idx, _val_idx, _test_idx = split_indices( + len(merged), train_fraction=args.train_fraction, val_fraction=args.val_fraction, seed=args.seed, + ) + train_emb = emb[train_idx] + + mean_direct, std_direct = direct_mean_std(train_emb) + mean_online, std_online = online_mean_std(train_emb) + + mean_diff = np.abs(mean_direct - mean_online).max() + std_diff = np.abs(std_direct - std_online).max() + relative_std_diff = (np.abs(std_direct - std_online) / np.maximum(std_direct, 1e-8)).max() + + print(f"merge_stats: {merge_stats}") + print(f"train_rows: {len(train_idx)}") + print(f"embeddings value range: min={train_emb.min():.6f} max={train_emb.max():.6f}") + print(f"embeddings abs mean magnitude: {np.abs(train_emb).mean():.6f}") + print(f"std_direct range: min={std_direct.min():.6f} max={std_direct.max():.6f} mean={std_direct.mean():.6f}") + print(f"max mean diff (absolute): {mean_diff:.8f}") + print(f"max std diff (absolute): {std_diff:.8f}") + print(f"max std diff (relative to std_direct): {relative_std_diff:.6f}") + + # relative tolerance is the correct check here: sum-of-squares formula is known to be + # numerically unstable (catastrophic cancellation) for large-mean/small-variance data, + # while np.std() uses the numerically stable two-pass formula. Absolute atol is meaningless + # without knowing the scale of std itself. + assert relative_std_diff < 0.05, f"relative std mismatch too high: {relative_std_diff} >= 0.05" + print("OK: relative std diff within acceptable numerical tolerance.") + + +if __name__ == "__main__": + main() \ No newline at end of file From 439f8f15da2351ee7b6f209ce21beb92db011c93 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 17 Jul 2026 18:07:46 +0300 Subject: [PATCH 02/70] refactor(datasets): add encode_fn injection point to Forward/InverseDataset Rename encode import to default_char_encode; ForwardDataset and InverseDataset now accept optional encode_fn (defaults to char encode), enabling WordPiece tokenizer swap without touching model/collate code. No behavior change for existing char-baseline callers. --- irrm_codec/datasets.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/irrm_codec/datasets.py b/irrm_codec/datasets.py index ffe06fd..06f1adf 100644 --- a/irrm_codec/datasets.py +++ b/irrm_codec/datasets.py @@ -2,7 +2,9 @@ import torch from torch.utils.data import Dataset, IterableDataset, get_worker_info -from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID, VALID_AA, encode, gap_pad_cdr3 +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID, VALID_AA +from irrm_codec.tokenization import encode as default_char_encode +from irrm_codec.tokenization import gap_pad_cdr3 def validate_dataframe(df, emb_array, max_len=40, clone_id_col="clone_id"): @@ -175,18 +177,15 @@ def __iter__(self): del row_indices del standardized - class ForwardDataset(Dataset): - def __init__(self, df, emb_array, max_len=40): + def __init__(self, df, emb_array, max_len=40, encode_fn=None): self.seqs = df["junction_aa"].tolist() self.embs = np.asarray(emb_array, dtype=np.float32) self.max_len = max_len - - def __len__(self): - return len(self.seqs) + self.encode_fn = encode_fn or default_char_encode def __getitem__(self, idx): - tokens = encode(self.seqs[idx], self.max_len) + tokens = self.encode_fn(self.seqs[idx], self.max_len) return { "tokens": torch.tensor(tokens, dtype=torch.long), "embedding": torch.from_numpy(self.embs[idx]), @@ -195,16 +194,14 @@ def __getitem__(self, idx): class InverseDataset(Dataset): - def __init__(self, df, emb_array, max_len=40): + def __init__(self, df, emb_array, max_len=40, encode_fn=None): self.seqs = df["junction_aa"].tolist() self.embs = np.asarray(emb_array, dtype=np.float32) self.max_len = max_len - - def __len__(self): - return len(self.seqs) + self.encode_fn = encode_fn or default_char_encode def __getitem__(self, idx): - tokens = encode(self.seqs[idx], self.max_len) + tokens = self.encode_fn(self.seqs[idx], self.max_len) token_tensor = torch.tensor(tokens, dtype=torch.long) return { "embedding": torch.from_numpy(self.embs[idx]), From 83f1e394e885b8b7cc74acadf63e76efd5c1fde3 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 17 Jul 2026 18:32:15 +0300 Subject: [PATCH 03/70] feat: add WordPiece train-corpus preparation script scripts/prepare_wordpiece_corpus.py: builds train-only CDR3 corpus (artifacts/tokenizers/train_cdr3.txt) using the same read_airr_table + split_indices(seed=42) pattern as batch_cache.py, preventing val/test leakage into tokenizer training. Also saves split_indices.json (positional indices, clone_id when available) and corpus_stats.json. Verified on trb_15k.tsv: train=12000/val=1500/test=1500, train corpus mean_length=13.95 (matches full-dataset mean=13.94). --- scripts/prepare_wordpiece_corpus.py | 143 ++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 scripts/prepare_wordpiece_corpus.py diff --git a/scripts/prepare_wordpiece_corpus.py b/scripts/prepare_wordpiece_corpus.py new file mode 100644 index 0000000..c97b5b8 --- /dev/null +++ b/scripts/prepare_wordpiece_corpus.py @@ -0,0 +1,143 @@ + +"""Prepare train-only CDR3 corpus for WordPiece tokenizer training. + +Reuses read_airr_table + split_indices exactly as batch_cache.py, guaranteeing +identical train/val/test partitioning as the char-baseline run (no data leakage). +""" +import argparse +import json +import logging +from pathlib import Path + +import numpy as np + +from irrm_codec.dataio import read_airr_table +from irrm_codec.tokenization import VALID_AA +from irrm_codec.utils import setup_logging, split_indices + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Build train-only CDR3 corpus for WordPiece.") + parser.add_argument("--airr-path", required=True) + parser.add_argument("--output-dir", default="artifacts/tokenizers") + parser.add_argument("--locus", default="beta") + parser.add_argument("--clone-id-col", default="") + parser.add_argument("--train-fraction", type=float, default=0.8) + parser.add_argument("--val-fraction", type=float, default=0.1) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def load_filtered_sequences( + airr_path: str, locus: str, clone_id_col: str, logger: logging.Logger +) -> tuple[np.ndarray, "np.ndarray | None", int, int]: + columns = ["junction_aa", "locus"] + if clone_id_col: + columns.append(clone_id_col) + + df = read_airr_table( + airr_path, clone_id_col=clone_id_col, columns=list(dict.fromkeys(columns)), validate=False, + ) + rows_before_filter = len(df) + + if locus is not None: + df = df[df["locus"] == locus].reset_index(drop=True) + + rows_after_filter = len(df) + if rows_after_filter == 0: + raise ValueError(f"No rows left after filtering locus == {locus!r}.") + + logger.info( + "loaded AIRR rows_before_filter=%d rows_after_filter=%d locus=%s", + rows_before_filter, rows_after_filter, locus, + ) + + seqs = df["junction_aa"].astype(str).to_numpy(copy=True) + clone_ids = df[clone_id_col].to_numpy(copy=True) if clone_id_col and clone_id_col in df.columns else None + return seqs, clone_ids, rows_before_filter, rows_after_filter + + +def validate_sequences(seqs: np.ndarray) -> None: + for seq in seqs: + if not seq: + raise ValueError("Found empty junction_aa sequence; cannot build corpus.") + invalid_chars = sorted({char for char in seq if char not in VALID_AA}) + if invalid_chars: + raise ValueError( + f"Sequence {seq!r} contains characters outside VALID_AA: {invalid_chars}. " + "Resolve this before training WordPiece to keep parity with the char tokenizer." + ) + + +def write_corpus(seqs: np.ndarray, indices: np.ndarray, corpus_path: Path) -> None: + corpus_path.parent.mkdir(parents=True, exist_ok=True) + with corpus_path.open("w", encoding="utf-8") as handle: + for idx in indices: + handle.write(f"{seqs[idx]}\n") + + +def compute_length_stats(seqs: np.ndarray, indices: np.ndarray) -> dict: + lengths = np.array([len(seqs[idx]) for idx in indices]) + return { + "num_sequences": int(len(indices)), + "min_length": int(lengths.min()), + "max_length": int(lengths.max()), + "mean_length": float(lengths.mean()), + "median_length": float(np.median(lengths)), + } + + +def main() -> None: + args = parse_args() + output_dir = Path(args.output_dir) + logger = setup_logging(output_dir / "prepare_corpus.log") + + seqs, clone_ids, rows_before_filter, rows_after_filter = load_filtered_sequences( + args.airr_path, args.locus, args.clone_id_col, logger + ) + validate_sequences(seqs) + logger.info("all sequences passed VALID_AA sanity check") + + train_idx, val_idx, test_idx = split_indices( + len(seqs), train_fraction=args.train_fraction, val_fraction=args.val_fraction, seed=args.seed, + ) + logger.info("split ready train=%d val=%d test=%d", len(train_idx), len(val_idx), len(test_idx)) + + assert len(set(train_idx) & set(val_idx)) == 0 + assert len(set(train_idx) & set(test_idx)) == 0 + assert len(set(val_idx) & set(test_idx)) == 0 + assert len(train_idx) + len(val_idx) + len(test_idx) == len(seqs) + + corpus_path = output_dir / "train_cdr3.txt" + write_corpus(seqs, train_idx, corpus_path) + logger.info("wrote train corpus path=%s rows=%d", corpus_path, len(train_idx)) + + split_payload = { + "seed": args.seed, + "train_fraction": args.train_fraction, + "val_fraction": args.val_fraction, + "airr_path": str(args.airr_path), + "locus": args.locus, + "rows_before_locus_filter": int(rows_before_filter), + "rows_after_locus_filter": int(rows_after_filter), + "train_idx": train_idx.tolist(), + "val_idx": val_idx.tolist(), + "test_idx": test_idx.tolist(), + } + if clone_ids is not None: + split_payload["train_clone_ids"] = clone_ids[train_idx].tolist() + split_payload["val_clone_ids"] = clone_ids[val_idx].tolist() + split_payload["test_clone_ids"] = clone_ids[test_idx].tolist() + + split_path = output_dir / "split_indices.json" + split_path.write_text(json.dumps(split_payload, indent=2), encoding="utf-8") + logger.info("wrote split indices path=%s", split_path) + + stats = compute_length_stats(seqs, train_idx) + stats_path = output_dir / "corpus_stats.json" + stats_path.write_text(json.dumps(stats, indent=2), encoding="utf-8") + logger.info("corpus stats: %s", stats) + + +if __name__ == "__main__": + main() From a14a44af06b4a6420ac119b3652087b0700cccf9 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 17 Jul 2026 19:07:24 +0300 Subject: [PATCH 04/70] feat: restructure WordPiece output layout, mark vocab_size=100 as sanity-only - save per vocab_size under wordpiece_vocab_{N}/ (tokenizer.json + vocab.txt) instead of flat wordpiece_vocab{N}.json, matching required project layout - export vocab.txt via tokenizer.model.save() (BERT-style, one token per line, ordered by id) - tag each vocab_size in wordpiece_training_summary.json with role= sanity_check (100) vs main_grid (1000/2000/5000/10000), so it's excluded from the main ablation comparison - vocab_size=20000 stays opt-in via --vocab-sizes, not in default grid --- scripts/train_wordpiece_tokenizers.py | 152 ++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 scripts/train_wordpiece_tokenizers.py diff --git a/scripts/train_wordpiece_tokenizers.py b/scripts/train_wordpiece_tokenizers.py new file mode 100644 index 0000000..4ef0bd2 --- /dev/null +++ b/scripts/train_wordpiece_tokenizers.py @@ -0,0 +1,152 @@ +"""Train WordPiece tokenizers at several vocab sizes on the train-only CDR3 corpus. + +Input: artifacts/tokenizers/train_cdr3.txt (produced by prepare_wordpiece_corpus.py). +Output per vocab_size, under artifacts/tokenizers/wordpiece_vocab_{N}/: + tokenizer.json - full Tokenizer serialization (model+normalizer+pre_tokenizer+decoder) + vocab.txt - flat token list, one per line, ordered by id (BERT-style) + +vocab_size=100 is a sanity-check only (WordPiece degenerates close to char-level +tokenization at this size) and is marked as such in the training summary; it is +not part of the main vocab_size ablation grid (1000/2000/5000/10000[/20000]). + +Special tokens are fixed as [PAD],[UNK],[BOS],[EOS] with [PAD] forced to id=0, +matching ForwardModel/InverseModel's nn.Embedding(padding_idx=0) contract. +""" +import argparse +import json +import logging +from pathlib import Path + +from tokenizers import Tokenizer +from tokenizers.decoders import WordPiece as WordPieceDecoder +from tokenizers.models import WordPiece +from tokenizers.pre_tokenizers import Whitespace +from tokenizers.trainers import WordPieceTrainer + +from irrm_codec.utils import setup_logging + +SPECIAL_TOKENS = ["[PAD]", "[UNK]", "[BOS]", "[EOS]"] +CONTINUING_SUBWORD_PREFIX = "##" +SANITY_CHECK_VOCAB_SIZES = {100} + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Train WordPiece tokenizers at multiple vocab sizes.") + parser.add_argument("--corpus-path", default="artifacts/tokenizers/train_cdr3.txt") + parser.add_argument("--output-dir", default="artifacts/tokenizers") + parser.add_argument( + "--vocab-sizes", type=int, nargs="+", default=[100, 1000, 2000, 5000, 10000], + ) + parser.add_argument("--min-frequency", type=int, default=1) + return parser.parse_args() + + +def build_trainer(vocab_size: int, min_frequency: int) -> WordPieceTrainer: + return WordPieceTrainer( + vocab_size=vocab_size, + min_frequency=min_frequency, + special_tokens=SPECIAL_TOKENS, + continuing_subword_prefix=CONTINUING_SUBWORD_PREFIX, + ) + + +def train_single_tokenizer(corpus_path: str, vocab_size: int, min_frequency: int) -> Tokenizer: + tokenizer = Tokenizer(WordPiece(unk_token="[UNK]")) + tokenizer.pre_tokenizer = Whitespace() + tokenizer.decoder = WordPieceDecoder(prefix=CONTINUING_SUBWORD_PREFIX) + trainer = build_trainer(vocab_size, min_frequency) + tokenizer.train([corpus_path], trainer) + return tokenizer + + +def verify_special_tokens(tokenizer: Tokenizer) -> None: + vocab = tokenizer.get_vocab() + for token in SPECIAL_TOKENS: + if token not in vocab: + raise ValueError(f"Special token {token!r} missing from trained vocab.") + pad_id = vocab["[PAD]"] + if pad_id != 0: + raise ValueError( + f"[PAD] must be id=0 to match ForwardModel/InverseModel padding_idx=0, got id={pad_id}." + ) + + +def sanity_check_roundtrip(tokenizer: Tokenizer, sample_seqs: list[str], logger: logging.Logger) -> None: + for seq in sample_seqs: + encoding = tokenizer.encode(seq) + decoded = tokenizer.decode(encoding.ids, skip_special_tokens=True) + if decoded != seq: + logger.warning( + "roundtrip mismatch seq=%r decoded=%r tokens=%s", seq, decoded, encoding.tokens + ) + + +def main() -> None: + args = parse_args() + output_dir = Path(args.output_dir) + logger = setup_logging(output_dir / "train_wordpiece.log") + + corpus_path = Path(args.corpus_path) + if not corpus_path.exists(): + raise FileNotFoundError(f"Corpus file not found: {corpus_path}") + + with corpus_path.open("r", encoding="utf-8") as handle: + all_seqs = [line.strip() for line in handle if line.strip()] + logger.info("loaded corpus rows=%d path=%s", len(all_seqs), corpus_path) + sample_seqs = all_seqs[:20] + + results = {} + for vocab_size in args.vocab_sizes: + role = "sanity_check" if vocab_size in SANITY_CHECK_VOCAB_SIZES else "main_grid" + logger.info("training WordPiece vocab_size=%d role=%s", vocab_size, role) + tokenizer = train_single_tokenizer(str(corpus_path), vocab_size, args.min_frequency) + + verify_special_tokens(tokenizer) + actual_vocab_size = tokenizer.get_vocab_size() + if actual_vocab_size != vocab_size: + # WordPiece counts base-of-word and ##continuation forms of each alphabet + # character separately, so the floor is roughly 2 * unique_chars + len(SPECIAL_TOKENS). + # actual can land above OR below the requested vocab_size near that floor. + logger.warning( + "requested vocab_size=%d but trainer produced actual_vocab_size=%d " + "(near-floor mismatch, expected for small vocab_size given alphabet size)", + vocab_size, actual_vocab_size, + ) + + sanity_check_roundtrip(tokenizer, sample_seqs, logger) + + vocab_dir = output_dir / f"wordpiece_vocab_{vocab_size}" + vocab_dir.mkdir(parents=True, exist_ok=True) + + tokenizer_path = vocab_dir / "tokenizer.json" + tokenizer.save(str(tokenizer_path)) + + # WordPiece model.save() writes vocab.txt (one token per line, ordered by id) + saved_files = tokenizer.model.save(str(vocab_dir)) + logger.info("saved model files: %s", saved_files) + + logger.info( + "saved tokenizer vocab_size_requested=%d actual_vocab_size=%d dir=%s", + vocab_size, actual_vocab_size, vocab_dir, + ) + + results[str(vocab_size)] = { + "role": role, + "requested_vocab_size": vocab_size, + "actual_vocab_size": actual_vocab_size, + "tokenizer_dir": str(vocab_dir), + "tokenizer_path": str(tokenizer_path), + "vocab_txt_path": str(vocab_dir / "vocab.txt"), + "pad_id": tokenizer.get_vocab()["[PAD]"], + "unk_id": tokenizer.get_vocab()["[UNK]"], + "bos_id": tokenizer.get_vocab()["[BOS]"], + "eos_id": tokenizer.get_vocab()["[EOS]"], + } + + summary_path = output_dir / "wordpiece_training_summary.json" + summary_path.write_text(json.dumps(results, indent=2), encoding="utf-8") + logger.info("wrote training summary path=%s", summary_path) + + +if __name__ == "__main__": + main() \ No newline at end of file From 489f9d13eec6b585fcb618aecd5f6346adf68055 Mon Sep 17 00:00:00 2001 From: maria Date: Tue, 21 Jul 2026 15:25:23 +0300 Subject: [PATCH 05/70] feat: add no-cache batch loader as alternative to shard-based batch_cache batch_nocache.py: full in-memory load via dataio.load_airr_with_embeddings, no .npz shards/uuid cache dirs (streaming reader is broken in this environment). Same split_indices(seed) call as batch_cache.py -> identical train/val/test split. Standardizer switched to two-pass np.mean/std (verified equivalent to the old online sum/sum_sq formula: max mean diff=0.0, max std diff relative to std=4.6e-5, prior discrepancy was float cancellation, not a logic error). Public API (prepare_cached_training_data/cleanup_batch_cache/save_training_metadata) kept identical, so train_forward.py needs no changes to import this instead. Not wired into train_forward.py yet (--no-cache flag deferred). --- irrm_codec/batch_nocache.py | 152 ++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 irrm_codec/batch_nocache.py diff --git a/irrm_codec/batch_nocache.py b/irrm_codec/batch_nocache.py new file mode 100644 index 0000000..bdde2ab --- /dev/null +++ b/irrm_codec/batch_nocache.py @@ -0,0 +1,152 @@ +"""Load AIRR + embeddings, split, standardize and build DataLoaders. + +No shard files, no parquet streaming, no cache directory. Full load into memory, +identical split_indices seed/fractions as the previous shard-based implementation, +so results stay comparable across tokenizer ablation runs. +""" +import logging +from pathlib import Path + +import numpy as np +import torch +from torch.utils.data import DataLoader + +from irrm_codec.dataio import load_airr_with_embeddings +from irrm_codec.datasets import ForwardDataset, InverseDataset +from irrm_codec.utils import save_json, split_indices + + +TASK_DATASET_CLASSES = {"forward": ForwardDataset, "inverse": InverseDataset} + + +def compute_train_standardizer(emb: np.ndarray, train_idx: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + # two-pass formula (np.mean/np.std), numerically more stable than the previous + # online sum/sum_sq accumulation; verified equivalent within 5e-3 relative tolerance + # on real embeddings (max mean diff=0.0, max std diff relative to std_direct=4.6e-5) + train_emb = emb[train_idx] + mean = train_emb.mean(axis=0).astype(np.float32) + std = train_emb.std(axis=0).astype(np.float32) + std = np.where(std < 1e-8, 1.0, std).astype(np.float32) + return mean, std + + +def build_dataloader( + *, + task: str, + collate_fn, + df, + emb: np.ndarray, + max_len: int, + batch_size: int, + shuffle: bool, + num_workers: int, + encode_fn=None, +) -> DataLoader: + dataset_cls = TASK_DATASET_CLASSES[task] + dataset = dataset_cls(df.reset_index(drop=True), emb, max_len=max_len, encode_fn=encode_fn) + return DataLoader( + dataset, batch_size=batch_size, shuffle=shuffle, num_workers=num_workers, collate_fn=collate_fn + ) + + +def prepare_cached_training_data(args, logger=None, *, task, collate_fn, encode_fn=None): + """Public API kept identical to the previous shard-based implementation + so train_forward.py / train_inverse.py require no changes on this step.""" + logger = logger or logging.getLogger("irrm_codec") + + logger.info("loading AIRR + embeddings (no shards, full in-memory)") + merged, emb, merge_stats = load_airr_with_embeddings( + args.airr_path, + args.embeddings_path, + locus=args.locus, + clone_id_col=args.clone_id_col, + embedding_column=args.embedding_column, + ) + merge_stats = {**merge_stats, "embedding_dim": int(emb.shape[1])} + logger.info( + "loaded merged_rows=%d embedding_dim=%d alignment_mode=%s", + merge_stats["merged_rows"], merge_stats["embedding_dim"], merge_stats["alignment_mode"], + ) + + logger.info("creating train/val/test split") + train_idx, val_idx, test_idx = split_indices( + len(merged), + train_fraction=args.train_fraction, + val_fraction=args.val_fraction, + seed=args.seed, + ) + split_row_counts = {"train": int(len(train_idx)), "val": int(len(val_idx)), "test": int(len(test_idx))} + logger.info("split ready train=%d val=%d test=%d", *split_row_counts.values()) + + logger.info("computing train-only standardizer") + mean, std = compute_train_standardizer(emb, train_idx) + + logger.info("building dataloaders task=%s", task) + train_loader = build_dataloader( + task=task, collate_fn=collate_fn, df=merged.iloc[train_idx], emb=emb[train_idx], + max_len=args.max_len, batch_size=args.batch_size, shuffle=True, + num_workers=args.num_workers, encode_fn=encode_fn, + ) + val_loader = build_dataloader( + task=task, collate_fn=collate_fn, df=merged.iloc[val_idx], emb=emb[val_idx], + max_len=args.max_len, batch_size=args.batch_size, shuffle=False, + num_workers=args.num_workers, encode_fn=encode_fn, + ) + test_loader = build_dataloader( + task=task, collate_fn=collate_fn, df=merged.iloc[test_idx], emb=emb[test_idx], + max_len=args.max_len, batch_size=args.batch_size, shuffle=False, + num_workers=args.num_workers, encode_fn=encode_fn, + ) + + data_stats = { + "num_samples": int(len(merged)), + "embedding_dim": int(emb.shape[1]), + "max_len": int(args.max_len), + } + manifest = { + "cache_version": 2, # v2 = no shards, full in-memory load + "standardizer": {"mean_path": "mean.npy", "std_path": "std.npy"}, + "split_row_counts": split_row_counts, + "data_stats": data_stats, + "merge_stats": merge_stats, + "airr_path": args.airr_path, + "embeddings_path": args.embeddings_path, + } + + return { + "manifest": manifest, + "mean": mean, + "std": std, + "data_stats": data_stats, + "merge_stats": merge_stats, + "split_row_counts": split_row_counts, + "cache_dir": None, # no shard directory to clean up + "train_loader": train_loader, + "val_loader": val_loader, + "test_loader": test_loader, + } + + +def cleanup_batch_cache(cache_dir, logger=None): + # kept as a no-op for API compatibility with train_forward.py's finally block + if cache_dir is None: + return + logger = logger or logging.getLogger("irrm_codec") + logger.info("no shard cache to clean up (cache_dir=%s)", cache_dir) + + +def save_training_metadata(output_dir, args, data_stats, merge_stats, split_row_counts, manifest): + save_json( + Path(output_dir) / "data_stats.json", + { + **data_stats, + **merge_stats, + "airr_path": args.airr_path, + "embeddings_path": args.embeddings_path, + "train_size": int(split_row_counts["train"]), + "val_size": int(split_row_counts["val"]), + "test_size": int(split_row_counts["test"]), + "standardizer": manifest["standardizer"], + "checkpoints": {"best": "best.pt", "last": "last.pt"}, + }, + ) \ No newline at end of file From 695d5721c132e32d9d5db4249982f2a578ca7b0f Mon Sep 17 00:00:00 2001 From: maria Date: Tue, 21 Jul 2026 15:25:32 +0300 Subject: [PATCH 06/70] feat: add tokenization statistics script with alarm checks and plots scripts/calc_tokenization_stats.py: computes per-split (train/val/test) length/UNK/pad/compression stats, top-token reports, cross-vocab-size example table, and three alarm checks (oversized vocab, misconfigured tokenizer, insufficient compression benefit) for each trained WordPiece tokenizer. Outputs JSON + colored console summary + plain-text summary (tokenization_stats_summary.txt) + two diagnostic PNG plots (train memorization vs vocab_size, val/test compression plateau), matplotlib import guarded/optional via --skip-plots. Empirical finding: at min_frequency=1, vocab_size approaching train corpus size causes WordPiece to memorize whole training sequences as single vocab entries (train fraction_encoded_as_1_token spikes while val/test stays ~0). Confirmed on both the 12k-row and 80k-row corpora, with the safe vocab_size ceiling scaling roughly with corpus size. --- scripts/calc_tokenization_stats.py | 580 +++++++++++++++++++++++++++++ 1 file changed, 580 insertions(+) create mode 100644 scripts/calc_tokenization_stats.py diff --git a/scripts/calc_tokenization_stats.py b/scripts/calc_tokenization_stats.py new file mode 100644 index 0000000..a93f136 --- /dev/null +++ b/scripts/calc_tokenization_stats.py @@ -0,0 +1,580 @@ +"""Compute WordPiece tokenization statistics on train/val/test splits. + +For each vocab_size tokenizer, computes required length/UNK/pad/compression +statistics per split, top-token reports on the train split, a cross-vocab-size +example table, and alarm checks (over-large vocab, misconfigured pre-tokenizer, +insufficient compression benefit). + +Uses the same read_airr_table + split_indices(seed) call as +prepare_wordpiece_corpus.py / batch_cache.py, so split membership here matches +what models are trained/evaluated on. +""" +import argparse +import json +import logging +from collections import Counter +from pathlib import Path + +import numpy as np +from tokenizers import Tokenizer + +from irrm_codec.dataio import read_airr_table +from irrm_codec.utils import setup_logging, split_indices + +try: + import matplotlib + matplotlib.use("Agg") # headless-safe, no display required + import matplotlib.pyplot as plt + MATPLOTLIB_AVAILABLE = True +except ImportError: + MATPLOTLIB_AVAILABLE = False + +SPLIT_NAMES = ("train", "val", "test") +MAIN_GRID_VOCAB_SIZES = (1000, 2000, 5000, 10000) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Compute WordPiece tokenization statistics.") + parser.add_argument("--airr-path", required=True) + parser.add_argument("--locus", default="beta") + parser.add_argument("--clone-id-col", default="") + parser.add_argument("--train-fraction", type=float, default=0.8) + parser.add_argument("--val-fraction", type=float, default=0.1) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--tokenizers-dir", default="artifacts/tokenizers") + parser.add_argument("--vocab-sizes", type=int, nargs="+", default=[100, 1000, 2000, 5000, 10000]) + parser.add_argument("--example-vocab-sizes", type=int, nargs="+", default=list(MAIN_GRID_VOCAB_SIZES)) + parser.add_argument("--output-path", default="artifacts/tokenizers/tokenization_stats.json") + parser.add_argument("--top-n", type=int, default=50) + parser.add_argument("--num-examples", type=int, default=20) + parser.add_argument("--max-len", type=int, default=40, help="Fixed length used for pad_token_fraction.") + parser.add_argument("--high-1-token-threshold", type=float, default=0.2) + parser.add_argument("--high-unk-threshold", type=float, default=0.001) + parser.add_argument("--min-compression-benefit", type=float, default=0.2) + parser.add_argument("--skip-plots", action="store_true", help="Do not generate the two diagnostic PNG plots.") + return parser.parse_args() + + +def load_split_sequences( + airr_path: str, locus: str, clone_id_col: str, train_fraction: float, val_fraction: float, seed: int, + logger: logging.Logger, +) -> dict[str, list[str]]: + columns = ["junction_aa", "locus"] + if clone_id_col: + columns.append(clone_id_col) + + df = read_airr_table( + airr_path, clone_id_col=clone_id_col, columns=list(dict.fromkeys(columns)), validate=False, + ) + if locus is not None: + # exact match, no LOCUS_ALIASES normalization - must mirror batch_cache.py + # so num_rows and split_indices() output match what models train on + df = df[df["locus"] == locus].reset_index(drop=True) + + seqs = df["junction_aa"].astype(str).to_numpy(copy=True) + train_idx, val_idx, test_idx = split_indices( + len(seqs), train_fraction=train_fraction, val_fraction=val_fraction, seed=seed, + ) + logger.info("split ready train=%d val=%d test=%d", len(train_idx), len(val_idx), len(test_idx)) + + return { + "train": seqs[train_idx].tolist(), + "val": seqs[val_idx].tolist(), + "test": seqs[test_idx].tolist(), + } + + +def encode_raw(tokenizer: Tokenizer, seqs: list[str]) -> list: + # tokenizer object is reused across splits/calls, a prior call may have left padding on + tokenizer.no_padding() + tokenizer.no_truncation() + return tokenizer.encode_batch(seqs) + + +def count_tokens_per_sequence(encodings: list) -> list[int]: + token_counts = [] + for encoding in encodings: + token_counts.append(len(encoding.ids)) + return token_counts + + +def count_unk_tokens(encodings: list, unk_id: int) -> tuple[int, int, int]: + total_tokens = 0 + total_unk_tokens = 0 + sequences_with_unk = 0 + + for encoding in encodings: + unk_count_in_this_sequence = 0 + for token_id in encoding.ids: + total_tokens += 1 + if token_id == unk_id: + total_unk_tokens += 1 + unk_count_in_this_sequence += 1 + if unk_count_in_this_sequence > 0: + sequences_with_unk += 1 + + return total_tokens, total_unk_tokens, sequences_with_unk + + +def count_short_sequences(token_counts: list[int]) -> tuple[int, int, int]: + count_1_token = 0 + count_2_tokens_or_less = 0 + count_3_tokens_or_less = 0 + + for num_tokens in token_counts: + if num_tokens <= 1: + count_1_token += 1 + if num_tokens <= 2: + count_2_tokens_or_less += 1 + if num_tokens <= 3: + count_3_tokens_or_less += 1 + + return count_1_token, count_2_tokens_or_less, count_3_tokens_or_less + + +def summarize_token_counts(token_counts: list[int]) -> dict: + token_counts_array = np.array(token_counts) + return { + "mean_num_tokens": float(token_counts_array.mean()), + "median_num_tokens": float(np.median(token_counts_array)), + "min_num_tokens": int(token_counts_array.min()), + "max_num_tokens": int(token_counts_array.max()), + "p95_num_tokens": float(np.percentile(token_counts_array, 95)), + } + + +def count_pad_tokens(tokenizer: Tokenizer, seqs: list[str], pad_id: int, max_len: int) -> tuple[int, int]: + # length=max_len mirrors what collate_forward/collate_inverse actually feed the model + tokenizer.enable_padding(pad_id=pad_id, pad_token="[PAD]", length=max_len) + tokenizer.enable_truncation(max_length=max_len) + padded_encodings = tokenizer.encode_batch(seqs) + + total_positions = 0 + total_pad_positions = 0 + for encoding in padded_encodings: + for token_id in encoding.ids: + total_positions += 1 + if token_id == pad_id: + total_pad_positions += 1 + + # reset so later calls on this tokenizer (other splits, top tokens, examples) get raw output + tokenizer.no_padding() + tokenizer.no_truncation() + return total_positions, total_pad_positions + + +def compute_split_stats( + tokenizer: Tokenizer, + seqs: list[str], + unk_id: int, + pad_id: int, + max_len: int, + mean_char_length: float, +) -> tuple[dict, list]: + num_sequences = len(seqs) + + encodings = encode_raw(tokenizer, seqs) + token_counts = count_tokens_per_sequence(encodings) + total_tokens, total_unk_tokens, sequences_with_unk = count_unk_tokens(encodings, unk_id) + count_1, count_2, count_3 = count_short_sequences(token_counts) + total_positions, total_pad_positions = count_pad_tokens(tokenizer, seqs, pad_id, max_len) + + mean_num_tokens = float(np.mean(token_counts)) + compression_ratio = mean_num_tokens / mean_char_length if mean_char_length > 0 else float("nan") + + stats = { + "number_of_sequences": num_sequences, + **summarize_token_counts(token_counts), + "unk_token_fraction": total_unk_tokens / total_tokens if total_tokens > 0 else 0.0, + "unk_sequence_fraction": sequences_with_unk / num_sequences, + "pad_token_fraction": total_pad_positions / total_positions if total_positions > 0 else 0.0, + "fraction_encoded_as_1_token": count_1 / num_sequences, + "fraction_encoded_as_2_tokens_or_less": count_2 / num_sequences, + "fraction_encoded_as_3_tokens_or_less": count_3 / num_sequences, + "mean_char_length": mean_char_length, + "compression_ratio": compression_ratio, + } + return stats, encodings + + +def aa_length(token: str) -> int: + # "##" is a continuation marker, not an amino acid - strip before measuring length + if token.startswith("##"): + return len(token[2:]) + return len(token) + + +def compute_top_token_reports(tokenizer: Tokenizer, train_encodings: list, top_n: int) -> dict: + token_counter: Counter = Counter() + for encoding in train_encodings: + for token_id in encoding.ids: + token_counter[token_id] += 1 + + all_seen_tokens = [] + for token_id, count in token_counter.items(): + token_text = tokenizer.id_to_token(token_id) + all_seen_tokens.append( + {"token": token_text, "id": token_id, "count": count, "aa_length": aa_length(token_text)} + ) + + top_by_frequency = [ + {"token": tokenizer.id_to_token(tid), "id": tid, "count": count} + for tid, count in token_counter.most_common(top_n) + ] + + top_longest = sorted(all_seen_tokens, key=lambda item: (-item["aa_length"], -item["count"]))[:top_n] + + non_single_aa_tokens = [item for item in all_seen_tokens if item["aa_length"] > 1] + top_non_single_aa = sorted(non_single_aa_tokens, key=lambda item: -item["count"])[:top_n] + + return { + "top_tokens_by_frequency_train": top_by_frequency, + "top_longest_tokens": top_longest, + "top_non_single_amino_acid_tokens": top_non_single_aa, + } + + +def compute_alarms( + train_stats: dict, + high_1_token_threshold: float, + high_unk_threshold: float, + min_compression_benefit: float, +) -> dict: + # train-only: alarms describe tokenizer fit behavior, not generalization - + # compare train vs val/test in `splits` manually (memorization looks fine on + # train alarms but shows up as a train/val gap, e.g. vocab_size=10000 case) + fraction_1_token = train_stats["fraction_encoded_as_1_token"] + unk_fraction = train_stats["unk_token_fraction"] + compression_ratio = train_stats["compression_ratio"] + + if compression_ratio == compression_ratio: # not NaN + compression_benefit = 1.0 - compression_ratio + else: + compression_benefit = float("nan") + + return { + "vocab_size_too_large": { + "triggered": fraction_1_token > high_1_token_threshold, + "value": fraction_1_token, + "threshold": high_1_token_threshold, + "message": ( + f"{fraction_1_token:.1%} of train CDR3s encode as a single token " + f"(threshold {high_1_token_threshold:.1%}); vocab_size may be too large." + ), + }, + "tokenizer_misconfigured": { + "triggered": unk_fraction > high_unk_threshold, + "value": unk_fraction, + "threshold": high_unk_threshold, + "message": ( + f"unk_token_fraction={unk_fraction:.4%} exceeds threshold {high_unk_threshold:.4%}; " + "check pre_tokenizer / alphabet coverage." + ), + }, + "insufficient_compression_benefit": { + "triggered": compression_benefit < min_compression_benefit, + "value": compression_benefit, + "threshold": min_compression_benefit, + "message": ( + f"WordPiece reduces sequence length by only {compression_benefit:.1%} " + f"vs raw amino acid count (threshold {min_compression_benefit:.1%}); " + "benefit over char tokenization may be marginal." + ), + }, + } + + +def build_examples_table(tokenizers_by_vocab_size: dict, example_seqs: list[str]) -> list[dict]: + examples = [] + for seq in example_seqs: + row = {"original_cdr3": seq} + for vocab_size, tokenizer in tokenizers_by_vocab_size.items(): + # reset in case this tokenizer object still has padding enabled from compute_split_stats + tokenizer.no_padding() + tokenizer.no_truncation() + encoding = tokenizer.encode(seq) + row[f"tokens_vocab_{vocab_size}"] = encoding.tokens + examples.append(row) + return examples + + +RED = "\033[91m" +YELLOW = "\033[93m" +GREEN = "\033[92m" +BOLD = "\033[1m" +RESET = "\033[0m" + +GENERALIZATION_GAP_THRESHOLD = 0.05 + +ROW_FORMAT = "{:<12}{:<7}{:>9}{:>9}{:>10}{:>10}{:>10}{:>10}" + + +def colorize(text: str, color: str) -> str: + return f"{color}{text}{RESET}" + + +def build_summary_rows(results: dict) -> list[tuple]: + # shared row classification (alarm / generalization-gap flags), consumed by + # both the console renderer and the plain-text file renderer below + groups = [] + for vocab_size, entry in results["per_vocab_size"].items(): + train_stats = entry["splits"]["train"] + train_frac_1_token = train_stats["fraction_encoded_as_1_token"] + any_alarm_this_vocab = any(alarm["triggered"] for alarm in entry["alarms"].values()) + + rows = [] + for split_name in SPLIT_NAMES: + stats = entry["splits"][split_name] + is_alarm_row = split_name == "train" and any_alarm_this_vocab + + gap_warning = False + if split_name != "train": + # large gap vs train means the tokenizer memorized train sequences + # rather than learning generalizable subwords (see vocab_size=10000 case) + gap = abs(train_frac_1_token - stats["fraction_encoded_as_1_token"]) + gap_warning = gap > GENERALIZATION_GAP_THRESHOLD + + rows.append((split_name, stats, is_alarm_row, gap_warning)) + + groups.append((vocab_size, any_alarm_this_vocab, rows)) + return groups + + +def format_row(vocab_size: str, split_name: str, stats: dict) -> str: + return ROW_FORMAT.format( + vocab_size, + split_name, + f"{stats['mean_num_tokens']:.2f}", + f"{stats['compression_ratio']:.3f}", + f"{stats['unk_token_fraction']:.4f}", + f"{stats['pad_token_fraction']:.3f}", + f"{stats['fraction_encoded_as_1_token']:.4f}", + f"{stats['fraction_encoded_as_3_tokens_or_less']:.3f}", + ) + + +def print_colored_summary(results: dict) -> None: + groups = build_summary_rows(results) + header = ROW_FORMAT.format( + "vocab_size", "split", "mean_tok", "compr", "unk_frac", "pad_frac", "frac=1tok", "frac<=3tok", + ) + + print() + print(BOLD + "=== Tokenization statistics summary ===" + RESET) + print(BOLD + header + RESET) + print("-" * len(header)) + + any_alarm_triggered = False + for vocab_size, any_alarm_this_vocab, rows in groups: + any_alarm_triggered = any_alarm_triggered or any_alarm_this_vocab + for split_name, stats, is_alarm_row, gap_warning in rows: + row_text = format_row(vocab_size, split_name, stats) + if is_alarm_row: + print(colorize(row_text, RED)) + elif gap_warning: + print(colorize(row_text, YELLOW)) + else: + print(row_text) + print() + + print(BOLD + "=== Alarms ===" + RESET) + if not any_alarm_triggered: + print(colorize("No alarms triggered.", GREEN)) + else: + for vocab_size, entry in results["per_vocab_size"].items(): + for alarm_name, alarm in entry["alarms"].items(): + if alarm["triggered"]: + print(colorize(f" [{vocab_size}] {alarm_name}: {alarm['message']}", RED)) + print() + print( + colorize( + f"Yellow rows: |train_frac_1_token - split_frac_1_token| > {GENERALIZATION_GAP_THRESHOLD:.0%} " + "(possible tokenizer memorization of train sequences).", + YELLOW, + ) + ) + + +def save_plain_summary(results: dict, path: Path) -> None: + # same content as print_colored_summary, no ANSI codes - readable in any text viewer. + # flagged rows get a bracket marker instead of color, since plain text has no color. + groups = build_summary_rows(results) + header = ROW_FORMAT.format( + "vocab_size", "split", "mean_tok", "compr", "unk_frac", "pad_frac", "frac=1tok", "frac<=3tok", + ) + + lines = ["=== Tokenization statistics summary ===", header, "-" * len(header)] + + any_alarm_triggered = False + for vocab_size, any_alarm_this_vocab, rows in groups: + any_alarm_triggered = any_alarm_triggered or any_alarm_this_vocab + for split_name, stats, is_alarm_row, gap_warning in rows: + row_text = format_row(vocab_size, split_name, stats) + if is_alarm_row: + row_text += " [ALARM]" + elif gap_warning: + row_text += " [GAP]" + lines.append(row_text) + lines.append("") + + lines.append("=== Alarms ===") + if not any_alarm_triggered: + lines.append("No alarms triggered.") + else: + for vocab_size, entry in results["per_vocab_size"].items(): + for alarm_name, alarm in entry["alarms"].items(): + if alarm["triggered"]: + lines.append(f" [{vocab_size}] {alarm_name}: {alarm['message']}") + lines.append("") + lines.append( + f"[GAP] rows: |train_frac_1_token - split_frac_1_token| > {GENERALIZATION_GAP_THRESHOLD:.0%} " + "(possible tokenizer memorization of train sequences)." + ) + + path.write_text("\n".join(lines), encoding="utf-8") + + +def plot_train_memorization(vocab_sizes: list[int], per_vocab_size: dict, alarm_threshold: float, output_path: Path) -> None: + train_frac_1_token = [per_vocab_size[str(vs)]["splits"]["train"]["fraction_encoded_as_1_token"] for vs in vocab_sizes] + + fig, ax = plt.subplots(figsize=(8, 5)) + ax.plot(vocab_sizes, train_frac_1_token, marker="o", color="tab:red") + ax.axhline(alarm_threshold, color="gray", linestyle="--", label=f"alarm threshold ({alarm_threshold:.0%})") + ax.set_xlabel("vocab_size") + ax.set_ylabel("fraction_encoded_as_1_token (train)") + ax.set_title("Train-set tokenizer memorization vs vocab_size") + ax.legend() + ax.grid(alpha=0.3) + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + +def plot_val_test_compression(vocab_sizes: list[int], per_vocab_size: dict, output_path: Path) -> None: + val_mean_tokens = [per_vocab_size[str(vs)]["splits"]["val"]["mean_num_tokens"] for vs in vocab_sizes] + test_mean_tokens = [per_vocab_size[str(vs)]["splits"]["test"]["mean_num_tokens"] for vs in vocab_sizes] + + fig, ax = plt.subplots(figsize=(8, 5)) + ax.plot(vocab_sizes, val_mean_tokens, marker="o", label="val", color="tab:blue") + ax.plot(vocab_sizes, test_mean_tokens, marker="o", label="test", color="tab:orange") + ax.set_xlabel("vocab_size") + ax.set_ylabel("mean_num_tokens (held-out)") + ax.set_title("Real generalization benefit vs vocab_size (val/test)") + ax.legend() + ax.grid(alpha=0.3) + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + +def save_diagnostic_plots(results: dict, output_dir: Path, alarm_threshold: float, logger: logging.Logger) -> None: + # needs at least 2 vocab_size points to draw a meaningful line + vocab_sizes = sorted(int(vs) for vs in results["per_vocab_size"].keys()) + if len(vocab_sizes) < 2: + logger.warning("fewer than 2 vocab_sizes computed, skipping diagnostic plots") + return + + per_vocab_size = results["per_vocab_size"] + + train_plot_path = output_dir / "train_memorization_vs_vocab_size.png" + plot_train_memorization(vocab_sizes, per_vocab_size, alarm_threshold, train_plot_path) + logger.info("saved plot path=%s", train_plot_path) + + valtest_plot_path = output_dir / "val_test_compression_vs_vocab_size.png" + plot_val_test_compression(vocab_sizes, per_vocab_size, valtest_plot_path) + logger.info("saved plot path=%s", valtest_plot_path) + + +def main() -> None: + args = parse_args() + output_path = Path(args.output_path) + logger = setup_logging(output_path.parent / "compute_tokenization_stats.log") + + split_seqs = load_split_sequences( + args.airr_path, args.locus, args.clone_id_col, + args.train_fraction, args.val_fraction, args.seed, logger, + ) + mean_char_length_by_split = { + split_name: float(np.mean([len(seq) for seq in seqs])) for split_name, seqs in split_seqs.items() + } + + tokenizers_dir = Path(args.tokenizers_dir) + results = {"per_vocab_size": {}, "examples": [], "max_len_used_for_padding_stats": args.max_len} + example_tokenizers = {} + + for vocab_size in args.vocab_sizes: + tokenizer_path = tokenizers_dir / f"wordpiece_vocab_{vocab_size}" / "tokenizer.json" + if not tokenizer_path.exists(): + logger.warning("tokenizer file not found, skipping: %s", tokenizer_path) + continue + + logger.info("computing stats for vocab_size=%d", vocab_size) + tokenizer = Tokenizer.from_file(str(tokenizer_path)) + vocab = tokenizer.get_vocab() + unk_id = vocab["[UNK]"] + pad_id = vocab["[PAD]"] + actual_vocab_size = tokenizer.get_vocab_size() + + split_results = {} + train_encodings = None + for split_name in SPLIT_NAMES: + seqs = split_seqs[split_name] + stats, encodings = compute_split_stats( + tokenizer, seqs, unk_id, pad_id, args.max_len, mean_char_length_by_split[split_name], + ) + split_results[split_name] = stats + if split_name == "train": + train_encodings = encodings + logger.info( + "vocab_size=%d split=%s mean_num_tokens=%.2f unk_token_fraction=%.6f " + "pad_token_fraction=%.4f fraction_1_token=%.4f", + vocab_size, split_name, stats["mean_num_tokens"], stats["unk_token_fraction"], + stats["pad_token_fraction"], stats["fraction_encoded_as_1_token"], + ) + + top_token_reports = compute_top_token_reports(tokenizer, train_encodings, args.top_n) + alarms = compute_alarms( + split_results["train"], args.high_1_token_threshold, args.high_unk_threshold, + args.min_compression_benefit, + ) + for alarm_name, alarm in alarms.items(): + if alarm["triggered"]: + logger.warning("ALARM vocab_size=%d %s: %s", vocab_size, alarm_name, alarm["message"]) + + results["per_vocab_size"][str(vocab_size)] = { + "role": "sanity_check" if vocab_size == 100 else "main_grid", + "vocab_size_requested": vocab_size, + "vocab_size_actual": actual_vocab_size, + "splits": split_results, + **top_token_reports, + "alarms": alarms, + } + + if vocab_size in args.example_vocab_sizes: + example_tokenizers[vocab_size] = tokenizer + + example_seqs = split_seqs["test"][: args.num_examples] + if len(example_seqs) < args.num_examples: + example_seqs = (split_seqs["test"] + split_seqs["val"])[: args.num_examples] + results["examples"] = build_examples_table(example_tokenizers, example_seqs) + + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.write_text(json.dumps(results, indent=2), encoding="utf-8") + logger.info("wrote tokenization stats path=%s", output_path) + + summary_path = output_path.parent / "tokenization_stats_summary.txt" + save_plain_summary(results, summary_path) + logger.info("wrote plain-text summary path=%s", summary_path) + + if args.skip_plots: + logger.info("--skip-plots set, not generating diagnostic plots") + elif not MATPLOTLIB_AVAILABLE: + logger.warning("matplotlib not installed, skipping diagnostic plots (pip install matplotlib)") + else: + save_diagnostic_plots(results, output_path.parent, args.high_1_token_threshold, logger) + + print_colored_summary(results) + + +if __name__ == "__main__": + main() \ No newline at end of file From ff5b75938c5ec744518a0e918cd2abee72589091 Mon Sep 17 00:00:00 2001 From: maria Date: Tue, 21 Jul 2026 15:26:26 +0300 Subject: [PATCH 07/70] fix: switch train_forward.py to use batch_nocache (streaming reader broken) batch_cache.py's shard-based/streaming loader is currently broken in this environment, so train_forward.py cannot run end-to-end against it. Temporarily import prepare_cached_training_data/cleanup_batch_cache/ save_training_metadata from batch_nocache.py instead (same public API, no other changes needed downstream). TODO: replace this direct import swap with a --no-cache/--cache-mode flag so both loaders stay selectable, and switch back to batch_cache.py once its streaming reader is fixed. --- irrm_codec/train_forward.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/irrm_codec/train_forward.py b/irrm_codec/train_forward.py index 942664c..fd5b391 100644 --- a/irrm_codec/train_forward.py +++ b/irrm_codec/train_forward.py @@ -6,7 +6,10 @@ import torch from tqdm.auto import tqdm -from irrm_codec.batch_cache import cleanup_batch_cache, prepare_cached_training_data, save_training_metadata +# TODO: implement switching using flags +# Switch back to using batch_cache.py once it is fixed +# from irrm_codec.batch_cache import cleanup_batch_cache, prepare_cached_training_data, save_training_metadata +from irrm_codec.batch_nocache import cleanup_batch_cache, prepare_cached_training_data, save_training_metadata from irrm_codec.datasets import collate_forward from irrm_codec.forward_model import ForwardModel from irrm_codec.losses import forward_loss, forward_metrics From 6614f6170f6387272266bec8e3eb8e10913badc7 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 22 Jul 2026 12:39:23 +0300 Subject: [PATCH 08/70] calc_tokenization_stats: read vocab_size grid from training summary, fail loudly on missing tokenizer Adds --training-summary-path (single source of truth from train_wordpiece_tokenizers.py's output) and --allow-missing-tokenizers. Previously a missing tokenizer.json was silently skipped with a WARNING, causing undetected drift between --vocab-sizes and what was actually trained. --- scripts/calc_tokenization_stats.py | 272 +++++++++++++++++++++++------ 1 file changed, 223 insertions(+), 49 deletions(-) diff --git a/scripts/calc_tokenization_stats.py b/scripts/calc_tokenization_stats.py index a93f136..a095d29 100644 --- a/scripts/calc_tokenization_stats.py +++ b/scripts/calc_tokenization_stats.py @@ -1,9 +1,14 @@ """Compute WordPiece tokenization statistics on train/val/test splits. -For each vocab_size tokenizer, computes required length/UNK/pad/compression -statistics per split, top-token reports on the train split, a cross-vocab-size -example table, and alarm checks (over-large vocab, misconfigured pre-tokenizer, -insufficient compression benefit). +For each vocab_size tokenizer, computes required length/UNK/compression +statistics per split, a per-sequence token-count histogram, top-token reports +on the train split, a cross-vocab-size example table, and alarm checks +(over-large vocab, misconfigured pre-tokenizer, insufficient compression benefit). + +vocab_size grid: pass --training-summary-path (wordpiece_training_summary.json +from train_wordpiece_tokenizers.py) to derive it automatically - this is the +single source of truth and avoids drift with --vocab-sizes. If omitted, +--vocab-sizes is used directly. Uses the same read_airr_table + split_indices(seed) call as prepare_wordpiece_corpus.py / batch_cache.py, so split membership here matches @@ -12,6 +17,7 @@ import argparse import json import logging +import math from collections import Counter from pathlib import Path @@ -31,6 +37,7 @@ SPLIT_NAMES = ("train", "val", "test") MAIN_GRID_VOCAB_SIZES = (1000, 2000, 5000, 10000) +SPLIT_COLORS = {"train": "tab:red", "val": "tab:blue", "test": "tab:orange"} def parse_args() -> argparse.Namespace: @@ -42,16 +49,27 @@ def parse_args() -> argparse.Namespace: parser.add_argument("--val-fraction", type=float, default=0.1) parser.add_argument("--seed", type=int, default=42) parser.add_argument("--tokenizers-dir", default="artifacts/tokenizers") + parser.add_argument( + "--training-summary-path", default="", + help=( + "Path to wordpiece_training_summary.json produced by train_wordpiece_tokenizers.py. " + "If set, vocab_size grid is read from this file's keys instead of --vocab-sizes, " + "eliminating drift between what was actually trained and what stats are computed on." + ), + ) parser.add_argument("--vocab-sizes", type=int, nargs="+", default=[100, 1000, 2000, 5000, 10000]) parser.add_argument("--example-vocab-sizes", type=int, nargs="+", default=list(MAIN_GRID_VOCAB_SIZES)) + parser.add_argument( + "--allow-missing-tokenizers", action="store_true", + help="Downgrade a missing tokenizer.json from a hard error back to a skip+warning.", + ) parser.add_argument("--output-path", default="artifacts/tokenizers/tokenization_stats.json") parser.add_argument("--top-n", type=int, default=50) parser.add_argument("--num-examples", type=int, default=20) - parser.add_argument("--max-len", type=int, default=40, help="Fixed length used for pad_token_fraction.") parser.add_argument("--high-1-token-threshold", type=float, default=0.2) parser.add_argument("--high-unk-threshold", type=float, default=0.001) parser.add_argument("--min-compression-benefit", type=float, default=0.2) - parser.add_argument("--skip-plots", action="store_true", help="Do not generate the two diagnostic PNG plots.") + parser.add_argument("--skip-plots", action="store_true", help="Do not generate the diagnostic PNG plots.") return parser.parse_args() @@ -85,7 +103,7 @@ def load_split_sequences( def encode_raw(tokenizer: Tokenizer, seqs: list[str]) -> list: - # tokenizer object is reused across splits/calls, a prior call may have left padding on + # tokenizer object is reused across splits/calls, a prior call may have left this enabled tokenizer.no_padding() tokenizer.no_truncation() return tokenizer.encode_batch(seqs) @@ -143,32 +161,16 @@ def summarize_token_counts(token_counts: list[int]) -> dict: } -def count_pad_tokens(tokenizer: Tokenizer, seqs: list[str], pad_id: int, max_len: int) -> tuple[int, int]: - # length=max_len mirrors what collate_forward/collate_inverse actually feed the model - tokenizer.enable_padding(pad_id=pad_id, pad_token="[PAD]", length=max_len) - tokenizer.enable_truncation(max_length=max_len) - padded_encodings = tokenizer.encode_batch(seqs) - - total_positions = 0 - total_pad_positions = 0 - for encoding in padded_encodings: - for token_id in encoding.ids: - total_positions += 1 - if token_id == pad_id: - total_pad_positions += 1 - - # reset so later calls on this tokenizer (other splits, top tokens, examples) get raw output - tokenizer.no_padding() - tokenizer.no_truncation() - return total_positions, total_pad_positions +def compute_token_count_histogram(token_counts: list[int]) -> dict[str, int]: + # JSON object keys must be strings; num_tokens is bounded so this stays small + histogram = Counter(token_counts) + return {str(num_tokens): count for num_tokens, count in sorted(histogram.items())} def compute_split_stats( tokenizer: Tokenizer, seqs: list[str], unk_id: int, - pad_id: int, - max_len: int, mean_char_length: float, ) -> tuple[dict, list]: num_sequences = len(seqs) @@ -177,7 +179,6 @@ def compute_split_stats( token_counts = count_tokens_per_sequence(encodings) total_tokens, total_unk_tokens, sequences_with_unk = count_unk_tokens(encodings, unk_id) count_1, count_2, count_3 = count_short_sequences(token_counts) - total_positions, total_pad_positions = count_pad_tokens(tokenizer, seqs, pad_id, max_len) mean_num_tokens = float(np.mean(token_counts)) compression_ratio = mean_num_tokens / mean_char_length if mean_char_length > 0 else float("nan") @@ -185,9 +186,9 @@ def compute_split_stats( stats = { "number_of_sequences": num_sequences, **summarize_token_counts(token_counts), + "token_count_histogram": compute_token_count_histogram(token_counts), "unk_token_fraction": total_unk_tokens / total_tokens if total_tokens > 0 else 0.0, "unk_sequence_fraction": sequences_with_unk / num_sequences, - "pad_token_fraction": total_pad_positions / total_positions if total_positions > 0 else 0.0, "fraction_encoded_as_1_token": count_1 / num_sequences, "fraction_encoded_as_2_tokens_or_less": count_2 / num_sequences, "fraction_encoded_as_3_tokens_or_less": count_3 / num_sequences, @@ -289,7 +290,7 @@ def build_examples_table(tokenizers_by_vocab_size: dict, example_seqs: list[str] for seq in example_seqs: row = {"original_cdr3": seq} for vocab_size, tokenizer in tokenizers_by_vocab_size.items(): - # reset in case this tokenizer object still has padding enabled from compute_split_stats + # reset in case this tokenizer object still has other state from compute_split_stats tokenizer.no_padding() tokenizer.no_truncation() encoding = tokenizer.encode(seq) @@ -306,7 +307,8 @@ def build_examples_table(tokenizers_by_vocab_size: dict, example_seqs: list[str] GENERALIZATION_GAP_THRESHOLD = 0.05 -ROW_FORMAT = "{:<12}{:<7}{:>9}{:>9}{:>10}{:>10}{:>10}{:>10}" +ROW_FORMAT = "{:<12}{:<7}{:>9}{:>9}{:>10}{:>10}{:>10}" +TOKEN_COUNT_ROW_FORMAT = "{:<12}{:<7}{:>8}{:>8}{:>6}{:>6}{:>8}" def colorize(text: str, color: str) -> str: @@ -347,16 +349,38 @@ def format_row(vocab_size: str, split_name: str, stats: dict) -> str: f"{stats['mean_num_tokens']:.2f}", f"{stats['compression_ratio']:.3f}", f"{stats['unk_token_fraction']:.4f}", - f"{stats['pad_token_fraction']:.3f}", f"{stats['fraction_encoded_as_1_token']:.4f}", f"{stats['fraction_encoded_as_3_tokens_or_less']:.3f}", ) +def build_token_count_description_lines(results: dict) -> list[str]: + # answers directly: how many tokens does one sequence get on average / at minimum / at maximum + lines = ["=== Token count per sequence: mean / median / min / max / p95 ==="] + header = TOKEN_COUNT_ROW_FORMAT.format("vocab_size", "split", "mean", "median", "min", "max", "p95") + lines.append(header) + lines.append("-" * len(header)) + for vocab_size, entry in sorted(results["per_vocab_size"].items(), key=lambda kv: int(kv[0])): + for split_name in SPLIT_NAMES: + stats = entry["splits"][split_name] + lines.append( + TOKEN_COUNT_ROW_FORMAT.format( + vocab_size, split_name, + f"{stats['mean_num_tokens']:.2f}", + f"{stats['median_num_tokens']:.1f}", + stats["min_num_tokens"], + stats["max_num_tokens"], + f"{stats['p95_num_tokens']:.1f}", + ) + ) + lines.append("") + return lines + + def print_colored_summary(results: dict) -> None: groups = build_summary_rows(results) header = ROW_FORMAT.format( - "vocab_size", "split", "mean_tok", "compr", "unk_frac", "pad_frac", "frac=1tok", "frac<=3tok", + "vocab_size", "split", "mean_tok", "compr", "unk_frac", "frac=1tok", "frac<=3tok", ) print() @@ -394,13 +418,17 @@ def print_colored_summary(results: dict) -> None: ) ) + print() + for line in build_token_count_description_lines(results): + print(line) + def save_plain_summary(results: dict, path: Path) -> None: # same content as print_colored_summary, no ANSI codes - readable in any text viewer. # flagged rows get a bracket marker instead of color, since plain text has no color. groups = build_summary_rows(results) header = ROW_FORMAT.format( - "vocab_size", "split", "mean_tok", "compr", "unk_frac", "pad_frac", "frac=1tok", "frac<=3tok", + "vocab_size", "split", "mean_tok", "compr", "unk_frac", "frac=1tok", "frac<=3tok", ) lines = ["=== Tokenization statistics summary ===", header, "-" * len(header)] @@ -430,6 +458,8 @@ def save_plain_summary(results: dict, path: Path) -> None: f"[GAP] rows: |train_frac_1_token - split_frac_1_token| > {GENERALIZATION_GAP_THRESHOLD:.0%} " "(possible tokenizer memorization of train sequences)." ) + lines.append("") + lines.extend(build_token_count_description_lines(results)) path.write_text("\n".join(lines), encoding="utf-8") @@ -467,7 +497,106 @@ def plot_val_test_compression(vocab_sizes: list[int], per_vocab_size: dict, outp plt.close(fig) -def save_diagnostic_plots(results: dict, output_dir: Path, alarm_threshold: float, logger: logging.Logger) -> None: +def plot_metric_vs_vocab_size( + vocab_sizes: list[int], + per_vocab_size: dict, + metric_key: str, + ylabel: str, + title: str, + output_path: Path, + hline: float | None = None, + hline_label: str = "", +) -> None: + fig, ax = plt.subplots(figsize=(8, 5)) + for split_name in SPLIT_NAMES: + values = [per_vocab_size[str(vs)]["splits"][split_name][metric_key] for vs in vocab_sizes] + ax.plot(vocab_sizes, values, marker="o", label=split_name, color=SPLIT_COLORS[split_name]) + if hline is not None: + ax.axhline(hline, color="gray", linestyle="--", label=hline_label) + ax.set_xlabel("vocab_size") + ax.set_ylabel(ylabel) + ax.set_title(title) + ax.legend() + ax.grid(alpha=0.3) + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + +def plot_fraction_short_sequences(vocab_sizes: list[int], per_vocab_size: dict, output_path: Path) -> None: + # train-only: this is what compute_alarms actually checks (fraction_1_token on train); + # showing all 3 thresholds together shows how fast short-sequence mass grows with vocab_size + metric_keys = ( + "fraction_encoded_as_1_token", + "fraction_encoded_as_2_tokens_or_less", + "fraction_encoded_as_3_tokens_or_less", + ) + labels = ("<=1 token", "<=2 tokens", "<=3 tokens") + colors = ("tab:red", "tab:orange", "tab:green") + + fig, ax = plt.subplots(figsize=(8, 5)) + for metric_key, label, color in zip(metric_keys, labels, colors): + values = [per_vocab_size[str(vs)]["splits"]["train"][metric_key] for vs in vocab_sizes] + ax.plot(vocab_sizes, values, marker="o", label=label, color=color) + ax.set_xlabel("vocab_size") + ax.set_ylabel("fraction of train sequences") + ax.set_title("Short-sequence mass vs vocab_size (train)") + ax.legend() + ax.grid(alpha=0.3) + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + +def plot_vocab_size_actual_vs_requested(vocab_sizes: list[int], per_vocab_size: dict, output_path: Path) -> None: + requested = vocab_sizes + actual = [per_vocab_size[str(vs)]["vocab_size_actual"] for vs in vocab_sizes] + + fig, ax = plt.subplots(figsize=(8, 5)) + ax.plot(requested, requested, linestyle="--", color="gray", label="y = x (no floor effect)") + ax.plot(requested, actual, marker="o", color="tab:purple", label="actual_vocab_size") + ax.set_xscale("log") + ax.set_yscale("log") + ax.set_xlabel("vocab_size_requested") + ax.set_ylabel("vocab_size_actual") + ax.set_title("WordPiece floor effect: requested vs actual vocab size") + ax.legend() + ax.grid(alpha=0.3, which="both") + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + +def plot_token_count_histogram_grid( + vocab_sizes: list[int], per_vocab_size: dict, split_name: str, output_path: Path +) -> None: + ncols = 3 + nrows = math.ceil(len(vocab_sizes) / ncols) + fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 4, nrows * 3), squeeze=False) + + for idx, vocab_size in enumerate(vocab_sizes): + ax = axes[idx // ncols][idx % ncols] + histogram = per_vocab_size[str(vocab_size)]["splits"][split_name]["token_count_histogram"] + num_tokens_values = sorted(int(k) for k in histogram.keys()) + counts = [histogram[str(k)] for k in num_tokens_values] + total = sum(counts) + fractions = [count / total for count in counts] + + ax.bar(num_tokens_values, fractions, color="tab:green") + ax.set_title(f"vocab_size={vocab_size}", fontsize=10) + ax.set_xlabel("num_tokens") + ax.set_ylabel("fraction") + + for idx in range(len(vocab_sizes), nrows * ncols): + axes[idx // ncols][idx % ncols].axis("off") + + fig.suptitle(f"Token count distribution per sequence ({split_name} split)") + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + +def save_diagnostic_plots(results: dict, output_dir: Path, args: argparse.Namespace, logger: logging.Logger) -> None: # needs at least 2 vocab_size points to draw a meaningful line vocab_sizes = sorted(int(vs) for vs in results["per_vocab_size"].keys()) if len(vocab_sizes) < 2: @@ -476,13 +605,34 @@ def save_diagnostic_plots(results: dict, output_dir: Path, alarm_threshold: floa per_vocab_size = results["per_vocab_size"] - train_plot_path = output_dir / "train_memorization_vs_vocab_size.png" - plot_train_memorization(vocab_sizes, per_vocab_size, alarm_threshold, train_plot_path) - logger.info("saved plot path=%s", train_plot_path) + plots = [ + ("train_memorization_vs_vocab_size.png", + lambda path: plot_train_memorization(vocab_sizes, per_vocab_size, args.high_1_token_threshold, path)), + ("val_test_compression_vs_vocab_size.png", + lambda path: plot_val_test_compression(vocab_sizes, per_vocab_size, path)), + ("unk_token_fraction_vs_vocab_size.png", + lambda path: plot_metric_vs_vocab_size( + vocab_sizes, per_vocab_size, "unk_token_fraction", "unk_token_fraction", + "UNK token fraction vs vocab_size", path, + hline=args.high_unk_threshold, hline_label=f"alarm threshold ({args.high_unk_threshold:.2%})", + )), + ("compression_ratio_vs_vocab_size.png", + lambda path: plot_metric_vs_vocab_size( + vocab_sizes, per_vocab_size, "compression_ratio", "compression_ratio (tokens / amino acid)", + "Compression ratio vs vocab_size", path, + )), + ("fraction_short_sequences_vs_vocab_size.png", + lambda path: plot_fraction_short_sequences(vocab_sizes, per_vocab_size, path)), + ("vocab_size_actual_vs_requested.png", + lambda path: plot_vocab_size_actual_vs_requested(vocab_sizes, per_vocab_size, path)), + ("token_count_histogram_train.png", + lambda path: plot_token_count_histogram_grid(vocab_sizes, per_vocab_size, "train", path)), + ] - valtest_plot_path = output_dir / "val_test_compression_vs_vocab_size.png" - plot_val_test_compression(vocab_sizes, per_vocab_size, valtest_plot_path) - logger.info("saved plot path=%s", valtest_plot_path) + for filename, plot_fn in plots: + plot_path = output_dir / filename + plot_fn(plot_path) + logger.info("saved plot path=%s", plot_path) def main() -> None: @@ -499,20 +649,45 @@ def main() -> None: } tokenizers_dir = Path(args.tokenizers_dir) - results = {"per_vocab_size": {}, "examples": [], "max_len_used_for_padding_stats": args.max_len} + + if args.training_summary_path: + # single source of truth: whatever train_wordpiece_tokenizers.py actually trained, + # not a hand-maintained CLI list that can silently drift from it + summary_path = Path(args.training_summary_path) + training_summary = json.loads(summary_path.read_text(encoding="utf-8")) + vocab_sizes_to_process = sorted(int(vs) for vs in training_summary.keys()) + logger.info( + "vocab_size grid loaded from training summary path=%s sizes=%s", + summary_path, vocab_sizes_to_process, + ) + else: + vocab_sizes_to_process = args.vocab_sizes + + results = { + "per_vocab_size": {}, + "examples": [], + "vocab_sizes_requested": list(vocab_sizes_to_process), + "vocab_sizes_skipped_missing_tokenizer": [], + } example_tokenizers = {} - for vocab_size in args.vocab_sizes: + for vocab_size in vocab_sizes_to_process: tokenizer_path = tokenizers_dir / f"wordpiece_vocab_{vocab_size}" / "tokenizer.json" if not tokenizer_path.exists(): + if not args.allow_missing_tokenizers: + raise FileNotFoundError( + f"Tokenizer file not found: {tokenizer_path}. This vocab_size was requested " + f"(either via --vocab-sizes or {args.training_summary_path!r}) but no matching " + "tokenizer was trained. Pass --allow-missing-tokenizers to skip instead of failing." + ) logger.warning("tokenizer file not found, skipping: %s", tokenizer_path) + results["vocab_sizes_skipped_missing_tokenizer"].append(vocab_size) continue logger.info("computing stats for vocab_size=%d", vocab_size) tokenizer = Tokenizer.from_file(str(tokenizer_path)) vocab = tokenizer.get_vocab() unk_id = vocab["[UNK]"] - pad_id = vocab["[PAD]"] actual_vocab_size = tokenizer.get_vocab_size() split_results = {} @@ -520,16 +695,15 @@ def main() -> None: for split_name in SPLIT_NAMES: seqs = split_seqs[split_name] stats, encodings = compute_split_stats( - tokenizer, seqs, unk_id, pad_id, args.max_len, mean_char_length_by_split[split_name], + tokenizer, seqs, unk_id, mean_char_length_by_split[split_name], ) split_results[split_name] = stats if split_name == "train": train_encodings = encodings logger.info( - "vocab_size=%d split=%s mean_num_tokens=%.2f unk_token_fraction=%.6f " - "pad_token_fraction=%.4f fraction_1_token=%.4f", + "vocab_size=%d split=%s mean_num_tokens=%.2f unk_token_fraction=%.6f fraction_1_token=%.4f", vocab_size, split_name, stats["mean_num_tokens"], stats["unk_token_fraction"], - stats["pad_token_fraction"], stats["fraction_encoded_as_1_token"], + stats["fraction_encoded_as_1_token"], ) top_token_reports = compute_top_token_reports(tokenizer, train_encodings, args.top_n) @@ -571,7 +745,7 @@ def main() -> None: elif not MATPLOTLIB_AVAILABLE: logger.warning("matplotlib not installed, skipping diagnostic plots (pip install matplotlib)") else: - save_diagnostic_plots(results, output_path.parent, args.high_1_token_threshold, logger) + save_diagnostic_plots(results, output_path.parent, args, logger) print_colored_summary(results) From 6709f8720ac741e0d9d594d42c00321358b8aecd Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 22 Jul 2026 12:40:32 +0300 Subject: [PATCH 09/70] add convert_pool_to_airr.py: adapt Zenodo pool file to AIRR schema Converts human.trb.aa.txt (VDJtools pool format) to the junction_aa/v_call/ j_call/locus schema expected by prepare_wordpiece_corpus.py. Dedupes by cdr3aa, filters VALID_AA/max_len, subsamples to --target-size AFTER dedup (pool file is sorted by descending count, so sampling raw rows would bias toward frequent clonotypes). --- scripts/convert_pool_to_airr.py | 125 ++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 scripts/convert_pool_to_airr.py diff --git a/scripts/convert_pool_to_airr.py b/scripts/convert_pool_to_airr.py new file mode 100644 index 0000000..41b2bb4 --- /dev/null +++ b/scripts/convert_pool_to_airr.py @@ -0,0 +1,125 @@ +"""Convert a VDJtools pool file (e.g. human.trb.aa.txt) to a minimal AIRR TSV. + +Input columns (tab-separated, header present): count, freq, cdr3nt, cdr3aa, v, d, j, +VEnd, DStart, DEnd, JStart, incidence, convergence, occurrences. + +Output columns: junction_aa, v_call, j_call, locus (only what read_airr_table / +prepare_wordpiece_corpus.py actually need). locus is written as the exact string +"beta" to match --locus beta used everywhere downstream (load_filtered_sequences +does an exact df["locus"] == locus comparison, no LOCUS_ALIASES normalization). + +Processing order: dedup by cdr3aa (file has many cdr3nt variants collapsing to the +same cdr3aa) -> filter VALID_AA/max_len -> random subsample to --target-size. +Subsampling is done AFTER dedup, over unique sequences, since the pool file is +sorted by descending count - sampling raw rows would bias toward frequent clones. +""" +import argparse +import logging +from pathlib import Path + +import numpy as np +import pandas as pd + +from irrm_codec.tokenization import VALID_AA +from irrm_codec.utils import setup_logging + +# must match --locus beta exactly (no LOCUS_ALIASES normalization downstream) +OUTPUT_LOCUS_VALUE = "beta" +INPUT_COLUMNS = ["cdr3aa", "v", "j"] + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Convert VDJtools pool file to minimal AIRR TSV.") + parser.add_argument("--pool-path", required=True) + parser.add_argument("--output-path", default="data/processed/trb_1M.tsv") + parser.add_argument("--target-size", type=int, default=1_000_000) + parser.add_argument("--max-len", type=int, default=40) # matches gap_pad_cdr3's target_len default + parser.add_argument("--seed", type=int, default=42) # matches split_indices() default elsewhere + parser.add_argument("--chunksize", type=int, default=1_000_000) + return parser.parse_args() + + +def is_valid_sequence(seq: str, max_len: int) -> bool: + if not seq or len(seq) > max_len: + return False + return all(char in VALID_AA for char in seq) + + +def collect_unique_sequences( + pool_path: str, chunksize: int, max_len: int, logger: logging.Logger +) -> dict[str, tuple[str, str]]: + unique_seqs: dict[str, tuple[str, str]] = {} + rows_scanned = 0 + rows_invalid = 0 + + reader = pd.read_csv(pool_path, sep="\t", usecols=INPUT_COLUMNS, dtype=str, chunksize=chunksize) + for chunk_idx, chunk in enumerate(reader): + rows_scanned += len(chunk) + for cdr3aa, v_gene, j_gene in zip(chunk["cdr3aa"], chunk["v"], chunk["j"]): + if not is_valid_sequence(cdr3aa, max_len): + rows_invalid += 1 + continue + # v_call/j_call are never read downstream; first-seen is fine, just needs to be deterministic + unique_seqs.setdefault(cdr3aa, (v_gene, j_gene)) + + logger.info( + "chunk=%d rows_scanned=%d unique_so_far=%d rows_invalid_so_far=%d", + chunk_idx, rows_scanned, len(unique_seqs), rows_invalid, + ) + + logger.info( + "collection done rows_scanned=%d rows_invalid=%d unique_sequences=%d", + rows_scanned, rows_invalid, len(unique_seqs), + ) + return unique_seqs + + +def subsample_sequences( + unique_seqs: dict[str, tuple[str, str]], target_size: int, seed: int, logger: logging.Logger +) -> list[str]: + all_seqs = list(unique_seqs.keys()) + if len(all_seqs) <= target_size: + logger.warning( + "unique_sequences=%d <= target_size=%d, using all unique sequences without subsampling", + len(all_seqs), target_size, + ) + return all_seqs + + # sampling over deduplicated set, not raw rows: file is sorted by descending count, + # so sampling raw rows would over-represent frequent/public clonotypes + rng = np.random.default_rng(seed) + sampled_idx = rng.choice(len(all_seqs), size=target_size, replace=False) + return [all_seqs[i] for i in sampled_idx] + + +def write_airr_tsv( + sampled_seqs: list[str], unique_seqs: dict[str, tuple[str, str]], output_path: Path +) -> None: + output_path.parent.mkdir(parents=True, exist_ok=True) + rows = [ + {"junction_aa": seq, "v_call": unique_seqs[seq][0], "j_call": unique_seqs[seq][1], "locus": OUTPUT_LOCUS_VALUE} + for seq in sampled_seqs + ] + pd.DataFrame(rows).to_csv(output_path, sep="\t", index=False) + + +def main() -> None: + args = parse_args() + output_path = Path(args.output_path) + logger = setup_logging(output_path.parent / "convert_pool_to_airr.log") + + unique_seqs = collect_unique_sequences(args.pool_path, args.chunksize, args.max_len, logger) + if not unique_seqs: + raise ValueError("No valid sequences found after VALID_AA/max_len filtering.") + + sampled_seqs = subsample_sequences(unique_seqs, args.target_size, args.seed, logger) + write_airr_tsv(sampled_seqs, unique_seqs, output_path) + + logger.info( + "wrote AIRR TSV path=%s rows=%d locus=%s", + output_path, len(sampled_seqs), OUTPUT_LOCUS_VALUE, + ) + + +if __name__ == "__main__": + main() \ No newline at end of file From 70aac1bc55c0af4416b4cf762848951f9113013f Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 22 Jul 2026 13:01:59 +0300 Subject: [PATCH 10/70] calc_tokenization_stats: add compact top_tokens_summary.txt Adds --top-k-summary (default 10) and a human-readable top_tokens_summary.txt alongside tokenization_stats_summary.txt, showing top-K by frequency/longest/ non-single-amino-acid per vocab_size. Full top-n (default 50) remains in tokenization_stats.json only - this file is a compact slice, not a replacement. --- scripts/calc_tokenization_stats.py | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/scripts/calc_tokenization_stats.py b/scripts/calc_tokenization_stats.py index a095d29..fc87f42 100644 --- a/scripts/calc_tokenization_stats.py +++ b/scripts/calc_tokenization_stats.py @@ -65,6 +65,10 @@ def parse_args() -> argparse.Namespace: ) parser.add_argument("--output-path", default="artifacts/tokenizers/tokenization_stats.json") parser.add_argument("--top-n", type=int, default=50) + parser.add_argument( + "--top-k-summary", type=int, default=10, + help="How many entries per top-token list to show in top_tokens_summary.txt (full top-n stays in the JSON).", + ) parser.add_argument("--num-examples", type=int, default=20) parser.add_argument("--high-1-token-threshold", type=float, default=0.2) parser.add_argument("--high-unk-threshold", type=float, default=0.001) @@ -464,6 +468,35 @@ def save_plain_summary(results: dict, path: Path) -> None: path.write_text("\n".join(lines), encoding="utf-8") +def build_top_tokens_summary_lines(results: dict, top_k: int) -> list[str]: + # compact, human-readable slice of the full top-n lists stored in the JSON - + # full top_n (default 50) stays in tokenization_stats.json only + lines = [f"=== Top tokens (train split, top {top_k} of each list) ==="] + + for vocab_size, entry in sorted(results["per_vocab_size"].items(), key=lambda kv: int(kv[0])): + lines.append("") + lines.append(f"--- vocab_size={vocab_size} (actual={entry['vocab_size_actual']}) ---") + + lines.append(f"top {top_k} by frequency:") + for item in entry["top_tokens_by_frequency_train"][:top_k]: + lines.append(f" {item['token']!r:<12} count={item['count']}") + + lines.append(f"top {top_k} longest tokens:") + for item in entry["top_longest_tokens"][:top_k]: + lines.append(f" {item['token']!r:<12} aa_length={item['aa_length']} count={item['count']}") + + lines.append(f"top {top_k} non-single-amino-acid tokens:") + for item in entry["top_non_single_amino_acid_tokens"][:top_k]: + lines.append(f" {item['token']!r:<12} aa_length={item['aa_length']} count={item['count']}") + + return lines + + +def save_top_tokens_summary(results: dict, path: Path, top_k: int) -> None: + lines = build_top_tokens_summary_lines(results, top_k) + path.write_text("\n".join(lines), encoding="utf-8") + + def plot_train_memorization(vocab_sizes: list[int], per_vocab_size: dict, alarm_threshold: float, output_path: Path) -> None: train_frac_1_token = [per_vocab_size[str(vs)]["splits"]["train"]["fraction_encoded_as_1_token"] for vs in vocab_sizes] @@ -740,6 +773,10 @@ def main() -> None: save_plain_summary(results, summary_path) logger.info("wrote plain-text summary path=%s", summary_path) + top_tokens_summary_path = output_path.parent / "top_tokens_summary.txt" + save_top_tokens_summary(results, top_tokens_summary_path, args.top_k_summary) + logger.info("wrote top tokens summary path=%s", top_tokens_summary_path) + if args.skip_plots: logger.info("--skip-plots set, not generating diagnostic plots") elif not MATPLOTLIB_AVAILABLE: From 78a6460249bd7c6d91d712102c1541593735d250 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 22 Jul 2026 13:43:09 +0300 Subject: [PATCH 11/70] add tokenizer_stats_report.ipynb: unified visual report for tokenization_stats.json Parameterized (STATS_JSON_PATH cell, papermill-compatible) so it can be re-run against any experiment's stats without editing the notebook body. Recomputes all 6 diagnostic plots directly from the JSON rather than depending on the PNG files the script may or may not have generated. --- notebooks/tokenizer_stats_report.ipynb | 1540 ++++++++++++++++++++++++ 1 file changed, 1540 insertions(+) create mode 100644 notebooks/tokenizer_stats_report.ipynb diff --git a/notebooks/tokenizer_stats_report.ipynb b/notebooks/tokenizer_stats_report.ipynb new file mode 100644 index 0000000..782842c --- /dev/null +++ b/notebooks/tokenizer_stats_report.ipynb @@ -0,0 +1,1540 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ec2f9f90", + "metadata": {}, + "source": [ + "# WordPiece Tokenizer Statistics Report\n", + "\n", + "Reads `tokenization_stats.json` produced by `scripts/calc_tokenization_stats.py` and renders all statistics: split-level metrics, alarms, top-token lists, and every diagnostic distribution across the vocab_size grid.\n", + "\n", + "Reusable across experiments - only the `STATS_JSON_PATH` in the next cell needs to change." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "980d96f5", + "metadata": { + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "# parameters\n", + "STATS_JSON_PATH = \"../artifacts/tokenizers_1M/stats/tokenization_stats.json\"\n", + "TOP_K_DISPLAY = 15 # how many entries to show per top-token list in this notebook" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "da5d5624", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded ..\\artifacts\\tokenizers_1M\\stats\\tokenization_stats.json\n", + "vocab_size grid: [100, 1000, 10000, 50000, 100000, 200000, 300000]\n" + ] + } + ], + "source": [ + "import json\n", + "from pathlib import Path\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "\n", + "pd.set_option(\"display.max_colwidth\", 200)\n", + "\n", + "stats_path = Path(STATS_JSON_PATH)\n", + "results = json.loads(stats_path.read_text(encoding=\"utf-8\"))\n", + "\n", + "vocab_sizes = sorted(int(vs) for vs in results[\"per_vocab_size\"].keys())\n", + "per_vocab_size = results[\"per_vocab_size\"]\n", + "split_names = (\"train\", \"val\", \"test\")\n", + "split_colors = {\"train\": \"tab:red\", \"val\": \"tab:blue\", \"test\": \"tab:orange\"}\n", + "\n", + "print(f\"Loaded {stats_path}\")\n", + "print(f\"vocab_size grid: {vocab_sizes}\")\n", + "if results.get(\"vocab_sizes_skipped_missing_tokenizer\"):\n", + " print(f\"WARNING - skipped (tokenizer.json missing): {results['vocab_sizes_skipped_missing_tokenizer']}\")" + ] + }, + { + "cell_type": "markdown", + "id": "0717ccf1", + "metadata": {}, + "source": [ + "## 1. Split-level summary table" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "37bdd010", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 vocab_sizevocab_size_actualsplitmean_num_tokensmedian_num_tokensmin_num_tokensmax_num_tokensp95_num_tokenscompression_ratiounk_token_fractionfraction_1_tokenfraction_le_3_tokens
0100100train7.257.022010.00.4860.0000%0.00%0.05%
1100100val7.257.032010.00.4860.0000%0.00%0.04%
2100100test7.257.021910.00.4860.0000%0.00%0.04%
310001000train4.144.02126.00.2780.0000%0.00%22.84%
410001000val4.144.02116.00.2770.0000%0.00%22.98%
510001000test4.144.02136.00.2780.0000%0.00%22.82%
61000010000train3.063.02114.00.2050.0000%0.00%76.44%
71000010000val3.073.0294.00.2060.0000%0.00%76.13%
81000010000test3.073.0294.00.2060.0000%0.00%75.94%
95000050000train2.532.01104.00.1700.0000%0.00%91.44%
105000050000val2.572.0284.00.1720.0000%0.00%90.73%
115000050000test2.572.0184.00.1720.0000%0.00%90.66%
12100000100000train2.382.0184.00.1590.0000%0.00%94.92%
13100000100000val2.442.0284.00.1630.0000%0.00%93.75%
14100000100000test2.442.0184.00.1640.0000%0.00%93.73%
15200000200000train2.242.0183.00.1500.0000%1.52%97.24%
16200000200000val2.372.0283.00.1590.0000%0.00%95.39%
17200000200000test2.372.0183.00.1590.0000%0.00%95.37%
18300000300000train2.142.0183.00.1440.0000%6.90%97.94%
19300000300000val2.352.0283.00.1580.0000%0.00%95.64%
20300000300000test2.352.0183.00.1580.0000%0.00%95.58%
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rows = []\n", + "for vocab_size in vocab_sizes:\n", + " entry = per_vocab_size[str(vocab_size)]\n", + " for split_name in split_names:\n", + " s = entry[\"splits\"][split_name]\n", + " rows.append({\n", + " \"vocab_size\": vocab_size,\n", + " \"vocab_size_actual\": entry[\"vocab_size_actual\"],\n", + " \"split\": split_name,\n", + " \"mean_num_tokens\": s[\"mean_num_tokens\"],\n", + " \"median_num_tokens\": s[\"median_num_tokens\"],\n", + " \"min_num_tokens\": s[\"min_num_tokens\"],\n", + " \"max_num_tokens\": s[\"max_num_tokens\"],\n", + " \"p95_num_tokens\": s[\"p95_num_tokens\"],\n", + " \"compression_ratio\": s[\"compression_ratio\"],\n", + " \"unk_token_fraction\": s[\"unk_token_fraction\"],\n", + " \"fraction_1_token\": s[\"fraction_encoded_as_1_token\"],\n", + " \"fraction_le_3_tokens\": s[\"fraction_encoded_as_3_tokens_or_less\"],\n", + " })\n", + "\n", + "summary_df = pd.DataFrame(rows)\n", + "\n", + "\n", + "def highlight_train_alarms(row):\n", + " if row[\"split\"] != \"train\":\n", + " return [\"\"] * len(row)\n", + " alarms = per_vocab_size[str(row[\"vocab_size\"])][\"alarms\"]\n", + " any_triggered = any(a[\"triggered\"] for a in alarms.values())\n", + " return [\"background-color: #ffcccc\" if any_triggered else \"\"] * len(row)\n", + "\n", + "\n", + "summary_df.style.apply(highlight_train_alarms, axis=1).format(\n", + " {\n", + " \"mean_num_tokens\": \"{:.2f}\", \"median_num_tokens\": \"{:.1f}\", \"p95_num_tokens\": \"{:.1f}\",\n", + " \"compression_ratio\": \"{:.3f}\", \"unk_token_fraction\": \"{:.4%}\",\n", + " \"fraction_1_token\": \"{:.2%}\", \"fraction_le_3_tokens\": \"{:.2%}\",\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "fcb5e42e", + "metadata": {}, + "source": [ + "Highlighted train rows have at least one triggered alarm (vocab_size_too_large / tokenizer_misconfigured / insufficient_compression_benefit) - see section 3." + ] + }, + { + "cell_type": "markdown", + "id": "ca8e2264", + "metadata": {}, + "source": [ + "## 2. Diagnostic plots" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "b3873ad3", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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1atNrYW/E+IBAAAAiCx+NYUqX768mQUQAAAAAPwOLAYPHiyPPPKInDp1irMIAAAAwL+mUO+8845pCjVz5kypUKGCREVFub2/detWTi0AAACQg/gVWDz00EPBPxIAAAAAOSuwuPvuu4N/JAAAAABy5szbR48elbVr1wbvaAAAAADknMBCA4pu3bpJ0aJFpXHjxs7lN998s6xatSqYxwcAAAAgUgOLRx99VI4dOyabNm1yWz5o0CB55plngnVsAAAAACK5j8W8efNkxYoVUqVKFbfll112manJAAAAAJCz+FVjER8fLyVKlDDPXYeaPXnyZKqhZwEAAABEPr8CiyZNmphaC+UaSLz88svSokWL4B0dAAAAgMhtCvXCCy9Ix44d5ccffxSHwyGjR4+WxYsXy2+//Sbfffdd8I8SAAAAQOTVWLRu3doEEIcPH5Zq1arJ1KlTpVy5cvLTTz9RYwEAAADkQH7VWCxfvlyuuOIKmTlzZqr3JkyYIAMHDgzGsQEAAACI5BqLzp07y/r161Mtf//99+X+++8PxnEBAAAAiPTA4sknn5QOHTrItm3bnMvGjx8vw4YNkzlz5gTz+AAAAABEalOo4cOHy8GDB6V9+/amX4WOEDVixAiZO3euXHvttcE/SgAAAACRF1io559/3gQXzZs3N/NaaHChgQYAAACAnMfnwGL69OmplrVq1UoWLFggt956q+zbt8+ZplevXsE9SgAAAACREVg8+OCDab63cOFC87AQWAAAAAA5i8+Bxd69e7P2SAAAAADkrFGhAAAAACAonbcTEhJkxowZsmXLFnE4HFK3bl254447JH/+/P5uEgAAAEBOqrHYvHmz1KpVy/S7WLVqlaxevdo812X6HgAAAICcxa/AQmfXbtOmjezatUuWL18uP/74o3neunVrZt4GAAAAciC/mkLppHg7duyQggULOpfp87Fjx0q1atWCeXwAAAAAIrXGIk+ePHLs2LFUy48ePSp58+bN1La++uor6dChgzRs2FB69+4t27dvTze99udYtGiRdO3aVerUqSO//PJLqjQ7d+6Uhx56yMyzobUojz/+uBw5csQtzdNPP23Wd3107tw5U8cOAAAAIIDAolOnTiYIWLdunSno62Pt2rVm/oqOHTv6vB2dXE8DBJ2xe9y4cXLq1Cm58sor5fDhw2mu88gjj8hrr71mgpE/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ljN//y3xSckSU6KEKTzENm3idwHCbHPNr5J04IAZrSWQbcE9n85u2yYJ1atLgWbNOKc5NK9STp82Q7N6jqxkAgetdUhISHf9qLx5z9UweIysZJosaSdpj2pyAPaihUa9K231FdAg4MUXXzQFzEDWee2110w7fy2s16pVSxo0aGACC22udPHFF5u74fq/rquF9DZt2pg74Frw/PHHH02h9vXXX/e6/2XLlpnCvQYGhw8fNv0RrMBi6tSp8vjjj5u77r/++qu5Q6/prUK27l/3p3f0NaC46aabzP/a3GvkyJHSrFkzc9NF1x0/frzpN6F+//13adu2rQlEdDI3fa2F5cGDBzuPS9Pq5ypTpox8++23Mnr0aHnkkUec7+tx6WfSgGLXrl2mMP/VV1+ZwCwt999/v0ycONEEX1p21HOZntOnT5uaAde80P250sCpY8eOJkBwreXQc6n7s4wYMcKcTw22rrrqKvn777/N+VIapOhrpWVZ/ayab95o0ysNsrRvSMQGFhptaybdeOONJprVQv5HH30ky5cvT7PDjC/rBCtNODq2ZInse2GMJOldTBFxLY5Ely0rZR4bKYWvvTagbQayLXg/pyc5pxGdV46UFBOUu8/pcKEGIimjeReioszNgQszSV+Yz0EfZmhWRrkBApqNOy16l17v3PuSVr+HMTExGabNbDlC7zC73mXWmgYtQOudaS0QBrKOlnf07rxnYVL7a2hwop9d39dCqn4erQXR4//uu+/M9rTgroV4TxrETJ8+Xe655x7Tl8CVFo71Dr8OYapzI1x00UWmP4ZVIFa7d+82aQoVKmReay2EBgA///yz1KtXzyzTAr9+Rr2zX6pUKXPHX4OfmTNnmvf1eL/++mu3fWvwpPtSWq7r37+/aQakN471HI0ZM0Z++OEHUwbUeXE0ENFARwvu3n5ntaA+btw4c3waDOlwrBqcpWfz5s0muNDAKj0afFifVen50IBIP6vlkksuMdeoBlEaWJQoUcL08bA6ZetrpZ/xgQceMLUwGqBUr17d1Ni40pvoq1evlqwU0sBCL9aWLVuaqhylF0+VKlVk2rRpJpP9XSdYacKxABR3/7A0x47XgpF5/43XfS4QpbVNHUkms9sC59RuMnP9J584KYlx50dUco6spP+fCx4c6RRGlNYquHWQdu3vUKG85MqbN0s/K5CTaWEyLVr4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0kSShIQE8xmtvNFrU39ntHB68OBBZ7phw4Y5qlatam5mqY8//tgRFRVlvofhmibSaMC9c+dO5+spU6Y4cuXK5fjtt9+cy7QMoIFxet577z1HoUKFHL///rt5vWrVKkeePHkcM2fODEmaSKM3IpYvX+58vW/fPvN3+4EHHnAu++6778z1unjxYvP633//NcH96NGjwzaNvwgsbET/0OmPyieffOJcpn8M9Uv82muvhfTYIimwuPHGGx2//vqrY+vWrebunict2OodP1f16tUz64YiTU6SVmChhVktyP7xxx/OZfqHTZctW7YsLNNEsowCiwcffNDxyy+/OHbt2pXq/bi4OPMHb+7cuc5lJ06cMHfU3n333WxPkxP8888/Jr+WLl1qXuvvnt4d10DRlQbG999/f1imySn02hw3bpxbYKG1uVobqnfOz549m2qd5s2bO+666y63ZXpHXe+yhyJNTnDttdeam0mWPn36mNYmrvR3UGukwjWNv3JGg98IoW2Ttc12kyZNnMu0f0X9+vVl7dq1IT22SLJ48WK56667TBvVKlWqyIIFC5zv7d6927Qddc0DpW3+rTzIzjQ4R8+H9oXRdtcWbSsfGxvrPFfhliYne+edd2TgwIGmj1jjxo3Nb5tl3bp1pl2563Wv5/Liiy92nrvsTJMTrF692vyvbfiVttk/fPhwqt+eZs2aOc9LuKXJCX7//XfTx6xGjRqp+p7dfvvt0q5dOylTpoxMmzbN+Z5e3+vXr0/370h2polky5cvl6VLl8ro0aPNb8sDDzzgfE8/v7fzon0y9NoOxzT+IrCwkfj4ePN/iRIl3Jbra+s9BKZDhw4SFxdnCjraibtnz57SvXt306nb1zzIzjQ4R8+H53nydj7DKU1O9X//939y8OBB84dXv2va0bFr166SkJBg3uc7lr20k/2wYcOkT58+5kZKOOYBv4ViAoq+ffuaG14aQFg0MNfOtzpIhHbkfuaZZ6Rfv37y008/mfd1QALt+J3e+c3ONJHs0UcflYceekj+97//SY8ePczNJIu3vwnW6/T+boQyjb8ILGwkJibG/H/69OlUPzg6sgcCd9NNN5kRaqyRNcaMGWPO+/z5833Og+xMA3GeK8/z5O18hlOanKp3796SP39+87xgwYIyduxY2bFjh6xatcos4zuWfbQAoTdTLrroInn33Xedy8MtD3L6b+HZs2elW7duZgSfzz77zG10uWuvvdaMvGS57777TI3brFmzzGvyKXtrLH777TdzI1JbPtx7773O97z9TdDrV6X3dyOUafxFYGEj1t0kvcvnSl9Xrlw5REcV2TS40CjeOud6d1V/1NPLg+xMgwvfDR3qz/WHUn8ktUrXOlfhlgbnaNMN67q2zp3ra2/XfXamiVR6Leqdbx2yVZt7ajM9S7jlQU7OJyuo0KGBly1bJuXKlfPpO2WdKx2e1vW1t3OXnWlygrJly5obKAsXLnQu02vY23nRAr6mD8c0/iKwsBHtS6FfWuvuufrrr79ky5Yt0r59+5AeWyTQ9qFWxO46X4i2OaxXr555rX98L7/8crc80Orfb775xpkH2ZkG57Rt29bkn2t/mC+//NIsu+aaa8IyTU6k3y/tJ+ZqyZIl5n/rO6btfosXL+523Wsbcq3VsK777EwTyUGF/sYsWrTI1By5Klq0qDRt2tTtvBw9elS+++4753kJtzSRKDEx0TTF3bx5s/ms3uYZ0L8JrvSGht41t75PSs/RF1984TaHif4euZ677EwTaTzzQGnzNNemRvr59bdOm4pZ5s2bJ23atHHWKoVbGr8F3P0b2UrHsNah21599VXH7NmzHfXr1zfjxuuQgQiMjt+s4zmPHTvWjOn+/vvvm+ENmzVr5jh9+rTbMG0xMTFmiEadQ6Rdu3ZmnPHjx4+HJE1OoCMq/fjjj47/+7//cxQvXtw814cOnWkZMmSIGS5v2rRp5lGqVCnH0KFD3bYTbmkizfbt202+vPTSS2aUoYULF5rXhw4dMu+vX7/ejBqjQ1LqMIf/+9//zJw8nnPF6Kg3Or76G2+84Zg1a5b5XuooK6FKE0l0JEH9TdO5Vaz8sR779+93pluyZIkjOjra8eSTT5pRs/TvjM6l4PqdC7c0kaZ79+6OAgUKmKF1XfNJhwa16Mg+OnzzV1995fjwww8dl156qZmPxXW4ZB2dTkeP7N+/v2P+/PlmtCKdr+W///4LSZpIo0PUW3+jv/jiC/Pbnzt3brchduPj4818MTfccIM5LyNGjDBluRUrVoRtGn9F6T+BhSbIbnPnzpUPPvjAzLzdqlUr01lIRzJB4LTD9ltvvWVGTChWrJhceeWVMmDAgFQRvHaMGzdunBm1SWuStNOWZ/VhdqaJdA8++KCsXLky1fIZM2Y4q9j1Tvh7771n7o6pjh07yt133+3WHjnc0kSaN99809m225X2VdLvkjWyjZ4XrW0tX768dO7cWW6++eZU63z66afy0UcfmU7dV111lYwYMcKtuU52p4kUOmu19iXz5qmnnjJt9i3ff/+96Xuh6zRs2ND89njOKBxuaSKJ5oU1qIGrO++804yqprTfhf59WLFihem7pCNl6QAJnmUC7dyt/Zm0Bl5H/3r44YdTjS6VnWkiid71nzBhgmmqdubMGfNZNX9cO29bTY1eeuklc360SduQIUPksssuC+s0/iCwAAAAABCwyL11BgAAACDbEFgAAAAACBiBBQAAAICAEVgAAAAACBiBBQAAAICAEVgAAAAACBiBBQAAAICAEVgAAMLa33//LQsWLMiSbe/YsUPmz5+fJdsGgJyGwAIAENYWL15sZsPOCjqb87333psl2waAnIbAAgCQY1WrVk26dOkS6sMAgIgQHeoDAACEn/j4eFmyZIl07txZYmNjncsPHTokX3/9tXTq1EkKFChglm3YsEG2bt0q5cqVk8suu0xy5Up9z2rnzp2ydu1aKVOmjDRt2lRy585tlu/du1e+++478zx//vxSu3ZtqVOnjtdjSkxMlPXr10tcXJzZT9myZX3+PHrcv/76q0RHR5v9Fy5c2CyvXLmydOjQwZluzpw5cubMmVTr33LLLRITE2Oe//vvv7Ju3TopUaKENG7c2O38AEBORmABAEhFg4Z77rlHkpKSpFevXs7lkydPlnHjxsltt91m3rv11ltNYNCiRQsTYGhhf+HChVKqVCmT3uFwyP333y8TJ040wcDp06dN4f6rr74yhft9+/bJ3LlzTdqTJ0/KTz/9JNdff71Mnz5doqKinPs9cuSI2YcGHykpKaZg/8knn5jAJyO6/T59+kiTJk0kT548sm3bNhk/fry0bdvWNIV64oknnNvRYz927Jhz3d9//102bdokR48eNcc9bNgwc2x6LAcPHpQ9e/bIZ599Js2aNeMqAgAHAABe9O/f33Hddde5LWvQoIFj5MiR5vnbb7/tKF68uOPff/81r48dO+a49NJLHQMHDnSmHzdunCM2Ntaxfv1657Kff/7ZsX//fq/n/MCBA45y5co5Zs+e7Vz21ltvOTRGefnll53LRo0a5ShbtqwjISEhw7xr2rSp44UXXnC+PnTokOO7774zz6dMmeKoUKGC1/V27NjhKFmypOPhhx82r99//31H9erVHQcPHnSmee655xx16tTJ8BgAICegjwUAwCutqdBmT/v37zev9c69NkWyajC0xkCfa3MiVahQIRk6dKjMnDnTuY1p06aZ2oJLL73Uuaxly5bOGg2ridPKlSvl888/l2+++UYqVaokv/zyi9ux5M2bV4YMGeJ8/eCDD5rj+uGHHzLMPa3l+Ouvv0xtiSpevLi0bt063XW09kT7XmhNxJgxY8yyKVOmmM+xbNky+fTTT2XWrFlSsGBB+eOPP0zNBQDkdDSFAgB4pYXv8uXLm0BBC/UfffSRNGrUSOrWrevsa9CtWze3dapXr26aEh0+fFiKFSsm//33n/To0SPNM7xx40a54YYbnP0rtAmWNo+yghmL9t/Q4MKiBXoNTvQYMvLWW2/JwIEDTfrLL7/cNHsaMGCA2/ZcafOtu+66y/S1+Pjjj519Rv755x85e/aszJ492y29NgvT5QCQ0xFYAAC80j4OPXv2NAHFfffdJzNmzDA1EpaSJUuaTt6u9LV2crY6RxctWtR0nE7L448/Ltdcc42p2bBcd911pnDvSvtYuNL3dZkeQ0YaNGhgakC0VmHp0qUyevRo05dDP483zz33nKk5WbVqlRQpUsS5XD+THuv//ve/DPcJADkRTaEAAGnSpk5awNaC/65du0ygYbniiitMx2jtTG3RJkLa1Mka9enaa681NR6ud/S1mVFCQoJzVCitqbDoay30e9Igwho9SumEebpfXzpN6yhSVq2Hfh4NjrTplTfz5s2TZ555xtRU1KpVy+09DXg0yDp+/LjX7QNATkeNBQAgTfXr1zcPbQqld+u1cG7R0ZQ0kNCmTDfffLOsWLHCFMxdA4Ann3xSFi1aZIKNO++80/Rz0EK7BgY6TGvXrl1l7Nixki9fPjPqkjZb0v89aRMp7auhQYEGFC+++KJ5rv0xMqLHdskll5hRqU6dOiWvvvqqW4DkGvD07t3bNAHTQEb7kLgON/vUU0+ZGg8NZrRplR6/Bl3bt2/3qa8HAES6KO3BHeqDAACELy1ga82E9jvQu/autD+EDt2q81joULP9+vVLNQ+F3uHXYWp1iFjts6FptC+G0iBBh2/VYV+1z0PHjh1lx44dpl+DDnerdD4NnX1b96/Hsnv3blP410DFdUjatGjncK1p0MBHh5vVAEk7Zus+dL/aCVuH0NXj1IDBGz1+DSQ0MNHj1YBCgyEddlb7kHgLhgAgpyGwAAAAABAwbrEAAGxNm1p5du626ChWrn04AABZh8ACAGBr2u9h586dXt/TYWkJLAAge9AUCgAAAEDAGG4WAAAAQMAILAAAAAAEjMACAAAAQMAILAAAAAAEjMACAAAAQMAILAAAAAAEjMACAAAAQMAILAAAAAAEjMACAAAAgATq/wFO4eKa2AIcAgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_train_memorization():\n", + " values = [per_vocab_size[str(vs)][\"splits\"][\"train\"][\"fraction_encoded_as_1_token\"] for vs in vocab_sizes]\n", + " threshold = next(iter(per_vocab_size.values()))[\"alarms\"][\"vocab_size_too_large\"][\"threshold\"]\n", + " fig, ax = plt.subplots(figsize=(8, 5))\n", + " ax.plot(vocab_sizes, values, marker=\"o\", color=\"tab:red\")\n", + " ax.axhline(threshold, color=\"gray\", linestyle=\"--\", label=f\"alarm threshold ({threshold:.0%})\")\n", + " ax.set_xlabel(\"vocab_size\"); ax.set_ylabel(\"fraction_encoded_as_1_token (train)\")\n", + " ax.set_title(\"Train-set tokenizer memorization vs vocab_size\")\n", + " ax.legend(); ax.grid(alpha=0.3); fig.tight_layout(); plt.show()\n", + "\n", + "\n", + "plot_train_memorization()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f630f69b", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAdWBJREFUeJzt3QecE2X+x/Ffku0LW1i20KR3EVSaoqJiQcVyoh72eojlbKdnOT17OfUs592pp/7VU1TsBe/s5RQFEbFQlS59gWV3ga3J/F+/Zzch2b7Z7Caz83n7ikkmk8lknoSdb57msizLEgAAAABoAXdLngwAAAAABAsAAAAAEUGNBQAAAIAWI1gAAAAAaDGCBQAAAIAWI1gAAAAAaDGCBQAAAIAWI1gAAAAAaDGCBQAAAIAWI1gAaNCgQYPkhBNO4CgBUfTQQw+Jy+WSjRs3ttlrPvPMM+Y1ly1bJm3tlVdekbS0NNm6dWtE9jta76Wt9uXZZ5+V7Oxs2b59e8S2CYSDYAHUMHHiRPOPfmZmppSWltY6Pvn5+ZKQkGDWueCCC2L6+I0YMcK8HwCwi7KyMrn22mvliiuukKysLHGCxx57zPxNWbVqVVjPP+OMM8yxuv322yO+b0BzECyAOiQlJUlRUZG89dZbtR57/vnnTbAAgPbsnHPOEcuypF+/fm36ui+++KKsWbNGLr74YmmPWuO4ejwemTZtmjz66KNSUFAQse0CzUWwAOqQnp4uEyZMMFXWNT399NNy0kkncdwAoJV+vT/ssMMkLy+P49sMp556qqnt+fe//81xQ9QQLIAGflX68MMPZf369YFl8+bNk59++knOPffceo/bO++8I+PHj5eOHTtKcnKyjBs3Tj744IOQdbTPglZ760V/acrJyTFhZenSpXX2b9Dl+oc2JSVFunXrZqq79RevhmRkZMgPP/wg77//fuC1evXqFbKO/rq11157mRoabfp13HHHmec05rnnnpPExES58MILpbKy0ixbt26d/O53vzP7pzU6+lo33HCD+UNXs524rquP5ebmSmpqqhxzzDHmF8pg27Ztk0suuUR69uxpjuOAAQNM04gtW7Y0uG/+19Dt6fra7rhDhw7mva1YsaLW+s3Z719//VX++Mc/SpcuXcz9+jR135vy2uqrr74ynyPdVo8ePeT++++Xjz76yOyDXvtdffXVEhcXV2t/3nvvPbPuZ599FvZ7b0qZ+bepn4s99tjDfK6GDBki9957b8g2m/q+g7377rtmP1599dVaj/3vf/8zj+nnsjnHP9ztqx9//FGOP/546dSpk3mfw4YNk3/84x+1vpeNHQ9/2fgv+h0fOXKk+QGjLuXl5U36XDemKceoZl+AHTt2hOxrzcu3337bojL2NzWdM2eOHHroobUea+6xCkdTjktz/42pqeZxve666+Siiy4yt3v37h14f/p+m7pPSr+bQ4cOlbfffjtixwNoNgtAiCOPPNLKzc21du3aZaWnp1v33HNP4LFLLrnE6t+/v1VRUaFnD9b5558f8txHHnnEcrlc1k033WT9+uuvVn5+vnX77bdbHo/HmjlzZp1HuqyszPr++++tCRMmWL169bKKiooCjw0cONA68MADrd/85jdmncLCQuuvf/2ree0XX3yx0ZIbPny4eT91ueaaa8x+PfDAA9aWLVusJUuWWIcffriVkpJizZ8/P2Qfjj/+eHPb5/NZN954o+V2u6377rsvsM6aNWusLl26WKNHj7bmzJljFRcXW59++qm1xx57BJ6rHnzwQbPv5513nvX0009bBQUF1rfffmvWO+igg0L2b9KkSdaAAQOsefPmWSUlJdaKFSvM8f3LX/7S4Hv2v8aUKVMCr6HvZ8SIEVbXrl1NmYS736eddpr11FNPWVu3brUef/zxevehKfve1Nf+7rvvrKSkJOu4446zli1bZm3evNm65ZZbrBNOOMHs04cffhhY9w9/+IMp05r++9//mnV1+61ZZqtWrTLfHf3cff755+azvHjxYuu6664z+9Cc162psrLS6t69uzVx4sRaj5199tnmu6rf2aYe/5Zs/8cff7RSU1OtQw891Fq0aJH5PPztb3+z4uLirCuvvLJZxyOYfr82btxovlv6HXv55ZfD+lw3RVOOkb6OvuYvv/xS73b089inTx8rIyPDWr9+fYvKWL3++uvmNT/++OMG12voWNW13015L009Ls0pi6buy6OPPmqWrVy5Mqx98tO/ScnJyeZvFBANBAugnmChpk6dag0ePNjcLi0ttTp16mTdeeeddQYL/WOi/6DrSUhdfxiGDh3a4LHWkxDd5quvvhpyUp+QkGBCSrBhw4ZZhxxySNjBQv/w6wmovr9geuKTmZkZ8hx/sNA/aL/97W/NCdWbb74Z8rwz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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_metric_vs_vocab_size(metric_key, ylabel, title, hline=None, hline_label=\"\"):\n", + " fig, ax = plt.subplots(figsize=(8, 5))\n", + " for split_name in split_names:\n", + " values = [per_vocab_size[str(vs)][\"splits\"][split_name][metric_key] for vs in vocab_sizes]\n", + " ax.plot(vocab_sizes, values, marker=\"o\", label=split_name, color=split_colors[split_name])\n", + " if hline is not None:\n", + " ax.axhline(hline, color=\"gray\", linestyle=\"--\", label=hline_label)\n", + " ax.set_xlabel(\"vocab_size\"); ax.set_ylabel(ylabel); ax.set_title(title)\n", + " ax.legend(); ax.grid(alpha=0.3); fig.tight_layout(); plt.show()\n", + "\n", + "\n", + "plot_metric_vs_vocab_size(\"mean_num_tokens\", \"mean_num_tokens\", \"Mean tokens per sequence vs vocab_size (all splits)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "1903e82a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWsJJREFUeJzt3QmcTeX/wPHvMGPGNnbGvoXIGllSoSKVLRFFSqJFRX5aKPwSKZWUikRUtIiQStqFkCVkzZqdEY11hpk5/9f36Xfu/95Z78y5M3Pvnc/79brm3nOfs9zz3HM93/NsIZZlWQIAAAAADuRxsjIAAAAAEFgAAAAA8AlqLAAAAAA4RmABAAAAwDECCwAAAACOEVgAAAAAcIzAAgAAAIBjBBYAAAAAHCOwAAAAAOAYgQUA5IDLL79cunTp4jfnfsuWLXLDDTdIZGSkhISEyNy5c8UfzJw50xzPrl27cvpQcpWJEyea83706NFs2yd5DQQ+AgsAfiUqKkquueaaFN87ePCgKew88sgjrmXt27c3y5o0aSKWZSVbJyIiQnr27OmxTNcpVKhQsrQ7duyQypUrS+nSpWXt2rWpHmPDhg3NNoJJr169zPnbv3+/+dutW7ds2/eUKVNMHu7bty/b9gkA8D0CCwBBYd26dfLxxx9nev01a9aYgCZPnjyyfPlyE6jkFqdPn5aNGzdKx44dpWjRouJP7r33XhPoXHbZZTl9KMhi5DUQ+AgsAAQ8rWFo3LixPPPMMxIXF5fh9b/77ju5/vrrTW3JihUrpGbNmpKbREdHm7/58+fP6UMBAAQwAgsAAU+b0bz88sumKc2bb76ZoXU//fRT6dChg2netGzZMilXrlya6fWOvt7dX7JkidmvPqpUqeKRZvLkyVK/fn3TDKtYsWLSqVMns056PvzwQwkPD5cHHnhA4uPjzbJDhw5J//79pXz58pIvXz6zr+HDh3sEUHZ7eE2r75UpU0YKFiwot956q2nalJYHH3zQVRvw0EMPme2ULFnSY7sHDhyQJ598UsqWLWteq2+++cb1+fVRoEABU8szY8aMZPvQ49LPVKlSJXNO6tSpI+PHjzef4emnnzb7VVWrVnVtT7efVrv7TZs2SefOnaV48eJmm/Xq1ZO33nrLozmck/Py1VdfpdrX5JdffjHvaX6pkydPysCBA00zOg3ONDAdPHiwnDhxwifb9/bzpneuM5pv6uLFi+azlCpVyjQf1O/ynj17JKO8OUdJ8/rs2bMex5r04d5c0ZvrBEA2sADAj5QpU8Zq2bJliu8dOHBAS1HWwIEDXctuuukms4665ZZbrGLFilknT550vR8eHm716NHDYzu6TsGCBa1JkyZZefLksTp27GidP3/e62Ns0KCB2UZKnnjiCStv3rzWhAkTrBMnTljbt2+32rZtaxUoUMD6/fffXelq1aplde7c2TxPTEy0nn32WXMsL7/8sivN/v37rbJly1pNmza1Vq9ebZ05c8b66aefrEqVKrnWVa+99po5L/fdd581Y8YM69SpU9batWtNuuuuuy7dz7Nz506z/uTJkz2W29u96667rOnTp1t///239c477yRbX4//6NGj5tj1M8yZM8f13r59+0z+6DlbunSpdfr0aWvbtm3W008/bS1evNik0f3qfvbu3Zts2/p59D09RtumTZtM/l1//fXW1q1bzXG98cYbVmhoqPX444/75LzEx8dbFSpUsNq3b5/svXvuuccqUqSI6zvToUMHq2bNmta6deusCxcuWHv27DHfrZdeeskn2/f283pzrr3NN/vc9ezZ03Xu9PvbsGFDq1y5clZ0dLSVEd6co5TyOqnjx49b1apVs4oWLWodPnw4Q9cJgKxHYAEgaAKLzZs3m0L90KFD0w0sdDv6aNKkiSnkZURqgYUWcHT/AwYM8FiuBTwNeNzXsQMLLWTp8WnBccGCBR7r3X333VZkZKQp/Ln78ssvzbEvW7bMoxA4evRoj3RvvfWWWb5jxw5HgcWwYcMsb2lB+cYbb3S91oKpfja7EJiSjAYWnTp1MudFC7vu9HuhBeTdu3f75LzYwZ5+79zzUoPEBx980LWsUKFCJqDMKG+37+3n9eZce5tv9rl75plnPNLpOdN9Dh8+PEPb9+YcpRdYaKDVvHlzK1++fCZwyOh1AiDr0RQKQNC44oorTAfQSZMmyV9//ZVmWm2O0a5dO9Oc4tVXX/XJ/pcuXSoJCQnStWtXj+WFCxc2+/r5558lMTHRtVybgbRp08Y0wdLmL9rUxd2iRYvkuuuuM0143Gl/EG0Kovtzp0183NWtW9f8zUzTFXfa/CUp/RwTJkyQK6+80jQvcm/C5N5s6euvvzafUZtR+coPP/xgzkHSjuY6kpUe108//eST83LfffeZpkba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FECuQB8LAAAAAI4RWAAAAABwjMACAAAAgGMEFgAAAAAcI7AAAAAA4BiBBQAAAADHCCwAAAAAOEZgAQAAkI3Wrl1rZuH2d4sWLZKDBw9m+37//vtvmTt3riQmJjraTkxMjNnOxYsXU01z7tw5k+bChQtpbuvAgQOydOlSCURHjx6V77//Plv2RWABAACQjd588015/fXX/eqcf/311/LXX395LOvbt68sX748249l27Zt0r179zQDAm/s3bvXbOf06dOppjly5IhJo8FMWvRc7Nixw2OZbnfJkiXyww8/yPnz5706pkuXLsk333xjHqlJb7unTp2S7777Tvbv35/i5/npp588lkVGRso999yTLcEsgQUAAEAu98ADDyQrkOJf3377rWzdulXuu+8+j2WVKlWSZ599VgYPHizVqlWT3377Lc1TNnLkSJOuf//+8sgjj6SYJr3t7tu3T+rWrSvjxo2TK6+80gSE7jSAOHTokMeyAgUKyKOPPirDhw/P8iwNzfI9AAAA5BKbN2+W7du3m+fFihWTevXqSenSpR2vs2rVKgkPD5fLLrtMVq9eLSEhIXLDDTeY5kqNGjWSfPnyyaZNm6RgwYLSvHlz8742Y9q4caNUrFhR6tevn+r+9c64NgXSJlqFChWSvHnzym233eZ6/8SJE2Y7+t5VV10lefL8/31pe/+67Pfff5cKFSpIgwYNXHfWtVCsx92wYUMpWrSox35jY2PNPnXfuo2SJUsmO7adO3fK7t27zefWR1L6GTds2GDuyjdr1szsy5saES2g16pVS7ytYerdu7eEhoa6mk/16tVLHnroIVPAV3369DHLtFbD/fy40/OntQZTpkyRWbNmJXs/te3qvvU7oiZNmiSdO3eWt99+Wz766CMTrNxyyy3mvffff9/sW9Mndffdd5vAQo/P28+dGQQWAAAAPqIF8Pnz57sK5FqQfOWVV0xh0ck6+lrb+WuTnapVq5qCugYW2kTniiuuMM2YateuLStXrjSBRZs2bUwBVguRv/76qwwYMMBsIyXarEYL9xqwaHt8DVLswOLDDz80BVLdjgYOug9tr6/Bh9L9a7Chd/Q1eLn99ttNYPHuu+/KE088YQIGy7JM0KPL9H2l6W+88UYpU6aMREVFmdcjRoyQ+++/33Vcd911lwkqNM0vv/wiY8aMkaFDh7reHzVqlLz88ssm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AAAAABwjsAAAAADgGIFFEAgPD5dRo0aZv/Bf5FNgIJ/8H3kUGMinwEA++b/wACrn0XkbAAAAgGPUWAAAAABwjMACAAAAgGMEFgAAAAAcYx6LAKeTlmzdulXi4+PliiuukNBQstQXzp07J7///nuy5fXr1082hrSm3b59uxQrVkyqVauW6vayK01usGHDBklISJDGjRun+L5eD1u2bDHXQ506dVKctNLf0gSb2NhYWb9+vZQtW1aqVq3q8d4///wjmzdvTrZOkyZNJCIiwmNZTEyM7Ny5U8qUKWMmiEpJdqYJJnoN6efVeZj09yS1/z8OHjwoR48elRo1aqQ6lr2/pQkm58+flz///FNKlSol5cuXT/b+mjVrJC4uzmOZfn8rV66canmhbt26kjdv3mTbys40wTiJ3a5du8zvR0r55I/lhSwpU+jM2whMO3bssC6//HKrdOnSVsWKFa3y5ctbv/76a04fVlD4/fffdUZ6q1mzZlbLli1dj02bNnmkmz17tlW4cGGrZs2a5m+bNm2sf/75J8fSBLs333zTqlOnjlW0aFGrevXqKaZZvXq1VaFCBXNNlClTxpyvbdu2+XWaYHLixAlr6NChVrly5az8+fNbgwYNSpZm8eLF5vpyv7b0cfDgQY90b7zxhtlG7dq1zd+uXbtasbGxOZYmmIwdO9aKiooy/4dUrVrV5NeCBQs80ujn79atm+u8REREWK+99ppfpwkmR44cse655x6rSJEiVsOGDa1ixYqZ62Tv3r0e6fT//ho1anhcS5MnT/ZIo785+tujv0H6e6QP/W3KqTTB5NChQ1bPnj2tEiVKWFdeeaUVGRlp8uDAgQN+XV7IqjIFgUUAa9SokdWxY0crPj7evH7ggQfMfw4XLlzI6UMLmsAiOjo61TQ7d+60wsLCrKlTp5rXp06dsmrVqmX17ds3R9LkBkOGDLH++OMPa9SoUSkGFlrw0P/EBgwYYF4nJCRYnTp1surXr++3aYLx2hk/fry5dho3bpxqYJE3b940t7Nq1SorJCTE+uKLL1z/eevv27Bhw3IkTbAZPny4x+/b888/bwrq7sHds88+a86DvWzRokXmd3HFihV+myaY6Pfy/fffty5dumRenzlzxrruuuusa6+9NllgMWPGjFS3k5iYaH5zunTpYn6DVL9+/czNDjt4zs40wWblypXWl19+aT67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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "unk_threshold = next(iter(per_vocab_size.values()))[\"alarms\"][\"tokenizer_misconfigured\"][\"threshold\"]\n", + "plot_metric_vs_vocab_size(\n", + " \"unk_token_fraction\", \"unk_token_fraction\", \"UNK token fraction vs vocab_size\",\n", + " hline=unk_threshold, hline_label=f\"alarm threshold ({unk_threshold:.2%})\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "05f3df0d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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rj3CSj5BnonzWBARERGRtwYW1atXt69PmjQJY8aMQbt27VSLxYQJE1x5fJXWxXks2GJBRERERJ6vVEM4nTlzxr4+evRo1WqxefNmtGjRAgMHDnTl8VVaBmtgweRtIiIiItIDl4wN261bN7WQ6xitw/YysCAiIiIiPeAEeR7eFcpo0GAxm919OEREREREhWJg4eHDzQotO9utx0JEREREVBQGFh4+3KywZGe59ViIiIiIiFwaWPz2228ws1tOhTBYcyxENs85EREREXlTYDF8+HBERkZi5MiR+PLLL5GUlFR+R1bJGY2OXaHYYkFEREREXhRYnD59Gj/++CMaNWqEWbNmqSCjT58+ePnll7F3797yO8pKyOTr2BWKORZERERE5EWBhcFgQNeuXfH8889j+/btOHLkCG699Vb8+uuv6NSpExo3boyJEyfi559/RmZmZvkddSVL3jab2WJBRERERF6cvF27dm2MHz8ey5cvR0JCAt544w0VUNx5552oUaOG646yEjIaL7ZYIJvDzRIRERFRJZggTwQEBOCaa65Ri/j7779dtetKyejQFcrMHAsiIiIiqqzDzV566aXltetKwejjEFhY2GJBRERERJ6N81h4KJNDjgWYvE1EREREHo6BhQcza4acWwYWRERERFQZAovs7Gxs3rwZJ0+edMXuyMpsrR6LhcPNEhEREZEXBhbr169XIz/ZXHvttejevbua3+Knn35y5fFVapq1ejSOCkVERERE3jgq1OTJk/Hmm2+q9S1btqhF5rRYsWIFnn32WQwcOLDY+5JWjvnz5yM2NhZt27bF6NGj4efnV+hz/vzzT6xcuRLnzp1D69atcdNNN6lRqWy++OILNbdG7qFxn376aeiJBTldoSxmtlgQERERkRe2WPzzzz9o06aNWl+9ejVuuOEG1K9fH7fddhv27NlT7P3s27dPBRObNm1CRESEmsF7wIABqmtVQR588EE8/vjjaj0sLEw9p0OHDjh79qx9GwkqJPho166dfWnevDn0hoEFEREREXl1i0W1atWwe/dudOzYEd9++y0efvhhVR4fH4/q1asXez9PPPGEGpZ22bJlalbvsWPHomHDhvjss89w++235/scmdlbZvi2mTBhggpKfvjhB4wcOdJeLt2y5DE906wtFmCLBRERERF5Y4uFXPRLd6cuXbrg6NGj9knxvvvu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Fl577TVV1qxZM7z99tvMrygPbLEgIiIiIm8MLJYsWaICCFnMZrMqM5lM9seGDRvm2qOs5F2hDAwsiIiIiMgbA4vhw4dDs86tYAso8nuMXDTzNng+iYiIiKgSzbwdFxeH0NBQV+6yUtMM1uphiwUREREReVOLhcyund+6sFgs2L9/P/r27eu6o6vsNM68TUREREReGFh06tRJ3a5Zs8a+buPr66tGihoxYoRrj7AS0wzWwAI5eSxERERERF4RWLz00kvqtkaNGnj00UfL65jILiewMFiYY0FEREREXpJj4TghXlFBRX6T51EZJshj8jYREREReUtgMW7cOFxxxRVYunQpLly4kOfx1NRULFy4EP3791fbkivYukJx5m0iIiIi8pLAYufOnRg0aBAefvhhNfJT27ZtVQK3BBKtW7dGWFgYnnjiCQwePFhtS67LsTBw+F4iIiIi8pYcCz8/PxVUPPjgg/j999/Vcvz4cRgMBhVg9OrVCz169MgzrwWVBVssiIiIiMhLJ8iTwOGyyy5TC1XMBHlgiwURERERVaYJ8sjFrBPkGZhjQUREREQejoGFDkaFkjUiIiIiIk/GwMKDSf6Kwq5QREREROThGFjoIMeCXaGIiIiIyNO5PbD49ddfcfPNN6Nv37544IEHcPr06UK3z8zMxAcffIAbb7wRV111FSZNmoTDhw+Xeb8eyd5iwXksiIiIiMhLA4uff/5ZDTNbu3Zt1KpVS61LWUmsW7dOzYPRtGlTPPbYYzhw4AB69uypJtsryNixY7Fnzx7cfvvteOihh1RQ0blzZzX0bVn264k02IbuZY4FEREREXnZcLNi3rx5uOuuu1SLwNChQ1UuwKZNm9QEeh9//DFuu+22Yu1n6tSpquXhhRdeUPf79euHmjVrqhaJRx55JN/nfPjhhwgKCrLflwAiODgYa9asUcFGaffrsS0WmnSFYmBBRERERF7YYjF9+nQVQHz22We4//77cd9996n1jz76CC+++GKx9nHhwgVs3rwZ1157rb1MAgZp+Vi9enWBz3MMKoQENGazWc0EXpb9eibbzNvsCkVEREREXthiId2PpKUit+uvvx533313sfYhXZcsFovqRuVI7kvrQ2EkcJBuUCkpKYiJicG3336Ljh07lmm/GRkZarGRfQvZlywVLec1rXGfQXPLMVDxSN1oGutIL1hf+sG60hfWl36wrvTF4ubrjJK8bqkCC8mr+OWXX5xaBWy5DXXq1CnWPrKystStv7+/U3lgYKD9sYK0bNkSs2fPxpkzZ1QriSRnt2vXDvXq1Sv1fmfMmIFp06blKY+Pj0d6ejrcUYlmW0uFxYy4uLgKPwYqfl0lJyerL73R6PbxEKgIrC/9YF3pC+tLP1hX+mJx83VGSXKUSxVYTJw4ESNHjsS9996LLl26qLI//vgD77zzDp5//vli7aNatWrqNjEx0ak8ISEB1atXL/S5oaGh6Natm1q/+uqr0aJFC8yZMwevvvpqqfc7efJkNcKUY4tF3bp1ERERgZCQELjjQ7TX5AuYc+aziIyMrPBjoOLXldSRfFYYWHg+1pd+sK70hfWlH6wrfbG4+TojICCgfAML6YYkF/CzZs3Ca6+9psqaNWuGt99+u9iJ29I1KTo6Gn/99RcGDx5sL5cApXfv3sU+FpPJpE60tF6UZb/SwpG7lUNIBbrvYjHndSV5mxesnk2+8O79rFBJsL70g3WlL6wv/WBd6YvBjdcZJXnNUh+dBBC7du1CWlqaWmS9uEGFzR133KG6Mp08eVLdX7p0qRpKVsoduyhJ64iQ15FWCccuTd99950KIqTloiT71QODkRPkEREREZE+lKrFIneLQWk988wzao6JJk2aqG5HJ06cwFtvvaXmpbA5ePAg/v77b7UuLQpJSUmqVUKGjz179qwKNmbOnIkRI0aUaL/6YAssONwsEREREXlJYCEzWIv169fb1wsi2xSHBAqLFy/GqVOnEBsbqwKBqlWrOm3z1FNP4dy5c/amGJmb4tlnn8X+/fvV/BWSLO7j41Pi/eqCgRPkEREREZGXBRa9evXKd90VpAUi9/CwNo0aNcpT5uvri9atW5dpv7pgsOVYcKhZIiIiIvKSwMI2i7WQoV2HDRuW73ZLlixxzZGRwwR5PBlERERE5NlKlbw9fPjwUj1GJWTNwmeLBRERERF5OpeOWSWTuMkcE+QaBnvyNrtCEREREZEXjQo1YMCAfNdtk3dIQnVRid1UfJoxJ3nbkBNfEBERERF5R2DRqVMndbtmzRr7umNCtcw34TjsK5URk7eJiIiIyBsDi5deeknd1qhRA48++mh5HRNZGa1NFZzHgoiIiIi8MseCQUVFt1hwWCgiIiIi8tKZt+Pj4/Hzzz/j2LFjyM7Odnps6tSprjg2so8KxcCCiIiIiLwwsPj9999xzTXXIDo6Gv/++y8uvfRSlbidlpaGDh06MLBwGWvyNgMLIiIiIvLGrlCPPfYYnnnmGezbt0/d37FjB06ePInBgwejX79+rj7GyotdoYiIiIjImwOLnTt34q677srZgdGIjIwMhIeH46233sIXX3zh6mOstAzWrlBGzmNBRERERN4YWJw7dw4hISFqPSoqCkePHlXrUpaUlOTaI6zEDGyxICIiIqLKMvN2//798fDDD+Pbb7/FuHHjVI4FuYZFy0narmI4j+1fvIPsjAyeWiIiIiLynsDizTfftK/PmjVLzbp9++234/jx4/jggw9ceXyV1h8fPI9L4j9S67VNCWi/fzISXmyOze9Nc/ehERERERG5ZlSo+++/375es2ZNrFixojS7oQJI8ND19Guwzo9nF2FIQsTp17D5PaDbhGd5/oiIiIhI3y0WERERrj8SUqS7U8NTc9V67sDCaL3f4NRcdosiIiIiIv0HFpqmITEx0fVHQ9i59GNEGZPsQURuUh5tTFLbERERERHpOrAYNWoUZs6cqXIryLXSEk+6dDsiIiIiIo/Nsdi1axfWrFmDL7/8Ei1atICfn5/T499//72rjq/SCaxWGzhTzO2IiIiIiPQcWLRp00Yt5Hptb7wTsS/OUona+XWHsmhAnBautiMiIiIi0nVgMXv27GJtJ3NbDB06tDQvUWn5+PvjcK2xavQnCSIcgwu5L47UGotof3+3HSMRERERkcsnyCvM9ddfX56791oylOwfNSchXgtzKpf7f9acxKFmiYiIiKhyBRZUel3HPY2sO3/FliYvINkSpMoSWj3GoIKIiIiIPBIDCw/vFtXh1vuwy9JS3U85sMHdh0RERERElC8GFjqQFpKTKB+a8a+7D4WIiIiIKF8MLHQguuMgddvYdAxZqWfdfThERERERHkwsNCBFn2uQKwlDH6GbBxcudDdh0NEREREVLGBhT+HRHUJHx8T/rM0Vutn9613zU6JiIiIiPQSWKSnp5fn7iuVtJDW6jY0nXkWREREROQlE+QlJSXhueeew++//47ExMQ8j//333+uODZyULPDIGDDfJVnkZ16Fj5Vnee4ICIiIiLSXWBx9913Y/fu3bjtttsQHh7u+qOiPJr3vRIxv4Yj2piEvSsXouWwCTxLRERERKTvwOLnn3/G9u3b0ahRI9cfERWcZ2FuhGjjViTv+wUAAwsiIiIi0nmORVhYGFsq3CDDNp9F+j53vDwRERERkWsDi+HDh2P27NmleSqVQVTHgQ7zWSTxXBIRERGRvrtC7dixA2vWrMGiRYvQuHFjGAwGp8e///57Vx0fOWjRxyHPYtUitLyR3aGIiIiISMeBRZs2bdRCFcvH1+dinsVe5lkQERERkc4DC3aDcp8Mmc8ibSvzLIiIiIio8kyQR64X1YF5FkRERETkRYGFDDk7YMAA1K5dG7Vq1VLrUkblq0Xfq3DaEg4/QzYOrvqKp5uIiIiI9BtYzJs3D4MGDUJ0dDQmT56MKVOmqHUpmz9/vuuPkpzyLA6ac+YPObtvHc8MEREREek3x2L69On4+OOP1czbNvfddx+uuOIKvPjii07l5Hrp1jyLsLS9PL1EREREpN8Wi8OHD2Po0KF5yq+//nr1GJWv6PYOeRbnzvJ0ExEREZE+AwvJq/jlFxnu1Nm6detQp06dEu3rzTffVHNhVKlSBd27d8emTZsK3X7Dhg0qgImKilLHcfPNN+PQoUNO20jriY+Pj9PSrl07eIsW/a5CjCUcvgYzDq5a5O7DISIiIiIqXWAxceJEjBw5Ek8++SS+/vprtTzxxBMYNWoUHnzwwWLvZ+7cuep5r776Kg4ePIgePXrgyiuvxPHjx/Pd3mw2q5yO22+/HTt37sTvv/+OCxcuoH///jh37pzTdkOGDEF6erp92bp1q9fNZyHO7l3v7sMhIiIiIipdjsVDDz2EatWqYdasWXjttddUWbNmzfD222+XKL/i5Zdfxh133GHvVvXKK69g4cKFePfdd1UeR24mkwm//fabU9lbb72FBg0a4I8//lABho3MBi4tFd4qvWprIJ15FkRERESk8+FmJYDYtWsX0tLS1CLrJQkqkpKSsHfvXvTr188pGJD7GzduLPZ+EhIS1G3VqlWdyleuXImQkBDUrVsXt956K44dOwZvEtX+SnXLPAsiIiIi8gRl/klfWhFK4/Tp0+o2MjLSqTwiIgJbtmwp1j6ky9MjjzyCSy+9FB07drSXN2zYUA1726dPH5w8eRIPP/wwevfurbpPSbCRn4yMDLXYpKSkqFuLxaKWiiavqWlaga/dvM+ViPk9HNHGJOxdtQjNh95d4cdIxasr8iysL/1gXekL60s/WFf6YnHzdUZJXrfYgUXfvn3V7fr16+3rBZFtSstoNKqTVxTZZvz48di9e7dK6HYMcCRvw0a6bH311VeoWbOm6mY1bty4fPc3Y8YMTJs2LU95fHy8ytFwRyUmJyer9ynnJD/7sxsh2m8rEnetQVyPIRV+jFT8uiLPwfrSD9aVvrC+9IN1pS8WN19npKamuj6w6NWrV77rpSUT6tku3B3FxcWpEZ8KIyf23nvvxbJly9RIVJLfUZjw8HDUq1cPBw4cKHAbSQqfNGmSU4uFdKOSFpSCWjnK+0MkXcPk9Qv6EO2UPIuMraieuT9Pyw95Vl2R52B96QfrSl9YX/rButIXi5uvMwICAlwfWLzwwgv5rpeWtCRIQCDD1t5www32gEFaO2TEqcLcf//9WLJkCdasWYM2bdoU+VoSJMhIU9JqURB/f3+15CYV6K6LRfkQFfb60R2uAjbNV3kW5rRU+AaHVvgxUvHqijwL60s/WFf6wvrSD9aVvhjceJ1Rktcs1dGdP38eS5cutd9fsWIFBg4cqOaPkMeKS/IjZAZvSbSWJp6pU6ciMTEREyZMsG8j3Z0c56CQ4WwXL16MtWvX4pJLLsmzT8mTGD58OLZt26bWpZVixIgRCA4OLjJg0ZuW/a7CaUs163wWi919OERERERUiZUqsJgyZYo9+VpGd5JJ6qQ1YPPmzXjssceKvR/Jd3jmmWcwduxYVK9eHT/88AN+/PFHNXysY4J2dna2fQQomVBPbtu3b+80Ad4nn3yitpFWB5lPQ1o1pAuUJHDLiFEyHG1RXaz0xsfPF/9l58xnkbx3rbsPh4iIiIgqsVKNCiXdkKRFQEhrQ4cOHdRkdzLJ3WWXXYZ33nmn2Pt6/PHH1VKQDz74wJ7MLcFHVlZWvts5Jm/L5HiyVAYZVVsCGVsQemGvuw+FiIiIiCqxUrVYSLclPz8/tS5dkq666ip7QrY85tIDNBqdggbHVgrHRfqeVUbR7XPOfSPTMWSdO+vuwyEiIiKiSqpUgYW0UDz77LOq29KiRYswaNAgVb5jxw7VRYkqPs/CT/IsVn/FU09ERERE+gksZs+ejVWrVmHYsGG455571AR1YubMmYV2ayLXM/n74b/shmr97B7mWRARERGRjnIspFVi7968ffoXLFiA0FAOeVrRMqq2UvNZhKUxz4KIiIiI3MOlw80+9dRTJRpullwjut2V6raR8Riyzrs2x4WIiIiIyOOHmyXX5VmcsuVZ/Mz5LIiIiIhIJ4GFDDd700035RluViauW7ZsmauPkYpgCvDHQdt8FsyzICIiIiI38PjhZql40qu0VLfMsyAiIiIid+Bws16iZrsr1C3zLIiIiIjIHTjcrJdoeflAlWfhq+azWOLuwyEiIiKiSobDzXpVnkVD1PJLRPLu1cCQO919SERERERUiZSqxcJRWlqafZ1zWLhXRpVW6pZ5FkRERESki8AiKysLU6dOVUPMBgUF2csnTJiAAwcOuPL4qJTzWWReSOG5IyIiIiLPDixeeOEFNazs22+/7VTer18/TJs2zVXHRiXU8vKrcNJSXeVZHFr9Fc8fEREREXl2YDF//nx88cUXuOGGG5zK+/Tpgx9++MFVx0alyLM4lN1Aras8CyIiIiIiTw4sTp06hcaNG6t1g8FgLzeZTEhPT3fd0VHp57O4sIdnj4iIiIg8O7Bo3rw5NmzYkCewkJaMSy+91HVHRyVW81LbfBbHkXmBkxUSERERkQcHFlOmTMGoUaMwe/ZsdX/RokUYO3YsnnjiCUyePNnVx0gl0KL/1Q55FpzPgoiIiIg8eB6Lm2++GUajUSVxWywWjBgxAq1atcKXX36JIUOGuP4oqdh81HwWDVDbLwHJe9YA13E+CyIiIiLy0MBCukENHz5cLZmZmdA0Df7+/q4/OiqVjKCWQPZWhJ3fzTNIRERERJ7bFapv3772dT8/PwYVHqZWuwHqlnkWREREROTRgUX9+vU5EZ4Haz5g0MU8izVL3X04RERERFQJlCqwePbZZ3H77bdjy5YtuHDhArKzs50W8oA8i6yGaj1598+sDiIiIiLyzByLMWPGqNvOnTvn+7jkXJB7ZQS3ALK3IPw857MgIiIiIg8NLNatW+f6IyGXqnnpAGDrZ2hkPKbms/ALCuUZJiIiIiLPCiwck7fJM7UYcDVO/FUDdYxnsG/NErS4lsPOEhEREZGHBRYiLS0NCxcuxN69e9V9mcdC5rcIDAx05fFRKfkEBuBQVgPU8T+D5N1rAAYWRERERORpydvbtm1D48aN8cgjj2DTpk1qmTRpEpo0aYIdO3a4/iip9HkWAMI5nwUREREReWJgMX78eFx99dU4ceIEfvvtN7XI+sCBA9Vj5Blqtu2vbm15FkREREREHhVY7Nq1CzNnzkRQUJC9TNZfeukl/PPPP648PiqDFldcjROWGvAxWHB47dc8l0RERETkWYFFo0aNEBcXl6dcyuQx8gw+QYE4lFVfrZ/dxfksiIiIiMjDAotHH31UJWqvWrUKSUlJSExMVOsjRozAY489xsnyPEhGUE6eRbULu919KERERETkxUo1KtQdd9yhbq+66qo8j40dO1YtNpwsz71qXtof2PY5GhqOIfP8WfgFh7n5iIiIiIjIG3GCvMown8UW63wW679Gi2tygkIiIiIiIlfiBHlezicoyD6fRcrO1QADCyIiIiLylBwL0peMoGbqNox5FkRERETkSYHFqVOnMHr0aDRs2BBhYWF5FvIsNS8ZoG4bG45i6zdzsPv3H2DOznb3YRERERFRZe8KddtttyEtLQ1TpkxhIKEDGcYkZGtGNZ9Fx7+fUWWxP1fHqe7Pov1VY9x9eERERERUWQOLjRs34siRI4iMjHT9EZFLbV85D+23PAJDrvIILQERGx/EdoDBBRERERG5pytUdHQ0MjIyyv7qVK6ku1Otjf9T64ZckYXRer/mxmnsFkVERERE7gksHn/8cUyYMEG1WpDn2rd5BaIMifYgIjcpjzYkqO2IiIiIiCo8sOjatSs2bdqkkrdNJhN8fHycFvIMKft2uHQ7IiIiIiKXz7zdvn173H333S5J3j579izOnDmDevXqwc/Pr1jPOX36tApiIiIiXLpfb+JnCSjWdhExK5B2aAACG3bL22eKiIiIiKi8Aot9+/bhxIkTqF69OsoiOzsb48ePx2effab2deHCBbzxxhtq1KmCvP3223jllVdUjocsEli899576Nu3b5n2642atu2J2BNhiDCczbc7lKblxBFNsncD8wfiVGAz+HSfgMjutwK+ge44ZCIiIiKqTF2hpAtUampqmV98+vTp+P7777Fnzx41N4Zc/I8dOxY7duTfNcdsNmPv3r1Yv3692j4uLg7XXHMNhgwZgvj4+FLv11tV7dIVu461VusWzfkxuS9FX8X1wg/pXZCh+aJW2n5Erp2E1OlNceTLR2BOOOyeAyciIiKiyhFY3HPPPbjzzjvVRX5WVpZqIXBciuuDDz5Q3akaN26s7kuLQrNmzfDRRx/lu73kc7z11luoX7++/f6jjz6KlJQUbN26tdT79VYGkwmdb30Ia/e0Q7zm3GUtzhKuyq8cdA+6tbsb3++/Fp8lXo4TlhqoqqWiwb8fwfBmexx5czBSd/0EWCxuex9ERERE5KVdoR588EF126pVq3wf16SPTRFiYmJw8uRJlQjuqHv37k5BQlF2796tbuvWrevS/XqLkCuvRBeZLX36DOyumgVzsAmm82bUSvVFl6cmq8fFDTcNw/kNG7Br/iKsyo5D8zon0NNnDxok/AYs+Q3xfnWQ1eEO1OpzJxDI2dWJiIiIyAWBxbp161BWCQkJ6jZ3nobcl4Tr4khOTsb999+vukO1bt26TPu15WzYSCuIsFgsaqlo8poSoLnitasMGICm/fqhztatyI6Ph09EBAI7dlQtGo77D+rVC1169cIl//6LmHmfY/7u2ghukoYrgrYiIvMEsPk5pG+eiVP1r0OtKx6AX622ZT42b+DKuqLyx/rSD9aVvrC+9IN1pS8WN19nlOR1SxVYOCZKl5ZtWNrMzEyncrm49/X1LfL5kpB93XXXwd/fH/Pnzy/zfmfMmIFp06blKZfcjfT0dLijEiVwkg+S0ViqHmt5NWiQswA4Zw3A8hUejqCH7seAhESkL1uG9b/4IKmxD7rV2IfmxhNodPQr4KOvcCT4EqD9aAS0vBowFV1n3qpc6orKDetLP1hX+sL60g/Wlb5Y3HydUZK86jJNOiHDuR44cEC9UclhKMnQs7Vr14bBYFDDxjqS+7ZuTQVJS0vD4MGDkZiYiLVr16JatWpl3u/kyZMxadIkpxYL2V5GnQoJCYE7PkTyPuT13XaxGhkJtGyBeg+lI+X773Hw88X4JLgV6jY4g36+O9Dg/D/AhseQtOklpLQehTqXj4chpCYqG4+oKyo21pd+sK70hfWlH6wrfbG4+TojIKB40xeUOrCQX/AfeeQRlSRtS9aWloJx48bh1VdfLdYBVKlSBZ07d8aPP/6IW265xd6qsHr1ajzxxBP27WRUJ2mdaNKkiVNQIS0JElTknseiuPvNTVo+ZMlNKtBdF4vyIXLn69sYg4JQ7aabED58OFpu+B1xn87DopNV4dMSuDxkByLMCQj/Zw6y/3kLx6KvQNSABxDUuGelmhPDU+qKiof1pR+sK31hfekH60pfDG68zijJa5YqsHj88cfx008/4csvv0S3bt3Um5WZuKVcRmqS4V2LQ7oeSZDQpk0blVz9+uuvIzg4GBMmTLBv88wzz2Dz5s3YtWuXCmJkaFlZX7hwIWJjY9Via6kIDw8v9n6p5KSeq/TupZZa+/cjcf58bFt9HqdahuOS6MPo6PMfGsb8BHz2E04HNoGp6zhE9hgN+AXxdBMRERF5OYNWnCGccomMjMSKFSvQsWNHp3IZdWnQoEH2i/3ikABFAhF5Ttu2bfG///0PDax5AOLZZ5/FP//8g2+++UZ1verVq1e++3nuuedwww03FHu/RZGuUKGhoapPm7u6Qsk8HXKuPflX8OyEBCR9uRAnFi/Fjohw1GhyDgMCtiHQkJPjct5QBXFNhqPulffDJyKn1cnb6KWuKAfrSz9YV/rC+tIP1pW+WNx8nVGSa+JSBRbSZUiGdbW1ENhIzkOtWrXckuzsagwsSsaSkaHyMBI+nYftqZlIbxuI3uG7UN8Yl/M4DDherQfC+t6H0DZXS7savIW7v/BUMqwv/WBd6QvrSz9YV/pi0VFgUaqj69ChA1555RWn+Spk/eWXX0b79u1Ls0vSOaO/P8JuvBGNvluGgS8+jcvSI3BkeXV8cuhK/JbVBkZoqJ/4O0K/vhVnZrTGyR9mQbuQ6O7DJiIiIiIXKVWOhQQQAwcOxNdff60SpcWff/6JEydOqC5IVMnzMHr2VEvUf/+h2fwFiF9+GAvq9ENQ8ywMCN6GGlmngL9eRMZfr+Bk3WtQ+8oH4V+XASkRERGRnpWqxULyHGSY2RtvvFGNbXvu3DkMGzZMlRWUA0GVj3+TJqj53DS0WrMKVw+6Cm03p+DXn1thXswA7DXXgz8y0Oj41/D/uC9OvNILCZs+B7Kd5x8hIiIiIn0oVY5FZcAcC9ezZGYi5fsfkDhvHuIOH8OeVo1Qu2EiLvfbAV+DWW2TbArH2ZYjUXfAvTCG1YYeuLvvI5UM60s/WFf6wvrSD9aVvli8PcdCkrNXrlyZp1zKvCFxm8qH0c8PYTdcj4bffoO277+NK0JroPY3MVi6qQe+PNsXsVoYQs1JqL/rLWiz2+DwOzfi/P71ksDDKiEiIiLycKUKLKZMmYLdu3fnKZeyp59+2hXHRV6ehxHcvTvqvv8emv74Pfr06IT2649h54/1MPf4lfjL3BwmWNAwbjWCvxiCmJkdELPmbSDjnLsPnYiIiIhc2RUqKipKTVKXe9ZraaaRUaFOnjwJvWNXqIqVnZSEs4sWI+nzz5GamIx/mjVBeLPzuCJgG4IMGWqbC4YgxDYahjpXPQDfyGbwFO5uoqSSYX3pB+tKX1hf+sG60heLt3eFSktLU0t+5fLiRCXlEx6OGhPGo8ma1Wg8/TlcBg1Nlx3FT790wIIzl+OwJRpB2gU0PDgfvu90xtHZV+Hs9m8BS05uBhERERG5V6kCi8suu0zNZJ2dnW0vk3XpBiWPEZWWwc8PoUOGoOHXS1F/3jx0btkIndb8i+PfheGTg1fil+xLYdEMqH92M8KWjUHC9JY4sXw6tPNneNKJiIiI9DaPxaxZs9C7d2/88ssv6N69u5ocb9OmTaqJ5Ndff3X9UVLlzMPo2kUtGYcPI3zBAkR+8y0yt2Tii4Z9ENBaQ/+graieHQtsnYnMra/hZO2rUfPKiQio38ndh09ERERU6ZSqxaJVq1b4559/MGLECCQkJCApKQm33HKLKmvdurXrj5IqNf+GDRH9zDNoum4taj08EV3PnUXr5QewcVUzzIu9ErssDeCHLDQ8+R0C5vbHiZd7IH7DPCA7JzeDiIiIiMof57EoAJO3PZcm82GsXInEuZ8ifc8epPoGYHerxqjVNAX9TFvgZ50TI8UYhqTmI1D3yvtgDK/ntUlVVDKsL/1gXekL60s/WFf6YtFR8napukIRuT0P49prETJ4MNK2bEHCp/NQde1amP8GvqnTHZb2QegTtAW1LIkI2fsezHs/wOGIvoi4/D5UadFf+lmxAomIiIhcjIEF6ToPI6hzZ7VkHj2KxPkLcOk330BbfgH7qtTCqk490DLyELoa96Bh/Fpg0VrE+teHueNdqHXZ7UBA4VE3ERERERUf+22QV/CrXx/RT09VeRiRjz6CulX80HX9NvgtPY/5O6/Ed9l9cU4LQFTGUdTa+DTSZjbDoXn3IDNmr7sPnYiIiMgrsMWCvIopNBTV77oL1caMQcrKVUj89FN03rUL2m5gdcQlON+jJrr5/4nGxtNodPgL4L0vcCy0E6pedh/C210HmPiVICIiIioNXkWRVzL4+iJ08DUIuWYQ0rZtQ+Kn89B89Wpg2QnE+FfFhh49UC/yKC7DVtRL3gIsH4vEFZE413Y06vafAEOVSHe/BSIiIiJdYWBB3p+H0bGjWjKPH0figgUwLlmKaus2IdtgxOLWg+DbGuiHX1E9Ow7Vtr+KzO1zcKLWQNQc8AACG3ZlsjcRERFRMTDHgioNv7p1Ef3UU2iyfh0iH3sMAdFRaLdrO1ov2o4ta1vgs6xb8bfWGH7IRqNT3yNw/lU49XI3xP36MZCVlv9OLWbgyAYEHPhe3ar7RERERJUQWyyo0jGFhKD6nXeg2pjbkLpqFRLmzUO9v/9BvaUncc43AJ/1H4Pq4YdxuWUTal3YB6ydhNT1z+JM0xGod9X9MFVrkLOjPd9B++kJGFNOIcy6by2kFgwDZwKtrnPnWyQiIiKqcAwsqNIy+PggZNAgtVzYvl3lYeDnn9Hxp59hgQE/drwWmS180Ct7LWpbzqDqvx/C8u9HOFK9NyKbdUbgptegQYPjrBhayilg8W0w3DSfwQURERFVKgwsiAAEtW+vlswTJ5C04DOcXbIELbZuBrYC/9Vsil/63YiGlk3ojn/QIOFXYNOv0DTAaMjbt9CiaUhf/hgCW1wDGE08v0RERFQpMMeCyIFfnTqImvwkmvyyHpFPPgHfWrUQefoo2n+xHEHfnMfizPuxwdhFbVvQBN4SbASmxcC8dQGQGguYs3mOiYiIyOuxxYIoH6YqVVD99ttRbdQopK5eo+bDwI4daPv110hqXRVoW/RpM/0wEfhhoupWdd4YgvO+4Uj3rw5zQHVowZEwVY2EX2gkgsJrokq1mvANjQKCIwC/YNYJERER6Q4DC6Ki8jAGXqWWtB07VKL3/mN7inXOzmpBqIo0mAwaqlqSUTUjGcg4AqQU/rx0QwBSTeFI86uGTAlCAmsAVSLhGxKJgLBoBFerqRajzLURGA4Y2fBIRERE7sfAgqiYAtu1Q5127bDvs+U4dWA/opGYJ8dCWDQgBtWx2vwAGrZqgnQ/AzKMmcgyX4DlwhkYzsfDJ+0M/DISEJyViKrms6hhSEYNJCPAkIUALR0B2acBWS4UfkxmGJFiDMMFaQ3xq4bswBrQgiNgkkAkLApBYTVRtXpNBIRF5Uz65+PP+iYiIqJywcCCqIQ6hBox4/yNmBn8oQoiHIMLuS9mn7sBt/3wIUywFliZQkPhExVlXVrANyoaxshIpFeLxKEq4Ujx80FaRioyzsYgMyUOlnNxMF44A9/0BARmJiA4OwnhlrOobkhBuOEcTLAg3JKI8IxEIOMgkFr4sZ8zBOOcKQwX/Kojy78azEERMFSJgE9IFPxDo1SXrKo1asG3aiQQEMrJAYmIiKjYGFgQlZB/ZASabz2Ke7o9hGd956OWIdH+WIxWDdOybkPnbXtQtVtXwGxGVlwssmPjoKWnw5ycrJaM/fvz7Ffik1AAYX5+8ImMVMGHb1QkfCJrwieqXc56VBQsNSKQGhyGPWkZSEmIxYWk08hIjkV2ShwM5+NgSkuAf0YCArMSEWJOQjWkoDqS4Wcwo4p2HlWyzwPZJ3NaQ5IKfp+Z8FGtIed9q11sDQmqAVPVKJUPEhgWjao1aqJKuHTLigBM/HNCRERUmfFKgKiEgjp1RB/tDPDHXgxt+xwaBccgEmcRhzAcPheFu3d9rx6v9/FCGEw5w81qmgZLcjKyYuOQrQKNWGTF5gQcaj0u59acmAgtMxNZJ06oJa2wL294OCJVy0ckfCOj4BMtgUinnNaQyJygxBASgrQsC2JSM5CUFI9zCaeQfjYGWdIakhoHw4Uz8EuPR0BmEqpkJyLUkqyCkKqGNDUDeQ3LGdTIOANkoMjWkGRDiDU3JBwZ/jVgCaoOg3TLqhqlumIFV6uFkBo1ERhe020J6ubsbOzdvAKJJw/iTO3GaNntaph8+GeQiIjIFfgvKlEJSbAQ9dRk9Jz4ELqd3o3d1Rsi0b8qemakonXCYdX9KWrObHtQoZ5jMMAUFqYWNG9W4L4tmZnIjosvIPi4uC7BhzkpSS0Z+/YVfKz+/jktH5GRqBEVhWhbK0hUA/g06ZqzHhEBg59fzutbNCSnZeFg8lkkn4nBhcQYZKTEqNYQnIuz54YEWXNDwrWzqIZUlaAeqqUgNDsFyD5aZGtIGvyRbAzHeZ8wZPhXQ1ZghGoNkYR0v9AoBITXRNVq0QiJqA3f4OouSVDfvnIeam2ahjZIyCnYC8Suro5T3Z9F+6vGlHn/RERElR0DC6JSCLnySmDObMROn4FLYg5e/EJFR6ugQz1eCkY/P/jVqa2Wgkjrh/nsWWRLK0dMzMXgI845EJFttIwMZB07ppbCmKpXv9jyERWFkKhIVFetIdHwbdldlRmrVlUBkqOMbDPiU9ORlBCLc4mnkZ50GlnJsTCfj4fxfDx8088gICNR5YaEWpLsCeqByECgJQbIlKXw1pBsSVA3hCBFWkN8c0bKMltHyvKpGgH/MBklKxoh1WujavUoGHwD8w0qLt34YM4dh7cQoSUgYuOD2A4wuCAiIiojBhZEpSTBQ9X+/XH+r7+QePAgqjVujODOnZ1aKsqDXNxLNyhZ0Lx5gdtZMjJygo9CWj7kcS0rC+aEBLVk7Nlb8OsGBqqWD1vyeU7+RxSCoqIQKut1G8GnfRcYfH0LDIjOZ2TjWFIiks+czskNORsDc2octHPxMKWdgX/GGQRmJqnckDAtWSWo+8CCatIykn0WyD4szR2FtoacQxDOSm6Ij4yUlZOk3uLMShVP5J7UUBLvJeG+zqZnkdxhAPwDg+HnFwCjrz8T14mIiEqIgQVRGUgQEdSlC841aICgyEgYPGhOCaO/P/zq1lVLQTSLJaf1wyn4iMmT/yH5IVpaGjKPHlVLgaTLV43q9pYP1QpizfmwrdeOjka9mu0AyFIws0VD4rkLOHvmFFITYpB+9jQyk2PtuSG+aTm5IcEqN0S6ZVkT1HEBVSwXgMxTOa0h55xbKfKcJwMQIZHK262cyjM1E7INPsiCL7Lgg2yDL7LhA7NB1v1gNsq6r1osRtsi5b6AdV0zyeILmPzsi8HHDwZ1659z6+sHo48s/iqgkVuTnx9McuvrDx9Z/ALg43dxXYIfX19fmEzGPK1IRERE7sLAgqgSk0DIp1o1tQS0bFngdpa0NNW6UVC3K9UKEhcPZGfDHH9GLdi9u8D9GYOC8rR8OAUistSogWohwagW0hRo1LTI95KRlY2YxHiknDmN84mnkHE2FtmpsQg8/js6pm0o8bmRIMUPZtlzToFt5GDbrTzkZhmaY+DjczEAkoBH1o2+TsGPBD0WWTf5QjP6qTK5hdw3+atbpwDIIQgyqgDIX62bfHMCHwmETH459319A2DytQZA0qVPBT9+8DUZ4WsyMADychwYgYgEAwsiKpIxMBB+9eurpdDWj8RE5+AjJiZPFyxLaiosFy4g8/BhtRT8okYVXNgDjvyCj8gomKrkjDDl7+uD6KiaagE62Hez+/cfgJ+LDix29JuHxh0uR3ZWJrIy05GdkY7srAyYszJhzrKtZ8Ai97PTVbmWLUuGWizZWeo+zBmAWW6z1K3BusCSBaMlE0ZLFgxqPQsm632Tlg0fLVPdmrQs+GjZ8JVb1UaSBT8tG/6GrDzH7G/Ihj+yc1WEQ/BjgVuZNYMKdlLhHACpdyWtPgaHFiAV/FhbgaS1x9oKlKkZsc83ULX+5ARAzq0/tltp9TH4SDc235zWH2uLT86tH0zS6mNtAZL7quXHPwC+Pj4q8JEAyM9khDG/WS+pUBwYgaj8mHU2mqHnHhkR6a/1QwKBGjWA1q0L3E6CikJbPmQ9Pl7NAaJyROLigJ0Fv66xSpWCWz4io9Co3iWItYQhwnC2wJnS47RwtOl2NXz8PXhmck2DZslGVmYGslTQk67WVcBju3VYLHJrDXws2ZnqvgqCzDkBkQp8sjNkKDIYzFk5wY8EQdagR4IgWTdZ11XQo4IgCXyswZCEC9YASDqKyRDFjmS0MBOyEAAJitIKDoDcKFszIhO+yIBJBUDyruR+TgCU0/oj6zktPz4q6JFWH+kKZ3Fo9VG3EvBYb7XcwY9JWnsk6LG2AFlbgSTIMfpIa09OICQtQPYAyM8ffr7S8iOtPkZ78COBkMnoGa1AHBiBqHy/X7V0NpohAwsiqlDSDcq/YUO1FESToCIhIf/gI/ZiK4jl/HlYzp1DpiwHL47OldvJtvVxeauzBc6UvmtvPbSZMweBrVqr4zMGBapWGlk3BAbBGByk7svwvW67mDMYYDD5wi9QlirwSJqmAhbNnNPSo4Igaf1RwU86sh0CIAl2pCVIWoByAp90FfTIuq0lSNYz087B36gBlmxry08mjBIIWVt7bK1AtkUCH1urjy0IknUJE/xUm4lzHzYfgwU+tu5u+b4n9wdAku+TZQ14JPiRySuzpEzl/ViDIGuXt5xWoJxub/aub/YA6GLQI+uwrucEP76q2xsk4LG1Ajm0+OSsSwDkZw96DAYf1Nr0P3WMxgIGRqi5aRpiuw6Dj4+P+u7YBlGQNYMxJ/0pT7kh13rubTwgoCIqb9t1OpqhQZOhWiiPlJQUhIaGIjk5GSEhIRV+hiwWC+Li4hAZGQmjByUEU16sK/cxnztf5JwfqvVD03CybQTatjyKKONZ+/NjzOHYta8eau+ML94LGo05AYYEHhKASNBhDUBUMKICEQlKgoosU/txDFrKeTQxPSqX75bForqlqe5qEtxkZ6iAJyszTQVDEvjIfQl65H5Oy09OC5AKgByCHmnxUUGQtbVHgiqD6gqX091NAiFby49j1zejtfUnp+XHFvjk3JdQweTuPmwulqwFqqBIro40tUislnddWDRDgY85lluQ83mwP264uD3yPNcAzeC8H9uxqPvqMaPT8y8+R1zcXsrszzXk3tfFMtlfzj6sz3d8nrXcto39Mdu29n05vreL2xX0HE0iNftjqhnZfvwqGLM/J6c8O9sMH19fFcDZ921wfD3n48vZrVGdA0Ou17m4b1tLWs7jzvu2bmffnyHX/dz7tm2TE4Hay637ke1t51yt25+bc0xqXf3duPhaRnlvDs+1H6v8bbe+b4O0BlqP1x4A247N4XVUsGu0vo51/wbbYyZTvuW21zFI3RsdHzPCYLLeGgywmLMRNrcnIrTEglvaDdURMXV/hXSLKsk1MVssiEi3JL/CVKUR/Bs1KnCbcxs34fgdd6jgIX5XEHY3qQtzsAmm82ZE/peA2lpOUBHQrh2MAQGqq5aWdgGW8xdU0rq6n2H9RdtiUa0kOH/e5bnb0hqSJ2ixBiASjBjylOUEKSposT1mDVJy9pOzrUx+yF94HciFhtFf/TIPyVeXz5Hkq8CDWMzWQOVilzUJXi52fctpBZLFooKgnOBHdX2zdoOzmB1zgKzBT7bDPlXLT043ONt6TtBjC4Jygh657yNBEBzyf5BlvQwvnlBDWt6ucAVxR2NEQW+FP7uSuxnyL5ZgIxoJ2P3HSrTueQ08CQMLIvJqwV27qIkLpfXCpGmoecDaV9VG5gWJikKDzz8rsNVAumZZ0tJhuXBeDbsrwUZO0JHmXCb37Y9fgJanzLq9Q5n6BV1eIyMDZglgzl5sUXEJk8kebKhAwxpwOJflaoGxtaLYg5mLrSz27mES1LA1tXwYTTJiAuAw2aNcX/hZF7eTjg4WM/b8/h1arR1b5Ob/dZ+Jxu16qwEepJPExSXnvsofUp0nLGobi2OZdTt1K/9ZbM815xyHdY4ctW+JBNQ+rceo1i++JqzPV6MaaFpOV0i1b8vFx9V7y3kt22vmbGM7HtvrOB9jzrY52118Pzm3BvtjDsdl34f1+2/bj5wDtZ0555oy13PVucjpbqL2YVD3HY4D+d1an2/bj7UsKysLvj7Wv3lynLbjV4/n3t7anmN9vYvb5Lw/521s/QdzymztR/bH83s9WzuTfRvn5xry2e7iYznHam9fctxHrtdzbPvKKXNu3xJG63vM206Ws++8bWqO+4DT4yUJwEsjLekkPA0DCyLyahIsyGzoJyc+lNMs7dj709qUL48X1hVJHstpHckZgcpV1AVPZmZOq4g98LAGI7bgJE+ZYzDjWGYLZqytLJmZ1v5iZpWHIourGQICcrWe5G1RKXH3MHlMumewH73nkrox+aB5j+sQu7a66vNdWHeNhv3vgkFyLNxxrJQvduGtYFpRgZ9z2d7NP6HluruK3G1geG14GgYWRFQpZknHnNmInT4D2TEx9nJpqZCgQj3uBqpvrXSBktGoZCZ1F9Kys+2tKqprV+7AxVqmAhRbt698yxyCFmuZ/Zfi9HSYZUkqZCr00vDxsQcnFj8/XKhSxdqK4tw9zB6gBAXnU5YryFE5LWxlcSXp2y2j00giaUEDI5zu/iyiPXhoTKIKYXDISSmGZj2vR+y6J4oM2lt0vQqexu3f9uzsbPz222+IjY1F27Zt0bqQYSodbd68Gfv27cPAgQMRHR3t9NimTZvw77//OpWFh4djyJAhLj12ItIPCR6q9u+P83/9hcSDB1GtcWMEd+7stUnT8guxqWpVtbi8lSUjw6EVxdp64tSyUnD3sJzWmdzdw3JabLQs61wdEhTJfCepqepuIWM2lVhOS0murl1BDsFJEd3DHLuCOe3DV5KTKx8ZlUZGp5EhMaNsQ2Ii56JHggpPHLWGyNOZdBy0u/WIEhMTccUVV6jbNm3a4JdffsEdd9yB2bNnF/icn376CU8++STMZjN27dqFdevW5Qks5s2bp7br27evvaxOnToMLIgqOQkigrp0wbkGDRAUGckcgdK2skgXqIAAoJpr60cCC3sryfkLMF84j4RTpxDq5w+kpxfePcwxp8VedjFosb9GWhrMsiQmuvbgZWK+XAHLxWT84IIT7gsZ3tjeyuLh3cIaG2ri1Pr62F21ln1ghFqpvmjcQyarJKLKFLS7NbB46qmnkJaWhp07d6JKlSr4448/0L17d1x99dW46qr8m3ckoPj0009Ro0YN1K1bt8B9d+rUSW1HRET6IL/6m2SxDmco/cB9a9RAlTION6sSeyUwcQhIit89zCHhPlfAopLvs62TAkpQJEtKClxKArl8Apb8RworQfcwCVhc0MqSsmpVTv6SDIxwsZehGppTlc+Z7bauhkR61/6qMTD3H4ld1pm3q1ln3vbElgobtx2ZNKcvXLgQU6dOVUGF6Nq1q1q++OKLAgOLa67JGVbrxIkThe4/ISEBixcvVuPudujQAREREeXwLoiIyNOpseatF9WoXt2l+1bJ9wV1BXMMUHIl1xfVPUyen/MCmmpxMctSDoGcfaSw/LqHOQYttpHCbEGLBDYBAYj53zTnARHsJ0ZTQZHkNUkXRG/tckhUEd2iWvW4Rjdzm7ktsDh+/LiaaCN3ToV0idq2bVuZ9y85FhK4nDx5Ert378arr76K8ePHF7h9RkaGWhwnA7H9YiZLRZPXlODLHa9NJcO60hfWl37ooq5ktCNrLosrL51VK4tT8nyaw8hh1i5ejgFLnpyVgp57QY0Upl4jKwvm5GRAlvKgaWqwhP29L1OtUDJIgZq9PsAfRpm5OyAABn8/GP1zbg2qLGcwA4N/rsdkWz9/GAOs+7AOemB7jn0QBOsM3+QF3y3ymPoqyeu6LbCQoEKEhYU5lVerVs3+WGmNHj0ab7zxBvz8ckb8fvfdd3Hfffep1pB27drl+5wZM2Zg2rRpecrj4+ORnp4Od1SinAf5IHl6dFrZsa70hfWlH6wrK8lnkaWIkcPkcto24V9B1HwHWVmqaxgk4EhPh5YmSxqQntNSospUeRpgfcx+Xz2Ws50l/gy0M2eKrsfERLVUCPn3UiaFlH//VeDhp4IOVebvd/ExCUictrE+ZttW8nqs2+Z5LPc28rjOhkjmd0tfLG6+Jky1DqTh0YFFYGDOxD/nZRbbXAdve6y0evbs6XT/nnvuwTPPPKMSugsKLCZPnoxJkyY5tVhIDod0oSpq+vLy+hDJHyl5fQYWno11pS+sL/1gXXm2C3/+ieO3Fz1BXuQzT8O/SVNoGek5I4plZKhbLT1n5nC5zSmXxzOt22Ve3M7xMQlspPuZ9dZ2305+WbUGRhU6ebZ16GhbICODG6h1GehAWlycWmAcWl2ktUWCHHnM2iqjWmDya52x7cO2b9t+SnGhye+WvljcfE0YID9seHpgUa9ePfj6+uLIkSNO5XK/cePGLn+9oKAglXdREH9/f7XkJhXorgt7+RC58/Wp+FhX+sL60g/WleeS4Zpts9rnm2dhndW+2s03l2uOheo2Zm2FcQpGJGBRgUs+5bKeeXHdMXBxDnZsz5N9SNBj3Z81qLG/b8mFcQhoXJ0PUxg1oaTqVuZfRHczawDjH6BaWtLN2UgKrwZjYEA+gYtDsOO03wAYrQET82YqhmY2I33LFmQdPIh0Nw2TXpLrULcFFtJNSYaaXbRoEe66K2d2QZnLYu3atXjrrbfs223cuFF1RyruHBQS1Z0+fRq1a1+cjVBGm5Kcjm7dupXDOyEiIqp8XDGrvcuS8+WHQX9/l+a5FMXWrcxSYCCT0/qSX1BTYCCTX1DjEMjYym15Muo4JKiSOWBSU0sc0KSXdSLL3IFMIUGNvXUmTx5N3qDmYmuNtcXHFuD46a/bWVlHXXOc2FX6+Egw786JXYvi1vGqZs6cqbot3XTTTeqif+7cuaqr0pgxF8fm/eSTT9RkeLbA4r///sOGDRuQZJ3pVbo3SSuHPE8WGY5WAhaZw0ISw48dO4b33nsPN954I66//nq3vVciIiJv46mz2lcEdXHr5weTXOy6eCLKomgyiaQtkFEBy8WuYYUGMtZ1Kb+QlIQAkynf7mZOgYzDun0SSyHHIMMt5+rSXu6sgWRRrTMXu5kVEtQ4dD/LE+xYu5zZWm1U97MKDGhSHIZydiQthJ48lLNbAwsZAervv/9WwYOM4iSjNknrhXSRspHAw3ECvJiYGKxfv16tSwAi92WRJHAJLOS5MqqUDFm7fft2NeP2kiVLVLBBRERErlXZZrX3BAYfH5iqyCVccKmeL707SjN8qXTLyZ3jkm/3M8cuZ7ZuZOo5hbTaFNoVLcMpj8Y20WVFy9MdLJ9uZganQMYxxyafYKeAHBppDYp94UVdDuVs0FRbHuUmydsyB4Zk4bsreVsvYxZXdqwrfWF96QfrSl9YX/qht7qSS9V8AxmnoOZi8r8qtwY5pcqpyS+PxgPVmzcPwV27eNQ1sedO3UdERERElZ50QXJrHk2uHJd8AxnHYCe9mIFMQUGNBDTFmDsiOz4enoaBBRERERFRYXk0VapU2Pk5/8efOOaQb1wQn4gIeBrPb/8iIiIiIqokgjp1VKM/2UZXy3co5+hotZ2nYWBBRERERORhQzkruYOLChzKuTQYWBARERERedhoa7XnzFZDNzuS+7U9dKhZwRwLIiIiIiIPE6LDoZwZWBAREREReSAJIoK6dMG5Bg0QFBmpZpr3ZJ59dEREREREpAsMLIiIiIiIqMwYWBARERERUZkxsCAiIiIiojJjYEFERERERGXGwIKIiIiIiMqMgQUREREREZUZAwsiIiIiIiozBhZERERERFRmDCyIiIiIiKjMfMq+C++kaZq6TUlJccvrWywWpKamIiAgAEYPn769smNd6QvrSz9YV/rC+tIP1pW+WNx8TWi7FrZdGxeGgUUBpAJF3bp1XVk3RERERES6vDYODQ0tdBuDVpzwo5JGh6dOnULVqlVhMBjcEh1KUHP8+HGEhIRU+OtT8bGu9IX1pR+sK31hfekH60pfUtx8TSihggQVtWrVKrLFhC0WBZATV6dOHbibfIAYWOgD60pfWF/6wbrSF9aXfrCu9CXEjdeERbVU2LDzPhERERERlRkDCyIiIiIiKjMGFh7K398fzz77rLolz8a60hfWl36wrvSF9aUfrCt98dfRNSGTt4mIiIiIqMzYYkFERERERGXGwIKIiIiIiMqMgQUREREREZUZ57HwQElJSfjvv/9Qu3ZtNRkJudb27dtx/vx5p7KaNWuicePGebbdu3cv0tPT0aZNG/j6+ua7v4rcprI4cOAAYmNj0aNHjwIn4/n3339VPcr58vPz08U23kg+s9u2bVPfoYYNGzo9dvbsWezatSvPczp16oSAgACnsuTkZFXvUVFRaiKo/FTkNt4oIyNDfU5lPPp69eoVOPnr/v37ce7cObRu3brAZFFP28YbnT59GnFxcWjUqJGarDf3Z3jnzp15ntOhQwcEBQU5lcnEZlLvERERqF+/fr6vVZHbeOukyvI51TRN1VdBn1O5tpO6a9WqFQIDA3WxTYnJzNvkOV588UXN399fa9WqlRYQEKCNHj1ay8rKcvdheZXWrVtrDRs21Hr27GlfXn75Zadtjhw5ol1yySVajRo1tAYNGmhRUVHaunXr3LZNZbFs2TKtd+/eWnh4uCZ/nlJTU/Nsc+LECa19+/ZatWrVVD3KeVu5cqVHb+ONzpw5oz366KNarVq1tMDAQG3ixIl5tlmxYoWqR8fvmixyzhy98cYbah8tW7ZUtzfccIOWnp7utm28TUpKivbggw+q75X8rZG/MW3atNG2bdvmtN3p06e1Ll26aGFhYVqjRo3UZ/r777/36G280c8//6x17NhRq1mzpqqvoKAgbdKkSZrFYrFvI/9G5PfdOnTokNO+3nvvPfX8Fi1aqNvBgwdr58+fd9s23uj999/X6tatq64tGjdurL5nUuYoPj5e69GjhxYaGqo1adJE3X799dcevU1pMbDwID/99JNmMpnsF5UHDx5Uf0hnzpzp7kPzKvLlf/311wvdplevXlr//v21zMxMdf+RRx7RqlevriUnJ7tlm8pi+vTp2vr167VvvvmmwMBiwIABKviwXQxOmTJF/VFMSEjw2G280fbt27VZs2apf6DkIqigwEL+phVm8+bNmsFg0L777jt1/+TJkypYmTx5slu28Ubyb8mcOXO0CxcuqPvyt2bEiBFavXr1nC5W5UKwa9eu9u2ef/55rUqVKlpsbKzHbuON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feyDDz5Qv2DafP3116qblNSv9Nt/5JFHVKuqI0/bxttIArCtf74j+fVf/kYK+T7J90y628j3TOpQ6liuGxzFx8erz7sMViKzYd9zzz3qb5S7tvFGMtP4u+++q1rUwsPD1b9VMjJU7hnQpYVg3rx5SElJUS2HMpBM7hnVPW2b0mBgQUREREREZcaO+0REREREVGYMLIiIiIiIqMwYWBARERERUZkxsCAiIiIiojJjYEFERERERGXGwIKIiIiIiMqMgQUREREREZUZAwsiIvIo33zzjZostDwsX74chw4dKpd9ExFVdgwsiIjIo9x9993YuHFjuexbZideu3ZtueybiKiyY2BBRESVxrXXXovGjRu7+zCIiLySj7sPgIiI3O/XX39FQEAAunTp4lT+yy+/qPKuXbuq+6mpqao1ISMjQ5VFRUXl2VdWVhb+/PNPJCUloXPnzk7brF69GmfOnIHBYEDNmjXRvn17VK1aNd9jOnXqFP7++2+EhISgR48e6jnFtW3bNpw4cQJNmzZFy5Yt7eVXXnkl6tevr9YPHDiArVu35nlu8+bN1XGJzMxMbN68GcnJyWjVqhWDEiKiQjCwICIibNq0CR9++CH+++8/+9mQi+rrr78er7zyigoi1qxZg2HDhqmL6ypVqqjg4bXXXsOECRPsz9m+fTtuuOEGGI1GtGjRQnU9ev755zFq1Ch7oCIX9JqmqVwHyaVYunQpevXq5VQLn3zyCR599FFccskl+Ouvv3DppZfihx9+gL+/f6G1JQHP1Vdfrd5Hhw4dcPDgQRVcyGtIYCLHM3XqVDRq1AiHDx/Gt99+a3+u2WxW+R0TJ05UgcWOHTswdOhQVKtWDbVr11YBxo033oj33nuPnxgiovxoRERU6R07dkwzGAza5s2b7efim2++0QICArTk5GQtLS1Nq1u3rvboo4/aH//00081f39/7dChQ+p+enq62ub222/XsrOzVZk876effirw/L744otamzZtnMqqV6+u1a9fX4uPj1f3T58+rUVHR2uvvfZakfX0/fffa+Hh4dq5c+fsZd9++61mNpvVuuz3ww8/zPe5jzzyiBYREaEdOXJEy8zM1Bo0aKC9/vrr9sfj4uK0mjVral9++WWl/7wQEeWHORZERIS6devisssuw+eff24/G7IuOQnSFen333/H8ePHMXnyZPvjt912GyIjI9Wv/EKSomWbl156CSaTSZVJN6qrrrrK6QxLK8XKlSuxaNEi+Pr6YteuXbhw4YLTNmPHjkWNGjXUenR0tHqtxYsXF1lTgYGBqtXi33//tZcNGTJEtaAU5rPPPsMbb7yBJUuWqK5S69atw9GjR9X7k7KvvvpKlUlrjdwSEVFe7ApFRETKyJEjVTch6d4kF/rff/+9uvgXcpEdFhamugXZSNci6VIkj9kCBglC8su7sJGuSHPnzlW5FxI4pKWlqfL4+Hh77oNo0KCB0/MaNmyIBQsWFFlTl19+OR588EF1K8fRv39/jBs3Du3atSvwOVu2bFEjUUlgIcGVOHLkCPz8/PDdd985bStdopo1a8ZPDBFRPhhYEBGRMnz4cHXhLwnWp0+fRnBwsMpXEBIESOJ2dnY2fHwu/tORmJhob1mQwOPcuXOqxSC/XAhJqH777bdVjoVtZCbJW5DcCcm5cCSJ37nv216nKDNmzMBzzz2nErO/+OILlZAuuR+tW7fOs21MTIzKo5AWEsdcEQmQJMfko48+UvkkRERUNHaFIiIie2AwaNAg1QVKlptuukl1VRLSwiABxbJly+xna9++fdi9e7c98bpPnz5qG8fuVLbWCNtFvHRVcmyZkG5G+XFMqpagQ7pb9ezZs8iakteQJGw57m7duqlWCBl1Kr/RnyRwkETzJk2aYM6cOU6P9e3bV7VYfPDBB07lsu/Y2Fh+YoiI8sEWCyIispPRm0aPHo309HT1q7+NDA371FNPqV/2JaCQi/VXX31V/drfr18/ey7Eyy+/jHvuuQc7d+5Uw7PK0LTS0iDl3bt3V7/+S8AyePBg/PHHHyp3IT8SsMgIVDI8rHTJklGeCgpCHEkuiBy3PLdevXoqH0K6bEnXqNwkF0RGnHr99dfVqFG5h5udPXu2asGR9yujYsnwtbLd9OnT1fETEZEzg2Rw5yojIqJKSrox3XnnnaplQYafzW358uWq65L82i8tFZJU7dg1SkgwIQGDdIvq3bu3ClRsc1DIEK/vvvuualmQC3hJrH7hhRfw5ptvIiIiQm0jORHynL1796qWBgliJFgp7sR2e/bswcKFC1UgIDkgt99+O+rUqaMek0BBWikkGJJcD0kiz01abeR9CelCJXkm0jVM9jVixAh13ERElBcDCyIiIiIiKjN2hSIiIt2QVogNGzbk+5jkVcgEdkRE5B4MLIiISDdOnjzplNjtSObMYGBBROQ+7ApFRERERERlxuFmiYiIiIiozBhYEBERERFRmTGwICIiIiKiMmNgQUREREREZcbAgoiIiIiIyoyBBRERERERlRkDCyIiIiIiKjMGFkREREREVGYMLIiIiIiICGX1fy2e3uXpFRxpAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_metric_vs_vocab_size(\"compression_ratio\", \"compression_ratio (tokens / amino acid)\", \"Compression ratio vs vocab_size\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "dcd6d085", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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MbAgIqJqqUWLFrj00ksDvRlERCEjItAbQERE/pWZmYkff/wRw4YNQ1xcnHV5RkYGfvrpJ1xyySWoUaOGWrZx40bs3LkTDRo0QK9evRAWVvZ81IEDB7B+/XqkpKSge/fuCA8PV8uPHj2KZcuWqduxsbFo27Yt2rVr53SbiouL8c8//+DQoUPqferXr+/255HtXrt2LSIiItT7JyQkqOVNmzbFoEGDrOt9/fXXKCwsLPP8K664ApGRker2vn37sGHDBtStWxddu3a12z9ERFQ+BhZERCFGgoa77roLJSUluOGGG6zL33vvPbzxxhu4+uqr1WNXXXWVCgzOOussFWBIY3/x4sVISkpS62uahrFjx+Ldd99VwUBBQYFq3H///feqcZ+amopvvvlGrXvy5EksX74cF110ET755BMYDAbr+2ZlZan3kODDZDKphv3cuXNV4FMRef0bb7wR3bp1Q1RUFHbt2oW33noL/fv3V0OhHn30UevryLbn5ORYn7t582Zs2bIF2dnZarvvv/9+tW2yLenp6Thy5Ajmz5+PHj16+HT/ExFVWxoREYWcW2+9VRs8eLDdsi5dumiTJk1St19//XWtTp062r59+9T9nJwcrXPnztrtt99uXf+NN97Q4uLitH/++ce6bMWKFVpaWprT9zx27JjWoEED7csvv7Que+211zT5p+i5556zLnviiSe0+vXra3l5eRV+ju7du2vTpk2z3s/IyNCWLVumbr///vtao0aNnD5vz549Wr169bSHH35Y3X/77be1Vq1aaenp6dZ1pk6dqrVr167CbSAiIjPmWBARhSDpqZBhT2lpaeq+nLmXoUiWHgzpMZDbMpxI1KxZE/fddx8+//xz62t8+OGHqregc+fO1mW9e/e29mhYhjitXLkSX331FX7++Wc0adIEq1evttuW6Oho3Hvvvdb748ePV9v1+++/V/g5pJdj+/btqrdE1KlTB+eee265z5HeE8m9kJ6I6dOnq2Xvv/+++hy//vorvvjiC8ybNw/x8fHYunWr6rkgIqKKcSgUEVEIksZ3w4YNVaAgjfpPP/0UZ555Jtq3b2/NNRgxYoTdc1q1aqWGEh0/fhy1a9fG/v37cc0117h8j02bNuHiiy+25lfIECwZHmUJZiwkf0OCCwtp0EtwIttQkddeew233367Wv/ss89Ww55uu+02u9ezJcO3brrpJpVr8b///c+aM7J3714UFRXhyy+/tFtfhoXJciIiqhgDCyKiECQ5Dtdee60KKO655x589tlnqkfCol69eirJ25bclyRnS3J0rVq1VOK0K5MnT8YFF1ygejYsBg8erBr3tiTHwpY8LstkGyrSpUsX1QMivQpLly7FlClTVC6HfB5npk6dqnpOVq1ahcTEROty+Uyyrc8++2yF70lERM5xKBQRUYiSoU7SwJaG/8GDB1WgYdGnTx+VGC3J1BYyREiGOlmqPg0cOFD1eNie0ZdhRnl5edaqUNJTYSH3pdHvSIIIS/UoIRPmyfu6kzQtVaQsvR7yeSQ4kqFXzixYsABPPfWU6qlo06aN3WMS8EiQlZub6/T1iYioYuyxICIKUZ06dVIXGQolZ+ulcW4h1ZQkkJChTJdffjn++usv1TC3DQAee+wxLFmyRAUbo0aNUnkO0miXwEDKtA4fPhwvvPACYmJiVNUlGbYk145kiJTkakhQIAHFjBkz1G3Jx6iIbFuHDh1UVar8/Hy8+OKLdgGSbcAzcuRINQRMAhnJIbEtN/v444+rHg8JZmRolWy/BF27d+92K9eDiIgAg2Rwc0cQEYUmaWBLz4TkHchZe1uSDyGlW2UeCyk1e8stt5SZh0LO8EuZWikRKzkbso7kYggJEqR8q5R9lZyHoUOHYs+ePSqvQcrdCplPQ2bflveXbTl8+LBq/EugYluS1hVJDpeeBgl8pNysBEiSmC3vIe8rSdhSQle2UwIGZ2T7JZCQwES2VwIKCYak7KzkkDgLhoiIqCwGFkREREREVGk8DUNEREFLhlo5JndbSBUr2xwOIiIKLAYWREQUtCTv4cCBA04fk7K0DCyIiIIHh0IREREREVGlsdwsERERERFVGgMLIiIiIiKqNAYWRERERERUaQwsiIiIiIio0hhYEBERERFRpTGwICIiIiKiSmNgQURERERElcbAgoiIiIiIKo2BBRERERERobL+D9b/7RINVVngAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_fraction_short_sequences():\n", + " metric_keys = (\"fraction_encoded_as_1_token\", \"fraction_encoded_as_2_tokens_or_less\", \"fraction_encoded_as_3_tokens_or_less\")\n", + " labels = (\"<=1 token\", \"<=2 tokens\", \"<=3 tokens\")\n", + " colors = (\"tab:red\", \"tab:orange\", \"tab:green\")\n", + " fig, ax = plt.subplots(figsize=(8, 5))\n", + " for metric_key, label, color in zip(metric_keys, labels, colors):\n", + " values = [per_vocab_size[str(vs)][\"splits\"][\"train\"][metric_key] for vs in vocab_sizes]\n", + " ax.plot(vocab_sizes, values, marker=\"o\", label=label, color=color)\n", + " ax.set_xlabel(\"vocab_size\"); ax.set_ylabel(\"fraction of train sequences\")\n", + " ax.set_title(\"Short-sequence mass vs vocab_size (train)\")\n", + " ax.legend(); ax.grid(alpha=0.3); fig.tight_layout(); plt.show()\n", + "\n", + "\n", + "plot_fraction_short_sequences()" + ] + }, + { + "cell_type": "markdown", + "id": "b101cada", + "metadata": {}, + "source": [ + "### Token count distribution per sequence (train split)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b98a0711", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAN2CAYAAAAosDpEAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAzHJJREFUeJzs3QeYE9X38PGzsPSy9N6L1BWR3nuVpiCgSLGDCAKiCBbkJ1IEKSoC0gQEQRFRUBARpPfmIiBFpPfe2+Z9zn2f5J8syZLdTbIp38/zzG5mMjOZmSRzM2fuPTfMYrFYBAAAAAAAAPChJL58MQAAAAAAAEARlAIAAAAAAIDPEZQCAAAAAACAzxGUAgAAAAAAgM8RlAIAAAAAAIDPEZQCAAAAAACAzxGUAgAAAAAAgM8RlAIAAAAAAIDPEZQCAMTb66+/LmnTpuUIJoKwsDB55513bOPHjh0z0yZMmOCT13f2ert27TLTvvnmG59sg6vtADzl+PHjkiZNGlm8eLHPDmogfKadbWNct/u///6TFClSyJ9//unFLQUA+DuCUgAQYubNm2cuHNwZ9u7dm9ibG1QOHDhgjuvkyZPFX/jjNgXiNiI49e/fX8qUKSNNmjSxTePz6L7YjlWBAgXkhRdekN69e0t0dLSH3jEAQKAJT+wNAAD4Vps2bcRisThMy5Ahgzz22GPcsQ5gefLkeeB9DabX8/ftQPA5fPiwzJo1y6c1/wL5Mx2f7e7evbupWaU10Z544gmvbRsAwH9RUwoAAACIYdKkSZI6dWpp1aoVx8ZLSpcubWqi+XNTRQCAdxGUAgA4pXk+6tatK+nSpTMXZhUrVpTvv//+oUdr586dkjdvXqlUqZKcPn3aTLtz54589NFHUqJECZNDJEuWLNKhQweTg8RZPqI5c+ZIsWLFJGXKlKYG1/Lly916l27fvi0ff/yxudBJlSqV2Y5XX31VTp06ZZvnwoUL5u683tVPnjy55MuXT3r16iVXrlyxzbNkyRKzLTFzndy7d89Mf++99+K83cuWLZOiRYuaxy+//LKtiWTfvn1j3acTJ05I+/btJSIiQjJmzGiau1y7du2B+Zzlc9FaCyNHjpRSpUqZvDi5c+eW1q1bS1RUlFvbZL9vM2bMMO9feHi4We5h+WOmTJkihQsXNseifPnysnTpUofn3T3GD9tGV9vhzvuc0M+c/fIP29/4fA9iHnNnHvYex+W1Y/u8xcxhFpfvSHz23Z33w53vu7v77czChQulSpUqZt1WCfnOWI+NddDPpX5mtIngzZs33c7XFp/Pqjufk7h+nmOKud3unvO0nPn999/l1q1bD30NAEDwISgFAHiANqWoX7++uXDRi5Z///3XjLdt21a+/PJLl0ds0aJFUr16dalcubK5WM2ePbvcv3/fNMsYN26cDB48WM6cOSPr1q0zAatq1aqZ4EHMC8GtW7eaC62DBw9Kzpw5TU2FmPPFpBd8mvdl9OjR5iLv6NGjsmHDBqlQoYK5wFI3btyQWrVqmdfQC8Zz586Z2hBz586VevXqmQvY+HrYduvx279/v3msr6kXidYLRVeuX78uderUkW3btpkggDYn0mOpwRZ3fPbZZyY48L///c8c7x07dkinTp3k008/jdM2zZ8/32yDXjjqMdXmng/LW6YXuKtXr5Z9+/aZoIFu94oVKySu4nPc4vo+x/czF5f9jev3wN1j/rD3OC6vndDPmyveOAe4832P6+vau3z5sjn3aUDGXkK+Mxqcss6vw9mzZ2XMmDFmezWvkjvi+1l153Pi6e+vu8dKb3hogHHjxo1xWj8AIEhYAAAhLyIiwlKrVi3bcShZsqSlaNGilnv37jkcm0aNGlnSp09vuX79uhnv3r27JU2aNObx6NGjLUmTJrW88847lujoaNsy06dP1yQjloULFzqs69y5c5a0adNaBg4caMajoqLMfDVr1nSY759//jHTx40bF+v7NHnyZDPf/PnzXc7z2WefmXmWLl3qMP3HH3800ydNmmTGFy9ebMZXrFjhMN/du3fN9Hfffdc2LS7bvX//fofXeZixY8ea+devX+8wfcyYMWZ6v379bNOOHj1qpo0fP942rVWrVpayZcvG+hqxbZN13ypUqPDAc85ezzp/pUqVHObVz1HhwoUtFStWtE2LyzGObRudbYe773NCP3Nx2d+4fg+cHXNn3HmP3X3tuHze4vL+eeMc4M733d3XdWbXrl1mWf0seeo748rIkSMtyZIlM8fuYd+t+H5W3fmcxOXz7GwbnU1z55z3559/mnn0/QIAhB5qSgEAHGjTl927d0vLli0ladKkDyRJ1+ZPmzdvtr+5Id26dZO3337b9LA0dOhQ00TD/s6+Nhex771KZc6c2TQ9WblypcP0mMluH3nk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JUsWmTNnjlcOa4ECBWTy5MleWTcAwHO4NgDcR1AKQKwsFossW7ZMWrduLcmSJZM2bdo4nW/Xrl1Su3ZtSZUqleTMmVPee+89iY6OjvM8AAD/dObMGRk2bJgULFhQwsLCzDndWZkxaNAgyZ07tznX16hRQ3bs2OGVeQAAwX9twDVG8CMoBfi5Ll26yLFjxxLt9ffv328uQtq3by8NGzZ0Os/ly5elfv36UrhwYTl8+LB89913Mn78ePnoo4/iNA8AwLX//vtPXnrppUQ7RB9//LFcunRJPv30U5fzfPLJJzJmzBiZNWuWHDlyREqWLGnO/efPn/f4PAAQikLp2oBrjBBhAQLUiRMnLEmSJLGsWrXKYfrcuXMtqVOntly9etWMz5kzx1KiRAlLsmTJLPny5bMMGzbMEh0d7bDMn3/+aalRo4YlVapUlgIFClhGjRplm2fx4sUW/arokDJlSkuZMmUs8+fPd1j+888/txQtWtQyePBgS+HChc18TZo0sRw/ftytfTly5IilRYsWlowZM1qyZs1q6dixo+X06dPmuWnTplly585tmzdz5sy27bEfLl68aNuXqlWrmm3Q5V577TXLlStXLJ7QsmVLS+vWrR+Yrvuvx/zGjRu2aXosdH/u3r3r9jwAEB9du3a11K1b94HpJUuWtHzwwQfm8dmzZy3PPvusJUOGDOZc37BhQ8uePXsc5tfzU58+fSx58uSxpEmTxtK4cWPL/v37bc9XqlTJds7NmTOnpUuXLpZz5845rEPP0fqauj3p06c365owYYLb+6Lzanmi2/joo4+aMs0qf/78lkmTJtnOqc7KgjfeeMM8f/PmTUvv3r3Nduq5t0KFCpalS5daPGH79u3mtaKiohym379/35ItWzbLoEGDbNNu3bplSZcunWXkyJEenQcAYuLaIPiuDbjGCA3UlELA0iqedevWNXdR7el4q1atJG3atLJu3Trp0KGD9O7dW86dOycTJkyQIUOGmP9WGzZskAYNGphI/aFDh+TPP/+Uo0ePmseqcePGppqqDrqOt99+W5599lmJiop64K7BmjVrzPL//POP3Lx509xBcEf37t0ladKksmfPHrOsvubcuXOdzqvbYN2eu3fvmiqvFStWlHTp0smWLVukefPm8tprr5lmFqtXr5a9e/fKyy+/bFte59FmF7ENvXr1itN7oce5UqVKpuqtVb169eTixYtmn9ydBwDi47nnnjPn3hMnTtimbd++XXbv3m2eU1oW/Pvvv7J582bzP1OmTNKoUSO5deuWbZm2bdvK4sWLzd3akydPmnOhfRmj5YWee7VpgZ5f9U61nm9j0lo+Xbt2NWWJ3k3u0aOHLF++/KH7sXXrVunZs6fJRXLhwgWZPXu2/Pjjj3L//v0H5n399ddtZYEOS5YskfDwcKlTp455Xssp3X89LloeaDnYsmVLh7KrWbNmDy0PtGaUuw4cOGBeS8slqxQpUkjVqlVNGeDJeQAgJq4Ngu/agGuMEJHYUTEgIbQWUaZMmSx37twx4+fPn7ckT57c8uuvv9qi90899ZTDMgMHDjR3m620hpLeDY+LJ554wuEOrkbxtdbW0aNHbdP07rp+xTZv3vzQ9UVGRlrGjh3rch/ta0rZ0zsdehfcWiNL97V79+4O8+zcudMSFhZmqznmjbshderUsbRt29Zh2sGDB83+W+/MuzMPAMSH1mwtWLCgQy2aN99801KxYkWHmj1//fWX7fnLly+bmjd6jlXbtm0z82zYsMHt19Xzu9bCvXfvnkNNqZdfftlhvg4dOphy42F++OEHU1vWVe1R+5pS9vbt22dqgGn5pnQ/9bxvrXFr9eSTT1r69u1r8VZNqZUrV5rpu3fvdpiutX/1Lr0n5wEAZ7g2CK5rA64xQgM1pRDQNMGe1kjSO9vq+++/lwwZMpiaT0rvEmsE3l6VKlVMu+UbN27Y7qbXrFnT5WvofHp3QHs9Sp48ublb8Msvv5gcF/ayZ8/u0EtekSJFzLboNjyM3lF/5513zJ38adOmmTv0DzNp0iSZMmWKuYueK1cu250ObYutd8u15lWSJEmkTJky5i66teaXr+hrKj1eCZkHAB5GzyFaM8haq0lrMmkPeNZaUnoe1juxkZGRtmXSp08vpUqVsp2jtSxImTKlubvsiiZ21YTbGTNmNK9ZoUIFc1c65jm7fPnyDuM6nztlgd4h1hpcet4eOHCgrFq1ymktKXtXrlwxNaC0hpQuYy0L9PyqZYN9eaDlhdYS8zXdloed5z01D4DQxrVB8F8bcI0RfAhKIaBptVStkmq9ENH/2mROT7z2Jy17Mac97EeuBotWrlwp8+fPN9VJdX4t8O7du+cwX0J+KGuV2r/++stcuPzwww9SqFAh+eqrr1zOv3btWtN0Q+exD7rphZgmB9Rt0wsZHbc27bBejHmjim6OHDnk7NmzDtOs4xqsc3ceAIgvDUBpYEmr/GuTtdOnT0u7du1iPc/bT3dWXtg7fvy4tGjRQp588knT9EHPs9amcJ4qDyIiImTnzp2myZ8md+3UqZOUK1fOZRM6PcfrzQwt82bMmGF7XZ2uAbbbt28/UB5oGeOt5nt6nlfOzvX2ZYEn5gEAZ7g2CK5rA64xQgNBKQTFhcjChQtNd6Ga08l6Z1zpXfBNmzY5zL9x40bJnz+/pE6d2ow//vjj5m60K9a8VDpfmjRpzAl927ZtD8x36tQph54wNCeG/pgvUaKEW/uhNav0hL9o0SLTHarmJHFGc5RoUEyDUnrBYk+3UfOKxEbv4NvnIXE2aI9HcaF5PvS4aq01K82forUJihcv7vY8ABBfeh7Rc6DenNBBewTKli2brSzQWq9aTlhdvXrVBLCs52hdVvNLac4pZzTgpXeY+/TpY34s6x3nmOWLVcx16Li7ZYHmTtKbLXoe1tpVeidbywVntKxYv369/PTTTyaPopV1XzQ4Fxtd78PKA63x6y4tx/SYr1ixwjZNA2NajmoZ4Ml5AMAVrg2C59qAa4wQkdjtB4GE0nxSmsNDe8V75JFHHJ5bs2aNJTw83DJ58mSTP2TJkiUm78aXX35pm2fdunVmno8++sjk3zh8+LDpfUnbNFtzgWgOC22brc+/+uqrpq1z586dbeuw9oKkuak0r5Suo3bt2pZq1aq53R77t99+s1y6dMly8uRJS/PmzU3PUDFzSum+litXzjxnn8PEauPGjSa/ifa4dOzYMcuFCxdM74HO2np7st24bnf27NktL7zwguXMmTOW1atXm1xfH374YZzmAYCE+PTTT03epYiICMvs2bMdnmvQoIE5lx84cMCcy7UnPu2RVXups2ratKmlVKlSJq+U9kykZYb1HPXPP/+Y3IHffPON5fr165bly5dbcuTIYc79hw4dsq1DyyPt4ei7774z5Y7Or+fl33///aHb//XXX5vX0xxR2tucnr+1fFq7du0DOaU0/5SuV7fD1fla82z98ccflmvXrln27t1regWMeVw8mVNKDR061PSctGLFCtPj4SuvvGKOiX0vhZ6aBwCc4dogeK4NuMYIDQSlEBS6detmfiD/73//e+C5OXPmWEqUKGFOyHnz5rUMGzbMJMW1pz/aK1eubC4kChUqZBk9erRtHg1GNWnSxHRZqj+QNdFqs2bNHghKaRfeGtjS5XU9jRo1ckh8HhsNnun82n14lixZTNI/LThiBqX0h7mzLsDtu33VdWlX5Nqduf6A1+S6WiAlhK4r5uvpuu1pYt2aNWtaUqRIYQqYAQMGmG694zoPACSkO/CkSZNa0qZNawJH9vT8qYEoDVilSpXKBKn27NnjMI8u07NnTxNs0nXouV+DWFZfffWVKUe0PCldurRJrO4sKKXBH03Oqud0PX/b3wiJjSad1R/jWp7oNmqAbOrUqbbn7YNSmrjWWVnwxhtvmOc12Na/f3+zjHYAUrx4cdPVdszjEhcjRoxw+ppaBlpp2akJ1zXRrp7r9eaMJpG356l5AMAVrg2C59qAa4zgF6Z/Eru2FgAAAAAAAEILOaUAAAAAAADgcwSlAB8oXbq0y94sRo4cyXsAACFg3rx5LssC+0TlAIDgxrUB8H9ovgcAAAAAAACfo6YUAAAAAAAAfI6gFAAAAAAAAHwu3PcvCQCAZ0VHR0uSJA+/z3Lv3j0z2NPlkidPzlsCAAAA+Bg5pWK5wDlx4oSkS5fOJCAFgFBmsVjk6tWrkitXLreCP74ydOhQGTNmjJw7d05KliwpY8eOlbp167qcv2vXrjJp0iRJliyZbVqpUqVk69atbr8m5QMA+H/5kBgoHwAg7uUDNaVc0IBU3rx5XR44AAhFR48elTx58og/mDBhggwZMkR+/PFHqVy5sowYMUKaNWsmf//9txQsWNDlck8++aTpBS2+KB8AwL/Lh8RC+QAAcS8fCEq5oDWkrAcwffr0Lg8gAISCK1eumEC99dzoD0aNGiUvvvii1K9f34x/+OGHMm3aNBOsGj58uEea+zlD+QAA/l0+JBbKBwCIe/lAUMoFa5M9DUgRlAIAx3NjYjt//rzs379fatWq5bBtOr5+/fpYl/31118lRYoUpoCsXr26fPrpp1K0aFG3X5vyAQBcnxtDGeUDAMS9fAjtht8AgIB0+vRp8z9r1qwO07Nly2Z7zpnixYvLTz/9JNeuXTN5pLStuwayLl686HKZ27dvmzs99gMAAACAhCMoBQAIWNoML+Z4bHdjevXqJQ0aNDA1pTTv1KxZs+TSpUsyd+7cWJOpR0RE2AbyDQIAAACeQVAKABBwcubMaf6fOXPGYbqO58iRw+31aPNsTbx48OBBl/P0799fLl++bBs01yAAAACAhCMoBQAIOBkzZpSSJUvKihUrHGpJ6Xi1atVs0+7duyd37txxuZ4LFy7IkSNHYu0RRGtVWfMLkmcQAAAA8ByCUgCAgNSvXz+ZOnWq/PDDD6Yb7j59+phcUd26dbPN07VrV3n88cdtuaGaNm0qq1atMonSt2/fLm3atDEBrueeey4R9wQAAAAITfS+BwAISJ06dTJBKG1ep8nNIyMj5ffff3eo9ZQsWTJT00np/759+8rgwYNNQEqDUTVq1JAZM2ZI5syZE3FPAAAAgNAUZtGuh/AA7V1JE9pq/hBtrgEAoYxzIscCACgfKCsBwNPXD9SUgl+JnB4Z52WiOkd5ZVsAAN49f7uDczwABOb524rzOIDYkFMKAAAAAAAAPkdQCgAAAAAAAD5HUAoAAAAAAAA+R1AKAAAAAAAAPkdQCgAAAAAAAD5HUAoAAAAAAAA+R1AKAAAAAAAAPkdQCgAAAAAAAD5HUAoAAAAAAAA+R1AKAAAAAAAAPhfu+5cEAAAAAO/ZuHGjfPnll3L69GmJjIyUt99+W7Jmzepy/lGjRsnPP//sMK1gwYIybdo03iYA8CKCUgAAAACCxpo1a6Ru3brSs2dPadGihYwbN06qVasm27dvlzRp0jhdZt++fWKxWGTQoEG2aa7mBQB4DkEpAAAAAEHj3XfflZYtW8rIkSPNeKNGjSRnzpwyadIk6dWrl8vltCZV7dq1fbilAABySgEAAAAICjdu3DA1pbSGlFXatGmlfv36snTp0liX3bp1qzRt2lSeeeYZ0/Tv3r17PthiAAhtBKUAAAAABIVjx45JdHS05M6d22G6jh8+fNjlcilTppSnnnpKunbtKjVr1pThw4dLgwYNzLpcuX37tly5csVhAADEDc33AAAAAASFO3fumP+pUqVymJ46dWrbc84MGTLEzGOlOalKliwp8+bNk7Zt2zpdZujQoQ45qAAAcUdNKQAAAABBIWPGjOb/+fPnHabruPU5Z+wDUqpYsWJSoEAB2bFjh8tl+vfvL5cvX7YNR48eTfD2A0CoISgFAAAAIChoM71s2bLJtm3bHKZv3rxZypYt6/Z67t+/LxcuXDDN+lxJkSKFpE+f3mEAAARY873Tp0/L7Nmzzf/IyEhp166dhIfHvll//PGHrFu3zsxXvXp1qVGjhsPz33//vaxdu9Zhmva40a9fP6/sAwAAAAD/0KVLF5k8ebK8+uqrkj17dlm4cKFERUXJxIkTbfOMGDFCdu/eLdOmTZO7d++axObdu3c31xeaR+r999+Xq1evmjxTAIAgDUrt379fqlWrZu5aVKxYUQYOHGgKht9++02SJk36wPxaQJQvX14yZ84sVapUMdVkmzdvLs8++6wpSOyDVhs2bDAFklWWLFl8tl8AAAAAEseHH34oe/bskSJFikjBggXNNceoUaPM9YPVP//8Y2pPKb3u0ATpuXLlkvz588vx48clWbJk8sMPP0jp0qV5GwEgWINSWnOpePHisnjxYkmSJIm8/PLLpvDQmlMdO3Z8YP6wsDCZOnWqPPbYY7ZpDRs2lEaNGkm3bt1MTSsrXU+vXr18ti8AAAAAEp8mOf/555/l33//Na0xND9UpkyZHOZ56623bL3l6XWI1pzSpOUazNLcUxqccnaTHAAQJEEprSb766+/ypgxY0xBoPLlyye1a9eWBQsWuAxK2QeklDUQpXc07INSBw8elAEDBkhERIRp3le1alWv7xMAAAAA/1CoUCEzOKOBKmfJzsuVK+eDLQMAJHqi8yNHjsjt27elcOHCDtN1XKvYuuvrr782d0MqVKjgELzSuyGamFDvkNSrV0969OgR63p0W/Ruif0AAAAAAACAIKspdePGDfM/Xbp0DtO11wrrcw+zYsUKk4dq9OjRJs+U1TvvvGOq3Fq1b99e6tatKy1btpT69es7XdfQoUNNlV0AAAAAAAAEcVDKGoy6dOmSw/SLFy8+EKhyRnvfa9GihQlAaU8Z9uwDUqpOnTqSN29eWbNmjcugVP/+/aVPnz62ca0ppcsgbiKn/18TSndFdY7iMAMAAAAAEGISrfme5o9Kmzat7N2712G6jpcsWTLWZdevXy+NGzeWnj17yv/+9z+3Xu/OnTsmj5UrKVKkMLW07AcAAAAAAAAEWVBKk5u3bt3a5IS6deuWmfbXX3/J2rVrpW3btrb55s6dK8OHD7eNb9y40RaQ+vjjjx9Y771792TlypUO07Q3P+15Q3vqAwAAAAAAQAg331PDhg2TWrVqmSTlZcuWNb3xPffccyb3k9Xvv/8uGzZskH79+sm1a9ekUaNGJoG5Pu7Vq5dD3qjKlSubJOdDhgwxzfFKlSplEqqvWrVKPvroI/NaAAAAAAAACPGgVI4cOWTHjh2yePFiU5PplVdekerVqzvMo8Gm2rVrm8fh4eHy4YcfOl2XNQ9V0qRJ5bfffpNt27bJ9u3bpUmTJjJlyhTJkyePD/YIAOBL2jT7jz/+MGVIZGRknLryPnTokCkvHn30UalatapXtxMAAACAnwWlVKpUqeSpp55y+bx9YnKtIWVfOyo2jz/+uBkAAMHp7NmzpmdVDUxpYKl3797Srl07mTBhwkOXvX37tmlCrnkM9YYIQSkAAAAgBINSAADEhzbTVlorNnXq1LJ161bTHLx58+byxBNPxLrsW2+9ZeaNjo7m4AMAAAChlugcAID40mDSd999J88//7wJSCltuqc1nubMmRPrsj///LNptjdq1CjeAAAAACARUVMKABBwjh49KlevXpWSJUs6TNfxLVu2uFzu2LFj8uqrr8rChQslTZo0br2WNvXTwerKlSsJ2HIAAAAAVtSUAgAEHGtgKEOGDA7TM2bM6DJodP/+fenQoYP07NlTypcv7/ZrDR06VCIiImxD3rx5E7j1AAAAABRBKQBAwNFOMpTWlrKnASlrc76YZs+eLTt37jSBJU2GrsP58+clKirKPLZYLC5zV12+fNk2aC0tAAAAAAlH8z0AQMDJnz+/JE+eXA4dOuQwXceLFCnidBmt4dS+fXv566+/bNNu3rxpevHbsWOHCUqFhYU9sFyKFCnMAAAAAMCzCEoBAAJOsmTJpHHjxiap+csvv2yCSSdOnJAVK1bIxIkTbfOtXLlSTp8+LW3btpXatWubwd6GDRvMtDFjxiTCXgAAAAChjaAUACAgDR8+3PS217JlS6lcubLMmDFDKlWqJM8995xtnpkzZ5rAkwalAAAAAPgXglIAgIBUvHhx0xRPg1FaG6pv377SqVMnCQ//v6JNa0FpUz9Xnn76aXnkkUd8tMUAAAAA7BGUAgAErDx58siAAQNcPm9fa8qZd9991wtbBQAAAMAd9L4HAAAAAAAAnyMoBQAAAAAAAJ8jKAUAAAAAAACfIygFAAAAAAAAnyMoBQAAAAAAAJ8jKAUAAAAAAACfC/f9SwIAAACA95w8eVK++eYbOX36tERGRsqzzz4ryZIlc2vZDRs2mGXr1KkjrVu35m0CAC+iphQAAACAoLFv3z4TiFqxYoWkS5dOPv74Y2nYsKHcv3//octeuHDBBLBmz54tq1ev9sn2AkAoIygFAAAAIGj069dPSpcuLb/88osMHDhQli9fLuvWrZNZs2Y9dNnnn39eXnrpJcmXL59PthUAQh1BKQAAAABB4e7du7J48WJT2yksLMxMy5Mnj9SuXVt++umnWJf97LPP5OLFi/LOO+/4aGsBAOSUAgAAABAUjhw5Irdv35aCBQs6TC9UqJCsXbvW5XI7duwwzfw2bdokSZK4d99eX0cHqytXriRgywEgNFFTCgAAAEBQuHnzpvmvuaTspU+fXm7cuOF0mevXr0u7du1k9OjRkj9/frdfa+jQoRIREWEb8ubNm8CtB4DQ4zdBqejo6DjNb7FYvLJeAAAAAIEpbdq05v+lS5ccpmuzPA1MOWPtpU/zTr3++utmOH78uPz555/msavrif79+8vly5dtw9GjR72wRwAQ3BI9KKV3GLJnz266aNVeMjQRYWx+++03adCgge2OxBNPPCF79uxJ8HoBAAAABDZNUK6BqZjXBzpesmRJp8tUrVpVBg8eLMWLF7cNKVKkkIwZM5rH1txUMek8GuiyHwAAARSUmjBhggwZMsT0hKF3F5566ilp1qyZHDp0yOn82o2rVqvV5IMnTpyQgwcPSpo0aUyQyr4Nd1zXCwAAACDwaT6op59+Wr7++mtbUz7NF6W1oLSJntXs2bPN9YLSG9jWGlLWIUuWLFKmTBnz2FVQCgAQ4EGpUaNGyYsvvij169c3dzQ+/PBDUwBoUMmZpEmTypIlS6RevXpmfp33008/NdVrN27cGO/1AgAAAAgOw4YNM73wlStXzvTCV7duXenSpYs0b97cNo+2otDAFAAgRHvfO3/+vOzfv19q1aplm6Z3IXR8/fr1bq/n5MmT5r9Wr/XkegEAAAAEnmzZssn27dtN2g/NFdWzZ0+pXLmywzwdOnQwN7pd0XxRuXPn9sHWAkBoS7SglBYQKmvWrA8UItoVqzvu3LkjvXr1kooVK5o7IQlZL126AgAAAMFB8z21aNHC5fN16tSJdXn7pn4AgCBOdB6zNwsdd6fdts6n1XCPHDkic+fOfWCZuK6XLl0BAAAAAABCICiVM2dO8//MmTMO03U8R44cbgWktJvWFStWSIECBRK8Xrp0BQAAAAAACIGglOaA0m5ZNahkH2zS8WrVqtmm3bt3zzTTs5/nhRdekGXLlpl5ixYtGq/1xkSXrgAAAAAAACHSfK9fv34ydepU+eGHH+TEiRPSp08fuXbtmnTr1s02T9euXeXxxx83jy0Wi7z88suyePFi0wtf/vz55datW2a4f/9+nNYLAAAAAACAEEx0rjp16mSCRdp0ThOUR0ZGyu+//y558uSxzZMsWTJTi0lduHBBZs2aZR5rcnN7EyZMME363F0vAAAAAAAAQjQopV577TUzuDJ+/Hjb48yZM5taUZ5YLwAAAAAAAEK49z0AAAAAAACEHoJSAAAAAAAACJzmez/99JOsXbvW5HmKafLkyQndLgBAEKMMAQBQPgAA4hWU0gTio0ePllq1aknGjBk5ivAbkdMj4zR/VOcor20LAOcoQwAAlA8AgHgHpaZOnSq//fabCUoBAEAZAgBIKK4xACD0xCsodf/+fSlfvrzntwYAEPQ8WYasWrVKxo0bJ6dPn5bIyEgZMGCA5MyZ0+X8d+7cka+//trcWLl27ZqUKlVKevToIQULFvTI9gAA4o9rDAAIPfFKdK41pPQHPQAAiVWGrFixQurVqydFixaVt956S/bv3y/VqlWTq1evulzm+eefl927d0uXLl2kV69ecujQIalQoYIcPXo0wdsDAEgYrjEAIPTEq6ZUvnz5pEOHDtKpUycpUqSIhIWFOTzft29fT20fACDIeKoMee+996R169YyePBgM16nTh1TS+qrr76SN9980+kykyZNktSpU9vGNaiVJk0a+eOPP0ygCgCQeLjGAIDQEx7fu9PFihWTjRs3miEmglIAAG+WITdu3JANGzbIa6+9Zpumwab69evLsmXLXAal7ANSav369aa5iDb9AwAkLq4xACD0xCsotWPHDs9vCQAgJHiiDNHmdtHR0ZIrVy6H6TqutZ5io8Esbbp35coVOXXqlCxYsEDKlSvncv7bt2+bwUqXAwB4HtcYABB64pVTCgCAxHT37l3zP0WKFA7TU6VKZXvOlRIlSsiYMWPkk08+kZo1a5pE50eOHHE5/9ChQyUiIsI25M2b10N7AQAAAIS2eNWUUmfPnpWJEyfKnj17xGKxSMmSJaVr166SJUsWz24hACDoJLQMyZQpk/l/4cIFh+nnz5+XzJkzx7qsBpYqV65sHjdp0kSKFy8uY8eOlU8//dTp/P3795c+ffo41JQiMAUA3sE1BgCElnjVlNIcIJqcdvLkyaZJg96V1sc6zVl+EAAAPFmGaDO9HDly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vlE+JM71QzB/bl0JtX0Otf0NxX1OH+T76075kKi973Xv3l2mTJlicnnonYXPPvtMjhw5Iq+88optnrffflvq168fp2XcmQcAENi8VYYAAAIb5QMABI5Eqyml3nzzTTl58qRUrlxZkiZNaiKEc+bMkRIlStjm0Sqwp06ditMy7swDAAhs3ipDAACBjfIBAAKIxQ/cvn3bcubMGUt0dPQDz124cMFy6tSpOC0Tl3ngnlu3blkGDhxo/iNuOHbxw3GLv1A7dt4qQxJTML+H7FtgCtb3LVj3K9j3LZTLh1B9b0Ntn0Ntf0Nxn0Ntf2MTpn8SOzAGAAAAAACA0JKoOaUAAAAAAAAQmghKAQAAAAAAwOcISgEAAAAAAMDnCErBpYsXL0qePHkeGH7++WeOWgznzp2TESNGSOnSpaVUqVJOj8/t27fl3XffNfNoT1/aM8z169dD/lju3LlTunbtKvnz55e33377geOxefNmp5/D3bt3h/SxO3jwoLz++utStmxZefzxx81j7VUuph9//FFq1KghRYoUkRYtWkhUVFSibC/cs2fPHnnllVfk0UcflfLly5vzhJ5fgommsmzXrp35Hv/2228SLH766Sdp2LChPPLII9K+fXs5dOiQBIPvv/9e6tevL0WLFpWKFSvKwIED5ebNmxJojh07Zra9WLFiZn+cuXz5svTs2VOKFy9uvoODBg2Su3fvSqCXo/pbY9SoUVK7dm2zby1btpQ1a9YkyrYiYY4cOSJ9+vSRcuXKyWOPPWbKC50WCrQn3ZIlS5qy4/79+xLM9u7dK88995w5X+n3dsmSJRLMJkyYYH6rajlTrVo1GT16tERHR0sw0M+qXjs3adIk1t89ixYtklq1aknhwoWlWbNmsn37dgklBKUQ65fo+PHjMnXqVNmwYYNtaNCgAUcthsaNG8vp06elUaNG5pg58+qrr8rs2bPl888/l0mTJsmvv/4qHTp0COljuWXLFunUqZP58Z89e3a5cOGC02CeHtOVK1c6fA614AplelGhP86+/vprU5j//fffUqdOHYdAp37G2rZta4b58+dLtmzZTIF34sSJRN12OHfjxg3zXumF/zfffCOfffaZrF271gQ67ty5EzSHbcyYMeYzqN/rQAxuODN27Fh59tlnpXXr1rZzuwZAgiHQpgG2J5980uzX4MGDZdq0adK9e3cJNNWr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/gY/3mPv0TscWqDkypVL/AHlg38Ite9cQnG8OF7B+PmifAit6wd3cb7jePH58h9X/Lx88OuglOaCSps2rezdu1caN25sm67jJUuW9NgyKkWKFGawlyFDBgkF+sEMpYsJ9jf48R57hz/UkLKifPAvofadSyiOF8cr2D5flA+hd/3gLs53HC8+X/4jvZ+WD36d6FwTlbdu3Vq+/vpruXXrlpn2119/mdxQbdu2tc03d+5cGT58eJyWAQAELsoHAADlAwAEPr8OSqlhw4bJzZs3pUKFCtKpUyepW7euPPfcc9KyZUvbPL///rvMnDkzTssAAAIb5QMAgPIBAAKbXzffUzly5JAdO3bI4sWL5fTp0/LKK69I9erVHeZp37691K5dO07L4P83WRw4cOADzRaDFfsb/HiPQwvlQ+ILte9cQnG8OF58vnyD8iHxcb7jePH58h8p/Pz3WpjFX/r3BgAAAAAAQMjw++Z7AAAAAAAACD4EpQAAAAAAAOBzBKUAAAAAAADgc36f6Bye9/fff8vSpUvl4sWLEhkZKU8++aSEh4fGR+HLL7+Uffv2yZtvvil58+aVYLZ69Wr5448/JFWqVKYzgPz580uwunLlisydO1cOHTok6dOnl/r160v58uUlWNy/f18WLVokf/75pzRq1EgaN278wDx37tyR2bNny549eyRPnjzSoUMHyZQpU6JsL0LD+vXrZeXKlXL37l3T262zzyWcn5t/+OEHadiwoTRt2pRDFMt5b8GCBbJt2zbJnTu3dOzYUdKlS8fxciI6OloWLlwo27dvN+OPPfaYtGjRQpIk4d4zEgflQ/xQPriH8iH4ygf/2hp4XZ8+feSZZ56RI0eOmEDUe++9JxUrVpRr164F/dHXH7cffvihjB071vTKGMwnny5duphg440bN+T27dvSsmVL2bVrlwQj/SwXK1ZMZsyYIWnTppWjR4+a3jY/+eQTCQZbtmyRwoULy+TJk2XmzJmyYcOGB+a5deuW1KpVS0aMGCEpU6aUefPmSZkyZeTYsWOJss0Ifk888YT07dtXLl26ZD5/es5p1aqVOf/ANS17NLgydepUWbduHYfKBb1pVq1aNXn33XclefLk5oZDjRo1TPAdD16c6c2KHj16mO+fDq+//rqZps8Bvkb5ED+UD+6hfAjS8kF730Po2L59uyU6Oto2fv78eUtERIRl1KhRlmB25MgRS+7cuS1z587V3iYtmzdvtgSrL774wpIqVSrLP//8Y5t27do1y6lTpyzBaOjQoZYsWbJYbt++bZv2/vvvW7Jnz24JBv/995/5/KrChQtbBg4c+MA8Y8eONd/js2fPmvE7d+5YIiMjLS+88ILPtxehYdu2bQ7jf//9tzm3/vrrr4m2Tf5Oy96GDRua8la/y++++25ib5Lfeu655yzFihWzXL161Tbt8OHD5tyGB3/X6Xdv3bp1tmlr16410/Q5wNcoH+KO8sF9lA/BWT5QUyrEaJW9sLAw27g279Fq8cePH5dgpZFgbcrUv39/KVmypIRCE0WtDffII4/YpqVJk0ayZ88uwShbtmym+ZD9HXSt+ZcjRw4JBtrs8mFNTX/66SfTdCpLlixmPFmyZKbJpk4HvKFs2bIO41pbUWu0BHNZklBae9NisUivXr0Se1P82oULF2TOnDmmmb3WfrXKly+fObfBkf6OS5o0qUONd32steEzZ87M4YLPUT7EHeWDeygfgrd8CI1EQnBp06ZNJgfN0KFDg/YoaZM9/WHbvXv3oG3CZqXN9Xbv3m2a1cyfP182b94sOXPmlNatW5vgYzDq1KmTyROmTfYqVaokJ06ckMuXL5v8SqFC979y5coO07TJ3/nz500BTm4peJt+3+7du2e+h3jQxo0bZcyYMbJ161aHG0N40M6dO81nSfMCTpgwwTTR1vOZBtr1BgscabDum2++MUG8xx9/3AQ+NXeIfieDPXcmAgPlQ+woH9xH+RC85QM1pULYqVOnpF27diYPiCY8C0YrVqwwuXimTZsmoUATfqtRo0bJpEmTTFLY5cuXm1oMa9eulWBtW67B1dSpU5uTryb5PnDggAm2hgoNRsZMAKwJ363PAd4UFRVlgv5vv/22FC9enIMdgwbJtfaq1mLNlSsXx8eN46Wef/55c7Gm5/aJEyeams5nzpzh+MWgFxmaa/Dq1aum/NMLDX2siaaBxEb5EDvKh7ihfAje8oGaUiHq7NmzpoeyQoUKyaxZsyRYDRw4UAoUKGCrCaY1R6xBG23upLVsgok1MKE1YxYvXmybronOBwwYYHrKCsaacCdPnjQ/fKy9SJYuXVo6d+4sDRo0sAVngpm+75pwOmawzvoc4C0a/NXv2dNPPy1DhgzhQDsxZcoUU11ez7/Wc/C5c+fk999/Nx1RaAcF+D/Wc5YmYh0+fLh5/NZbb0nRokXl008/tU3D/6c9s3722WemxmyRIkXMNO14QI9XvXr1TNJpIDFQPjwc5UPcUD4Eb/lAUCoE6Y9h/SBqLh7tIjJVqlQSrPTuvQYsrLRnMqVN2rJmzSrBRps2aA6icuXKOUzXca05FYz27t1r8hdYA1JKm31cv37dNPvQAFWw0xoEehzs6bjWyoiIiEi07UJw++eff6Ru3brSpEkTc36hWZpzNWvWfKDrZc2NpN9NPV/DkTX3o305liJFCnMu//fffzlcMei5PkOGDLYLDqWPdZoGBfzpogOhg/LBPZQPcUP5ELzlA0GpEKM1hTQgpQmRNXqq1eKDmTZPtKc5pfQuqzal0MBFMNJ9++2330xODg3UaNXNP/74Q8qUKSP/r737gLKqOvsH/IIoighib6BYMCpVDKJYo4gldiJ2iV0DiTFqRP00JhoUY/uM0VhjNBFLFEVswfahgr2gKFYELIgVRSCK8197Z937n4GhqMyZ9jxr3TX37nvaPTN4nN+8+z0NUfpFJTX0TiFUqd/I/fffnwPI1IekMdhnn33i2GOPzbdNb9++fS7NTRWQaRxqQvqr27bbbpsDqTRFes7Qhf8vXWvmvN78+c9/jh49euRbM1NV+qPRNttsEyNHjiz/NyxVgj799NPxy1/+0umq5hqYKmPT+Sn9nKV+kumcbbTRRs4XhXN9WHiuD9+N60PDvT40Sbfgq+2DoDhpylr6H71DDz20SiCVmp81tKls1UmhVKdOnfI/yIYaSqVpIjvssEMOJjbbbLP8H6LU7Dp93ysn5Q1pKmr6BWbGjBk5cJ08eXI8/PDDcemll+af8/oufe9+//vf5+d/+9vfcs+e1NQ8fS9Lv9CmO0ym6VNpjnj63qf546kCMvVUa9OmTS1/AhqiNC06/ZEj9f2pHEila0x6MH/p329q3H3WWWc5VfP4pTZV4aW7yKY/LqQ/NKSqsnvvvbfB/zHt+0j//5ZubrLnnnvmP0QNGzYs9tprr/j73/9e24dGI+T68MO4Psyf60PDvD4IpRqZVD2RfomfU2qEnf7i3dClX6Kuv/762H///fP0xYYqhRSpX8mECRNyU7sU1pSmLjbUz5sCmDS1I5Wk9urVq8HcbTA1r7/mmmvmGk8NC/v27VtlLJ2DVKqbPnsKBpZYYokCj5TGJFX6pGrMOaXAdM47QTK3FDCn6276wwHz/gNL6o2Y/sqbzlWa5mKK6Lw9//zz+ZHOUaqM7tq1qx8taoXrww/j+rBgrg8N7/oglAIAAACgcJpAAAAAAFA4oRQAAAAAhRNKAQAAAFA4oRQAAAAAhRNKAQAAAFA4oRQAAAAAhRNKAQAAAFA4oRQ0IJMmTYq+ffvGZ599VtuHAkAd4voAgOsDdZFQCuqgDz74IIdLU6dO/U7rff755/Gvf/0rZs6cWWPHBkDtcX0AwPWBhkQoBXXQl19+mcOl6dOn1/ahAFCHuD4A4PpAQ9Kstg8AanMqw69//es477zzYujQoTF+/Pho3759HHfccdG6deu8zMsvvxxnnHFG3HzzzdG06X8z3DQ17vDDD48LL7ww2rZtW97OmWeeGcOGDYvXXnstb+f444+PadOmxWWXXRYTJ06M7t27x4ABA6JZs/n/s/vqq69i4MCB+fmxxx4bLVq0iG7dusWpp56aK6CuuuqqeOKJJ/L4HnvsETvttNN8t3fjjTfG3XffnT/nKqusEhMmTIgrr7wy3nnnnVhzzTXj5z//eay77rrl5c8///xYZpllol27dnHPPffkfe65556x4447VqnIStt46aWXYqWVVor9998/unbt+oO+HwB1heuD6wOA64PfHyiGSikardJUt5/85Cfxn//8J7beeusYMWJElfAlTZ9Ly3z77bflsRTSpLG0fuXtlMKhLbfcMm644Ybo3bt3fqSAZ6uttsoh1kknnbTA41p88cVjl112yc933XXX2HffffOxVVRU5H1ceumlsfnmm8dqq60We+21V1x00UXz3NbFF1+cg60jjjgiB1IpzNpkk03yX9r79OkTs2bNymHZU089VV5n9OjRccopp+RwqkuXLjl0Ssdx7733lpfZYYcd8rnaZpttYtVVV42jjz46nnnmme/8PQCoi1wfXB8AXB/8/kBBKqCRGjt2bEX6J/D3v/+9PDZu3Lg89sYbb+TXDz30UH799ddfl5d5//3381hav/J2rr/++vIyN910Ux675ZZbymNXX311xcorr7xQx/b666/n9d9+++3y2K233lrRvHnzinfffbc8dvnll1css8wyFZ9++mmVY0nHeNppp+X9Pffcc+Xlu3XrVjF48OAq+zrhhBMq+vTpU3699957V3To0KHKZ95nn30qDjzwwPx86tSpeR+vvfZa+f20bOkYAOo714f/cn0AcH3w+wM1zfQ9Gr1UxVSyzjrr5K/vvvtu+fnCShVSJWuttVa1Y1OmTMlVV6WpgN/Fo48+Gj179swVUiU/+9nPcpXSiy++WOVzpOl/Tz/9dF6nNDXvww8/jOeeey6WW265eP7553PlVXqkaXyTJ0+usq9UiVV5mmE6F2PGjMnP0/rps6SqrzRFsUePHtG8efNYdtllv/NnAqjLXB9cHwBcH/z+QM0SStHopUClpBQWVZ6u90O2M69tf59Q6uOPP442bdpUGUtBUNpWeq+ycePGxeqrr56n7JWkXlilqXdrr712leWXWGKJeX6W0rGXzkl6PmrUqLjgggvimGOOyT2q0jTCNFVwzuMDqM9cH1wfAFwf/P5AzRJKwXwsueSS+WvqvVSqHJozAKoJTZo0mWssVSelRuqVvf322zksKlVmldx+++1xyCGHxM4775yblS+99NK5wmqxxRaLFVdcMfr27fuDjm+NNdbIoVSSQqnUn2rw4MExZMiQH7RdgPrC9aF6rg9AY+f6UD3XB+ZFo3OYjzT1LQU5Dz74YH6dprulRuM1bYUVVig3Wi/ZZ599cgXUXXfdVT6Ws88+OzbccMPo3LlzlfVbtWoV9913X3z99dc5mJo+fXq0bNkybyOtk6YnlqQphSnEWlhp3eHDh5dfp0AsNTtPdw0EaCxcH+bm+gDg+lAd1wfmRygFCwiHBg0aFP369ct35evYsWN88MEHNX7OWrduncOk1DMqTY1LQVLa97nnnpuDpXTXu06dOuUqqGuvvTYHZ3MqBVOpyqsUTP3lL3+J9ddfPzbYYIPYfvvtc4+qzTbbLAdcCytVXV111VV5CmC6S+BGG22ULzS/+c1vFvFZAKi7XB/m5voA4PpQHdcH5qdJ6nY+3yWggZo2bVrcf//9seuuu5b7hqR/Dv/6179i6623ztPcSsaPHx9vvfVWDnRSr6ZUKZR6M6Xgp7rtfPrpp/HAAw/E7rvvHosvvni56umRRx6Jvffeu9rpeXNK0/KefPLJeP/99/OxbLHFFnk8vX722WejRYsWOVRaaqml5vuZ0q3N//3vf+dqqg4dOuSx119/PV599dVYeeWVo0uXLlX6pqSG5ul1t27dymMvv/xyfPTRR/m8lKRpe6lyK/1i1r1792qDMYD6yPXB9QHA9cHvDxRDKAUAAABA4TQ6h1pw9dVX56l31dlkk03i5JNPLvyYAKh9rg8AuD7QmAiloBak6W6pb1R1UtNwABon1wcAXB9oTEzfAwAAAKBw7r4HAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUjCH4cOHx+TJk2vkvNxzzz0xYcIE5xwAAIBGTygFc/j5z38ejz76aI2cl2OOOSZGjhxZq+d8+vTpMWrUqHjggQfigw8+qHaZ2bNnx+jRo2PEiBHx7rvv1otlAAAAqF+EUlCgnXfeOdq3b19r5/ziiy+ODTbYIM4444z4/e9/n4/lpJNOqrLMhx9+GN27d49+/frFkCFDYr311osLLrigTi8DAABA/dOstg8AksceeyyaN28em2yySZUTkiqWllxyyfJ4qvIZM2ZMzJo1K3784x/HiiuuONcJ/Oabb+KZZ56JTz/9NIcZlZd56KGH4uOPP44mTZrEqquuGl26dImll1662m/ClClT4sUXX4xWrVpFjx498joLK62XpgCmACU9SnbddddYZ5118vM333wznnvuubnWTcun4yp9lieffDI+//zz2HDDDWPNNdf8QT8wK620Urzyyivlz5yqpbbffvvYa6+9omfPnnnsuOOOi6ZNm8b48eNjqaWWittuuy369u0b2223Xfm46toyAAAA1D9CKeqENJ3smmuuiddee6089vXXX8fuu++eq2NSKJUCpRRGtG3bNlq2bJkDnYsuuiiOOOKI8jovvPBC7L333jnMWX/99XOQ8cc//jH233///P6///3vvI+Kiop466238vS1f/3rX7H55ptXOZ6//e1v8Zvf/CY22mijHHCl/d955505OJuf//znP/HTn/40Xn755ejWrVsOnjp37hxDhw7NoVaavnfaaafF4YcfHq+//noeL/n222/zPn75y1/mSqCxY8fGHnvskQOk1VdfPYdT++23X/z5z3+uEua9//778z2mdA4XX3zx/DytX1kKupIUeiVfffVVPh+XXnppDoCSFFittdZa8Y9//COHQHVtGQAAAOonoRR1QgqNTjnllBy8pKqk5O67786hRAqiZs6cmXs9HXLIIeWpWynEOvbYY6N37945pEiB0G677RZbb711fq9Zs2YxY8aMePjhh8v7SQFVZX/4wx9yUJTCrMrGjRuXQ69UWfTee+/FxhtvHH/9619zYDQ/qV/UU089FZMmTcrBWZJClRSCzVlpteOOO+ZHyW9/+9tYdtllY+DAgTmQS4FUOrYTTjihXLnVtWvX2GqrrWKfffYph3lPP/30AqcMlkKpZOLEifk8p0qyq666Kvbdd998DpMU4qXzmIK0ytLrVP1VF5cBAACgfhJKUSe0a9cuttxyy1z9Ugql0vNUddS6det48MEH45133olTTz21vE4KqVJvpNtvvz1+/etf52VS4JIqq1IglaTqmp122qnKvlKj7FdffTU+++yzXIWUwo0UfrVo0aK8zKGHHpoDqWS11VaLgw8+OG688cYFhlKpkiqFKKlCqlTFkyq3FiRt+8ILL4z7778/93lKFV1vv/12Pi/Dhg3LoVZ6pKl9acpdKZQ6+eST47tK5zFVaKWQK4Vn6bOl6XGVK6batGlTZZ3ll18+V3/VxWUAAACon4RS1BkHHHBAnH766bkSKvWOGj58eHl624QJE3I4lcKIklR5lPozpfdKYUvq/7TKKqvMcx8pvLriiity5dMKK6yQK7CSqVOnVunXNGcz8rXXXjuHZAuS+hyl6q0UsKVphul1ml7YqVOnea7z7LPPxmGHHZanIm6zzTZ5LAVSqbrp5ptvrrJsCspKPam+z/S9JB1beiSPP/54rixbY4018nKl6YkppKvsyy+/zL29krq2DAAAAPWTUIo642c/+1meupamwKWgJVUulaqcUhiVgojUK6pUBZV88skn5aAqhVZpmVSptMQSS8y1/TQdL919LlVJdejQIY898cQTce+99+YqpMpSFdWcr5dbbrmF+hznnXdenH322XmK3D//+c/cbP35558v92+a885yaZregQcemMOskmWWWSZP4Uu9rUrTAKvzfabvVZZ6aaVz8cgjj+RQKoVvSao4q9yvKb1Od+1L6toyAAAA1E//nbMDdUCaopUClFSRlB5pilopXEp32kthVKqeKkn9htIUrl69euXXqeJnscUWy0FQZelue0kKutJ0vsqVRulObtW54447qrxOU+hK+5mfFDKlhuXpuLfYYov4y1/+kgOm6oKjFJ6lqX2pQis18q4sVUylICn1fKosbTtVdZWk6Xu33nrrfB+laYmpv9YXX3wx17lJAU+q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AAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAABoOKHU+++/HwcddFCsvfbaseyyy871AAAAAKDxalZTGz7ssMPio48+ikGDBkWbNm1qajcAAAAA1EM1FkqNGjUqXn311Vh99dVrahcAAAAA1FM1Nn1vxRVXjObNm9fU5gEAAACox2oslDr44IPjD3/4Q8yePbumdgEAAABAPVVj0/fuuuuueOaZZ2Lo0KGx1lprRZMmTaq8P2bMmJraNQAAAACNNZTaY4898gMAAAAACgulTjvttJraNAAAAAD1XI31lKqsoqIiPwAAAACgxkOpG2+8Mbp27RpLLbVUtGjRIj9PYwAAAAA0bjU2fe+SSy6J3/72t3HkkUfGySefnBudjx49Og477LD4+OOPY8CAATW1awAAAAAaayh14YUXxg033BB77bVXeaxfv36x1VZbxQknnCCUAgAAAGjEamz63uTJk6N3795zjW+//fb5PQAAAAAarxoLpdZaa60YMWLEXOPDhw/P7wEAAADQeNXY9L3UR6p///4xcuTI6NGjRx574okn8pS+yy67rKZ2CwAAAEBjDqUOPfTQWGWVVWLIkCFxxx135EbnG264Ydx+++2x884719RuAQAAAGjMoVSSwicBFAAAAACF9ZQCAAAAgEIqpTp27Ji/vvTSS+Xn85KWWViffvpp3HrrrTFlypTo1KlT7Lbbbnk64MJ44YUX4pZbbonNN99c1RYAAABAQwylDj/88Gqf/xDvvPNO9OrVK9q3bx+bbLJJDBw4MK6++uoYNmxYNG06/0KvL774IvbZZ5/44IMP4ssvvxRKAQAAADTEUOq4444rP19yySXj6KOPrna5yy+/fKG3edJJJ0Xbtm3joYceimbNmsWAAQPiRz/6Udx8882x7777znfdo446Kvr27RsjRoz4Dp8CAAAAgHrbU+qYY475Xu9V9s0338Tw4cPjoIMOyoFUss4668RWW20Vt91223zXveaaa+L111+P3/3ud9/xyAEAAACo13ffq86kSZNiueWWW6hlJ06cGDNmzIh11123yvh6660Xo0ePnud6r776apx88snx6KOPxuKLL75Q+5o1a1Z+lEybNm2h1gMAAACgDoRSXbt2rfZ58u2338aECRNi1113XahtTZ8+PX9t1apVlfHWrVuX35vTzJkzo1+/fnHWWWdFhw4dFvq4Bw8eHGeeeeZCLw8AAABAHQqlDjzwwPJd70rPS1LV0lprrRW77LLLQm2rZcuW+evnn39eZfyzzz4rvzenG264ITdHT1VWp512Wh5Ljc5TZVV6/fvf/77aBumDBg2K448/vkqlVOplBQAAAEA9CKVOOOGE/HWFFVaI/v37/6BttWvXLlq0aBGvvfZa9OnTpzyeXqdm59VJ1VmlYyhp0qRJLLbYYrn5enpenebNm+cHAAAAADWvSUVFRUVNbfzjjz+O5ZdffoFj87P//vvnhuWPP/54rrQaP358bLTRRjF06NB8Z71k2LBhuVfVwIED5xlUbbPNNnHRRRct9H5TpVSaJpiqtOacPlhfdbquU63te+whY2tt38AP1xD/mwgAADTQu+/99a9/jVNOOWWu8TR25ZVXLvR2zj333Jg6dWr06tUrjj322Nh2221jjz32iL333ru8zF133ZX3BwAAAEAjv/vekCFDYuTIkXONn3TSSbHzzjvHEUccsVDbSX2dxo4dG7fffntMmTIlrrnmmjyVr/I0vD333DN69Ogxz20MGDAg1lxzze/5SQAAAACoN9P3llpqqZg8efJcU/U++uijHDTNmDEj6rKGOFXF9D3g+2qI/00EAAAa6PS9zp07x9///ve5xq+77rro2LFjTe0WAAAAgMY8fe/000/PvZ+eeuqp2GqrrSIVZP3f//1f3HLLLXHHHXfU1G4BAAAAaMyh1C677JIbkP/xj3+ME088MfeA6tatW9x9992xww471NRuAQAAAGjMoVSSGpKnBwAAAAAU0lMKAAAAAGqlUurtt9+O4cOHx8SJE+Obb76p8t5FF11Uk7sGAAAAoDGGUvfdd1/stddeuY/UY489Ftttt128+OKLMXXq1Nh2221rarcAAAAANObpe6eeemr87//+bzz66KP59ciRI3PF1AEHHBDrr79+Te0WAAAAgMYcSo0bNy769euXny+22GIxc+bMWHLJJWPIkCFx22231dRuAQAAAGjModSMGTOiZcuW+fkqq6wSb775Zn7erFmz+PLLL2tqtwAAAAA09kbnJTvttFMcffTRccghh8TNN98cPXv2LGK3AAAAADS2Sqkbb7yx/DxN2VtrrbXinHPOiSWWWCKuuuqqmtotAAAAAI25UmrfffctP2/Tpk1cf/31NbUrAAAAAOqZGquUatq0xjYNAAAAQD1XY8nRiiuuGB9++GFNbR4AAACAeqzGQqkjjzwy/ud//idmzZpVU7sAAAAAoJ6qsZ5S99xzTzzzzDNx0003xdprr50bnFc2ZsyYmto1AAAAAI01lNpjjz3yAwAAAABqNJT605/+FCeccEJ+3r9//1hjjTUW5eYBAAAAaCAWaU+pE088sfy8bdu2i3LTAAAAADQgi7RSatVVV4177703evXqlV9/+eWX81y2ZcuWi3LXAAAAADTWUGrQoEHx05/+NGbPnp1fL7PMMvNctqKiYlHuGgAAAIDGGkoNHDgw9ttvv5gwYUL8+Mc/jtGjRy/KzQMAAADQQCzyu++tsMIK+XHJJZdEz549F/XmAQAAAGgAFmmj88oGDBhQU5sGAAAAoJ6rsVAKAAAAAOZFKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4ZpFPfDNN9/EqFGjYsqUKdGpU6fYaKONFrjOBx98EE899VQ0a9YsunfvHiuttFIhxwoAAABAAwilPvnkk+jdu3f+2rFjx3jkkUfi0EMPjYsuuqja5SsqKvL7DzzwQHTt2jW++uqrGD16dPzpT3+KY445pvDjBwAAAKAehlKnnHJKzJgxI8aOHRstW7aMJ554IjbbbLPYaaedok+fPtWGUltvvXVceeWVuUoqufrqq+Ooo46KHXfcMdq3b18LnwIAAACAetNTKgVMQ4cOzZVPKZBKNt100/z45z//We06TZs2jf79+5cDqWTXXXeN2bNnxyuvvFLYsQMAAABQTyulJk2aFJ9//vlcPaTSNL5nn312obdz77335rAqrTcvs2bNyo+SadOmfc+jBgAAAKBeV0qlQCpZdtllq4wvt9xy5fcW5I033ohf//rX8ctf/jLatWs3z+UGDx4crVu3Lj/atm37A48eAAAAgHoZSi211FL56/Tp06uMf/HFF+X35mfixImx/fbbxzbbbBPnnXfefJcdNGhQDrpKj1SlBQAAAEAjnL6XKpsWX3zxmDBhQpXx9HqdddaZ77opVEphVLdu3XJfqso9pqrTvHnz/AAAAACgkVdKLbHEEtG7d++46aabymNTpkyJBx98MH7605+Wxx5//PG44447yq8nT56cA6kuXbrEzTffnIMtAAAAAOqOJhXpFnd12EsvvRS9evWKPn36RM+ePePaa6+NpZdeOkaNGlUOmw4//PAYM2ZMXnbmzJnRuXPnPAXvrLPOqhJIpe2st956C7Xf1Og89ZZK22nVqlU0BJ2u61Rr+x57yNha2zfwwzXE/yYCAAC1q05P30vSHfNeeOGFuOaaa2L8+PFx1FFH5RBqzrBplVVWyc+/+eab2HzzzfPzxx57rMq21l577YUOpQAAAABoxJVStaUhVgWolAK+r4b430QAAKB21emeUgAAAAA0THV++h4NnwouAAAAaHxUSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIVrVvwuG75O13WqtX2PPWRsre0bAAAAYGGplAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAArXLOqJSZMmxZQpU6JDhw7RqlWrGlsHSjpd16nWTsbYQ8b6RgAAANCg1flKqZkzZ8bee+8d66+/fhx00EGxyiqrxCWXXLLI1wEAAACgOHW+UurMM8+MJ598Mt58881YddVVY9iwYbHnnntGjx49YtNNN11k6wAAAABQnDpfKXXttdfG4YcfnsOlZI899oiOHTvm8UW5DgAAAADFqdOVUu+9917uCdW9e/cq46ni6bnnnltk6ySzZs3Kj5LPP/88f502bdp3Pu7ZM2ZHbZnf8TquhnG+oDZ/JisqKnwDAACAhh9KffLJJ/nr8ssvX2U8vS69tyjWSQYPHpyn/c2pbdu2UZ+0PqZ11EWOq2GcL/jiiy+idWs/nwAAQAMPpRZffPFy4/LKZsyYEUssscQiWycZNGhQHH/88eXX3377bQ6xUpjVpEmTaOwVEimcS3czdBdD58vPV+P895gqpFIgtdpqqxW2TwAAoGGr06FU+sWradOm8e6771YZT6/btWu3yNZJmjdvnh+VLbvssj/o+Bua9AuwUMr58vPVeP89qpACAAAaTaPzFi1axOabbx533nlneWz69OkxcuTI6N27d3nsjTfeKPeLWth1AAAAAKg9dTqUSs4666wYNmxYnl6XgqZ0J72VVlopjjzyyPIy55xzThx00EHfaR0AAAAAak+dD6W23nrreOihh+Kdd96Jiy++ODbaaKN49NFHo2XLluVl1ltvvdh4442/0zosvDSt8YwzzphreiPO16Lg58v5AgAAGqcmFe7vDQAAAEDB6nylFAAAAAANj1AKAAAAgMIJpQAAAAAonFCK+Uotx95444145ZVXYtasWc7WQvrkk09yc/2JEyc6Zwvw1VdfxXPPPRdTpkxxrhbiXL300kv5kZ4DAADUZ0Ip5umyyy6LtdZaK3bcccfYY489YrXVVovrrrvOGVuAb7/9Nvbee+98F8grrrjC+ZqPc845J1ZeeeU4+OCDY/PNN48jjzwyZs+e7ZxV49JLL41VV1019tlnn/xIz9MYAABAfSWUYp6mTp0ajz/+eK6UGj9+fJx77rlx2GGHxdixY521+TjrrLNi+eWXj/bt2ztP83HxxRfnc3Xffffln6k333wzevbsGf/5z3+ctzmkiruBAwfG+eefH+PGjcuPIUOG5DHVeAAAQH0llGKeTj/99Fh99dXLr1Mg1bRp0xg9erSzNg+jRo2Kq6++WoXUAqTg6Q9/+EP86le/yhVSJYceemgstdRSfr7m8NFHH+WptJtttll5rFevXnns448/dr4AAIB6qVltHwD1xwsvvBBff/11rLvuurV9KHW2j9SBBx6YQ6nllluutg+nzv8spTBl1113jQ8//DAmT56cK8vatGlT24dWJ2288cbRr1+/+MUvfhEnnHBCDqPOO++82H///aNbt261fXgAAADfi0opFkpqqpyqWLbYYovYdtttnbVqpEqyn/3sZ7H99ts7Pwvw3nvv5a9Dhw6Nzp0755+t1LPsqKOOyj25mNvRRx8d7777bg6lTjzxxHj//fdzDy4AAID6SqUUC5TuurfXXnvF9OnT45577okmTZo4a3P45z//GY899lgMGDAg33UvmTlzZkyaNCn35ao8RY2IxRdfPJ+GdFfHCRMmxJJLLpnvKLfpppvmkCpVBPH/vfzyy9G7d++49tprczVecv311+ex559/PjbccEOnCwAAqHeEUiyw908KpN566614+OGH853SmFuaTtWhQ4c444wzymNpetpDDz2Up6Y98MADTlsl6a6OSf/+/XMglXTs2DFX4qW+XEKpqu69995o0aJFOZBKDjrooByCpveEUgAAQH0klGKBgdTrr7+ew5U0vYrqHXDAAflRWeq9te++++Y7zFHVBhtsEO3atcvT0SpLr1O4R1UrrrhirlT89NNPy323Ug+zNJbeAwAAqI+EUsxTClQeeeSR3Lj77bffzo8khQnpAd9XmgI6ZMiQ3CcpVQCts846cfPNN+epfKqk5rb77rvHGmusEbvttlu50fn5559fHgMAAKiPmlSk326gGtttt13uJzWn1JQ6PVhwqJfO4RFHHOFUzcP999+fQ89UAbT++uvHcccdlwMq5jZ16tS4+OKLcw+pFOp16dIlfvWrX6mUAgAA6i2hFAAAAACFa1r8LgEAAABo7IRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRS0IB8/vnnMXTo0Jg5c2ZtHwoAAADMl1AK6qAvv/wyh0vTp0//TutNmjQp9ttvv/jss89q7NgAAABgURBKQR30wQcf5HBp6tSptX0oAAAAUCOEUjRalae6vf7663HXXXfFSy+9VGWZDz/8MC9TUVFRHkvLp7G0/pzbGT9+fAwfPrzKdp577rm444474u23316o4/r6669jxIgR+XnaVtr2I488Un5/8uTJeXv//ve/46uvvlrg9iZOnJi3MWXKlCrHNGzYsPz122+/rbL8Y489Fk8//XSu1ho1alTez7Rp0+ba7ltvvZXP2ZNPPpmPGQAAAL6LZt9paWhASlPddttttxwYtW3bNh5++OH41a9+FX/84x/zMuPGjcvL9O3bN5o1++8/lzQ1Lo2NHTs2WrduXd7O1ltvnQOqlVdeOUaOHBknn3xyDqdSiLT88svnYOmGG27I25qfFPCkICi5//77Y+mll46uXbvm7Z977rlx5plnxmabbZarqFLQlAKqnj17VruttP8+ffrEAQccEPvuu298+umnsddee+XP26VLl3j55Zfz8d555535GJMLL7wwB1npc6677rr5eVrv0Ucfjfbt2+dlBg0aFH/5y19iyy23zO/NmjUrbr/99nwOAQAAYGGolKLRW3PNNePFF1/M1Uk333xzDBky5HtNm0vBUao8uvfee+Occ86Js88+O370ox/lqqP77rsvh1Snn376ArfTokWLuOiii/LzSy65JFc5pXVTCHbKKafELbfcEg888EA+5l122SUOPfTQ+Oabb+bazuOPP56DrOOOOy5/pmTAgAGxwgorxBtvvJHDrFdffTVatWoVp556apV1U8VXOua777477yeFTaVjShVUKRxLnzNVSqXKquuuuy5mzJjR6H+WAAAAWHhCKRq9o48+unwOttlmm5g9e3a8+eab3/m8HHXUUeXnqZKpurE0TbDyVMDvIgVmHTt2zEFUSQqTXnnllRwcVZYCox133DHOO++8OPHEE/NYapqetpGCsjR1L4Vbt912W7Rr1y4eeuihKuun6qpSVVTTpk1zRVQKqpLFFlssllhiiRySlT7LRhttFB06dPhenwsAAIDGyfQ9Gr3llluufA6aN2+ev6b+UN9VmzZt5trOnGOpoimFXqWpgN/FO++8E2uvvXaVsRQcpdAovbfxxhuXx4899tjYfffdcxVVybvvvpv3/8wzz+RwrLIttthinuekdOylc7LUUkvlyqiTTjopV36laqw0PTBNgwQAAICFJZSC+UiBT1K5Gfj3CawWhTTtLoVPlaW+T+nY0nuV3XjjjXHwwQfn3lhpyl+SpumVpvDtvPPOP+hY+vXrlx9p+l+a9rj//vvHBRdcEEceeeQP2i4AAACNh+l7MB+rr756/pp6MJXMOdWtJrRs2XKuACxVM40ZMybee++98liagpfCps6dO1dZf9NNN809oVLvp8GDB+exVVZZJTc3v/zyy+faX6qiWlipp1TpbnxpKuBvfvObPN0vHRsAAAAsLJVSMB/rrLNO9OrVK1cdpd5TqVLpH//4R42fs3RHvNRc/KyzzspVTSkcS3fNS8HUT37yk1ztlJqxpwbm6ZHuAjindEe+Um+pJk2a5GbpV1xxRQ6Q0mPPPffMAVO6w1/37t3L4dWCfPLJJ/kY0vobbrhhTJgwIe65554ckAEAAMDCUilFo7XsssvmKWipR1Ll6XppbKWVViqPpTvQpQBm9OjRscwyy+RKqbRMWn9e20k9mdJYaghekraZxkpTAucnhUip0ilVN6XpcWnfpWNJd9NLfaE++uijuPPOO2PgwIHz/EypuXoKpl544YV49tlno0ePHjFu3Ljc0D1t88MPP8xhVeVAKgVfP/7xj6scT6rESkFUkhqjP/HEE/nYRo0ale+698gjj1RpwA4AAAAL0qTi+94KDAAAAAC+J9P3oBakqqXXXnut2vfSVL0tt9yy8GMCAACAIgmloBak6XRpel51Nt54Y6EUAAAADZ7pewAAAAAUTqNzAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAKJo/w8XfchFn/zUpwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import math\n", + "\n", + "\n", + "def plot_histogram_grid(histogram_key, xlabel, suptitle, get_histogram):\n", + " ncols = 3\n", + " nrows = math.ceil(len(vocab_sizes) / ncols)\n", + " fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 4, nrows * 3), squeeze=False)\n", + " for idx, vocab_size in enumerate(vocab_sizes):\n", + " ax = axes[idx // ncols][idx % ncols]\n", + " histogram = get_histogram(vocab_size)\n", + " keys = sorted(int(k) for k in histogram.keys())\n", + " counts = [histogram[str(k)] for k in keys]\n", + " total = sum(counts)\n", + " fractions = [c / total for c in counts]\n", + " ax.bar(keys, fractions, color=\"tab:green\")\n", + " ax.set_title(f\"vocab_size={vocab_size}\", fontsize=10)\n", + " ax.set_xlabel(xlabel); ax.set_ylabel(\"fraction\")\n", + " for idx in range(len(vocab_sizes), nrows * ncols):\n", + " axes[idx // ncols][idx % ncols].axis(\"off\")\n", + " fig.suptitle(suptitle); fig.tight_layout(); plt.show()\n", + "\n", + "\n", + "plot_histogram_grid(\n", + " \"token_count_histogram\", \"num_tokens\", \"Token count distribution per sequence (train split)\",\n", + " get_histogram=lambda vs: per_vocab_size[str(vs)][\"splits\"][\"train\"][\"token_count_histogram\"],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "9cbc3c86", + "metadata": {}, + "source": [ + "### Token length distribution, frequency-weighted (train usage)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "ef9d6da8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKQAAAN2CAYAAADHclF6AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3QeYU8X7//2h915FmvRepSNIFSmKFEWpoiBFEAFRrIAFUFEBERRQUWxYaYooAgICgiLSy1d6772T5/rM/zn5JbvZ3exuNpvsvl/XFdmcnHNycnadydwzc08Kl8vlMgAAAAAAAECQpAzWGwEAAAAAAABCQAoAAAAAAABBRUAKAAAAAAAAQUVACgAAAAAAAEFFQAoAAAAAAABBRUAKAAAAAAAAQUVACgAAAAAAAEFFQAoAAAAAAABBRUAKAJCsPf744yZz5swmFOzfv9+kSJHCTJkyxYSDjRs32uudOXNmwM+t8z7zzDOJdm98vV9Cft7YXEewHThwwGTKlMn89NNPyepzh7Ldu3ebdOnSmSVLliT2pQAAEGcEpAAAYeebb76xjVV/Hlu3bk3syw1rO3futPdx2rRpJhyFw/WH+jUOHz7cVK5c2dx9991hc81JXdGiRU3Pnj3Nk08+aW7evJnYlwMAQJykjtthAAAkng4dOhiXy+W1LXv27KZKlSqMGEiiChYsGOl3npTeL1SvY8+ePeazzz4L6qiwUPjc4aB///52BJlGrrVq1SqxLwcAgFhjhBQAAAB8mjp1qsmYMaNp27YtdyjEVKhQwY5cY1ojACBcEZACACRZyq/SuHFjkyVLFtuorlmzpvn6669jPG79+vWmUKFCplatWubIkSN229WrV83LL79sypYta3O35M6d23Tu3NnmuvGVY+jLL780pUuXNunTp7cjt3777bc4f46EeG8de//995ts2bKZHDly2Ok/58+f98rd9Ouvv5qSJUvan3v16uWeBjl06NBI54vr5z148KDp1KlTpOvwJ6eQRtC8+eabpnz58jbH0a233mrat29vNmzY4Nf1e96zTz75xN7f1KlT2+NiymE0ffp0U7x4cft5b7/9drNw4UKv1xcsWGCPj5jj5/r163b7888/79c1RnUdJ0+etCNkNJIobdq0pnDhwmbQoEHm7NmzAf17nDt3rqlTp47JkCGDe1t87qvz+Z2Hrl33UdMC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aqkR0Lx5cztK7MCBA2bKlCnmpZdeMu+//37A9wEAGFO/fn3jcrls8D6xOiv69etn6tWrZ3r06BHlPpoBcunSJbN161azdOlS8+uvv5rHHnssUfZBiHIBIe7dd9913XLLLa4bN254be/YsaOrXbt29ucrV664nnzySVe+fPlc6dKlc9WoUcO1ePFir/1v3rzpevPNN10lSpRwpU+f3lWrVi3XihUr3K8/8sgjLv0voUeuXLlcrVu3du3cudPrHA0bNnT16tXL1aFDB1fu3LldOXPmdA0fPjzStUVl/vz5rqpVq7oyZszoKlmypL0e59hWrVq5nnjiCfuzrt25Fs9HkyZN3J/ljTfecBUrVsx+lnLlyrmmT5/uCoRr167Z9/riiy8ivabPr/vuqUqVKq4ePXrEah8AiK9//vnHllXbt2/32j5+/HhbZ1y/ft0+nzJliqt48eKuNGnS2H/1PKI5c+bYekPlqcrmDz/80P3aRx995C6DM2XK5KpZs6Zr0aJFXsc/99xzrrp167qGDh3qKly4sC3jVQ6eOnXKr8+yZcsWV7NmzVxZs2Z1FShQwNW3b1/XmTNn7GujR492Va9e3at8jvhQvef5WapVq2a3FSlSxPXMM8+4Ll265AoE1Zv9+/ePtF2fX9etusnx+OOP2/o20PsAQHSuXr1qv8d7luPy119/edUZ+q6tcl9lpdoPgwcPtu0JTxs2bHC1bNnSlSVLFlf+/PldTz/9tOvy5cv2tR07drjLYNUvZcqUcb333ntex//000+uVKlS2e/oZcuWtXVMnTp1XBs3bvTrl6h6oFu3bq48efK4smfP7mrTpo19X1m2bJl9b6d8V/nsq35Ys2aN+7O0aNHC1mM6X6dOnVwHDx4MyB/TkCFDXJUrV460XZ9f1+DZnvryyy9dKVOmdL93MPdBaGKEFELeAw88YI4fP25+++0397azZ8+auXPnmi5durh7kL/77js7reDQoUPmrrvustML9u7d6z7m2WefNWPHjjVvvfWWOXr0qJkwYYL57LPP3K9PmzbN9jTosXHjRpMvXz47skcRd0/qKa5du7bZuXOn+frrr+2IonfffTfGz3HmzBnTvn1706tXL3Ps2DHz888/2+vYtGlTpH3VO+xcix6K9GfLls00adLEvq4e4xkzZthpdSdPnrTvP2zYMPPNN9+4z6F7oql30T00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AAAAAAAgqAhIAQAAAAAAIKgISAEAAAAAACCoCEgBAAAAAAAgqFIH9+0AAIibs2fPmiVLlpirV6+a+vXrm/z588d4zNatW83GjRtN7ty5Te3atU369OkDcl4AAAAA8UNACgAQ8latWmVat25tihUrZrJkyWJ69OhhPvroI9OxY0ef++/Zs8d0797dHDlyxJQvX95s377dnDx50nz77bemVq1acT4vAAAAgMBgyh4AIKS5XC7TrVs306ZNG/Pnn3+aRYsWmWeffdY8+uij5tSpUz6PuXTpkhk1apTZsmWL+eabb8z69etNw4YN7Xnic14AAAAAgUFACgAQ0tasWWN27NhhnnjiCfe2fv362aDTvHnzfB5TpkwZ06BBA/fzFClSmFatWtmRUleuXInzeQEAoe3gwYOma9euduRr5cqVzbhx42wHREzTuwcNGmQKFy5sHnrooUiv79u3z07njvj49ddfE/CTAEDSx5Q9AEBIUw4oKVeunHtb9uzZza233up+zR8LFiywgap06dLF+bwKZjkBLSf/FAAgNFy7ds00a9bMFCxY0Hz//fd2+raCU5cvXzbPPfecz2MOHTpk7rvvPtO7d28bwNL07ohu3Lhhp4CvXLnSFC1a1L09R44cCfp5ACCpIyAFAAhpZ86cMRkzZjRp06b12p4zZ077mj+++uor89lnn5kffvghXucdPXq0GTlyZJw+BwAgYSlPoEY7LV682OTNm9cGmBSIeu2118xTTz0VqbyXfPny2end8tdff5njx49HeX4tkMHCFwAQOEzZAwCEtAwZMtje7Zs3b3ptP3funH0tJj/99JNNcP7222/bfFHxOe/w4cNtsMp5aBoHACA0/P777zYIpWCU46677rLltXIJ+pIypf/NIS2CUbx4cdOiRQs76hYAED8EpAAAIU1f/hU02rt3r9e0DOUJ0WvRUYOhXbt2dmTTwIED431eTffLmjWr1wMAEBoOHDhgRzx5cp6rbI+Pzp07m+nTp9scg3fccYfNS/j5559Hub+md2tat+cDAOCNgBQAIKTVr1/fZMuWzU67c8yZM8cmH2/ZsqV7m1bT02p5joULF9q8IJqq8eSTT8b5vACA8KDk5alTe2ckcZ4rD1RcFSlSxMycOdPUq1fPlC1b1k4DfOSRR6Kdwq2OENUxzqNQoUJxfn8ASKrCIoeUhtl+9913Nplg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t2xQSatT5M6dO9K86zfeeMNcvXo1VseEAw3zfemllyIN9w0nfIbQkBR+D0nlcySFz5AYNB17wYIFdm66GhNqHES0atUqkyFDhlgd488++D/J/e83uX9+4R5wD0KdOqSV7+nEiRO2TtDIJk+33XabzaGi9oG/x/i7T1IW7v/vc/2Jj98B99+XFK5wWccVAAAAAAAASULIT9kDAAAAAABA0kJACgAAAAAAAEFFQAoAAAAAAABBRUAqBN24ccPMnj3btGjRwmtZ2nCilaqeeOIJU61aNVO1alXTt29fu6JJODl//rwZPXq0qVevnl2hsW3btub333834eqLL76wf0+PPfaYCSfvvfeevW7PR+nSpU240d/TCy+8YP9/qFy5sv3bUhJtINRpJaqJEyeaxo0bmzJlypjWrVub3377zSRXEyZMsOWQ/n9ObpYuXWratGljSpYsae655x6zYcMGk5zMmDHD3HnnnaZEiRI2wbXK8WvXriX2ZQEJRqmGf/jhB/v/u7576e9/2rRp5ubNm2F51/UdWOW3vhOHk2PHjtl2VYUKFUyNGjXMBx98YMKJrrdBgwa27Kxbt64ZN26cbe+G6neejz/+2F6n/lbUpvVlypQp9neh+rBLly52oYRQcPPmTbsiaKtWrez1//jjj5H22bNnjxk0aJBtp1epUsX+f5GY109AKgS9/PLL5sMPPzQ9evTwWpY2nNx333220Jk+fbqZOnWq+d///mcLorNnz5pwMXz4cFtYvvPOO+bbb7+1QammTZuatWvXmnCj+z9s2DCTM2dOuzpMONHfTK5cuewKas5j8eLFJpxcuXLFNGrUyC4XrSWiv/76a3P58mXz5ZdfJvalATF69tlnzc6dO20ARp0l+pLWrFkzs3DhwmR39/766y+7iq9WCjp16pRJTlRuNW/e3Nxxxx32C64aR88//7xJLj755BPTq1cv0717d7sypz7722+/bZ5++unEvjQgwXz++efuv/05c+bYhuuQIUPMqFGjwu6uz5w50/z777/m8OHD5sKFCyZcHD9+3NSqVcvs2LHDtg8VGNfnWLJkiQmXjmUFP/r06WPLTrVHXnnlFTNy5EgTinr37m3bGQ8++KBth/vqPH733Xft/wd6fPXVV/b7gDrt9N0+sY0dO9ZMnjzZPPzww/b6L168GGmfdu3amWLFitngstrqe/futXX7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ACCpef75581DDz2UaO9fvXp127ldsmRJW2/oetSWUKDKsWPHDvv9ftu2bfb7vUYB69/z58+H7D5IfClcCnECieSHH36wo4feeustr+1Tp041R44csYWdrFq1ynz55Zc2YFGpUiXTu3dvkzlzZq9jdu7caWbMmGEj4JUrVzZ9+vQx6dOnt68pMq4RUJI7d25Tp04dW6inSJHCfby+4NavX98WXEuWLDE3b960PcW33367X5/lxIkTZvr06bbQu/XWW03Xrl1toe1M2cufP78dIaUecV/TPypWrOieuqEC9OOPPzYHDx40xYoVs72/BQoUMHE1YsQI2+BQL39UevToYRsna9asMSlTprQ90Hpv9SS89NJLQd8HQPK1detWM3LkSDuKUqM5HeqZVTmrh3pl1fOp+kIjLQsXLmx69eplihQp4nWuU6dOmY8++siWOYUKFbJ1g1OeLl261EyePNn+rDqlfPnytn7JlCmT+3jVQyo7x44da3uHjx8/blq1amXatWvn12dRAGXmzJk24KP3uOeee0zDhg3ta/pyrO0aIaU6x1djI23atO4p3/os06ZNM5s2bbJ1SseOHW0jIa5Onjxp/82ZM6f9kq767t133/XaR+83YMAAs2/fPlt/ihoh169ft6MBQnEfAMnH119/bdauXWvLaE/vvfeeHVGkTmFROa4p2GfPnrXf9R999FGvsl70HV7Bbn3/1j6qDzTiSSZNmmTrILUdVPbUq1fPPPDAA15tCZWjrVu3tiP/1b7Raz179rTn8sexY8dsGad2gOo0dWbfdttt9jXVE/qurBFS69evN6NHj450vILzw4YNc9ejahcpaK8AkurHfPnymbhy6lmH6qEKFSrY9kWTJk3sNo2Y0n4rVqywn133v2jRovaanN9DqO2DxMcIKSQqFaxvv/22LXgdipEqYONUEt9++61p0KCBDVzUqlXLfPbZZ6Zu3br2S75j4cKFNlD133//2ddU+KiScKgicEYGaeqcAjQK8kSkxs8777xjC9hr167ZykaFWEz0RVjBLA2n1TEZMmSwU/90PaJKyem9VSUWcaTSggULbMEuixYtsp9T0yj0uRVg0/Uo4ObQHHIVstE9VKl60j1R5Ttw4EB7D9X48fTjjz+a9u3b2/ssGTNmtJXq/PnzE2UfAMmXvjwruKAAkCcFS/SFUsEo1RvqfNiyZYst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AKDyScET1Q36V/kzXnzxRa/y0jO/RcS6QVQneOaUikijczWiSr3RDpXLEWkqmHqYnTJTz9UzHlVQKWJjRKO09FB9pLL/iSee8DlFWVM7VP+pk0KBsogjcdX5Ed0IqISYsqfRuGrkRSyv1bng1Fmhtg+A5EVBKCfPrMpPpaNwpkl7tiU8vxurvnCCOJ5tCV8jWJWfSmku9P1d07qd8/niqy2hTmZ/RjtpJK4zpU75otSW0GfTiNmI1MGhulFTBj3bDE5bSNep46MSlyl7mr2h93rmmWfcCzE5VAbrXkf3/T7U9kGI0Cp7QGL74IMPXPny5XPdc889roceesjrtTvvvNNuv379un2+Zs0aV6pUqVwLFizw2qdhw4au8+fP2+c3b950zZkzx/58/PhxTb52LVq0yP1a79697ba5c+e6z6Hj06dP79qyZYt9fvHiRVeNGjVcPXv2jPH6t2/f7lqyZIn7+Y0bN1yVKlVyvfTSS/Z5q1atXE888YT9+ezZs65y5cq57rvvPnstETVu3NhVrVo114kTJ9zb9u/f7/rpp59ccfXZZ5/Za3J88cUXkT7/qFGjXPnz53cdOnTIPt+4caMrXbp0rpkzZybKPgCwefNmW1b16tXLVaRIEa8y8/nnn3cVK1bMlvFy7Ngxu88LL7zgtY/qll27drm3qe64fPmy/bls2bKukSNHul/7+OOP7fs9/fTT7m3PPfec3fbpp5+6t/Xp08dVpkwZr3LVF72uc3ru99hjj7maNGlifx49erSrevXq7tcefPBBV4kSJVwnT56MdK4XX3zRlTVrVtemTZvc2y5cuGDL80CoVauWq3///pG2//bbb/bz//777/b5mTNnXKVKlbL3IFT3AZD8TJgwwVWoUCFXixYtIn13r1Onjqtjx47usnjFihWulClTen13r127tqtZs2b2+79oX+d78oEDB2y5o+Oc17p37263/fLLL17laKZMmVw7d+60z9UuqVy5sqtfv35+1XfO+UXtntKlS9t6QlRvOHXTqVOnXCVLlnR16tTJ57nq1q1rr+X06dPubXv27HEtXLjQFVfLli2zn03f4aPy7LPPugoWLOg6evSofb5u3TpX6tSpXd98803I7oPER0AKIUEFqwISKth//PFHr9e2bt3qKlq0qP3Cedddd9nCcNCgQV777Nu3z1W1alUb5GjZsqUtpPXl3aFgkI5r3bq1DQapoE6TJk2kgJS233rrrbYyU8NG76lKKCbaR0ExNW7uvfde21DR+xw8eDBSQErBN31ObXvggQfcj1deecW+rmN0HTlz5nTdfffdtoLU5/EMwMWW7tdtt91m742CbLoXY8aM8drn0qVL9v7myZPH1bx5c9vwefjhh70agMHcBwBEAXqVmfpi6encuXO23FXASWVl3rx5XY0aNXJ3TIgCTypfM2fObBsat99+u9332rVr9vXPP//c1j36ol+/fn37xVUBoYgBqeLFi9tyXedXXaMya+nSpTH+glSmqdFSuHBhW+arbM+VK5c7mOIZkHKCb2pEeNYNXbt2ta9fvXrVlpMZMmSwn1udF7recePGxfkPxbk/eui6VNfo56FDh3rtp3ufMWNGV9OmTe17qh6JGDQLtX0AJC8KOijYoHJUgWtPGzZssMEqfU/X906VH57lvKjjomLFiq4CBQrY8lrl/quvvurVmZAlSxZXmzZtbH2gdoOvgJTqErUlVNfoPdUeOHLkSIzXr4CRji1fvryrbdu2tg2iYJYTTPEMSCn4pvdWh71nfTF27Fh3u6hmzZqu3Llz2+/++lnBLadzPrYUgNNnz549u9f76eHZllInieom1cu6zzomYmdBqO2DxJdC/0nsUVqAkyBPOTI0b1pDbT1pGp9yNGmOt4brO8NlPWn6hBINaj64hutq2psnDfHXUFtN/dPcb+WQUi4OJ6n5b7/9Zofp6nXl4dCUPi0JG9W8bV+U10rDfZXgT7k+nES6y5Yts1P/lDxQQ4R9Lf+qY7SCkuf1al9dj/I9xTSsNiZHjhwxf//9t53yoaGqUa2coXuoocmaguhMcUzMfQAkbyqPlWRc5aOTPDViOaIpdBqar3LXFx2v8ln1gspTTyqD9B7K06fV21avXm2naTsLR2h4v1Za0mvaT/lI6tev79dUboemietYlb+qf5ypG86iHMobqHxXSkwbkfKUeK74p+v9559/7PVWq1bNK0dIbCmJu+rCiJRfQ/lHPDmrP2mlWN0Lz0TxoboPgORFiz+oLFWZGbFMUJJr5WjS66oHPFdY9WxLKL+qpldrn4jTgFX2agqeplCrvlEOqUaNGtnp0qJpfWpX6LnKfFFakth8h1cSdrVXbrnlFvsezlRx5W5y6iYtyqTv9BGpzeCsehfxevV5PJOtx4bCBc7qtRGpbePkrHX2VTtHidW16qkzLTLi+UJpHyQuAlIAAAAAAAAIKpKaA372bmuVp6ho2dOYlvEGACQ9vXv3totE+KJEtBpNBQBI3jSSV6utRkULI8VnxCsQrghIAX7Q1IjoVi7yZ+UMAEDSc/fdd5srV674fM3Xyq8AgORHwabo2hKxSRECJCVM2QMAhAXl2lGOHeWUa9KkSYx5AJQLQksUa8lfLbncrFkzryWfnR5J5a7zVKNGDXt+AAAAAAmHDJAAgJD3888/22SU8+bNMytXrrTJnBVMiooSfirx58iRI83WrVvN9OnTTbFixex5PL3xxhs2UagWTHAely5dCsInAgAAAJI3RkgBAEKaVrzU6mgdOnQwb7/9tt02adIkM3ToULN792736jaetKqMplEpiOXo27evmT9/vl2lzFGiRAl7nj59+gTp0wAAAAAQRkgBAEKaRkTt37/f9OrVy72te/fudilfjZjyRcs5ewajRMmldZ6I+X60xLMCXd988405ceJEAn0KAAAAAJ5Iah5N7hGtrKZk1ilSpIhqNwAIOwrknDt3zhQoUMCkTBn6/RJbtmyx/5YqVcq9LXPmzObWW291v+YPBZwqV67slThUn18r32hhgi+//NI89thj5vPPPzd33XWXz3MomOUZ0FJdcfLkSZubiroCQFITbvWF4+jRo2bt2rX2e3zt2rVNmjRpYvycmzdvtiNoNb27dOnSXq9fvHjR/Pjjj5GOU0dH/vz5/bom2hYAkjJXHOsLAlJRUDCK1XEAJPUk4QULFjSh7vz58yZTpkwmdWrvKit79uz2NX+89957djTVokWLIgWplGvKc1pf165d7VRAX6tnjh492ualAoDkJFzqC/nwww/NgAEDbK5BfZ9PlSqVWbhwoZ367YvyCA4cONAGjPTdX6Nmdex3331nA1pOgKtjx46mRYsWtj7yHI3rb0CKtgWA5GBfLOsLckhF4cyZM7axoxuaNWvWQP1+ACDRnT171n7pVgJvLUMc6j744AOb4+natWu2YeGZ/+nee+8148aNi/b4mTNnmp49e5oZM2aYBx98MNp9N23aZCpUqGCnCapXPaYRUqorChcuTF0BIEkKt/pCnQka3aROiEceecTWG02bNjXp06ePtKiFQ7kFFVgqV66cfa6p2wpItW3b1owfP959Xu2zY8cOW/fEBW0LAEnZ2TjW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u9dWNsrt5EnPly5dauIjderUplatWqZhw4Z26l6/fv3MF198Yb7//vtoA2SeUwXPnj0br2sAABjz6quvmhEjRkRqXIg6IH799ddY3aYLFy6Ya9eumezZs/t9zJkzZ+w0b42cjejw4cORri1Lliy2MwMAEBwq19u2bWs7pX0ZPXq0eeaZZ/h1AEASE6eA1KBBg8yjjz5qnn76aZMjR444vbET/MmYMaPXdiU0v3z5somPl19+2eu6WrdubXNVzZ4929x7771RVnRKkA4ACAx1CIwaNcrMmjXLtGjRwmTIkCFeo6w06nXRokUmZcqUplKlSuaTTz4xZcqUifKY5cuXm3fffdfMmTPHXL161WdQrH79+rZzJVOmTO5tqt8URAMABIc6jjXzYt26daZChQq2cxkAkPTFKam5htK+8MILcQ5GidP7fOrUKa/tahjEpufbl4jXpSkhGua7Zs2aaPNZqRfdeezbty9e1wAAyZ1GwlarVs3cd9998QpGSZcuXWx9oRVZ9a/K9DZt2the9ajMmDHDdkK888470Z5bHRL79+93PwhGAUBwqW2h2RdVqlQhGAUAyUicuh/UI717925Tvnz5OL9xwYIFbeDo33//NS1btnRv13P1fAeSphCeO3fOpEqVKsp90qVLZx8AgMAoVaqUXYDixo0b0Za/Mdm5c6edKv7zzz+7Oxxef/11U6xYMbu9VatWPo+bOnWq/ffjjz+O9vw3b960I7By585tUqRIEefrBADEjdoWGs0aCCrTNeJqxYoVdgr2gw8+aANdMbUVVMd89913pnTp0mbIkCFerx8/ftwMHTo00nFPPvmkqVy5ckCuGwCSoziNkOrbt6/p3r27Wbx4sR1J5NmzrIc/9KW/c+fOZvr06eb06dN2m3JHaRSTesIdU6ZMsavq+Uu95Z999pnXtnHjxtnk6+pNBwAEh6ZgN2rUyDz88MPmn3/+iVRX6Au+P/7880/7b7169dzbbrvtNpsTynktPgYMGGAT5mranuqlo0ePxvucAAD/NW7c2Pz999/2O/u2bdsi1RfqWPZX165dbb4pjaTVcTVq1DA//fRTlPurjaA64O233zZ//fWX+eWXXyLtozyEGnVbrlw5u0K489DiHACAII+Q6tWrl7vyiGtScyfZrSqfsmXL2sfq1avNs88+63XetWvXmlWrVrmfL1myxOYEuXTp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8QaAZCpdunTu+kKrIymZ+euvvx5pv+heAwAkfVmzZrUPmT59up3G3alTp0j7RfcaACAZJjVftGiRz+03b940ixcvju81AQCSAOUD+fvvv6PMHbJ+/fqgXxMAIPRo9e7s2bP7fG3btm0mT548Qb8mAECIBaR27tzp82cnGKXcIbfeemvgrg4AEHYuXbpkDhw4YA4ePGh/jlhfXL161Xz//ffUFwCQzKnj4tSpUzaHlBKbR6wvzp49a5YsWWIGDRqUaNcIAAiRgFTJkiV9/uyZD2TixImBuTIAQFhasWKFVzJzX/VFgQIFzNy5c4N8ZQCAUPLGG294JTN/8803I+1Tq1Ytc++99wb5ygAAIReQ2rVrl/33tttuc//sSJMmjcmXL59JnTpOswABAElE/fr1bR2hwNTkyZPNzJkzvV7PmDGjnX6RIkWKRLtGAEDie/rpp02fPn1sUEr5pPr27et+TXWEpvGR0BwAkq5YRY+KFi1q/z137pzJnDlzQl0TACCMabSs6otChQqZ9u3bs5oeAMCnHDly2Mf48eNtAEod3ACA5CNlXA5SviitjhSRtmmuNwAAqVKlMv/9959ZtmyZ181Qp8bnn3/ODQIAWGnTprULI0WcgbF161azdOlS7hIAJFFxCkgNGTLEXLhwIdL28+fPm2HDhgXiugAAYe769eumY8eOJn/+/F7bs2TJYmbPnm2++eabRLs2AEDo2LJli21DRFwcSSNt+/XrZ/bv359o1wYACLGA1HfffWenYUSkbXoNAIANGzbY6Xq+kppTXwAAHPPmzTN33XWXHSnlKVOmTKZevXpm4cKF3CwASILiPGVPy7RGpG1azhsAANUVJ0+e9HkjqC8AADG1LagvACBpi1NASst5Dx061E7R88wJMnjwYNO0adNAXh8AIExVqlTJXLx40bz++uvG5XK5tyuv1JgxY6gvAACW2g/KLRgx56BGTunRuHFj7hQAJPdV9hxvvPGGueOOO0yRIkVM1apVbUNj3bp1Ni8IiQcBAKLVkqZNm2bzSE2ZMsWUKVPGnD592vz111+mUaNG5pFHHuFGAQBM9erVzYABA0yDBg1s26JAgQJm7969dur3q6++akqVKsVdAoAkKE4BKQWiVEF88skn5u+//7bLtLZt29Z069bNZMuWLfBXCQAIS23atDEbN240M2fOtCOjihYtap588kmb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3HHHHS5TONppohkHABC7pGVIyeOPP26tW7e2Zs2aua621Tueeju64IILguNMmzbN5syZY/369Yt6mmjGAQDkDKrxNHLkSHcMV/FYZcHquP7CCy9YxYoVg+O9/vrr1qVLF7vwwgujmiba+QIAcgZlMunhhK77zzvvPNfkUAXJv/jii+A4Kuvx3HPPWbt27dz40UwTzTgAgBwWkKpUqZL9+OOP9sknn7inDjfeeGNYd6py+eWXW5s2bWKaJppxoqE028GDB2dIt82pctP65KZ1yW3rk5vWRVif1NC2bVsXNPrss89s//79LnP26KOPDhvn/vvvD+sFKZppohknGuwnqYvvJnXx3aSunPzd3HvvvXb++efbrFmzXH2nc845x8qWLRv8ux44DB061OrXrx/1NNGOk5e2czKwvdhW7Fu577eYL5BT+nEFAAAAAABArpAzKtoCAAAAAAAg1yAgBQAAAAAAAF8RkAIAAAAAAEDeKWqeCr755hvXk1/hwoVd70wnnnjiYZnGDzNmzLBvv/3WDh486Lozb9++fZbjqzepqVOnhg0rVaqU60Uk2dQdb3rqcvdQxemnT5/u1kndtqvnrEaNGlmyPfroo7Zx48YMw1VM84Ybbsh0mk8//dS9QqkHsEceecT8tmfPHhs7dqwtWLDAevTo4XquTE891rz11luu15ljjz3WrrzySjviiCOynG880ySCunl+++23rWjRoq5AaXrbtm2zCRMmuN5zqlSp4va7o446Kst53nXXXXbgwIGwYerpTb19Hk579+513838+fOte/fu1qRJk7C/6zg1ZcqUsGFa7yFDhmQ5X20DfTerVq2yY445xn03mi4v+/fff+29996ztLQ0tz9cccUVh9wv4pnGD//8849NmjTJdf5RpkwZO/vss10PUlkZNmyYrVy5MmxY06ZNXY9TyaTf6Ysvvphh+MCBA+3II4+MOJ1+r/puFi1a5MbTd6MOUZJpy5YtEc+/WR1P/vvf/9pvv/0WNqxx48Z29dVXm9/+/PNPe+ONN2z9+vXu3Fe8ePEM46gTgXHjxtnOnTutVatWrjD0ocQzTXapxOrnn3/uzsUtW7a0rl27ZhhnxYoVrgOdv/76y+rVq+fOF1kVeNX4zz//fIbh/fv3P+z7nzr50Xezbt06e/jhh11R7lBaLi1fKF1DXXPNNVnOV9Pou9mxY4eddtpp1qlTp8Oy/LlRMvbrnGjTpk2ZXv/26tXL/e5gtnDhQndOU5H9vn37ZrpJvvrqK9crpI5Run9t2LBhntx06sDmww8/tDlz5tjFF1+c4d5S99Pvv/9+ptdBeXFbTZo0ye1ful4899xzM/3NLV261MaPH2+7du1yndF16NAhps/J0xlSOrh17tzZ3XCvXbvWXVzrx5zoafxw1llnuQtwndS0M+gG8rLLLnMXVJGol5DJkydbrVq1gq/q1atbKlB3vPoRhC5b+oun9B5//HF3Mtf662K4efPmLvCQbFWrVg1bD/XuovVbs2ZNxGl0kPzoo4+S/t3ogK0exxTY0DIvW7Ys0xsQBaneeecdF1DSAVsXpbt3744433imSQR18awbBp2UR44cmeHvuvk46aST7Ouvv7ZixYq59VavbQr0ZkXbRsGh0O9Lwd3DSfuHlk0BWH3+zz//nGGc7777zgXXQperRo0aWc5XN1a6mX3zzTfddzN8+HA79dRT3e8qr1LwQkGbBx54wD2I0A2oLuTS37xldxo/KMio4JOOjYUKFXL7jQKZL730UpbTvfvuu+7mKf2xLNkU0Nb+H7pcemndItFDG11UDRo0yI2n31CDBg0yPb75SQ9S0q/H33//7dYvX758EadTUFoXg8n+bvr162fNmjVzD4a0zLpOSk83Q/od6MGAfiMKpN92221ZzjeeabJLv9PjjjvOXVfoxkTLkNn14Hnnned+F/qNP/XUU245dfMcia4btW10HI52f00EXR/qd+59N5kdz7We2sax7Ec6V2qdFXTX9aaCV7179z6Ma5J7JGO/zqn0AFP7ra6rQvfPvP6gzDuf6fpZ+4/2KT1MzIyuRfSgXtequg7Q8UABhLxG20jXzjrevfzyy+7BXHoapvuT9OfjvOa3335z14u6/tM56qeffnIPKV599dWw8XR9q3snnQv1IFbxh0hB0YgCedSqVasCBQsWDLzzzjvBYffee2+gYsWKgX379iVsGr/Mnz8/7P28efMUiQp8+eWXEafRsrdu3TqQirTs06ZNi3r8tWvXBgoVKhQYM2ZMcNjgwYMD5cqVC+zZsyeQSl5//fVA/vz5A7///nvEcbTsp512WiDZfvrpp8DmzZsD//zzj/tOQvd9T+/evQPHH398YO/eve69xi9btmzgySefjDjfeKZJhOnTpwe3b926dTP8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mjRpErjkkkuC77UP6neybNmyTNcv2mkOp0i97O3YscP9TcvnHS/T0zJq3/N+J9988407R3jWr18fOPLII921mx8i9bKn996xyqPrRfVGGdor53PPPRcYOXJkWO+bXbp0Cb5XL176baXfJ5FRsvfrnGTWrFmuF0vPtm3bXC9onTt3TupypZpIvezp963z9UsvvRQcpt4x69Spk/T712SK1Mte+nuwuXPnumNhXrwOHjVqlLueGDt2bMRx6tevH7jyyiuD73WO0PaKpVfMPBuQkhEjRrgfqLrh7tChQ6BEiRKBL774IuyiUCfu0B/woaZJFnXdWapUqcB//vMfd/HjvUJ/VF4Xn6Hd2Tdt2jRw3XXXuYO6uijXwSxSQMsvumBT8EldcGvZjj76aHdzHxog8AIkoQcSXcDqu7nwwgtdQEABjqlTpwZSgW4MdKGh7sYzoyBA+fLlg++7desWaNy4sVv/8847z303d9xxh+/fjXcjp/1K2/ucc85x70MPTLow0H6k7+nqq68OVKlSxQXfQm8S069fNNMcDrqY1vLrIlonIu934gXGdBDVerZt2zbsdxTanaloHC/4qe521fW19led4LWvKtilE9jh5N3o6KXl0T6vf4cGLbt37x7cj7R82o9uu+22sP1IwTlti9CbrObNm7t10Hejbsw179CbqLxI20KBDm1TBZbUZXfoTZ2CHPoe1KVwtNMkgwKoOhbpAiL9Ph5646mbJe8CQ0EevW/Xrl3ghhtucPtHuXLlkhYgD/Xss8+684WW9YorrnCBHO2vf//9d4YAiY5nHv0mdExSEKphw4buWJSsAE56ChjrO4q0PDp+XXbZZcGAho6l3nejvymg/vbbb/u81IHAxIkT3X6kAIW2t4I4eq99zqMu7bXdTz/9dLcO6j768ccfj7h+0U6TaN4DSb10ftI+on8/9thjwXG0z2k9e/ToEfY7evHFFzMEgNLS0oLnIO2v2lf10nel7y5SQCtRdHzSsunaVcujfUXvtW1F3aA3a9bMPfzT30455RR3XnjjjTfC5qMA3MUXXxx8r6CujnEafvnll7vrLnULjkNLxn6dUylYpwCU7lt0Xq1cubLbX1etWpXsRUsJTz75pPs963pPv0fvWLR79+7gOP/73/9cUoV+vzrm6EGj92A1L9F1jrd9FGhRooD+HRpoV0LDiSee6B4g6pipe8trr702ZRIc/KL7bj1g8M5/oS9dF3q+++47d+3VunXrwKWXXur2s9AEkWjk038sD1Ndoq+++so1VVHadWgvQ0qfVXFQNYNTbaVopklmobHMqOifimGLekZSUcDQmhRq5qcaIGpGovGyKoLuJzWL1DZWzSiv7W5o3SXttur95cwzz3Q91HiUIvjll1+69uX6bipXrmypQKmxU6dOtV69eoX10uhRzzyLFi1yRbQ9KnyqGiCqMaHvRj3X+E1deX744YcZhqumVdu2bcPSM1VrSSnB6hFRfwtNo85s/Q41zeEwbty4TLvkVjNK/QZ++OEHV5MgMyrgHPp7a926dbA5n+rIaX9Vb5XaX9W+OpoutrNjzZo1Nn78+AzDGzRoENbMR/ueaoCoOZLqR6Xv1Ue9ci1YsMB69+4d1lTD+27U+5qOgaTFm9s3VKdPBVa9mjEeFbBX/Rh1SBDabCeraZIh0n4jqsmhmkyiOgHlypVzx1GvKc63334b7NFU55YyZcpYKlBzbS2bUuq9OmmZHcdU9yq0DsmsWbNs4cKFbp3VTXGyvxuPfnubN29230dm3nvvPVcwVPuT992otoW+G53z1Ltu6Hr6RcugTlXS69y5s2sK7FEPiCpEvHPnTresOmZltX7RTJNo3vVfevpNqEaXqDOAzHrMVCF51TEL/b2pHpO6wRadJ9QLq/ZXNWnwrtEOJ13/ZVbvTfv9scceG7yu0vFKTS90XavtrPVNfw7VuaRTp05htUL03aj5ooq6h14vI2t+79c5mY6J+t2oR1Xts9rXuC75P6oDuXHjxgzbTNd1ofccahL69ddfu2E6t+u6JK9Rj9PqICo9XeuGHte0rXTvomt51fBV79l5zaoI94CiDrZCO1xRB1Cffvqpux/SPZB64otFng9IAQAAAAAAwF95tqg5AAAAAAAAkoOAFAAAAAAAAHxFQAoAAAAAAAC+IiAFAAAAAAAAXxGQAgAAAAAAgK8ISAEAAAAAAMBXBKQAAAAAAADgKwJSyPXGjh1rgwYNstyoe/fuNnfuXEsVl1xyiaWlpSV7MQAgLjpX6JyR2/zyyy/u+Lx3715LBTpPaHkAICf6559/3DFs6dKlltuMHz/eBg4caKnirbfesoceeijZi4HDiIAUcowJEyZYv379Yp5uyZIl9tVXX1lu9OGHH9q6deuS8tlXXHGFzZs3L8NJbMOGDUlZHgDw6OJVF7Gx0rlC54zcZvPmze74/O+///r+2bph042bbuA8Ok9oeQAgJz5MPXDggDuGbdq0yXKbn3/+2b788suUSSLQd/Ptt98mZXngDwJSyDF0UfvFF18kezHw/3zwwQf2xx9/sD0ApBxdvJKtmRp0w6YbN93AAUCq4WFq6sjNSQSIrGAWfwNShgJRetqtbCAvzb9379521lln2cqVK+2VV16xVatWWfXq1e3GG2+0unXrRpyXntIOGDDAihcvbg888IDly5fPPv/8cxdg2bNnj5100kl20003WdGiRYPT6DP79+9vc+bMsQULFli5cuXs1ltvtZo1a0b8nNtuu80FbPLnz29Vq1a1888/384888yYx4lVItZF20jb9LvvvnPb9Oqrr7ZnnnnGrrnmGjvttNPcPDXO448/bqNGjbLy5cu78WX//v32/PPPR72dACCRhg0b5oJRa9eutRUrVrhhL730klWsWNGmT59u7777rm3bts0aNWrkjmUlS5aMOC+dc5SZ26VLl2CWz5gxY9x8jjjiCGvbtq117do1OL4+98EHH7Thw4fb//73P/vtt9/shBNOsP/85z9hx+FQGzdudOczKVy4sNWpU8euu+469/9YxolVotblr7/+sueee85tb/29c+fONnjwYBs5cqTt2LEj+LRbWbU61+kcd9xxx7lhOv9Fu50AINF0HPWyal9++WWrXLmyO+YdPHjQ3Xfo/kPHrfbt29vll1/u7hkiUSBF89C9xfHHH++C8Tq+Kcii+V522WXWtGnT4Pia/6+//modO3a0999/37Zs2eLua3SsjETLo/OZlChRwho0aODODbqniWWcWCVqXebPn2+vvfaay9Y99dRTrUKFCvbNN9/YU089ZZ9++qnLkNI5xbvXu/3224PT6p4k2u2EnIUMKeQICjApuFK2bFl3QtBLw3SzoZsK/b9du3YuKHXyySe7dNPM7N692y644AKbMWOGO8jpxKKTkE5ItWvXttatW7sDYsuWLW3fvn1hT090ka3POeOMM2z58uVunJ07d0Zc5k6dOrnl1EFVy33RRRe5C/RYx4lFotZF8xgyZIg1b97cBZV0ItaNy5o1a9zftQ0LFChgrVq1csuv96HTxrKdACCRTjnlFDvqqKPcDYF3vtCF+Ntvv+0uYhWA0vFJgSkF2BVEj1R3SX8vXbq0OzbrAvrss8+2119/3X1Gw4YN7d5773VB9/RN0RR0UZBHn6Ogfbdu3SIur5bNW06dE3Thf+KJJ9qyZctiGicWiVoXPfjQ9Lqh0PlAAaY2bdq46XTe0bbWNhcFu7T8LVq0CE4fy3YCgES78MILg8ci7/gqN9xwg/Xt29fdYyigowfIemVVQkPXwpqfzj16WK77Fl0H6xpax0L9P7SpsoL+Q4cOdcfdY445xurVq2e9evVyD3Uj0b2Pdy7QcfOTTz5x19mhTaKjGScWiVoXBaMUhNJ5Q8szbtw469Gjh02bNs39XdNpW+vhkbf83gNtlQiJZTshhwkAOcSQIUMCTZo0CRt2+eWXB9q0aRM2rH379oEuXboE3w8ePDhw2mmnBbZs2RI49dRT3d937tzp/vbLL78EChQoEFi2bFlw/H/++Sdw9NFHB1599dXgMP1U7rnnnuD73bt3B4oXLx6YMGFC1Mv/+uuvB4455phsjxNKy/Dhhx8mdF3S0tIC+fLlC3z33XfBcSZOnOime+edd4LDihQpEpg0aVLY8iRiOwFAdp111lmBfv36Bd/v378/ULly5cAjjzwSHLZ169ZAmTJlAs8//3xwmM4VOmfMnz8/cOSRRwYGDRoU/Nsrr7zijs/79u0LDtNxV8fL3377zb2fNm2aOw5OnTo1OM6XX37phnnnnWhcccUVgd69e2d7HM/s2bPdMuzYsSOh6zJs2DC3nXSs99x2221unI0bN7r306dPd+/37NkTHCdR2wkAskvHHR2TPAsWLHDHwjlz5gSHff7554H8+fMHlixZ4t7reKbpdHx77bXXAqVKlQp88sknwfG7du0a6NmzZ9jnvPzyy4G6desG3+scVbp0aXd/4hk4cGCgZcuWUS+7zm1Vq1YNjB8/PlvjhHr44YcDLVq0SPi6dO7cOXDhhRcG3x84cCBQv379wEknnZThni1UIrYTUhtN9pCjKdMpfaFzZRvdd999GQq66imBnlq8+eabrsmDTJ061QoVKmT333+/grNumP6vTKr09Uc0vUdNCqpUqZJlQXE9wVa2k2pfbd++3S2DmiXoyXTBggWjHidaiVoXNeVTdoGyozx6YqSMqGjEup0A4HDTcVXZOxdffHFwmDKf9JR35syZdssttwSHz5492zVBU3M1NSHzKONU2VRqwqxjq/dSc47Fixe7zNTMjoNeE3IdB4899thMl++nn35yTR5Wr17tesJTlq+aRcQ6TrQStS7aVh06dAhrZqem52ryEo1YtxMAHG46J+jaNTSbU5meOmfomKd7CY/OFSoArmOqskU9eq9myMry8Y6v3jW+rsuLFSvmxlN2qlpIhB4H1SIhK8p4+uyzz+zPP/909wvKRlX2UqzjRCtR66Jtp/IfHp1v1GJD8z+UeLYTcg4CUsjRdEAMPUCJmpipfbEOmF5bb9Wx0OvSSy8NBqNk69atLvU0fffTGi/0glyKFCkS9l4HUrUxj7RcajqoA6guzrVMOhGofbluJNSmO5pxYpGoddG2K1OmTNjfFYyKdnli2U4A4AcdbyWz88Xvv/8eNkxNk3XxrmNz+mPs0UcfneEYq1oaOpZHOg7qGCiRjoMqwK6gzvXXX+/qOJUqVco1ZVAT9FjGiUWi1kXnC68elCf9+SMrsWwnAEjWvYV3vvDOJR7VVNLwWrVqBYepAwfdc6h5ml6hVMsp9IFzrNfMKs3xwgsv2M0332xNmjRxDwP0sCK0NEY040QrUeuiezKdd9KfH6I9X3BvkbsRkEKOkVkhQZ0AVEQvlN6rzXHo+Brv6aefdsX2FFwZOHCgG66C3bqgVv2pWC6ioyksrrbaU6ZMCS6HMrNiHScWiVqXGjVquOK0WjZlXIlOIioCHCqrwo4AkEzpj0/ezYLOD8oA9eh9+sLgCuLrBuO8886zyZMnu5pI3jFW2azpgzjZpae8qlEVWg9DnxvrOLFI1LrofJE+oKd6I6E4VwDISXS+UCZqaGsFPShW9mZo4EkU+NFxWTWo9EBZWau6z1CGlQJBiT5fqFWFarx6xdjlzjvvjHmcaCVqXXQeqFatGucLZIqi5sgx1BODehoKpQKoI0aMcD0yeE3g1MNFZoVRVUBP6atPPPGEO1CLMpP0FEQHap14QtNKFy1aFPeyKgtLaawK5IiCOaFpqtGOE4tErYuCdnqqoe3oUe8X0XwfAJAK0h+fdEGtjh6efPJJ98TXOzaqqUVm5ws11Xv00UddcwIV7BZd3M+dO9cV3/bo6e8bb7wR1nFErHQuULMKj5rMqaehWMeJRaLWRYXK1VzcO8do2v/+978ZvgvhfAEgJ5wvzj33XBdACX0AoOtzdS6hZt6hFLBSBxn169d3QSnvON2zZ08XrFJmkkeZRmp2nR06F6xfvz74Xj3f6SFyrOPEIlHrovOFlkUlSkRBv/feey9sHO4t8iYypJBjnHPOOa7HC7XRrlq1qksVvfvuu11bb50IGjdubAsWLHDNLPr375/pPBSUUltlBV10stF4kyZNCvbapzbSerqrA6IuzOOlmktaDi2XeujQcmnesY4TC7VtT8S6KKil+h833nijO8mqzoiejKjJXmgdKXW3qu9j4sSJLuPglVdeiXvZASCR1PRMxyhdlOsmQl1g6xil84h66FFmj+rl6RjmZUClp55Y1cxAx2plsiqg9eKLL7qefoYNG+aOe2qukd3upxX8Ui0lnQ80zx9//NGdE0KbbUQzTiwStS46l6oOlZpy6NysHla9+ire+UK9IjVr1sxl76oHJTU5TN/MDwCSRcc8He8VHFH2qK6BFThRIEbDdJxVzT5lqmbWAsELSum842VKDRo0yGVU6djXtGlTd8+hmkuR7k+iNXjwYPdA4YsvvnAPtfVA3qu/F8s4sUjUuqh1ilqH6Bysc4HOOeq9T8Etj863Gu/000+3SpUque8FuV8+VTZP9kIA0VIW0Q8//OCyitQu2kudXbhwoauloRNJ+voXOuDpYBx606FhOrmo22vdrCijSPNVhpWKqaYvqPr++++7m4EjjzwyOExPhXWAj3SQ1wlMNzxqb66gk05iehqvLmG9C/VoxsnKhAkTXPFxPf33JGpddPJRkEzbVMNVs0QnWd3IePRUXM011LRPT5Ti2U4AcDjonKAnurog1/FJhVcVYP/uu+/cOeTEE08Mdint+frrr93xK/ThgIapuYbOF6Knu8ouUqaV5qGLZo/ONar3FNq0QV1cK6Cl4I3q/GVG89Ry6Zygi37NR0XYdXMTyziRqDl3ZueWRK2LzgU6ZygYpW2u4vG7du0KfpbOSzrXaZ4KBuoVz3YCgMNBQX6dM1SryDvW//333+6YqwCMHmjrwa9Hx+EPPvjAHX/Lly/vhqnUhR4M695ED8lFmUk6PuoaWg8RQuuxKtNVn9GqVasM5y2dsyLRPHXfo3nqHkDHVj181n1ELONEoubcmZ1bErEuOhcokUDnHAWjHnnkEfd5KsLu0XzmzZvn7vl0rtN5Kp7thJyDgBSADNRERScwr+ekBx54wPUkohsOrzcNAACUdezdwClwp9pbekjx8ccfs3EAAI4CTEoI8HojVAciSi5QplWfPn3YSnkYTfaAFDVt2rSIzeD0BF/NLQ4XPYlQSq2eduuJiNrEK1WZYBQApB7VN1FNrMyoqVyvXr0O22cr8+q2225zvfbp6bmewitzAACQenr06OEyWDOjOrSnnXbaYflcZZ/169fPZS2rRYiyz5ThdMsttxyWz0POQYYUkKLUPnv+/PmZ/k3NDFUL5XBSUEqfrywp1S2hCQUApCY1x4hUtLZ27druKfThpOK0evKtHqbUJCS0K3AAQOr46KOPXPP1zKhponrDO1xUKSgtLc3Vd1R9Qcp5QAhIAQAAAAAAwFf5/f04AAAAAAAA5HUEpAAAAAAAAOArAlIAAAAAAADwFQEpAAAAAAAA+IqAFAAAAAAAAHxFQAoAAAAAAAC+IiAFAAAAAAAAXxGQAgAAAAAAgK8ISAEAAAAAAMBXBKQAAAAAAADgKwJSAAAAAAAA8BUBKQAAAAAAAPiKgBQAAAAAAAB8RUAKedLGjRvt/ffft0AgkPB5//33327e//zzT8LnDQAAAABAbpAvcDjuyIEU9/XXX9uZZ57pgkYFCxZM6Lx/+OEHa9asmQtMlSlTxpJl/fr1tmjRIitdurSdfPLJdsQRR2QYZ9u2bTZnzhy3DU499VQrWrRoyo8DAAAAAMj5EnsnDsDKlStnF198sRUuXDgpW2PHjh1244032uzZs+2EE06wVatWuYywMWPGWMeOHYPjffLJJ3b55ZfbcccdZ7t377bNmzfb5MmTrUmTJik7DgAAAAAgdyBDCr45cOCATZgwwU477TSrVKlShuHKiKlcubIbtnr16mB2T4sWLTIN7mzdutXmzp3rMn+aN29uRYoUccP37NljU6ZMcf8uVKiQ1alTxxo0aGD58uXLNEPql19+sd9++83q169vtWrVinp99DnKhtq3b5/LQCpfvrwbrsyoL774wi644AL3+d98840LCKWnz/em2bJlS3BdGjVq5NY7Xn/99Zd99913dt555wWH9e7d2yZNmmRr164NBq20rjfffLM9/PDDbtgVV1xh8+fPt59//tltq1QbBwAAAACQexCQgq+aNm1qHTp0sMceeyw47LPPPnPBEzUxq1Chgt133302dOhQF4has2aN/fvvv/bxxx/b8ccfH5zmxRdftHvuuccNU7MuBacU1FLwScEdZQiJgkXz5s2zo48+2s2jRIkSYQGpzp07u2CUPldBnCeeeMJuv/32Q65HWlqatW/f3qpUqWJHHnmkLV261AYPHmzXXntthiZ7Gv7TTz8Fp123bp1rljZz5kwXhHv55Zetf//+Lqh18OBBW7x4sY0YMcK6dOnixtewDz74IMvlOeqoo6xVq1YR/z58+HC3XbWdFNx577337Morr7Q///zTrbso+KNsJG0HBfhSbRwAAAAAQO5Bkz34SkGH5557zh599NFg1subb77pmpIpEDF9+nQbMmSIyyo6/fTTXTDqoosucgEm/U30/1tvvdXGjRvnmsbJ8uXLbdeuXcEmcyoq7tm7d6+1bt3aBbkGDRoUtjxly5Z1ASAvSNO9e3eX2XSoTCnNSwGtd955J/gZ06ZNy3TcBx98MPhvLaOCUOecc461bNnSNavr16+fC04pi0sUfLrmmmvs999/d8unDLJ33303y+U58cQTMwSkNG8F9H799Vd76aWX3Hb3trmyzxRM84I/3jy8vykAlGrjAAAAAAByDwJS8FW3bt2sb9++NmPGDBdAUa0gZTa99tpr7u8K8Ch4pGCU20ELFrSBAwfaKaec4oIr1atXt9GjR7ugjheMkmOPPTbTLCY1/VPTupo1a7qspPSUZeUFaS677DL3WePHj7e77rory/VQ80BlVinjSFlQamoX2kQuM+o/QIEmZW1pPfPnz2+jRo1yy75ixQrXdFDj6OU1B1QWlpr9hQbYoqXA3axZs1z2ljKoQjPMVDxcwa5Q2talSpVy65SK4wAAAAAAcg8CUvCVake1bdvW3nrrLReQmjhxogsInX/++e7vK1eudM3uQqm5nfc3BaRUpFuFryNRMWxlXKlekrJsFNRYtmxZpr3M1a5dO8N7BbEORc3f1DxPWT3K3jn77LNdnaasaj+pNpKyqL7//vvgeMqCUhNDZYmFUnDLW954m+wp2OZRFta5557rPk/bQwE1BQNDKRCmYd7npto4AAAAAIDcg4AUfHfVVVfZnXfe6eoaKTClTCfVgRIV+U6fEaOAjfc3UTBHQadInn32WRfkUkaVsotEWVlfffVVhnH1WcWLFw97ryZ/h1K1alWbOnWqWw7Vo3rqqadcs7off/wx0/EVeFNASoXFQ7O5SpYs6YJrWWVAxdtkL5Qys5588knXPFHZZQr6/fHHH66ou7eNVMNLTSS9gGCqjQMAAAAAyD3yJ3sBkPdceOGFrubSmDFjXFBHASqPmuqph7rt27cHhyk7SBlAXqaUmrF9/vnnrgC2R1lEKiIuCmwo6OMFNhTkUCAoUqDIo+whBZTUC+Ch6DO8IJkCaqp7tXDhwmAdq1AqaK7aVBpHmVShlMn15ZdfujpPoTZt2uSCMeI12cvqdf/994f1spfeggULgoE073OVffTpp58Gxxk7dqwLzp1xxhkpOQ4AAAAAIPcgQwq+U1aQmujdcccdroc6FQf3XHfdda7XOTXru+mmm1yQ6JlnnnE1pgoXLhwcRxlDqit12223uewqvVcGkoIXau52+eWXW7169axy5cqu5pSCV15AK5R6+1PwR8uhzCotS7t27Q65Dsq4Ui0oLaeWS8usYFNotpXniiuucMuhQumhmVD6LDX7U8BNQTD17qfxVMRbATQFx1RHKVYK8r366qtuOyiQp1paWj5lpamWlmhb/Oc//3HbcsCAAS4YpELzCpp5PRGm2jgAAAAAgNwjX0CFWgCfqeC2en1TtpMCT6F27txpr7zyis2fP981z1OxcRU6D6WsJ2VYffvtt64mkgJQaormmTx5siuWriwjBak0zty5c+2JJ54IZi0NHjzYBbtef/11V6BcvdwpKOI1H8yKfjYKJCmba//+/dasWTO7+uqr3bSal+o3vfHGG1asWDG74YYbgtlboR555BEXNFOTPPUYqHnp340aNXJN7LTM8VJGlDKM1q1b57Ki1HOgevVLvw4K5H322Wcu8KVML/X+l8rjAAAAAAByBwJSAAAAAAAA8BVN9oBMfPfdd64oembU9K5p06ZsNwAAAAAA4kRACsjE7NmzbcaMGZluG9V+IiAFAAAAAED8aLIHAAAAAAAAX+X39+MAAAAAAACQ1xGQAgAAAAAAgK8ISAEAAAAAAMBXFDWP4ODBg7Z+/XorWbKk5cuXz99vBQAOo0AgYDt27LAqVapY/vw8lwAAAADgPwJSESgYVb16dX+/DQDw0Zo1a6xatWpscwAAAAC+IyAVgTKjvBu2UqVK+fmdAMBhtX37dhdw945zAAAAAOA3AlIReM30FIwiIAUgN6I5MgAAAIBkoXgIAAAAAAAAfEVACgAAAAAAAL4iIAUAAAAAAABfEZACAAAAAACArwhIAQAAAAAAwFcEpAAAAAAAAOArAlIAAAAAAADwVUF/Pw6IX8PRDaMeN61HGpsaAAAAAIAURYYUAAAAAAAAfEVACgAAAAAAAL4iIAUAAAAAAABfEZACAAAAAACArwhIAQAAAAAAwFcEpAAAAAAAAOArAlIAAAAAAADwFQEpAAAAAAAA+IqAFAAAAAAAAHxFQAoAAAAAAAC+IiAFAAAAAAAAXxGQAgAAAAAAgK8ISAEAAAAAAMBXBKQAAAAAAADgKwJSAAAAAAAA8BUBKQAAAAAAAPiqoL8fB/iv4eiGMY2f1iPtsC0LAAAAAAAgQwoAAAAAAAA+o8keAAAAAAAAfEVACgAAAAAAAL4iIAUAAAAAAABfEZACAAAAAACArwhIAQAAAAAAwFcEpAAAAAAAAOArAlIAAAAAAADwVUFLss2bN9vYsWNtw4YN1rBhQ7vwwgstf/6s42QzZ860WbNmWcGCBe3000+3Zs2aJWS+AAAAAAAAOPySGqH5/fffXbDovffes127dtldd91l5513nh08eDDT8TX8lFNOsf79+9vGjRvt119/tbZt21qfPn2yNV8AAAAAAADkkQypfv36Wa1ateyLL76wAgUKWO/eve24445zgaRu3bplGD9fvnw2bNgwa9GiRXDYueeea506dbKePXta/fr145ovAAAAAAAA8kCG1L///muTJk2yq666ygWNpE6dOta6dWv74IMPMp1GAanQYJQ0btzY/X/NmjVxzxcAAAAAAAB5ICC1evVq27t3rx199NFhw/V++fLlUc/nzTfftCJFiliTJk2yNd99+/bZ9u3bw14AAAAAAADIRQEp1XaSUqVKhQ0vXbp08G+HMmPGDLvvvvtsyJAhVrFixWzNV/PQON6revXqMa8TAAAAAAAAUjggVaJECff/bdu2hQ3funVr8G9ZmTt3rnXu3Nn+85//2J133pnt+Q4YMMBN4728JoAAAAAAAADIJQGpGjVqWPHixW3ZsmVhw/X++OOPz3LaefPmWYcOHVwh8yeffDIh81WzP2VVhb4AAAAAAACQiwJSKjh+4YUX2htvvGH79+93w5YsWeKa4XXt2jU4ngqRq2c9z/z58619+/YuGPXMM8/EPV8AAAAAAAAkR75AIBBI0mfbunXrrFWrVla2bFlXlPyjjz6yNm3a2DvvvON61JPrr7/e5syZY4sXL3Y1oJQBVbBgQbv22mvD5nXxxRdbs2bNop7voaiouWpJqfke2VKpoeHohlGPm9YjLa7p0k8L5EYc3wAAAAAkW8FkfnjVqlVt0aJFLmC0YcMGu/TSS61du3YZAk2nnHKK+3f+/Pmtb9++EZvcxTJfAAAAAAAA5MEMqVRGBkHqIUMKSAyObwAAAADybA0pAAAAAAAA5E0EpAAAAAAAAOArAlIAAAAAAADwFQEpAAAAAAAA+IqAFAAAAAAAAHxFQAoAAAAAAAC+IiAFAAAAAAAAXxGQAgAAAAAAgK8ISAEAAAAAAMBXBKQAAAAAAADgKwJSAAAAAAAA8BUBKQAAAAAAAPiKgBQAAAAAAAB8RUAKAAAAAAAAviIgBQAAAAAAAF8RkAIAAAAAAICvCEgBAAAAAADAVwSkAAAAAAAA4CsCUgAAAAAAAPAVASkAAAAAAAD4ioAUAAAAAAAAfEVACgAAAAAAAL4iIAUAAAAAAABfFfT34wCzhqMbRr0Z0nqksckAAAAAAMhlyJACAAAAAACArwhIAQAAAAAAwFcEpAAAAAAAAOArAlIAAAAAAADwFQEpAAAAAAAApH4ve3/88Yfdc889NnPmTNuyZUuGv2/dujWm+f3111/uVadOHStWrFhU02zatMlWrlxpxx13nJUsWTLsb6tXr3bzC1W0aFGrX79+TMsFAAAAAACAFAlI9ezZ0wWEBgwYYGXLlo37w/fv32/XXnutjR8/3ipXrmwbN260oUOH2g033BBxmoULF9pTTz1ln332mVuGr776ytq0aRM2zmOPPWZjx451AS7P0Ucfbe+++27cywoAAAAAAIAkBqSmT59uS5cutapVq2brwx955BEXUPrll1+sevXq9t5771m3bt2scePG1qRJk0ynmTt3rnXs2NEefPBBF2SKpG3btvb+++9na/kAAAAAAACQIjWkKlasaEWKFMn2h7/22mt2/fXXu2CUXHbZZXb88cfbiBEjIk6j8bt3737Iz//nn39syZIltm7dumwvJwAAAAAAAJIckLr66qvt4YcftgMHDsT9wapDpVezZs3Chrdo0cLmz59v2TVp0iTr0qWLqxtVt25d+/zzz7M9TwAAAAAAACSpyd7kyZNt3rx5riZTrVq1LF++fGF/nzNnziHnsXnzZvf/8uXLhw2vUKFC8G/xOuuss2zQoEGuSaEypfr27WsXXnihpaWlueXNzL59+9zLs3379mwtAwAAAAAAABIYkFLmkV7ZUahQIff/0CCQ7NmzJ/i3eHXt2jXsc55++mkbOXKkTZgwwe64445MpxkyZIirSwUAAAAAAIAUDEjdd9992f7gatWqucyq9evXhw3X+xo1amR7/qEKFizo6l6tXbs24jjqMbBPnz5hGVJebSsAAAAAAAAkuYZUqEAg4F6xKl68uLVs2dKmTJkSlh31xRdfuCZ3nlWrVtlPP/0U0/Kkz7r67bffbOXKla5geiQqkl6qVKmwFwAAAAAAAFIoIPXOO+9Yo0aNrGjRolasWDH3bw2LhQqjjxs3zjWVmzp1ql1yySVWpkwZu+mmm8LGUe97HtWX+uGHH2zRokXu/bJly9x7L9NKNaOaNm1qL774on3zzTc2ZswYO/vss61BgwZ2xRVXxLu6AAAAAAAASGZAavjw4dazZ09r06aNjRo1yr30bw17/vnno56PMqE+++wzW7hwoQtKqYncjBkzwrKTVIRcwSTP7NmzrVevXnb//fdbkyZN7NVXX3XvVWhdChcu7LKuVqxYYQ888IB9+OGH1rt3b/vuu+9c8AwAAAAAAADJlS8QR3u7OnXquELhF110UdjwDz74wO6++27XRC6nUw2p0qVL27Zt22i+l2ANRzeMety0Hmm+Tpd+WiA34vgGAAAAIEdmSKk4ePv27TMMb9euXZaFwwEAAAAAAIC4AlJqRhdajNwzadIk9zcAAAAAAAAgkoIWh/79+9s111xjn3/+uTVv3twNU42mN99801566aV4ZgkAAAAAAIA8Iq6A1HXXXWeVKlWyJ5980iZOnGj58uWzE044wRUQP/fccxO/lAAAAAAAAMjbASlR4IngEwAAAAAAAHypIQUAAAAAAAAc9gypBg0auP8vXrw4+O9INA4AAAAAAACQrYDU9ddfn+m/AQAAAAAAgMMSkLrjjjuC/z7iiCOsV69emY738ssvx7QAAAAAAAAAyFviqiHVu3fvuP4GAAAAAAAAJLSo+Zo1a6xcuXJsVQAAAAAAAGS/yZ40atQo03/LwYMHbeXKlXbeeefFMksAAAAAAADkMTEFpK666ir3/4ULFwb/7SlUqJDVqlXLOnXqlNglBAAAAAAAQN4NSN19993u/xUqVLBrrrnmcC0TAAAAAAAAcrG4akgpGLV58+YMwzMbBgAAAAAAAGQ7IPXKK6/YwIEDMwzXsFdffTWeWQIAAAAAACCPiCsg9eSTT1r//v0zDL/nnnvs6aefTsRyAQAAAAAAIJeKKyC1fv16K1WqVIbhpUuXttWrVydiuQAAAAAAAJBLxRWQOvHEE+2NN97IMHz06NHWoEGDRCwXAAAAAAAAcqmYetnz3H///dalSxebO3eunXHGGRYIBOzbb7+1cePG2cSJExO/lAAAAAAAAMjbAalOnTrZ5MmT7bHHHrO+fftavnz57OSTT7aPP/7YOnTokPilBAAAAAAAQN4OSEnHjh3dCwAAAAAAADjsNaQAAAAAAAAA3zOkfv/9d5s0aZLrVe/ff/8N+9uwYcPiXiAAAAAAAADkbnEFpD777DO76KKLXN2omTNn2llnnWWLFi2yjRs32plnnpn4pQQAAAAAAEDeDkjde++99t///td69uzpCpp//vnntnfvXrv++uutZMmSiV9KIEkajm4Y9bhpPdIO67IAAAAAAJCna0gtWbLELrvsMvfvAgUKuGDUEUccYU8++aR98MEHiV5GAAAAAAAA5PWA1J49e6xEiRLu35UqVbJff/3V/btgwYK2c+fOxC4hAAAAAAAAcpW4i5p7zjnnHOvVq5f16NHDxo4day1btkzMkgEAAAAAACBXiitD6p133gn+W830atWqZY8//rgVLlzYXnvttUQuHwAAAAAAAHKZuAJSl19+efDfZcuWtTFjxtiKFSts8uTJVrt27ZjmNX78eGvdurXVq1fPunbtasuWLcty/AMHDtiECRPs7LPPdoGwOXPmJGS+AAAAAAAASOGAVP78cU2WwcSJE11wSwGjt956y2VYnXHGGbZp06aI0/Tv399GjhzpiqqvWrXKFVRPxHwBAAAAAADgj7giSxUrVrS//vor2x/+0EMPWffu3e3WW2+1Jk2a2KhRo1wG1MsvvxxxmiFDhriAU/v27RM6XwAAAAAAAKRwQOrGG2+0QYMG2b59++L+4B07dtj8+fOtY8eOwWGFChWys846y77++uuI06knv8MxXwAAAAAAAKRwL3uffPKJzZs3z9577z2rU6eOaxIXKlJdp1Br1651/69UqVLYcL1ftGhRPIuVrfkquBYaYNu+fXvcywAAAAAAAIAEB6S6dOniXtlx8ODBTDOelM2k5nV+z1dNAR988MG4PxcAAAAAAAAJDkg9/fTTdvfdd7t/X3PNNVatWjXLjgoVKrj/b968OWy4Co+rRpXf8x0wYID16dMnLEOqevXqcS8HAAAAAAAAsllDqm/fvsF/JyJQc9RRR1mNGjVs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VqNGDXe8Of/8823EiBFhQc1PPvnE7SulS5e2v//+2+rUqWOTJk2yypUrJ3X5AQAAACAWNNmLwg033GD58uVzgYNff/3V7rzzThds+euvv2La2LmZgjAzZswIvvJiMEoUgFLgZOrUqRHHueuuu2zNmjUug2rZsmU2dOhQu+6661wAIrdbunSpC7499thjWY43cODAsP0ptwej5JdffrG7777bBTIXLFjg9g0FOO+7777gOJs2bbLLLrvMbr/9dncs0jGpUKFC1rNnz6QuOwAAAADEioDUIWzYsMGmTJliffv2taJFiwYDCoFAwMaOHRvzBs/NWWTK7NANc1528803W+fOnS1//vwRm1q9/fbbdttttwUzyhRMUDaQsu5yu0ceecSaN29+yPG0H2l/0u8vr7jkkkusffv2YZli5513ngvIecaNG2cHDhxwxyAvO1FBrE8//dT++OOPpCw3AAAAAMSDgFQUzWgUfGrSpElwmAJTqiOlLAb8HzU1UmBFtX7UlFEBKmSkrJfdu3eH7U/KvmvatCn7U4iHHnrIrr/+etccrU2bNq7eVl6j4868efPs6KOPDg7TMef4448Pa8KnAJ/G/fHHH5O0pAAAAAAQOwJSURQYlvLly4cN13vvb3nd888/7zJaFLxbsWKFa47Wo0ePZC9WSmJ/ii4Ype2kAIuKe//zzz+umVr6wvm53TPPPBOsK+XRdsnsWOT9DQAAAAByCgJSh6D6LLJ3796w4Xv27LHChQsfvm8mB1Emi9dETT3r3X///a6GEjfIGbE/HZrqaRUs+H8dgFaoUMEeffRR1/OeaiblFWPGjHF1tEaPHm2NGjUK238yOxYJxyMAAAAAOQkBqUPwuppft25d2HC9V09YyOioo45y/1fBZbA/JWp/Sv8bzK3eeust1/x15MiRGToH0PEos2ORcDwCAAAAkJMQkDoEZScoS+Ojjz4KDvv5559dj1ihBYjzql27dmUYpuwo1dlS/R+EU6HqevXqhe1P6q1x9uzZ7E9Z7E8FChRwtZNyu3feecdliL3++ut25ZVXZvi7jjnKFFuyZElw2MSJE61cuXLWuHFjn5cWAAAAAOL3f+1iEHkDFSzomgz95z//sdKlS7smaQ888IC1bdvWOnTokOe33IQJE+zdd9+1rl27up7ivvzySxs2bJgNGTIkrPByXqFsFRXgVi0trwj1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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_histogram_grid(\n", + " \"token_aa_length_histogram_train\", \"token aa_length\", \"Token length distribution (train usage)\",\n", + " get_histogram=lambda vs: per_vocab_size[str(vs)][\"token_aa_length_histogram_train\"],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "bac92f5c", + "metadata": {}, + "source": [ + "## 3. Alarms" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b512e365", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No alarms triggered.\n" + ] + } + ], + "source": [ + "alarm_rows = []\n", + "for vocab_size in vocab_sizes:\n", + " for alarm_name, alarm in per_vocab_size[str(vocab_size)][\"alarms\"].items():\n", + " if alarm[\"triggered\"]:\n", + " alarm_rows.append({\"vocab_size\": vocab_size, \"alarm\": alarm_name, \"message\": alarm[\"message\"]})\n", + "\n", + "if alarm_rows:\n", + " display(pd.DataFrame(alarm_rows))\n", + "else:\n", + " print(\"No alarms triggered.\")" + ] + }, + { + "cell_type": "markdown", + "id": "0c0d5dab", + "metadata": {}, + "source": [ + "## 4. Top tokens (train split)\n", + "\n", + "Full top-n (default 50) is in the JSON; showing top `TOP_K_DISPLAY` here per list." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "4add4d20", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "vocab_size=50000 (actual=50000)\n", + "\n", + "top by frequency:\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenidcount
0##G2783339
1##S2520999
2##ETQYF676171
3##TDTQYF765873
4##NEQFF595850
5##EQYF535785
6##DTQYF625587
7##QETQYF965248
8##EQFF554929
9##YEQYF634772
10##TQYF504571
11##YNEQFF774144
12##SYEQYF1074081
13##SYNEQFF1653929
14##YGYTF793687
\n", + "
" + ], + "text/plain": [ + " token id count\n", + "0 ##G 27 83339\n", + "1 ##S 25 20999\n", + "2 ##ETQYF 67 6171\n", + "3 ##TDTQYF 76 5873\n", + "4 ##NEQFF 59 5850\n", + "5 ##EQYF 53 5785\n", + "6 ##DTQYF 62 5587\n", + "7 ##QETQYF 96 5248\n", + "8 ##EQFF 55 4929\n", + "9 ##YEQYF 63 4772\n", + "10 ##TQYF 50 4571\n", + "11 ##YNEQFF 77 4144\n", + "12 ##SYEQYF 107 4081\n", + "13 ##SYNEQFF 165 3929\n", + "14 ##YGYTF 79 3687" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "top longest tokens:\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenidcountaa_length
0##PGLAGGSSYNEQFF38092214
1##RSRPNHSGANVLTF44569214
2##LAGGPSSYNEQFF13942613
3##TSGGPSSYNEQFF20968613
4##TSGGLSSYNEQFF28237413
5##RLAGGSSYNEQFF44438313
6##LAGGSSSYNEQFF35627313
7##LAGGLSSYNEQFF20962313
8##LAGGPGSYNEQFF46644213
9##LAGGRSSYNEQFF38509113
10##PGQGSSGANVLTF34381113
11##LAGGPLSYNEQFF37491113
12##LAGGSSYNEQFF57722912
13##TSGRSSYNEQFF133511512
14##TSGGSSYNEQFF155781312
\n", + "
" + ], + "text/plain": [ + " token id count aa_length\n", + "0 ##PGLAGGSSYNEQFF 38092 2 14\n", + "1 ##RSRPNHSGANVLTF 44569 2 14\n", + "2 ##LAGGPSSYNEQFF 13942 6 13\n", + "3 ##TSGGPSSYNEQFF 20968 6 13\n", + "4 ##TSGGLSSYNEQFF 28237 4 13\n", + "5 ##RLAGGSSYNEQFF 44438 3 13\n", + "6 ##LAGGSSSYNEQFF 35627 3 13\n", + "7 ##LAGGLSSYNEQFF 20962 3 13\n", + "8 ##LAGGPGSYNEQFF 46644 2 13\n", + "9 ##LAGGRSSYNEQFF 38509 1 13\n", + "10 ##PGQGSSGANVLTF 34381 1 13\n", + "11 ##LAGGPLSYNEQFF 37491 1 13\n", + "12 ##LAGGSSYNEQFF 5772 29 12\n", + "13 ##TSGRSSYNEQFF 13351 15 12\n", + "14 ##TSGGSSYNEQFF 15578 13 12" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "top non-single-amino-acid tokens:\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenidcountaa_length
0##ETQYF6761715
1##TDTQYF7658736
2##NEQFF5958505
3##EQYF5357854
4##DTQYF6255875
5##QETQYF9652486
6##EQFF5549294
7##YEQYF6347725
8##TQYF5045714
9##YNEQFF7741446
10##SYEQYF10740816
11##SYNEQFF16539297
12##YGYTF7936875
13##TEAFF8736325
14##STDTQYF20834937
\n", + "
" + ], + "text/plain": [ + " token id count aa_length\n", + "0 ##ETQYF 67 6171 5\n", + "1 ##TDTQYF 76 5873 6\n", + "2 ##NEQFF 59 5850 5\n", + "3 ##EQYF 53 5785 4\n", + "4 ##DTQYF 62 5587 5\n", + "5 ##QETQYF 96 5248 6\n", + "6 ##EQFF 55 4929 4\n", + "7 ##YEQYF 63 4772 5\n", + "8 ##TQYF 50 4571 4\n", + "9 ##YNEQFF 77 4144 6\n", + "10 ##SYEQYF 107 4081 6\n", + "11 ##SYNEQFF 165 3929 7\n", + "12 ##YGYTF 79 3687 5\n", + "13 ##TEAFF 87 3632 5\n", + "14 ##STDTQYF 208 3493 7" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def show_top_tokens(vocab_size: int) -> None:\n", + " entry = per_vocab_size[str(vocab_size)]\n", + " print(f\"vocab_size={vocab_size} (actual={entry['vocab_size_actual']})\")\n", + "\n", + " freq_df = pd.DataFrame(entry[\"top_tokens_by_frequency_train\"][:TOP_K_DISPLAY])\n", + " print(\"\\ntop by frequency:\")\n", + " display(freq_df)\n", + "\n", + " longest_df = pd.DataFrame(entry[\"top_longest_tokens\"][:TOP_K_DISPLAY])\n", + " print(\"\\ntop longest tokens:\")\n", + " display(longest_df)\n", + "\n", + " non_single_df = pd.DataFrame(entry[\"top_non_single_amino_acid_tokens\"][:TOP_K_DISPLAY])\n", + " print(\"\\ntop non-single-amino-acid tokens:\")\n", + " display(non_single_df)\n", + "\n", + "\n", + "# change this to inspect a different vocab_size from the grid\n", + "show_top_tokens(vocab_sizes[len(vocab_sizes) // 2])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91cfce8b", + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment to dump top tokens for every vocab_size in the grid\n", + "# for vs in vocab_sizes:\n", + "# show_top_tokens(vs)\n", + "# print(\"\\n\" + \"=\" * 80 + \"\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "04a95b22", + "metadata": {}, + "source": [ + "## 5. Tokenization examples" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "21711059", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
original_cdr3tokens_vocab_1000tokens_vocab_10000
0CAISVQDRDTEAFF[CAIS, ##VQ, ##DRD, ##TEAFF][CAISV, ##QDR, ##DTEAFF]
1CATSEGTAGTGYEQYF[CATSE, ##G, ##TAG, ##TGY, ##EQYF][CATSEG, ##TAG, ##TGYEQYF]
2CASSESRLAGANEQFF[CASSES, ##RLAG, ##AN, ##EQFF][CASSESR, ##LAGANEQFF]
3CASSPRQDRNTEAFF[CASSPR, ##QD, ##RN, ##TEAFF][CASSPRQ, ##DRNTEAFF]
4CSARDPPTVYGYTF[CSARDP, ##P, ##TV, ##YGYTF][CSARDP, ##P, ##TVYGYTF]
5CATSDNRGGYNEQFF[CATSD, ##NRG, ##GYNEQFF][CATSDN, ##RGGYNEQFF]
6CSAIRDRDGGQYF[CSAI, ##RDR, ##DGG, ##QYF][CSAIR, ##DRDG, ##G, ##QYF]
7CASSVPILGLSNEQFF[CASSV, ##PI, ##LG, ##LS, ##NEQFF][CASSVP, ##ILG, ##LSNEQFF]
8CASSPYPTSGGANQETQYF[CASSPY, ##P, ##TSGGA, ##NQETQYF][CASSPYP, ##TSGGA, ##NQETQYF]
9CASSKRRENEKLFF[CASSK, ##RR, ##E, ##NEKLFF][CASSKR, ##RE, ##NEKLFF]
10CASTLGPRDRYNEQFF[CASTL, ##G, ##PR, ##DR, ##YNEQFF][CASTLG, ##PR, ##DRYNEQFF]
11CASKPGANPYNEQYF[CASK, ##PGA, ##NP, ##YNEQYF][CASKPG, ##ANP, ##YNEQYF]
12CASSETGANTGELFF[CASSE, ##TGA, ##NTGELFF][CASSETG, ##ANTGELFF]
13CSAKRKGPIHYNEQFF[CSAK, ##RK, ##G, ##PI, ##HYNEQFF][CSAKR, ##KGP, ##IH, ##YNEQFF]
14CASSRRRASYNEQFF[CASSRR, ##RAS, ##YNEQFF][CASSRRR, ##ASYNEQFF]
15CASSRRGTSPGNEQFF[CASSRR, ##G, ##TSP, ##G, ##NEQFF][CASSRRG, ##TSP, ##G, ##NEQFF]
16CASSYPELGTTGSDTQYF[CASSYP, ##EL, ##G, ##TTG, ##SDTQYF][CASSYP, ##EL, ##G, ##TTGS, ##DTQYF]
17CASSVGQIQPQHF[CASSVG, ##QI, ##QPQHF][CASSVGQ, ##IQPQHF]
18CSARPPGQRGTEAFF[CSARP, ##PGQ, ##RG, ##TEAFF][CSARPP, ##G, ##QRG, ##TEAFF]
19CASSITGSPSYNSPLHF[CASSI, ##TGS, ##PS, ##YNSPLHF][CASSITG, ##SPS, ##YNSPLHF]
\n", + "
" + ], + "text/plain": [ + " original_cdr3 tokens_vocab_1000 \\\n", + "0 CAISVQDRDTEAFF [CAIS, ##VQ, ##DRD, ##TEAFF] \n", + "1 CATSEGTAGTGYEQYF [CATSE, ##G, ##TAG, ##TGY, ##EQYF] \n", + "2 CASSESRLAGANEQFF [CASSES, ##RLAG, ##AN, ##EQFF] \n", + "3 CASSPRQDRNTEAFF [CASSPR, ##QD, ##RN, ##TEAFF] \n", + "4 CSARDPPTVYGYTF [CSARDP, ##P, ##TV, ##YGYTF] \n", + "5 CATSDNRGGYNEQFF [CATSD, ##NRG, ##GYNEQFF] \n", + "6 CSAIRDRDGGQYF [CSAI, ##RDR, ##DGG, ##QYF] \n", + "7 CASSVPILGLSNEQFF [CASSV, ##PI, ##LG, ##LS, ##NEQFF] \n", + "8 CASSPYPTSGGANQETQYF [CASSPY, ##P, ##TSGGA, ##NQETQYF] \n", + "9 CASSKRRENEKLFF [CASSK, ##RR, ##E, ##NEKLFF] \n", + "10 CASTLGPRDRYNEQFF [CASTL, ##G, ##PR, ##DR, ##YNEQFF] \n", + "11 CASKPGANPYNEQYF [CASK, ##PGA, ##NP, ##YNEQYF] \n", + "12 CASSETGANTGELFF [CASSE, ##TGA, ##NTGELFF] \n", + "13 CSAKRKGPIHYNEQFF [CSAK, ##RK, ##G, ##PI, ##HYNEQFF] \n", + "14 CASSRRRASYNEQFF [CASSRR, ##RAS, ##YNEQFF] \n", + "15 CASSRRGTSPGNEQFF [CASSRR, ##G, ##TSP, ##G, ##NEQFF] \n", + "16 CASSYPELGTTGSDTQYF [CASSYP, ##EL, ##G, ##TTG, ##SDTQYF] \n", + "17 CASSVGQIQPQHF [CASSVG, ##QI, ##QPQHF] \n", + "18 CSARPPGQRGTEAFF [CSARP, ##PGQ, ##RG, ##TEAFF] \n", + "19 CASSITGSPSYNSPLHF [CASSI, ##TGS, ##PS, ##YNSPLHF] \n", + "\n", + " tokens_vocab_10000 \n", + "0 [CAISV, ##QDR, ##DTEAFF] \n", + "1 [CATSEG, ##TAG, ##TGYEQYF] \n", + "2 [CASSESR, ##LAGANEQFF] \n", + "3 [CASSPRQ, ##DRNTEAFF] \n", + "4 [CSARDP, ##P, ##TVYGYTF] \n", + "5 [CATSDN, ##RGGYNEQFF] \n", + "6 [CSAIR, ##DRDG, ##G, ##QYF] \n", + "7 [CASSVP, ##ILG, ##LSNEQFF] \n", + "8 [CASSPYP, ##TSGGA, ##NQETQYF] \n", + "9 [CASSKR, ##RE, ##NEKLFF] \n", + "10 [CASTLG, ##PR, ##DRYNEQFF] \n", + "11 [CASKPG, ##ANP, ##YNEQYF] \n", + "12 [CASSETG, ##ANTGELFF] \n", + "13 [CSAKR, ##KGP, ##IH, ##YNEQFF] \n", + "14 [CASSRRR, ##ASYNEQFF] \n", + "15 [CASSRRG, ##TSP, ##G, ##NEQFF] \n", + "16 [CASSYP, ##EL, ##G, ##TTGS, ##DTQYF] \n", + "17 [CASSVGQ, ##IQPQHF] \n", + "18 [CSARPP, ##G, ##QRG, ##TEAFF] \n", + "19 [CASSITG, ##SPS, ##YNSPLHF] " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "examples = results.get(\"examples\", [])\n", + "if examples:\n", + " display(pd.DataFrame(examples))\n", + "else:\n", + " print(\"No examples stored in this run.\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "irrm-codec", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.15" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 7e9ea7ebfac51652ffcfc828430f32d4c849f1f3 Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 23 Jul 2026 18:50:11 +0300 Subject: [PATCH 12/70] calc_tokenization_stats: integrate top-token position analysis --- scripts/calc_tokenization_stats.py | 194 +++++++++++++++++++++++++---- 1 file changed, 173 insertions(+), 21 deletions(-) diff --git a/scripts/calc_tokenization_stats.py b/scripts/calc_tokenization_stats.py index fc87f42..b14071d 100644 --- a/scripts/calc_tokenization_stats.py +++ b/scripts/calc_tokenization_stats.py @@ -38,6 +38,22 @@ SPLIT_NAMES = ("train", "val", "test") MAIN_GRID_VOCAB_SIZES = (1000, 2000, 5000, 10000) SPLIT_COLORS = {"train": "tab:red", "val": "tab:blue", "test": "tab:orange"} +POSITION_REGION_NAMES = ("start_third", "middle_third", "end_third") + + +def relative_position(start: int, end: int, seq_len: int) -> float: + # midpoint of the token's character span, normalized by THIS sequence's own length - + # comparable across CDR3s of different lengths, not tied to a fixed anchor char-count + midpoint = (start + end) / 2.0 + return midpoint / seq_len if seq_len > 0 else 0.0 + + +def classify_relative_position(rel_pos: float) -> str: + if rel_pos < 1 / 3: + return "start_third" + if rel_pos < 2 / 3: + return "middle_third" + return "end_third" def parse_args() -> argparse.Namespace: @@ -209,7 +225,53 @@ def aa_length(token: str) -> int: return len(token) -def compute_top_token_reports(tokenizer: Tokenizer, train_encodings: list, top_n: int) -> dict: +def compute_token_position_stats( + train_seqs: list[str], train_encodings: list, target_ids: set[int] +) -> dict[int, dict]: + bucket_counts = {token_id: Counter() for token_id in target_ids} + relative_positions_by_token = {token_id: [] for token_id in target_ids} + + for seq, encoding in zip(train_seqs, train_encodings): + seq_len = len(seq) + for token_id, (start, end) in zip(encoding.ids, encoding.offsets): + if token_id in target_ids: + rel_pos = relative_position(start, end, seq_len) + bucket_counts[token_id][classify_relative_position(rel_pos)] += 1 + relative_positions_by_token[token_id].append(rel_pos) + + stats_by_token = {} + for token_id in target_ids: + buckets = bucket_counts[token_id] + total = sum(buckets.values()) + rel_positions = np.array(relative_positions_by_token[token_id]) + stats = { + "mean_relative_position": float(rel_positions.mean()) if total > 0 else float("nan"), + "median_relative_position": float(np.median(rel_positions)) if total > 0 else float("nan"), + "std_relative_position": float(rel_positions.std()) if total > 0 else float("nan"), + } + for region in POSITION_REGION_NAMES: + stats[f"fraction_{region}"] = buckets.get(region, 0) / total if total > 0 else 0.0 + stats_by_token[token_id] = stats + return stats_by_token + + +def compute_position_macro_composition(top_by_frequency: list[dict]) -> dict: + # count-weighted average across the top-N tokens: "of all top-N frequent-token + # OCCURRENCES in train, what fraction sits in each relative third" (not a per-token average) + totals = {region: 0.0 for region in POSITION_REGION_NAMES} + grand_total = 0 + for item in top_by_frequency: + for region in POSITION_REGION_NAMES: + totals[region] += item[f"fraction_{region}"] * item["count"] + grand_total += item["count"] + if grand_total == 0: + return {region: 0.0 for region in POSITION_REGION_NAMES} + return {region: totals[region] / grand_total for region in POSITION_REGION_NAMES} + + +def compute_top_token_reports( + tokenizer: Tokenizer, train_encodings: list, train_seqs: list[str], top_n: int +) -> dict: token_counter: Counter = Counter() for encoding in train_encodings: for token_id in encoding.ids: @@ -222,9 +284,16 @@ def compute_top_token_reports(tokenizer: Tokenizer, train_encodings: list, top_n {"token": token_text, "id": token_id, "count": count, "aa_length": aa_length(token_text)} ) + top_by_frequency_ids = [tid for tid, _ in token_counter.most_common(top_n)] + position_stats_by_token = compute_token_position_stats( + train_seqs, train_encodings, set(top_by_frequency_ids) + ) top_by_frequency = [ - {"token": tokenizer.id_to_token(tid), "id": tid, "count": count} - for tid, count in token_counter.most_common(top_n) + { + "token": tokenizer.id_to_token(tid), "id": tid, "count": token_counter[tid], + **position_stats_by_token[tid], + } + for tid in top_by_frequency_ids ] top_longest = sorted(all_seen_tokens, key=lambda item: (-item["aa_length"], -item["count"]))[:top_n] @@ -232,10 +301,20 @@ def compute_top_token_reports(tokenizer: Tokenizer, train_encodings: list, top_n non_single_aa_tokens = [item for item in all_seen_tokens if item["aa_length"] > 1] top_non_single_aa = sorted(non_single_aa_tokens, key=lambda item: -item["count"])[:top_n] + # frequency-weighted: what fraction of the tokenized train corpus is made up of + # tokens of each aa_length, not just how many distinct vocab entries have that length + aa_length_histogram: Counter = Counter() + for item in all_seen_tokens: + aa_length_histogram[item["aa_length"]] += item["count"] + return { "top_tokens_by_frequency_train": top_by_frequency, "top_longest_tokens": top_longest, "top_non_single_amino_acid_tokens": top_non_single_aa, + "token_aa_length_histogram_train": { + str(aa_len): count for aa_len, count in sorted(aa_length_histogram.items()) + }, + "top_tokens_position_macro_composition_train": compute_position_macro_composition(top_by_frequency), } @@ -477,9 +556,12 @@ def build_top_tokens_summary_lines(results: dict, top_k: int) -> list[str]: lines.append("") lines.append(f"--- vocab_size={vocab_size} (actual={entry['vocab_size_actual']}) ---") - lines.append(f"top {top_k} by frequency:") + lines.append(f"top {top_k} by frequency (mean relative position, 0=start / 1=end):") for item in entry["top_tokens_by_frequency_train"][:top_k]: - lines.append(f" {item['token']!r:<12} count={item['count']}") + lines.append( + f" {item['token']!r:<12} count={item['count']:<10} " + f"mean_rel_pos={item['mean_relative_position']:.3f}" + ) lines.append(f"top {top_k} longest tokens:") for item in entry["top_longest_tokens"][:top_k]: @@ -581,20 +663,32 @@ def plot_fraction_short_sequences(vocab_sizes: list[int], per_vocab_size: dict, plt.close(fig) -def plot_vocab_size_actual_vs_requested(vocab_sizes: list[int], per_vocab_size: dict, output_path: Path) -> None: - requested = vocab_sizes - actual = [per_vocab_size[str(vs)]["vocab_size_actual"] for vs in vocab_sizes] +def plot_token_aa_length_histogram_grid( + vocab_sizes: list[int], per_vocab_size: dict, output_path: Path +) -> None: + # token length (amino acids per subword piece), frequency-weighted by train usage - + # distinct from plot_token_count_histogram_grid, which is sequence-level (tokens per CDR3) + ncols = 3 + nrows = math.ceil(len(vocab_sizes) / ncols) + fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 4, nrows * 3), squeeze=False) + + for idx, vocab_size in enumerate(vocab_sizes): + ax = axes[idx // ncols][idx % ncols] + histogram = per_vocab_size[str(vocab_size)]["token_aa_length_histogram_train"] + aa_lengths = sorted(int(k) for k in histogram.keys()) + counts = [histogram[str(k)] for k in aa_lengths] + total = sum(counts) + fractions = [count / total for count in counts] - fig, ax = plt.subplots(figsize=(8, 5)) - ax.plot(requested, requested, linestyle="--", color="gray", label="y = x (no floor effect)") - ax.plot(requested, actual, marker="o", color="tab:purple", label="actual_vocab_size") - ax.set_xscale("log") - ax.set_yscale("log") - ax.set_xlabel("vocab_size_requested") - ax.set_ylabel("vocab_size_actual") - ax.set_title("WordPiece floor effect: requested vs actual vocab size") - ax.legend() - ax.grid(alpha=0.3, which="both") + ax.bar(aa_lengths, fractions, color="tab:blue") + ax.set_title(f"vocab_size={vocab_size}", fontsize=10) + ax.set_xlabel("token aa_length") + ax.set_ylabel("fraction of tokens") + + for idx in range(len(vocab_sizes), nrows * ncols): + axes[idx // ncols][idx % ncols].axis("off") + + fig.suptitle("Token length distribution, frequency-weighted (train usage)") fig.tight_layout() fig.savefig(output_path, dpi=150) plt.close(fig) @@ -629,6 +723,60 @@ def plot_token_count_histogram_grid( plt.close(fig) +def plot_top_tokens_position_composition(vocab_sizes: list[int], per_vocab_size: dict, output_path: Path) -> None: + fig, ax = plt.subplots(figsize=(9, 5)) + bottoms = [0.0] * len(vocab_sizes) + colors = {"start_third": "tab:blue", "middle_third": "tab:gray", "end_third": "tab:orange"} + for region in POSITION_REGION_NAMES: + values = [ + per_vocab_size[str(vs)]["top_tokens_position_macro_composition_train"][region] for vs in vocab_sizes + ] + ax.bar([str(vs) for vs in vocab_sizes], values, bottom=bottoms, label=region, color=colors[region]) + bottoms = [b + v for b, v in zip(bottoms, values)] + ax.axhline(1 / 3, color="black", linestyle=":", linewidth=1, label="uniform baseline (1/3)") + ax.axhline(2 / 3, color="black", linestyle=":", linewidth=1) + ax.set_xlabel("vocab_size") + ax.set_ylabel("fraction of top-N frequent-token occurrences") + ax.set_title("Where do the top-N most frequent tokens sit, relative to sequence length? (train)") + ax.legend() + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + +def plot_top_tokens_position_grid(vocab_sizes: list[int], per_vocab_size: dict, output_path: Path) -> None: + ncols = 3 + nrows = math.ceil(len(vocab_sizes) / ncols) + fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 5, nrows * 4), squeeze=False) + + for idx, vocab_size in enumerate(vocab_sizes): + ax = axes[idx // ncols][idx % ncols] + top_by_frequency = per_vocab_size[str(vocab_size)]["top_tokens_by_frequency_train"] + sorted_rows = sorted(top_by_frequency, key=lambda r: r["mean_relative_position"]) + y_positions = range(len(sorted_rows)) + means = [r["mean_relative_position"] for r in sorted_rows] + stds = [r["std_relative_position"] for r in sorted_rows] + labels = [r["token"] for r in sorted_rows] + + ax.errorbar( + means, y_positions, xerr=stds, fmt="o", color="tab:purple", ecolor="lightgray", + capsize=2, markersize=3, + ) + ax.axvline(0.5, color="gray", linestyle="--", linewidth=1) + ax.set_yticks(list(y_positions)) + ax.set_yticklabels(labels, fontsize=6) + ax.set_xlabel("relative position") + ax.set_title(f"vocab_size={vocab_size}", fontsize=10) + + for idx in range(len(vocab_sizes), nrows * ncols): + axes[idx // ncols][idx % ncols].axis("off") + + fig.suptitle("Top-N frequent token relative positions (mean +/- std, train)") + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + def save_diagnostic_plots(results: dict, output_dir: Path, args: argparse.Namespace, logger: logging.Logger) -> None: # needs at least 2 vocab_size points to draw a meaningful line vocab_sizes = sorted(int(vs) for vs in results["per_vocab_size"].keys()) @@ -656,10 +804,14 @@ def save_diagnostic_plots(results: dict, output_dir: Path, args: argparse.Namesp )), ("fraction_short_sequences_vs_vocab_size.png", lambda path: plot_fraction_short_sequences(vocab_sizes, per_vocab_size, path)), - ("vocab_size_actual_vs_requested.png", - lambda path: plot_vocab_size_actual_vs_requested(vocab_sizes, per_vocab_size, path)), ("token_count_histogram_train.png", lambda path: plot_token_count_histogram_grid(vocab_sizes, per_vocab_size, "train", path)), + ("token_aa_length_histogram_train.png", + lambda path: plot_token_aa_length_histogram_grid(vocab_sizes, per_vocab_size, path)), + ("top_tokens_position_composition_vs_vocab_size.png", + lambda path: plot_top_tokens_position_composition(vocab_sizes, per_vocab_size, path)), + ("top_tokens_position_grid.png", + lambda path: plot_top_tokens_position_grid(vocab_sizes, per_vocab_size, path)), ] for filename, plot_fn in plots: @@ -739,7 +891,7 @@ def main() -> None: stats["fraction_encoded_as_1_token"], ) - top_token_reports = compute_top_token_reports(tokenizer, train_encodings, args.top_n) + top_token_reports = compute_top_token_reports(tokenizer, train_encodings, split_seqs["train"], args.top_n) alarms = compute_alarms( split_results["train"], args.high_1_token_threshold, args.high_unk_threshold, args.min_compression_benefit, From 3969b8669f87b1617b4936cc33fa8b4368116aee Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 23 Jul 2026 18:56:32 +0300 Subject: [PATCH 13/70] calc_tokenization_stats: add relative-position histogram, enrich text summary --- scripts/calc_tokenization_stats.py | 70 +++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/scripts/calc_tokenization_stats.py b/scripts/calc_tokenization_stats.py index b14071d..3028f10 100644 --- a/scripts/calc_tokenization_stats.py +++ b/scripts/calc_tokenization_stats.py @@ -227,7 +227,7 @@ def aa_length(token: str) -> int: def compute_token_position_stats( train_seqs: list[str], train_encodings: list, target_ids: set[int] -) -> dict[int, dict]: +) -> tuple[dict[int, dict], dict[int, list]]: bucket_counts = {token_id: Counter() for token_id in target_ids} relative_positions_by_token = {token_id: [] for token_id in target_ids} @@ -252,7 +252,18 @@ def compute_token_position_stats( for region in POSITION_REGION_NAMES: stats[f"fraction_{region}"] = buckets.get(region, 0) / total if total > 0 else 0.0 stats_by_token[token_id] = stats - return stats_by_token + return stats_by_token, relative_positions_by_token + + +def compute_relative_position_histogram(relative_positions_by_token: dict[int, list], num_bins: int = 20) -> dict[str, int]: + # flattens ALL top-N token occurrences into one distribution: "where, across the whole + # relative-position axis, do frequent-token occurrences concentrate" - not just 3 buckets + all_positions = [pos for positions in relative_positions_by_token.values() for pos in positions] + if not all_positions: + return {} + counts, _ = np.histogram(all_positions, bins=num_bins, range=(0.0, 1.0)) + bin_width = 1.0 / num_bins + return {f"{(i + 0.5) * bin_width:.3f}": int(counts[i]) for i in range(num_bins)} def compute_position_macro_composition(top_by_frequency: list[dict]) -> dict: @@ -285,7 +296,7 @@ def compute_top_token_reports( ) top_by_frequency_ids = [tid for tid, _ in token_counter.most_common(top_n)] - position_stats_by_token = compute_token_position_stats( + position_stats_by_token, relative_positions_by_token = compute_token_position_stats( train_seqs, train_encodings, set(top_by_frequency_ids) ) top_by_frequency = [ @@ -315,6 +326,9 @@ def compute_top_token_reports( str(aa_len): count for aa_len, count in sorted(aa_length_histogram.items()) }, "top_tokens_position_macro_composition_train": compute_position_macro_composition(top_by_frequency), + "top_tokens_relative_position_histogram_train": compute_relative_position_histogram( + relative_positions_by_token + ), } @@ -556,11 +570,21 @@ def build_top_tokens_summary_lines(results: dict, top_k: int) -> list[str]: lines.append("") lines.append(f"--- vocab_size={vocab_size} (actual={entry['vocab_size_actual']}) ---") - lines.append(f"top {top_k} by frequency (mean relative position, 0=start / 1=end):") + macro = entry["top_tokens_position_macro_composition_train"] + lines.append( + f"position composition of top-{entry['top_tokens_by_frequency_train'].__len__()} " + f"frequent tokens (train, count-weighted): " + f"start_third={macro['start_third']:.1%} " + f"middle_third={macro['middle_third']:.1%} " + f"end_third={macro['end_third']:.1%}" + ) + + lines.append(f"top {top_k} by frequency (relative position: mean / start-mid-end thirds):") for item in entry["top_tokens_by_frequency_train"][:top_k]: lines.append( f" {item['token']!r:<12} count={item['count']:<10} " - f"mean_rel_pos={item['mean_relative_position']:.3f}" + f"mean_rel_pos={item['mean_relative_position']:.3f} " + f"[{item['fraction_start_third']:.0%}/{item['fraction_middle_third']:.0%}/{item['fraction_end_third']:.0%}]" ) lines.append(f"top {top_k} longest tokens:") @@ -777,6 +801,40 @@ def plot_top_tokens_position_grid(vocab_sizes: list[int], per_vocab_size: dict, plt.close(fig) +def plot_top_tokens_relative_position_histogram_grid( + vocab_sizes: list[int], per_vocab_size: dict, output_path: Path +) -> None: + # true density view: distribution of ALL top-N frequent-token occurrences along the + # relative-position axis - complements the thirds-based composition/errorbar plots above + ncols = 3 + nrows = math.ceil(len(vocab_sizes) / ncols) + fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 4, nrows * 3), squeeze=False) + + for idx, vocab_size in enumerate(vocab_sizes): + ax = axes[idx // ncols][idx % ncols] + histogram = per_vocab_size[str(vocab_size)]["top_tokens_relative_position_histogram_train"] + bin_centers = sorted(float(k) for k in histogram.keys()) + counts = [histogram[f"{c:.3f}"] for c in bin_centers] + total = sum(counts) + fractions = [count / total for count in counts] if total > 0 else counts + bin_width = bin_centers[1] - bin_centers[0] if len(bin_centers) > 1 else 0.05 + + ax.bar(bin_centers, fractions, width=bin_width * 0.9, color="tab:purple") + ax.axvline(0.5, color="gray", linestyle="--", linewidth=1) + ax.set_xlim(0, 1) + ax.set_title(f"vocab_size={vocab_size}", fontsize=10) + ax.set_xlabel("relative position (0=start, 1=end)") + ax.set_ylabel("fraction") + + for idx in range(len(vocab_sizes), nrows * ncols): + axes[idx // ncols][idx % ncols].axis("off") + + fig.suptitle("Distribution of top-N frequent-token occurrences by relative position (train)") + fig.tight_layout() + fig.savefig(output_path, dpi=150) + plt.close(fig) + + def save_diagnostic_plots(results: dict, output_dir: Path, args: argparse.Namespace, logger: logging.Logger) -> None: # needs at least 2 vocab_size points to draw a meaningful line vocab_sizes = sorted(int(vs) for vs in results["per_vocab_size"].keys()) @@ -812,6 +870,8 @@ def save_diagnostic_plots(results: dict, output_dir: Path, args: argparse.Namesp lambda path: plot_top_tokens_position_composition(vocab_sizes, per_vocab_size, path)), ("top_tokens_position_grid.png", lambda path: plot_top_tokens_position_grid(vocab_sizes, per_vocab_size, path)), + ("top_tokens_relative_position_histogram.png", + lambda path: plot_top_tokens_relative_position_histogram_grid(vocab_sizes, per_vocab_size, path)), ] for filename, plot_fn in plots: From e9f65a5f428503dfe88386da694ca1f4d822b132 Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 23 Jul 2026 20:41:28 +0300 Subject: [PATCH 14/70] tokenizer_stats_report.ipynb: add top-token position analysis section --- notebooks/tokenizer_stats_report.ipynb | 1071 ++++++++++++++++-------- 1 file changed, 726 insertions(+), 345 deletions(-) diff --git a/notebooks/tokenizer_stats_report.ipynb b/notebooks/tokenizer_stats_report.ipynb index 782842c..f6b4f19 100644 --- a/notebooks/tokenizer_stats_report.ipynb +++ b/notebooks/tokenizer_stats_report.ipynb @@ -86,345 +86,345 @@ "text/html": [ "\n", - "\n", + "
\n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
 vocab_sizevocab_size_actualsplitmean_num_tokensmedian_num_tokensmin_num_tokensmax_num_tokensp95_num_tokenscompression_ratiounk_token_fractionfraction_1_tokenfraction_le_3_tokensvocab_sizevocab_size_actualsplitmean_num_tokensmedian_num_tokensmin_num_tokensmax_num_tokensp95_num_tokenscompression_ratiounk_token_fractionfraction_1_tokenfraction_le_3_tokens
0100100train7.257.022010.00.4860.0000%0.00%0.05%
1100100val7.257.032010.00.4860.0000%0.00%0.04%
2100100test7.257.021910.00.4860.0000%0.00%0.04%
310001000train4.144.02126.00.2780.0000%0.00%22.84%
410001000val4.144.02116.00.2770.0000%0.00%22.98%
510001000test4.144.02136.00.2780.0000%0.00%22.82%
61000010000train3.063.02114.00.2050.0000%0.00%76.44%
71000010000val3.073.0294.00.2060.0000%0.00%76.13%
81000010000test3.073.0294.00.2060.0000%0.00%75.94%
95000050000train2.532.01104.00.1700.0000%0.00%91.44%
105000050000val2.572.0284.00.1720.0000%0.00%90.73%
115000050000test2.572.0184.00.1720.0000%0.00%90.66%
12100000100000train2.382.0184.00.1590.0000%0.00%94.92%
13100000100000val2.442.0284.00.1630.0000%0.00%93.75%
14100000100000test2.442.0184.00.1640.0000%0.00%93.73%
15200000200000train2.242.0183.00.1500.0000%1.52%97.24%
16200000200000val2.372.0283.00.1590.0000%0.00%95.39%
17200000200000test2.372.0183.00.1590.0000%0.00%95.37%
18300000300000train2.142.0183.00.1440.0000%6.90%97.94%
19300000300000val2.352.0283.00.1580.0000%0.00%95.64%
20300000300000test2.352.0183.00.1580.0000%0.00%95.58%0100100train7.257.022010.00.4860.0000%0.00%0.05%
1100100val7.257.032010.00.4860.0000%0.00%0.04%
2100100test7.257.021910.00.4860.0000%0.00%0.04%
310001000train4.144.02126.00.2780.0000%0.00%22.84%
410001000val4.144.02116.00.2770.0000%0.00%22.98%
510001000test4.144.02136.00.2780.0000%0.00%22.82%
61000010000train3.063.02114.00.2050.0000%0.00%76.44%
71000010000val3.073.0294.00.2060.0000%0.00%76.13%
81000010000test3.073.0294.00.2060.0000%0.00%75.94%
95000050000train2.532.01104.00.1700.0000%0.00%91.44%
105000050000val2.572.0284.00.1720.0000%0.00%90.73%
115000050000test2.572.0184.00.1720.0000%0.00%90.66%
12100000100000train2.382.0184.00.1590.0000%0.00%94.92%
13100000100000val2.442.0284.00.1630.0000%0.00%93.75%
14100000100000test2.442.0184.00.1640.0000%0.00%93.73%
15200000200000train2.242.0183.00.1500.0000%1.52%97.24%
16200000200000val2.372.0283.00.1590.0000%0.00%95.39%
17200000200000test2.372.0183.00.1590.0000%0.00%95.37%
18300000300000train2.142.0183.00.1440.0000%6.90%97.94%
19300000300000val2.352.0283.00.1580.0000%0.00%95.64%
20300000300000test2.352.0183.00.1580.0000%0.00%95.58%
\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 3, @@ -803,6 +803,12 @@ " token\n", " id\n", " count\n", + " mean_relative_position\n", + " median_relative_position\n", + " std_relative_position\n", + " fraction_start_third\n", + " fraction_middle_third\n", + " fraction_end_third\n", " \n", " \n", " \n", @@ -811,112 +817,236 @@ " ##G\n", " 27\n", " 83339\n", + " 0.544017\n", + " 0.535714\n", + " 0.088600\n", + " 0.006264\n", + " 0.899183\n", + " 0.094554\n", " \n", " \n", " 1\n", " ##S\n", " 25\n", " 20999\n", + " 0.555127\n", + " 0.566667\n", + " 0.084928\n", + " 0.008381\n", + " 0.907996\n", + " 0.083623\n", " \n", " \n", " 2\n", " ##ETQYF\n", " 67\n", " 6171\n", + " 0.828905\n", + " 0.833333\n", + " 0.022141\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 3\n", " ##TDTQYF\n", " 76\n", " 5873\n", + " 0.805695\n", + " 0.812500\n", + " 0.024052\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 4\n", " ##NEQFF\n", " 59\n", " 5850\n", + " 0.829440\n", + " 0.833333\n", + " 0.022314\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 5\n", " ##EQYF\n", " 53\n", " 5785\n", + " 0.855252\n", + " 0.857143\n", + " 0.018866\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 6\n", " ##DTQYF\n", " 62\n", " 5587\n", + " 0.829122\n", + " 0.833333\n", + " 0.021887\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 7\n", " ##QETQYF\n", " 96\n", " 5248\n", + " 0.801115\n", + " 0.800000\n", + " 0.023889\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 8\n", " ##EQFF\n", " 55\n", " 4929\n", + " 0.856863\n", + " 0.857143\n", + " 0.019761\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 9\n", " ##YEQYF\n", " 63\n", " 4772\n", + " 0.826485\n", + " 0.833333\n", + " 0.022154\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 10\n", " ##TQYF\n", " 50\n", " 4571\n", + " 0.854780\n", + " 0.857143\n", + " 0.020152\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 11\n", " ##YNEQFF\n", " 77\n", " 4144\n", + " 0.803750\n", + " 0.812500\n", + " 0.024259\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 12\n", " ##SYEQYF\n", " 107\n", " 4081\n", + " 0.801584\n", + " 0.800000\n", + " 0.022645\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 13\n", " ##SYNEQFF\n", " 165\n", " 3929\n", + " 0.783411\n", + " 0.781250\n", + " 0.024249\n", + " 0.000000\n", + " 0.000000\n", + " 1.000000\n", " \n", " \n", " 14\n", " ##YGYTF\n", " 79\n", " 3687\n", + " 0.824113\n", + " 0.833333\n", + " 0.023157\n", + " 0.000000\n", + " 0.000271\n", + " 0.999729\n", " \n", " \n", "\n", "" ], "text/plain": [ - " token id count\n", - "0 ##G 27 83339\n", - "1 ##S 25 20999\n", - "2 ##ETQYF 67 6171\n", - "3 ##TDTQYF 76 5873\n", - "4 ##NEQFF 59 5850\n", - "5 ##EQYF 53 5785\n", - "6 ##DTQYF 62 5587\n", - "7 ##QETQYF 96 5248\n", - "8 ##EQFF 55 4929\n", - "9 ##YEQYF 63 4772\n", - "10 ##TQYF 50 4571\n", - "11 ##YNEQFF 77 4144\n", - "12 ##SYEQYF 107 4081\n", - "13 ##SYNEQFF 165 3929\n", - "14 ##YGYTF 79 3687" + " token id count mean_relative_position median_relative_position \\\n", + "0 ##G 27 83339 0.544017 0.535714 \n", + "1 ##S 25 20999 0.555127 0.566667 \n", + "2 ##ETQYF 67 6171 0.828905 0.833333 \n", + "3 ##TDTQYF 76 5873 0.805695 0.812500 \n", + "4 ##NEQFF 59 5850 0.829440 0.833333 \n", + "5 ##EQYF 53 5785 0.855252 0.857143 \n", + "6 ##DTQYF 62 5587 0.829122 0.833333 \n", + "7 ##QETQYF 96 5248 0.801115 0.800000 \n", + "8 ##EQFF 55 4929 0.856863 0.857143 \n", + "9 ##YEQYF 63 4772 0.826485 0.833333 \n", + "10 ##TQYF 50 4571 0.854780 0.857143 \n", + "11 ##YNEQFF 77 4144 0.803750 0.812500 \n", + "12 ##SYEQYF 107 4081 0.801584 0.800000 \n", + "13 ##SYNEQFF 165 3929 0.783411 0.781250 \n", + "14 ##YGYTF 79 3687 0.824113 0.833333 \n", + "\n", + " std_relative_position fraction_start_third fraction_middle_third \\\n", + "0 0.088600 0.006264 0.899183 \n", + "1 0.084928 0.008381 0.907996 \n", + "2 0.022141 0.000000 0.000000 \n", + "3 0.024052 0.000000 0.000000 \n", + "4 0.022314 0.000000 0.000000 \n", + "5 0.018866 0.000000 0.000000 \n", + "6 0.021887 0.000000 0.000000 \n", + "7 0.023889 0.000000 0.000000 \n", + "8 0.019761 0.000000 0.000000 \n", + "9 0.022154 0.000000 0.000000 \n", + "10 0.020152 0.000000 0.000000 \n", + "11 0.024259 0.000000 0.000000 \n", + "12 0.022645 0.000000 0.000000 \n", + "13 0.024249 0.000000 0.000000 \n", + "14 0.023157 0.000000 0.000271 \n", + "\n", + " fraction_end_third \n", + "0 0.094554 \n", + "1 0.083623 \n", + "2 1.000000 \n", + "3 1.000000 \n", + "4 1.000000 \n", + "5 1.000000 \n", + "6 1.000000 \n", + "7 1.000000 \n", + "8 1.000000 \n", + "9 1.000000 \n", + "10 1.000000 \n", + "11 1.000000 \n", + "12 1.000000 \n", + "13 1.000000 \n", + "14 0.999729 " ] }, "metadata": {}, @@ -1294,15 +1424,266 @@ }, { "cell_type": "markdown", - "id": "04a95b22", + "id": "2cb9499f", "metadata": {}, "source": [ - "## 5. Tokenization examples" + "## 5. Top-token position analysis\n", + "\n", + "Where, relative to sequence length (0 = start, 1 = end), do the top-N most frequent tokens occur? Position is normalized per-sequence, not a fixed character-count anchor, so CDR3s of different lengths are compared on the same scale." ] }, { "cell_type": "code", "execution_count": 13, + "id": "63efe7a0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 vocab_sizestart_thirdmiddle_thirdend_third
010026.4%56.1%17.4%
110008.9%50.9%40.2%
2100000.7%35.2%64.1%
3500000.3%38.2%61.5%
41000000.2%36.5%63.4%
52000000.2%37.7%62.2%
63000000.2%40.0%59.9%
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "position_macro_rows = []\n", + "for vocab_size in vocab_sizes:\n", + " macro = per_vocab_size[str(vocab_size)][\"top_tokens_position_macro_composition_train\"]\n", + " position_macro_rows.append({\n", + " \"vocab_size\": vocab_size,\n", + " \"start_third\": macro[\"start_third\"],\n", + " \"middle_third\": macro[\"middle_third\"],\n", + " \"end_third\": macro[\"end_third\"],\n", + " })\n", + "\n", + "position_macro_df = pd.DataFrame(position_macro_rows)\n", + "position_macro_df.style.format({\"start_third\": \"{:.1%}\", \"middle_third\": \"{:.1%}\", \"end_third\": \"{:.1%}\"})" + ] + }, + { + "cell_type": "markdown", + "id": "d4f52706", + "metadata": {}, + "source": [ + "Count-weighted across the top-N frequent tokens: what fraction of their occurrences in train falls in each third of the sequence. 33.3%/33.3%/33.3% would be the uniform baseline (no positional preference)." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "482a56a8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3kAAAHqCAYAAAC5nYcRAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAiZVJREFUeJzt3Qd4FMUbx/E39N57R5rSEQQpVlCKBQUVCygqKFhQERVQ/2IHFHsXGyoiIgqCCKgggoCANAVBeu9VOuT+z2/CnpfkEpJwl+SS7+d5DnJ7c7uzs+X23ZmdifL5fD4DAAAAAGQIWdI6AwAAAACA0CHIAwAAAIAMhCAPAAAAADIQgjwAAAAAyEAI8gAAAAAgAyHIAwAAAIAMhCAPAAAAADIQgjwAAAAAyEAI8gAAAAAgAyHIw2mrX7++tWnTJqJLMioqyvr27Rv25fz5559uWZ999lnYl4X0Ze/evXbrrbdaqVKl3D7Qo0ePtM5SpqDjWuWdkezZs8et04svvmjpzRtvvOHytmXLloiYLzKWSNtPnnnmGZfff//9N+zL+uijj6xYsWK2f/9+i5Tt8eabb1rZsmXtwIEDIc9bZkCQl4lde+21lj179ngnl4MHD1qOHDncgblhw4ZYn0VHR1uRIkXs/PPPT+XcRo4VK1a4shs6dGimzoNo31I+9Hr++efjfT5u3Dj32ahRoyySpKR8n376afvuu+/s119/NZ/PZ++8845lNgMGDHDldvjw4bCkz8x0EaWyeuWVVyxSKWjVOuzYscPSi/SYJ0SWUO1Dy5Yts9tvv92qVq1qefLksTPPPDPJx7uCpEcffdQefvhhy58/f8jzFi7du3e3bNmy2eDBg9M6KxGJIC8Tu/jii+348ePuojOQ3mu6TiI///xzrM8WLFhgu3fvdt8FkmPgwIHp9ockNfzyyy/WpEkTq1atWlpnBRGuUKFC7kZBnz59LLO455573DqrJhzIjJ544glr3ry5zZw507Zu3Wq33HKLPfDAA/byyy8nqRZv165ddscdd1gkHbeqcFCg9+qrr1KblwIEeZmYF6jFDeT0vlatWnbhhRcG/UxatmyZijlFpLvkkktcDfFTTz1lmZUC3Ny5c6d1NgAAEWjEiBF22223WfHixV1tXL9+/dwNnzFjxpzyu2o5cvnll7v0kaZz587ucQetP5KHIC8Tq1GjhpUrV86mTJkSL5C76KKLggZ5SqsaPtVIxLVq1Spr3bq15c2b10qXLm3/+9//3B2cuH744QcXYBYoUMBd9J577rk2fvz4oM/5/f33326e+fLls65du7rPjh496pq+nXXWWZYzZ07Xxvymm26K17Q0mE2bNtn1119vBQsWtMKFC7sTZkJt4XXX6+6773ZlpLtJFSpUsPvvv9/27duX4Px//PFHf02N7j55TRWD3XHXCUvbIFeuXG5945Z1Stc1KXlIyroFPj/4wQcfWJUqVVxeGzVqZJMmTbLkqF69uruDqB8aNXVMrsC86I6kmqtoP7vsssts8+bNLo3yqPVWHs877zzXtCWupKy39lk1YdGNDi1DzwN07NjRFi9enOTyDaSmqPp8zZo19vXXX/vTq1Y8cL2GDRvmtrOapmgZorLS9i5ZsqTLr5arGlE1m457TDVs2NCtu7aTykLz1Ly1jMAfS617XB9//LFLq+MtUFKW7z3zpiaVKtuiRYu6CxA1Bw+sudXx++STT7q/ddwHlkMwSUn/22+/2aWXXuqOZ6VRGSTledelS5e6ctJx5x1Lar0waNAgt91VjmqWft1117nzmkfbUHnQfvzNN9/409auXdu+//77oM+j1K1b152/dE5s3769zZs375T5O9X34j6TN2vWLJdOdGffK6vkPvcZuH4jR45066Um/d9++63/c20XLUv7wxlnnOG2kcouMd4x4L20XvoNGT58eKw7/g899JD7WxexXtrp06cHfbbnyy+/dO+178elbaHPtI0C1y25eT9VnmTu3LnuPKSLZ+9cnpRm3KqJ0flD5yDtu/otUFM6tZQJlNR867dZZao8VKpUyT3LpO2m/Gr/8GifCHah720jrU9yl+89V6a89+7d25WVtvFVV13lPz/Hnad+e3Uu8o4f1dQcO3Ys2eudVOFYj59++skaN26caJknZR8SrXtSlhlozpw57lxQuXLlRNOtXr3a/vrrr3gtsE6VN688dB6/77773O+A19QzKcd0Qs/kJbecVbZax7Fjxya6ngjCh0ytS5cuvixZsvh2797t3u/Zs8eXNWtW39dff+37/fffFaH5/vnnH/fZsWPHfPnz5/ddeumlseZRr149X9OmTX1XX321b968eb69e/f63njjDffdjz76KFba999/3xcVFeV75JFHfOvWrfPt2LHDN2jQIJcHLTNw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Irq4V1qvGaWuFefPn+9Pqw4zwtmT4QMPPOBqvUQ1YKq9CszrqUyePNld27744ouu8kJd5z/33HMu6BgzZkystL169XI1dnEpWMyePbv7++qrr3Y1U0899ZR7lk3za9++fZJq8vQsmddcUZUohQsXtuHDh8dKo22jZ9DUocjFF1/sas08CqJUg+U9Q6eaKi8YVWWMnq9TjaWCKm1v1ZxpPsl9NlH5VJNIufHGG11NnwK+lC5ny8kmncWKFbPkmjhxolWrVs01yYzb8lDNP2+66Sb3fJ4CzbhUa5rU5qSZIsgLthFUSGqbnBC1K9bBEvgCAABA2tDFeGBnFmoG+MILL7i/N2zY4JotqtZKhg0b5jqx8KgmTBf6opovpfWaN+pRIDXT8/Ts2TOsHVwokAmkICnYs3kJUc2T5qFmh558+fJZ5cqV3WeBNC0YNRGMO4h23GlJqS1TByMe1TopUPLyoGtp1ezpMSttC22vb775JtYzZQ8++KCrvVJTSdWu6XOviaICLgXnqmXU82mqqdQ81LQzuTV5gWXuBaVemadkOTlOBozJ6QAyWFPNQC+99JLLi2IXBf5qWhr4vKRXpjlz5rRwCX93NWEYGFAPWwbSe939SIiqj3WXI90b8F/vSwh12e4N03zZZmHFdos8bLPIFI7txvkxvCLhWMtX3qz5ELNth8yyxR7c+c72zazjeTXNNsXUuo147QnLnzePe18uyxGb98PnVq1MNvf+5ksb2KX13/an/XjQw5YrVw73vtixYy5tlYr53fvrzj/Lmn33sT/t2wPutWzZsvrfJ0XUvpNB2vZlZpv+u748fvSI2e41see1c0Xs98cPm+3d8N803wmzXatj3pdpEG9ZClLiXvyLmlsGdgIiCV7rblpglutksLDjZGAYmKddq8x80QmXwY7l7r9Dq+dY4UPF/8vDnu2W11fWfe/1d4bZb79OsdUzv7MypWLS/O+Ft23spF/8861ZyGzFtK/s9/l/2pTf5lrv++6xd14dbBOHv2U5og9ai0Z1bOzHrySwDvPNtp3sX2PLIrOjheO/P5nPWOu76+TwCtv+NtvkS9py4qicO6ZZ7IY/frRitWtYUimAnTBhgn399dcJplGArSaln332matxVnNdjwJkBdLhElE1eV7krmr7QHof905KID33p2p875VYjz8AAAAIr9Ili1uds6r539es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5i5aalUqlrOPRo61a+98ONHmjH2eetnu6v+8FStSyPVAf95559muXbtifadPnz521113uZZyCaWJ64033rB27dq5ALFiudL24Ygx1uLq2+3YsWOnXLcGtWpY1qxZrEaVinbu2XWsYd2z/J/d+ciz9sOU39w6T5051xpfdrMdPHQowfVTObXtcq9NnjbbalWvYuVKl3CxwUXX3mEffjnWvZ+z8C+XBhFQk6e7BB988IHrgOWPP/6w6Ohoq1+/Pk01AQAAkCFce3kre+PZvu5v1VDVuugau7rNRfbC4w+4ac0a1bMml99s23bsshLFisT7/up1G+21D0fYD5+9bi3Pa2JWpoHVrVvXOnXq9F+a1avttddecy3iWrZs6abFTRPXhg0brHfv3jZ79mxr0KCB2ab5dtct11nNizrasFHj7fYbrkp0vTq1b22393nKNde8qs1FsT678tLz7c3n+rm/u990tZWo28omTp1pV7e9OMH5tWrRxD559Sn/+2FfjbNlK9famlnjrHChAm7aXf2et7eHfZVovpBOBkOXsmXLuhcAAACQkbRs0dj/d9VK5d3/FzePP23jlm1Bg7zpv8+3/PnyxAR4J3Xs2NGyZfvv8nv69OmWP39+f4AXLE1cEydOtCxZsti7777ravLswA7zmc9OnIi2BX/F7kwluRT4efLkzm3ly5S0DZu3Jfqdthc3j/VetZ8tW5zjD/Ck05WXEuRFQpC3aNEi+/zzz23QoEHxunvt0qWL1alTJ1T5AwAAAFJd7lw5/X9nyRIVZFrMU08KroLZtmO3FS1UMNa0rFmzusec/Gm2bbOiRYsmmiauHTt2WN68ea1Ro0YxE/asc/81rl/bqp9RwU5H4Pp5eVHzy8QUKpAv1nvVbAY+xydqrooICPI0VoeaasalZ/LU+cpPP/0UirwBAAAAEUm1YJu37bDjx4/7a+b+/fdf27lz539pypd3w48lliYutaLbs2ePXXvttVawYEHXXDO5AnvHD7XyZUrZqnUbYk1bu4Eh1iKi45Xff//dzj777HjTNU3tgwEAAIDMTE0fVROm8eE8r776akwTSy9Nq1YxaT74IME0wSpVChQoYP369XP9YniWLF91ysHMPUUKFbBde/ZaOHRoe7H9NH2O/fl3zDh/qgl8/aMRYVkWQlyTV7x4cddt64UXXhhruqYVKRK/TTIAAACQ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BQAAAACI4CDv008/dcMlqEdNvfS3pgEAAAAAIizIe/XVV61nz57Wpk0bGz58uH3xxRfu7x49erjPAAAAAAAR9EzeK6+84gY+b9++vX9ax44drUWLFta7d2+77777QplHAAAAAEA4a/I2btxoF198cbzpmrZhw4aUzBIAAAAAkFZBXuXKlW3s2LHxpo8ZM8Z9BgAAAACIoCCvf//+dtttt1nXrl3trbfecq9bbrnFbr/9dvdZpPjrr7/8fy9ZssTWr1/v/j58+LD98ccftn//fvd+69atbvB3z7Jly9zg73Ls2DGXdu/eve799u3bbf78+f60//zzjxsgXtQLqdLu3r3bvd+5c6d7r8HkZdeuXe4lmrZ582Y7ePCge3/o0CH3Pjo62r3XPPR9jz47cOCAP/967/V6umfPHtuxY4c/7ZYtW+zff/91fx85csSlPX78uHuv9dA6eLTuXjlosHul1TrLvn37bNu2bf60+lvTvHJRWn1HNA/Ny6NleGWmZSut8iLKm/LoUd61Dl4ZKq3WUbTOeu9RmXjlq7LSZyo7r3xV3l4Zrlq1ylasWOH/rj7zyknz0HuvXLQNly9f7k+7YMEC/7p7ZeiVt9YrsLy13l55e2XozVflFVjemqdX3l4ZeuWt6YHlre955e2VoVfeWl5geSs/Xnl7ZeiVt8owsLwTK0Ptj4HlrTL10nr7rJc2lPusyttbH62zto2X/3Xr1tnSpUv9aRctWuTPo8pBab08qaVB4HGf3vdZr7wj6RwRWN5q9RFY3vrba+2hNErrLUfL0LbzaJtq2wbmIdzl7ZWhV95K55W3l8eklrfy55V3JJwj/v77b395e9vR+67mqWPQo3Oh97um+Qb+rmm99D61zxGZ9Xct7nXEypUr3csrb33mlan3u+aVobahrlE8unbxyonyDs85IqHrCO93zdu3dCzqmPTo3OjtP97vmre/6JzKdUTq/a5tiHMdob/1W+dtc6X1zltaxuLFi0MeawSuV8iDPAV03333nVvRp59+2p555hm3guPGjXOfRQo9R+jR4O4vvPCC+1vr1bBhQ5s3b557P2zYMLvooov8aRXcar29glba6dOnu/cjR460c889159WHdR4ga82utL++OOP7r3KUO+9HXLixInuJTqBvPfee/4TggISvfd+iH7++WcbP368fzkffPCBf6fTyUFpvRPNtGnTXC2r55NPPvHvSNoBldb7Efvtt99s1KhR/rR69tIrBx0ASuud0H7//XcbMWKEP63WfdasWf6TmdJ6P4D68fjss8/8aUePHu0vMx10SusdJDogPvroI39a1RpPnTrVf1Aorbfj60Lw/fff96edMGGCv3x18CqtF8h9//33rry9MuzTp0+s50f12bfffuv+njJlinvvlcvjjz9ud9xxhz9t8+bN/euuA1bL8Q5qlfc333zjT6v9xwv8dZJRWu/HfebMmfbVV1/506ojozlz5vj3LaX1DmZN1+cefU/fF81Pab0fAS1Py/UoP8qXKJ9K651o/vzzT/vwww/9abVfav29E6HSrlmzxr3Xj47ee3744QebNGmS+1v7sT7zLhpU7nrvnUS1XbR9PNpuXnCm7am03o+Wtndga4Hzzz/f7Yvefqdt410EDRo0yG666SZ/2tatW7vjwduXlFbHj6hjqA4dOvjTahtqfqL9WnnwTvTa771lio4LHR+i/UJpvTzoeNJx5dHx5pW3jkOl9S6gdZx6+RMdxzqeRfum0nr51fGv994FRSScI1Te3j7wxhtvxHp2W2Xvdc6l/Cqt9wOo/GnbebRNtW0D8xDuc4TyrffeOVn7tvZxjz7zLrx0TOi9dxGvY0bHjkfHlI6tSDlHdOnSxZ599ln3ty48tW287+o40TnPo3Ohzomi/UJpvXOGzqF6n9rnCO0P3r6k/URpvQs6/dboN8ej3yKvvPUbpbReEKXfMP2WRco5Iu51xAMPPOBeXnnrM2+/VPnqvbcf6tpE1ygeXbt46851RHjOEQldR+hY07bxgj4dizomPS1btvSf8xQcKq13jnvppZe4jgjzOaJhItcR+o3Tb523fyitgjl59913rW3btiGPNQLzmpgon3f1kAxamXvuuSfZn6UXOvkWLFjQnYybNm3qpmmD5M+f38qXL+92EL2vVq2am6YNrB/GevXq+aPrXLlyWcWKFd0JVztNlSpV3Dx18teGa9CggX+DZ8uWzTVj1UlBJ3r9XbhwYXd3TTul0kZFRVmvXr3cd4oUKeIu4LRMzTNPnjzu7oB+pEuWLGlZsmRxP0i6O1S0aFH3Hf2QFChQwPLmzevyr89LlChhWbNmdd/TiapYsWIureabL18+99LJRz9cxYsXd/nUXQLdtdB70bpr+SoHTVeeNZ/s2bO7ctSytBzRyUnlonyoXLRTKn85cuRwdyr0Q6b8i8pJ07V+ypvea71z5szpDjq9SpUq5dJqPspboUKFXBlqOSo/LUs/VspH6dKlXVrlT+Wjz1U+yr++p4tFradOuvXr13dpdMAqTdWqVd13dZekQoUKbv1UfrrLWbduXbds/a11ql69uv8kW6ZMGVeL7ZWhV94qQ6X1ylt50HZReXtl6JW38q7ve+WtddOQJCpvrwy98lYZaj/wyltlpvJSeXtl6JW3yk9l45W35qN5qLy9MvTKW+k0b6+8EypD5UvbUOvnlbfWW/uu0nr7rJc2FPusd+JUeWuZmpfKTD+4tWrVcvnXxYjW4ayzzvLf8VR5Kr3KQUGQPlOedGwq/95Fc3reZwPLW/NVOXs3WNLzOeKaa67xl7d+SDVvbSvv4lX5LVeunMuvLuB1TGk5yp/KVMec6DPlVcek8qDzY7jL2ytDr7xVRipnLdcrw6SWt8pQZaJ1iIRzhC4+tF4qb+VBAarOjfqulrlp0yZ37hQdU1qefss0Xx1z3u+a8qNj8uyzz7YBAwaE/RyR2X/X4l5HeLV4uiZReetCVdcqyrP3u6ZrGZWh/lY+da0jSqtj880336S8w3SOuPvuu+NdR2hf837XNByZ9iEdQ9q3zjzzTP/vmtJpud7vWs2aNd3+ot+1559/nuuIVPpd23DyOiLwd037R9myZf2/azVq1HDnLe0POtbr1KkT0lhD16/6W/nQuSmkQZ527IS+lthn6S3IO1XhpDb9ICKyypZtFl5st8jDNotM4dhunB/Di2Mt8rDNItOAdHZ9ntQ4JsWDoQeju0ne3QwAAAAAQDofJ0/VyMH+FlVpq3r56quvDl3uAAAAAADhC/K6devm/tdDvd7fHrVlr1SpkrVp0yZ5OQAAAAAApE2Qd//997v/9RBj586dQ5cLAAAAAEBIpOiZPAI8AAAAAEifQtrxCgAAAAAgbRHkAQAAAEBmDPIGDhzo/1sDSgMAAAAAIjjI69+/v3+Q88qVK4czTwAAAACAcPeuWbp0aRs/frw1b97cvd+zZ0+CaQsVKpTS/AAAAAAAUiPIe/TRR91A58ePH3fvCxcunGBar8YPAAAAAJBOg7y77rrLbrjhBlu7dq01aNDA5syZE96cAQAAAADCOxi6au/0evvtt61Ro0bJXxoAAAAAIP0NodCjRw//3ydOnHAvAAAAAEAEj5P36aefWu3atS137tzupb81DQAAAAAQYUHeq6++aj179rQ2bdrY8OHD7YsvvnB/q4ZPnwEAAAAAIuCZPM8rr7xin3/+ubVv394/rWPHjtaiRQvr3bu33XfffaHMIwAAAAAgnDV5GzdutIsvvjjedE3bsGFDSmYJAAAAAEirIK9y5co2duzYeNPHjBnjPgMAAAAARFBzzf79+9ttt91mkydPtsaNG7tps2fPds/mvf/++6HOIwAAAAAgnEHeLbfcYqVLl7bBgwfbxIkTLSoqymrWrGnjxo2zSy+9NCWzBAAAAACkVZAnCuYI6AAAAAAgg4yTBwAAAABIfwjyAAAAACADSXFzTYTex4fPoVjDZAAlCwAAgEyCmjwAAAAAyEAI8gAAAAAgswd5GzdutBtuuMEqVKhg+fLli/cCAAAAAETQM3m333677d2715588kkrXLhw6HMFAAAAAEi9IG/GjBm2bNkyK1OmTMqWCgAAAABIP801S5QoYdmzZw99bgAAAAAAqR/kde3a1QYMGGDHjx8/vaUDAAAAANK+uebo0aNtwYIF9uWXX1rFihUtKioq1udz584NVf4AAAAAAOEO8jp16uReAAAAAIAMEOT17ds39DkBAAAAAKT9YOgnTpxwLwAAAABABAd5n376qdWuXdty587tXvpb0wAAAAAAERbkvfrqq9azZ09r06aNDR8+3L744gv3d48ePdxnAAAAAIAIeibvlVdesc8//9zat2/vn9axY0dr0aKF9e7d2+67775Q5hEAAAAAkEQpqsnbuHGjXXzxxfGma9qGDRtSMksAAAAAQFoFeZUrV7axY8fGmz5mzBj3GQAAAAAggppr9u/f32677TabPHmyNW7c2E2bPXu2ezbv/fffD3UeAQAAAADhDPJuueUWK126tA0ePNgmTpxoUVFRVrNmTRs3bpxdeumlKZklAAAAACCtgjxRMBeKgO7o0aP2008/2datW61OnTrWsGHDU35n3bp1ruYwW7ZsriaxbNmyp50PAAAAAMgITnsw9NOxfft2F9Tdf//9Nn78eGvVqpUbhiEhPp/PbrjhBrvwwgvtq6++sg8++MCqVavmevsEAAAAACSjJu/MM890///999/+vxOiNEnRr18/9//8+fMtT548Nm/ePDvnnHPsiiuusMsuuyxokKdhGzR8Q5YsMfGpBmDv2rWr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vvS2jdiOsf3666/21ltv2eOPPx5rm+XJk8dy5coVrywDyzE9pckM1NFa37597cEHH7RPPvnEunXr5gJdLwBUZzrB9v/du3e7m/npLU1mli2tM4DIkT17dndABdLBJTly5EhyGoRv+0iw8g/cPqFIg/S/jdiOSVOhQgX38qgW7c4777QRI0bYs88+G9JzH+fQ8Elv24jfwv+oJU/79u3trrvuilUjpDLSDWBdiEdFRcUqy8ByTE9pMoOyZcu6mjxZunSpnX/++a5MHn300UR/V7Jly+bKLb2lycyoyUOSVaxY0TZu3Bhrmt6XKlXKf6AlJQ3Co2DBglaoUKGg5e9dxIYqDVKmfPnyrhleYmWbmmkQXMmSJWOVW0LnNfHKMjXTIL6Eyk0XeToW0mOazGDhwoXWqlUru+mmm+yVV16J9ZnKSK1GAodaUtNADd0TeDykpzSZzVlnnWWXX365a+0gWbNmdUFgsH1b5Zce02RmBHlIsksuucTGjx/vTnqesWPHuunJSYPw0Y/pd99953+vMX60PQLLP1RpkHxqCtSsWTN3THgOHDhgP/74o79sUzMNYsokrsmTJ1vt2rX971VeGutM4x96xowZY5UrV7YqVaqkehrEp3L7+eefY21Pldu5555r+fLlS5dpMrpFixZZy5Yt7frrr7fXX3893ufnnXeeez4v8Bz1yy+/uLHZvHNUekuTGc+HGqszsDmkykLXB15TSF3v6X3ca8H0lCbTSuueX5A+qNc2dZOvl8a16dWrl/tbY7N51q1b53revOGGG3xjx4713XbbbW4Mp7///jtZaZAyu3fvdttk6tSprgcw9dSm9ytWrPCnUe9g6u5YPWOq/DVmm3rqC+wePlRpEN/WrVvdNlG36dpGGpNO79euXetPo+2XPXt2N7yBhqRQr6XqvSywV8fUTJPZ9enTx40RqqEvVEY6d2kIg0mTJvnTqDt1da2ul7bt888/74YU+fLLL9MkTWajnka93ycNJ6GxH/V34FiG+g3TuILqUe/bb7/19evXz5Xbzz//nG7TZGQab05jzbVo0cK/7byX17umPPnkk25MyPfee89136/x2W688cZY80pvaTKypk2b+p555hnf999/74bc6dSpkxsr77fffvOnWb58uSujrl27uusDlU/hwoXdeMvpNU1mFaV/0jrQRNpbsWKFde3aNd50tcV+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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_top_tokens_position_composition():\n", + " fig, ax = plt.subplots(figsize=(9, 5))\n", + " bottoms = [0.0] * len(vocab_sizes)\n", + " region_names = (\"start_third\", \"middle_third\", \"end_third\")\n", + " colors = {\"start_third\": \"tab:blue\", \"middle_third\": \"tab:gray\", \"end_third\": \"tab:orange\"}\n", + " for region in region_names:\n", + " values = [per_vocab_size[str(vs)][\"top_tokens_position_macro_composition_train\"][region] for vs in vocab_sizes]\n", + " ax.bar([str(vs) for vs in vocab_sizes], values, bottom=bottoms, label=region, color=colors[region])\n", + " bottoms = [b + v for b, v in zip(bottoms, values)]\n", + " ax.axhline(1 / 3, color=\"black\", linestyle=\":\", linewidth=1, label=\"uniform baseline (1/3)\")\n", + " ax.axhline(2 / 3, color=\"black\", linestyle=\":\", linewidth=1)\n", + " ax.set_xlabel(\"vocab_size\"); ax.set_ylabel(\"fraction of top-N frequent-token occurrences\")\n", + " ax.set_title(\"Where do the top-N most frequent tokens sit, relative to sequence length? (train)\")\n", + " ax.legend(); fig.tight_layout(); plt.show()\n", + "\n", + "\n", + "plot_top_tokens_position_composition()" + ] + }, + { + "cell_type": "markdown", + "id": "287a0cea", + "metadata": {}, + "source": [ + "### Distribution of relative positions (density view)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e2e97d02", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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e/asNX78eCssLMwaNmxYtO198sknHdu7bt06K3/+/GbZ+Lj7Ojt37jSv89VXX8W7zrj2NaH75c77EN9ncMGCBdbs2bPN/1OnTnU837dvXzPtxo0bca4ntn2P77MVEhJivfLKK9bhw4fNfr711ltWaGio9dNPPznWMXjwYCt16tTW5MmTzT7t2LHDHJv777/f7KezLFmymG2O6pFHHrFKlCjhMs3d19fvVt26da2HH37Y2rJli3Xp0iXrgw8+MPs1ffp0l3XWqFHDatKkiZUQcS2j77e+7++++67ZPv08tGjRwnw+9L123sYHH3zQ8fj11183+zFu3DjHtGPHjlkFChSw7rnnHvP5v3LlirVixQqraNGiLstOmDDB7Nvjjz9uffHFF+aY637rfPfdd1+8+7N7924rY8aM5v3Zs2ePde7cOevjjz+2UqVKZT377LOO+fSY58uXz6pUqZK1fPly6/Lly9a+ffvM+/Hzzz+7Pc9LL71ktjeqxYsXm+l6H3XfunTpYn322Wdm23Qf7969az5Ter7VY7Fy5UpzvO33t3PnzuY8rN8NXeaff/6xOnToYGXPnt36999/zTxnzpwx69bPmp5rDh06ZJ06dcp8P8PDw62DBw+6bJ8ur8dJP4fHjx83886cOdN64YUXHPO487qzZs0yn+Mvv/zSnAP0O7Zo0SKrffv2cb5P9va2bdvW6tmzp9le3Q79vun07777zjHvyJEjzedJX9/ZvHnzzLy6DfG9Trt27awePXqY47B3715r6dKljve3Zs2a1vr1681nctmyZVbhwoXN/DY9r+g69u/fH+NrREZGWidPnrTeeecds516LosaO6Jue0zr1c9BwYIFzXcsKj1Gen65fv26eezutsd1/tf3V7dBv2Mav6tWrWrikh4zm57vNIY2btzY8X366KOPzGfq+eefd8zXunVrq3Tp0tbmzZvN+VqPs37e33777TiPY0KOT0K2x97H3r17O/ZRz1l6fBo0aGDF58cffzTLL1myJNpzcW2z/bpdu3Y1323dvk8//TRBn5mY9jsx+/PEE0+Yc/WdO3fi3V8AcBdJKQApnpTShJPOc+3atRiTM/rDSgt7I0aMiPO13ElKjRo1KtpzcSWlRo8eHS0xoYWjN954I0WSUs2bNzeFMy0MRP0hqD+Q7Xnt7f3Pf/7jMp8menS6XbiLjbuv46mkVEL3y533wZ2klKpVq5ZVqFAhRxLKU0mpqJ8tLSjo50IL7FE99NBDVpkyZRyJFE3KPPfccy7zaIFQP/eJTUq5+/p2wkdfSwvtzqpVq2bVr18/2ZJSuu/6fmshyJl+LnLkyOGyjJ2U0qS0FsbSp09v/fDDDy7LaZJJkyCaeHC2cOFC8x5pgdo5cfPaa6+5zKcFO52uSae4aDJEX0ePsTN9D/Vz+ddff5nHmqjUAtvRo0djXZc78yQmKeWc+LFpUkqf00SdM03w6HRNYjnT74QmJezPm5180cRWRESEYz5Nbun76HyO/uWXX8y8n3zySaz75e7r9uvXzzxOKHt79XuhyRhntWvXdvlu2Z/Fl19+Odox03OVfu7iex1NakZ9nccee8wk3TQ54Mw+Pn/88YdbSSlnmlDSuJnYpMvw4cNNksI51mgyVL9TeqwTuu1xnf9fffVVl+madNbX1qSrTZOG+jpRLzJobNV59SKU0u9cTJ/r+PY3ocfH3e2x9zFqHJo4caKZrvsaFzvxr4mvxCSlnC/gJPQzE1dSKiH7o58lfU6/PwDgKTTfA5Di7OrwMTVPsadr0w5t3qadamqV9cTSpgNJmV+bfZQoUUKWLl0qyU2bjWhzN202ErV5oDbV0iYnK1ascJmu1eyjbq+Ka5TDxLxOUiTm9eJ7H3RUPecmC85NHaLSJjb6GdKmCp4UdRu1z7Rr167Jo48+Gm1e7UNEmydpkz/dVz0mUZcvVKiQ1KhRI9Hb4+7rOx9TbRbjTKe5O0KmNqd1Pv7abC8+2lxI329tjulMPxfarMx+3qZDpmtTF33f9bhFXe7nn3+WevXqmeYszho1amT6s/PE90VpU0RtEqlNe6J+fvV8Zn8utenk/fffb5o+xcadeTx5rtMmew0aNIh23PQ9e+SRR1yma7MlbUoa9bhpM0dtfm3TZrV6zJ2Pm+6X6tq1a6zb6O7ranM4u1mmNndy/ky4Q5v66fvvTJsvahPgAwcOmMfafE+nffHFF3L79m0zTZ/TPui0yWGaNGnifR39PEV9Hd1HPd7a1MmZfo513+M6t2rTxvfee0+qV69umlE5n9uiNjdLiN69e5vPqTbhch6l9Pr16/LEE094ZNtj+xxqkzttRukcQ/X7pOvUpptRv096DPRcZn8O9P3RJqoJbb6dEO5uT1LPIxcvXjT32iTVU99xT3xmErI/9qAf9r4AgCeQlAKQ4rR/E/3xF1cH0tofSJMmTcyofdq/hyYktO+khI76ktCCX9Qf4/Y05z4sYhO1b5mEunr1qikcxdQBqj0t6nZELYy784MxMa+TFIl5vaS8D1Fp0kL7CtE+ezTJ4SlRP1vaD5bSAnd4eLgprGpBXm/aD5nS17e3IbZ9dFfUz5u7rx/bZ8f+/CRnYcN+/dg+C9pP1KVLlxzTtM8r7UdIk2pa6HKmiT39PCxatMixv/Y+a0JBn4/6fifm+6Lr0W2K7/Or82kfOHGdc9yZJ7HnmNjWGdN0/azourTfn6ifFe17KL7jFtNn5fTp06ZQrEmw2Lj7upqMevvtt00yoHbt2pItWzbzHXa3T6m4vlvO5xAdAU37+bH7W9ILIbp9zomauEQ9ttrvkh4T7ccp6mdS+/rRdcd1DtJ+fTTm6XZpgkyTcbqMJkfsPtQSQ/sp0qSL9jNkf4Y02aMXf7T/IU9su7vnbn0dTZ67Ew80caYJxldffdX0baX7oX0XejI+JWR7knIeUXbS6/Lly4na1pi+y574zCRkf+xt1+8kAHgKSSkAKUqvdv7111+m1kFctAaHDp2sBbhNmzZJjx49zNXSmGqBxCVVqlQJmt+5JonzNK0ZYNNC140bN0wB05l2FpoUWltEO5aNbRtU1NoosdU28/TrJEViXi++90E7b/7/TdAdN7sD55hoAVcLHqNHjxZPifrZsvdBkyRaMNDPh17F1pu9jVpjwN6HuI6HM/28XblyJdr0qJ83d18/KZ8dZ/agBfbNnYKiXdMotn3XY+qc1NCEhHbCrIVTrb3iXGNGC8xayNMknL2/9j7b26SdbjtLzD7r62ghLb7Pr86nBbW4zgPuzKPsYxD1fY9rudjOdTFN1+3V6ZowjumzogmmhB43TTTpd8w5qZjY19VEiHborElJreWoNWa1s3SNG1E7RI9JXO+V87lca9Tpd+KTTz4xg1xo0kaTNJqscUfUY6vJUD3fderUKdbPpNZqiY2OaqadvmtH/poQsWth/fPPP5JUmmjTmi9aa3XPnj2mBppz8i2p2+7uuVtfR5OX7sQDHbxAv/+aDNOBMvS46OAYWsPNUxKyPUk9d9o1U+0LCAkV03fZE5+ZhOyP1mDUC4r6fQcATyEpBSDF6I9bu8mPFjjcoVdstUnTyJEjzY/lP/74w/Gc/pBU8Y0KlBDafMHZ7t27zdVHrbVl01pbui/6w97ZL7/8Em19CdlG/TGpzXq0+YgW7qLWHLOfT6rkep3Y9jUxr+fO+5AQOnqj/mjXwq27zdMSSrdNf6x/9913cc6nzWN0n6Puo9Yg1IJXVPp505HfoiYntAljYl4/Me9rQr9jsS2j77N+p+fOnesyXT8X2txEj40+76xbt25mpDddRgujmhC2tWnTxjQL8mTNiZjosdXCfNSaA/r51fOZJjeUjuamTZziSh65M4++5yrq+x7TOSYx9LhpLYqYRtBLLHskOx0h0ZOvq4kJTUjqSGha41KTKfHRpoRRR9zUUfI0KWAfW5uOerZ69WpTG0eTH+7WkoprH3V0RHuk2ISK2mxQz31RzwuJiX3a9FWTwlpDSm/6OnpcPbntKup5TZuQaax0PnfbTXKj1hjS75MmJO3vk03PCToSo75Hjz32mKxZsybaRaGkHJ+Ebk9iaRNVpRfakrrNCf3MeMqGDRvMiK5Rz9MAkBQkpQAkK/3hqFe/9Yeq/vDTQpUO9a0/amKjVyd1mHoddliHTtcfaevWrTM/Gp1rWNn9Hmhzg6Q0bXC2d+9eU0NLr/brj7ouXbqYQpHd/ElptXit7TB48GCTSNCrnlqFPqbq7AndxjFjxphaBB07djS1BLRwoH0hffnllzJkyBCzLZ6QHK8T174m9PXceR8S6vXXXzc1thYvXizJQa+mv//++6bAp0lXTaJpAkX3Vz/z+rmxm2A8++yzJkGm0zXRoYUIbbIU0/dCh2fX4cr1eGmhafv27WaYdK1FlJjXT8z7qskRLVy620Q1tmW0Hx/93miNFN1W/Rzo9mnCWT8fY8eOjXF9WljWpJUmpbVGnF141Pm1MKd9HmnSSKfr+UbPFbpOPW94whtvvGGSHFora9++faYZsTb10kSJJjW03xz7c661t3R7NPGk+6Q1Q7UwbSeU3JlH91ebPOn7qLVLdZ+0lp9+fj1Bm0Tpd0o/R1rzRM+zmhjUz5ZeANDvSmLWqZ8x3WY9Nnpe1KZx+j22L0K4+7p6TLUmniYztAaTJvA+//xzU/iOK3bYtPaTJqF1WHvdDm36rU3/tAlv1FohPXv2NDWEtBaQJnV1+5JCa2Xqdtrvr9Z205im/RZpTd+NGzfG2WeQJkI0qabHRZNlmiSLmhRxPtfa/WHFR7dJE7y6fq1downeqH2kJWXbbXre0fXruVvfV/0e6md50KBBjnn0s6wxQj8vWvNNv0/6XdLPjZ7jixcvbpbX3wzz5s0zcVZ/B+jr68WN+vXrR+vLKynHx53t8QStXaTn7Zj6qEzMe5qQz4wn6GdBY1VC++oEgHh5rMt0AHAa+cy+6QhfOXPmtOrUqWNGjok6hHhso9D9/vvvZrh6HUpaR6oqVaqUGSVJhwd3piP66ChNOkKO82hb9ghpUUfTie317Pl15DgdASpbtmxmJDMdBjumbdbRrKpXr26lTp3aKl68uBm6PKbR9+Laxpi2Q23cuNFq1aqVGQ1I11+xYsVoI1rFtn/62jpdtyU+7rxOQkbfi2tfE7pf7r4P7oy+50xHzLM/m0kdfS+mz5bS4b5btmxpRvBKmzatGfWuf//+1r59+xzz6EhmOuKRjgqYJk0aM0Lghg0brE6dOkUbfU9Ho9TRCPW46vruv/9+M3pT1NH3EvL69sh2UcU0sqSObKcjkulIWLrfBQoUiPO4ubOMvu+VKlUynwP9POj26lDkzmLaRp0nV65c5rt3+vRpM03vBw4caL6Hur68efNazZo1MyOA2iOj2SPURf2u2e/x9OnT492n7du3m1G6smbNal6nXLlyZvQqfX+c6ah6Tz75pDl36XurI9fpZ8Z5NDd35lm3bp35XOhr6WdCR8SKa/S9qPum9D2oUqVKjPuj262jD9asWdO855kyZTKjL7755puOUQbtUeZ0iPmoYnp/9HjrCKD63up+6WdWRxt0HlHMndfVfdERCPU19DOs76meA/SYxMV5e7/77jvz2dfjV758eXNeiI1+P3Q5HX3OHXEdF6Wj1z377LNWsWLFzOvrcdD3QkePtEcxjGk0NB2F8umnnzb7q8emUaNG1rZt28yImlG/Q3ou02n2udY+38U1qp9+hu3z32+//ZbobY+JPZKbjuj5zDPPmPOPju6nn5GYtmXr1q1WmzZtzOii9nv04YcfunyfNH506NDBKliwoPkdULJkSWvo0KHW+fPnHfPEtr8JPT7ubE9sI8zqsjo9rs+YberUqWb01ZhGqY1tm+Ma2dbdz0xco++5uz86v74PzscfADwhRP/En7oCACD5aU2GYcOGmSvVUUdCCgadO3c2tXu0/xwAKePll182tYS0tp0nmkgHI63JqZ2Qa59DMXUajv+jtaDKlStnaq1pDUx/qvVeoUIFM1Lf+PHjvb05AAIMzfcAAAAQlPTa7OzZs00TTO3TDEhO2gRXE6CaxPPkaLDJbcaMGabvvhEjRnh7UwAEIJJSAAAACDpa++PTTz81I5Vpv4BJHZEScIf2XaX93zmPBOnrdARkTUoFYw1mAMmPoRMAAAAQVLTjfO3QWzv71o7YtcNzAACQ8uhTCgAAAAAAACmO5nsAAAAAAABIcSSlAAAAAAAAkOJISgEAAAAAACDFkZQCAAAAAABAiiMpBQAAAAAAgBRHUgoAAAAAAAApjqQUAAAAAAAAUhxJKQAAAAAAAKQ4klIAAAAAAABIcSSlAAAAAAAAkOJISgEAAAAAACDFkZQC3JAzZ06ZNWtWshyrokWLyueff877AAB+5OOPP5ayZcsmy7qnTp0qBQsWTJZ1AwCSD2UGIOFISgFB7vTp0zJu3DgpVqyYhISEyK5du6LNY1mWjBo1SgoUKCDp0qWT+vXry7Zt2xI8DwDA9+n5/Pfff5dHHnlEUqVKJR06dIhxPo0XDRs2NOf8fPnyyfDhwyUyMjJZ5gEABE+ZgbJHcCEpBXjZoUOH5Mknn/Ta648ZM0YuXrwo48ePj3We//znP/LBBx/IjBkz5PDhw1K+fHlp2rSpnDt3LkHzAADi16tXLzl69KjXDtX+/ftNwaNz587SvHnzGOe5dOmSOceXKFFC/v33X5k9e7ZMmjRJRo8e7fF5AADBVWag7BFkLMBH9evXz2rcuHG06eXLl7dee+018/+ZM2esrl27WlmzZrXSpUtnNW/e3Nq7d6/L/NevX7cGDx5sFSxY0MqQIYPVokULa//+/Y7na9WqZelXQW/58uWzevXqZZ09e9ZlHTly5DCvqduTOXNms67Jkye7vS86b6lSpcw2Vq5c2fruu+8czxUpUsT67LPPzP8TJkxwbIvz7bnnnjPP37hxw3r++efNdqZPn9669957rd9++83yhK1bt5rX2rlzp8v0iIgIK3fu3NaoUaMc027evGllypTJevfdd92eBwCS6vjx41ZoaKi1cuVKl+l6TtVz4pUrV8zjWbNmWeXKlbNSpUplFS5c2Bo3bpwVGRnpsszy5cut+vXrm/Ny0aJFrffee88xz4IFCxzn37Rp01pVqlSxfvzxR5fl9Xyt5/U333zTKlGihJmvZcuW1rFjx9zal8OHD1tt27a1smXLZuXKlct67LHHrFOnTpnnvvrqK6tAgQIuMSim2HDhwgXHvtx3331mG3S5p59+2rp8+bLlCe3atbMeeeSRaNN1//WYa4y16bHQ/blz545H5wGAuFBmCKwyA2WP4ENSCj5r1apVpvDh/AN/y5Yt5iT4119/mceahKpdu7ZJMp04ccLq3LmzKYDoidjWunVrUzhZs2aN+ZG+cOFC6/XXX4/2eloY+fvvv62mTZtaHTt2dHlOCwT6Y3/27NnWpUuXrG+++cYUdpYsWRLvfmzatMlKnTq1tWjRIrNdu3btMtt59+7daEmpqHRbw8PDrXnz5pnHDz/8sPXAAw9Yf/75p3X16lVr5syZpkC1Y8cOxzIPPvhgjIWXmAoy7gQYfS2dvmLFCpfpuh3t27d3ex4A8AQ9R/ft29dlmiZ39AKFWr16tRUWFmZNmTLFnK9//fVXczHhk08+ccy/du1acw7XH8UnT560Dh06ZH68HzhwINrr6bl2xowZJgY4n2vtiwh6oePIkSPWv//+azVs2NAkutzRpk0bc07X1z9//rx5jY8++ijGpJQzTdTo69SsWdPEkY0bN5of8xqXNMYdPHjQXEDp1KmTYxmdJ764YBdk3E1KdenSxWrUqJHLND2uui77OHlqHgCIC2WGwCozUPYIPiSl4LM0SVSsWDGXmjZDhgwxP8SdT4jOJ1ctgOiPc/1B75zEWrdunduvqz/etbBiJ43spNRTTz3lMl+3bt3MyTw+P/zwg7kKHtsV39iSUpp40xpgI0eONI91P0NCQhxX0m0adIYOHWolVWwBRoOGTt+zZ4/LdL2qr1fm3Z0HADxBz+/Zs2e3bt++bR6fO3fOJP41+WQnUaImw/U8quda5ySWJpMSQs/3zld2NSmlF040IWXTCyR6LtQ4Ep9KlSpZH374Yaz7GFtSSmtB6ZVv+4KN7uuAAQNc5tm+fbuJF3bNsaSILSmliaSoF3A0qaf7b1+N99Q8ABAXygyBVWag7BF86FMKPks70Ovatatpb6y001MdAa979+7m8Z49e0zneJUqVXIskzlzZqlQoYJ5Tm3dulXSpk0rNWvWjPV1tDNX7WAvW7Zs5jXvvfdeuXPnjpw4ccJlvnvuucflsc5nv05cmjRpItmzZ5cqVarIyJEjZeXKlRIRERHnMpcvX5Z27dpJo0aNzDJq06ZNptO//PnzS3h4uISFhUloaKjMnTtXDh48KClNt0WPV1LnAYCE0M63b9y4IQsWLDCP58yZI1mzZpVmzZqZx3perlWrlssyderUMf0VXb9+3REbGjRoEOtr6HyDBg0yo6OmTp3anMfmz59v+r5wlidPHpdR8kqWLGm2xZ3Y0K9fP3n55ZelW7du8tVXX0WLOTH57LPP5IsvvjDnfY0FdmzQPpic44LGGz3//vPPP5KS9DVVXOd9T80DADbKDMFRZqDsEbhISsGnaQJKCw979+6V5cuXy6lTp6RTp05xnpicp9s/bGNz7Ngxadu2rTz88MOyb98+uXv3ruzcudM8p/87S+yP4yxZssj27dtNp7HaoWuPHj2kRo0apqPAmGjyTQspGkSmTZvmeF2drgm2W7dumW3TxJZO03384YcfHMu3bt3aLBPXLbbXjknevHnN/ZkzZ1ym62MtkLk7DwB4QqZMmaRNmzaOCxZ6rx1y6zkztvN+1Gnx/bDVZNGKFSvkxx9/lAsXLpj5NRnmqbignn76admxY4e5wKHn8OLFi8uUKVNinX/16tXyzDPPmHmck24aB7RT8KhxQW/2RRstoMQXFzQJlxB63o/pnK+cY4Mn5gGA+FBmCJwyA2WP4ENSCj6tbNmyUr16dVPo0JuOApQ7d27znNaI0qvZzsORXrlyxSSwypUrZx7rsjdv3pSNGzfGuH5NeOmVg8GDB5sToV5J2LBhQ4zzRl2HPrZfJz5p0qQxhSgdaUKvoOvV619++SXGeXUo7LVr18pPP/0kGTNmdEy390WTc3HR9doFkthueiXfXXrlX4/5smXLHNM0yK1Zs0buu+8+t+cBAE8WPn7++Wdz/l+1apWjBq0dG6Kex9evXy9FihSR9OnTO86nWms1Nnru0osDOl+GDBnMD/otW7ZEm+/kyZMuo+T9/fff5ge8u7FBz52aDNLztp77dbShmBw5csQkxTQppRc2nOk2Lly4MM7X0Zq+8cUFjU8Joed2Pa5aa822dOlSU+tYY7cn5wGA+FBmCJwyA2WPIOTt9oNAfMaPH2/6AsmSJYvppM9Zs2bNTPtj7aBc201rR7dROzpv1aqVVaFCBdOvVNSOzrUjPe0TRDuIvXbtmrV06VIrb968pq3zP//8E29H54sXL453+6dOnWpeT/uI0tEldFQn7YhQO+ON2qeU9j+l69XtiK1vD+1nSztY104L9+3bZ0YFjHpcPNk+XI0dO9aMhLRs2TIz4mGfPn3MMXEepdCdeQDAE7Q/KT2/6Kh4pUuXjtbhrZ5jP//8c3O+1nO+9rXh3NG5Dnyh84wePdrEDu2kXEdptTs61z4DNbZov036vHasrufHnj17xtvRed26dd3aBz2f6wAYFy9eNAN1aMfnOnhH1D6ldF9r1KhhnnPu69C2fv16Eze0o/ajR4+aTtM1zsTUD5Qn+5TS7c6TJ4/Vu3dv6/Tp09Yff/xh+vpyHkjEU/MAgDsoMwROmYGyR3AhKQW/GAJcR1LKmDGjSRw50xOZJqI0YaUjSmiSau/evS7z6DIDBw40ySZdhw7ZrUksm47QVKhQIfOjvmLFiqZj9ZiSUnoi1w5ZdRQnLSw4F3Dioh3N6o9rHTpct1ETZF9++aXjeeeklHZWG9eoSJpsGzZsmFlGO/YtW7asGTo76nFJiHfeeSfG19QCl3MHktp5onaumyZNGlPo0k7knbkzDwB4Sv/+/c256o033oj23KxZs8yoq3pe1/P7uHHjzDnKmf5Q19Fb9YJD8eLFrffff98xjyajNFboMNr6w1k7YNWRXKMmpfS8roktXV7Xo6MHOXd8HhdNnun8GlNy5sxpOvvWpFLUpJTGufhGRdJ16Yh7GTJkMPFKO2XXZFVS6Lqivp6u25l2ptugQQNzztfE0iuvvGKG8k6OeQAgPpQZAqfMQNkjuIToH2/X1gIAAAAAAEBwoU8pAAAAAAAApDiSUkASff/997GOWOHcUTkAIHhUrFgx1tjw7rvvenvzAAApjDIDEDOa7wEAAAAAACDFUVMKAAAAAAAAKS5cvGzHjh3y6aefyqlTp6RSpUry3HPPSdasWeNc5q+//pIpU6bIvn37ZOzYsWY5Z9evX5fp06fLmjVrJDw8XOrVqyc9evSQsLCwZN4bAAAAAAAA+HxNqQ0bNkitWrUkMjJS2rRpI4sWLTIJpBs3bsS6jCahdF5NMM2fP1/OnTvn8ryuq0KFCrJt2zZp0qSJ3HvvvTJq1CizjD4HAAAAAACAIO9TSpNG2hH0Tz/9ZB5fvHhRChYsKOPGjZNnnnkmxmWOHz8u+fLlk2PHjkmhQoVk2bJl0rBhQ8fzujtnzpyR3LlzR0t+rV+/XmrWrOnWtmkCS18rU6ZMplNSAPBXel68cuWK5M+fX0JDabXtScQKAIGCWJF8iBUAAoWVDOUKrzXfu3nzpqxYsUK++OILxzRttqeJqoULF8aalNKdj4smkJwTUipv3rzm/vLly25vnyakNOkFAIHiyJEjJvEPzyFWAAg0xArPI1YACDRHPFiu8FpS6vDhwxIRERFtR+zaT5703nvvSfbs2U1tqdjcunXL3Gx2BTI92JkzZ/bo9gDO/Z9pH2mlS5eW9OnTc2CQLDQhr+dWrfkJz7KPKbECyYlYgZQQLLFC+5ydOHGioz/bl19+WfLkyePWsrNmzZKPP/5YOnbsKAMHDnT7NYkVSAnECvhrrPBaUur27dvmPmpBXB/bz3mCdniuweP777+P88BpX1Xa91RUmpAiKYXkop8tuyYfkNxoipx8x5RYgeRErEBKCuRYsXLlSmnatKkMHjzYJJa0jFC3bl3TF612KRKX/fv3ywsvvGCa4h08eDBBr0usQEogVsBfY4XXOhexR9g7f/68y3TtuDy+0ffcNWfOHHniiSfks88+k4ceeijOeYcNGyaXLl1y3PSqN5ASVzS2bNli7gEAIFYAyefVV181ZQLtv7Zdu3Yyb948OX36tBnVOy7amqJTp07yzjvvSK5cuXiL4JMoV8BfeS0pVaBAAcmRI4ds377dZbpeqahSpUqS1//DDz9I9+7dZfLkyfL444/HO3+aNGkcV7q54o2UognQn3/+2dwDAECsAJKvwK5N99q2beuYliFDBlNzavHixXEu++KLL5rRvTt37szbA59FuQL+KtSb1b0ee+wx+fzzz03tKKUBQWuN9OjRwzHfhAkTZMCAAQla99y5c6Vr164yadIk6d27t8e3HQAAAID/0FYQ2vROL4w708fa121s9OKh3rQfKndpzSrtd8X5BgDwsT6l1OjRo01NqTJlypiOnrdu3SpvvPGGNGjQwDGPPr9u3TrH4yVLlsj7779vRu+zm91pjStNQulNT/pavTZLlizy448/mptNOyRs3rx5Cu8lAAAAAG+6c+eOuU+bNq3L9HTp0sXan+2xY8fkySefNC0wEtLHbGx91QIAfCwppR0KLl26VHbs2GFGwNBqsfnz53eZRxNJzjWnNIHVr18/8/+gQYMc0zWpZQcW50SUs3LlyiXTngAAAADwVToSt7JbaNj0sf1cVNrnlDb70xH6bH///becOXNGNm3aJCtWrJCwsLBoy+lFc+1MPepoVQAAH0tK2SpXruz2cwULFjS32KRKlUpa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2rVLVq1aJd9//71jvjlz5sjhw4dlyJAhpqneli1bpHbt2i59U23dulXatm3rpT0BgMBCUgrwIu2bQEeBWTD+IO8DACDOWKH3ABLv7bfflvr160utWrWkevXq8ssvv0iXLl3k4YcfdsyzaNEiWbdunUlKhYSEyCuvvCKRkZFSvnx509RPR/Br2rSpDBgwgLcCPoVYAX9FUgrwIr1KV7JkSQm1DvM+AADijBUAkiZfvnyyY8cOk4w6deqU9OjRQxo2bOgyT8eOHaVevXrm/1SpUsnSpUtlw4YNpnaUNv979dVXpUKFCrwV8DnECvgrklKAF125csV0mBkZeltCI1PzXgAAYo0VNWrUiLdDZgBxS58+vUk8xaZ58+bRptWsWdPcAF9GrIC/oqNzwIuuXr0qK1asMEkpAADiihV6DwAAsQKBhKQUAAAAAAAAgq/53q1bt+S3334z7borVapkOh70xDLnzp0zVxUvXLhghoBt1KiRhId7fXcBAAAAAADg7ZpSp0+flmrVqslLL70kS5YskZYtW8qTTz6Z5GV+/vlnKVKkiEycOFHWrFljRsfQDglPnDiRzHsEAAAAAAAAd3i16tDLL79sRrXQYVfTpUsn27ZtM514tmvXTtq0aZPoZXRUjEcffVS++uor8/j69etSokQJmTx5sowaNSpF9xGIS9q0aU1tv6NLqMUHAIg7Vug9AADECgQSr9WUioyMlO+//1569eplkkuqatWqct9998l3332XpGW0mV7WrFkdj/VHnI60QfM9+Jps2bJJ+/btJSyCggYAIO5YofcAABArEEi8Vj3jyJEjZtjKcuXKuUzXx5s2bUrSMp988olp0vfss8+aZnxLly6V8uXLy8CBA+Psp0pvtsuXLydh7wD33L1713zWLImUEMYdAADEESsyZ87MBTYAQJzlCmIF/I3Xakppckk512hSehUwtoSQu8ukSZPG1KTasWOH7NmzR/755x+zTGho7Ls7duxYyZIli+NWqFChJO0f4I4zZ87IhAkTJCL8OgcMABBnrNB7AACIFQgkXktK2c3v7ESTTZNL2tQusctERESY/qXq169vRt/78ssvTb9TWpNq2LBhsW6PPnfp0iXHTWtlAQAAAAAAIMCa7xUuXFhSp05tajE5O3jwoJQqVSrRyxw/ftwklFq0aOFSc6phw4aydu3aWLdH59EbAAAA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JoEMLTY2Vnbu3GnuAQAAAACwE7eH76lq1aol+VglJCTIvn37pH379mm3dwAAAAAAAMiQUhSU6t27t7n/448/nI8dwsLCpHjx4nLHHXek7R4CAAAAAADA3kEpnSVM5c2bV/r27Zte+wQAAAAAAIAMLkVBKQcNSJ08eVLy5MnjsjypZTfz22+/ycSJEyU6OloqV65sAl8328bWrVvlf//7n+zYsUPefvttqVq1qsvr7733nsyfP99lWYkSJeSjjz5K0b4B6S179uzSunVrcw8AAAAAgJ14FJTSgNDvv/9u7hMbMWKE3HbbbfLQQw+5tZ01a9ZIs2bNzIx9emH+4YcfSoMGDWTjxo2SNWvWJNu88sorMnPmTOnSpYssX75cTp8+fd06f/31l1y5ckVefPFF57Js2bKl+DiB9Kbfy3r16vFBAwAAAABsx6Og1BtvvCHLli27bvmzzz4r7dq1czsopUEsrUH17rvvmufa9pZbbpGPP/5YHn/88STbDBgwwASbDh48aAJUycmfP7+0bNnS7WMCfCEmJkb++ecfKVmypERERHASAAAAAAC2EexJo8OHD0tkZOR1y3PkyCH79+93+2J81apV0qlTJ+cyHcLUokULWbp06Q2DTe7QTK4OHTrIvffeK5MnT5b4+Hi32gHedObMGfn222/NPQAAAAAAduJRUKpKlSryxRdfXLf8888/l0qVKrm1jQMHDkhCQoIULlzYZbk+37dvn6RGeHi4tG/f3tS+ql27towaNUratGlj3i85sbGxcu7cOZcbAAAAAAAA/Gj4ng6f0wynDRs2SOPGjcWyLPn5559Nrae5c+e6tQ2t+aSuHbKUJUsW52ueev31111qUukwPg2WzZ49W+66664k24wePVpefvnlVL0vAAAAAAAA0jFTSutALViwQA4dOiTPPPOMDB061AzpW7hwoXnNHbly5TL3p06dum4GP8drnrq2SHr58uWlePHiZkhfcoYPHy5nz5513jSTCwAAAAAAAH6UKaV0OJzePFWoUCHJly+fCRQlDmTp81q1akla0mF7GvzKnDnzDYf86Q3wptDQUClYsKC5BwAAAADATjzKlEor9913n3zyySdy7Ngx81wzrTZv3myWO4wbN87t2fzU1atX5YMPPnAWNtehhS+99JKcP39eOnfunA5HAXhOA7MPP/ywuQcAAAAAwE48Ts/Y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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_top_tokens_relative_position_histogram():\n", + " ncols = 3\n", + " nrows = math.ceil(len(vocab_sizes) / ncols)\n", + " fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 4, nrows * 3), squeeze=False)\n", + " for idx, vocab_size in enumerate(vocab_sizes):\n", + " ax = axes[idx // ncols][idx % ncols]\n", + " histogram = per_vocab_size[str(vocab_size)][\"top_tokens_relative_position_histogram_train\"]\n", + " bin_centers = sorted(float(k) for k in histogram.keys())\n", + " counts = [histogram[f\"{c:.3f}\"] for c in bin_centers]\n", + " total = sum(counts)\n", + " fractions = [c / total for c in counts] if total > 0 else counts\n", + " bin_width = bin_centers[1] - bin_centers[0] if len(bin_centers) > 1 else 0.05\n", + " ax.bar(bin_centers, fractions, width=bin_width * 0.9, color=\"tab:purple\")\n", + " ax.axvline(0.5, color=\"gray\", linestyle=\"--\", linewidth=1)\n", + " ax.set_xlim(0, 1)\n", + " ax.set_title(f\"vocab_size={vocab_size}\", fontsize=10)\n", + " ax.set_xlabel(\"relative position\"); ax.set_ylabel(\"fraction\")\n", + " for idx in range(len(vocab_sizes), nrows * ncols):\n", + " axes[idx // ncols][idx % ncols].axis(\"off\")\n", + " fig.suptitle(\"Distribution of top-N frequent-token occurrences by relative position (train)\")\n", + " fig.tight_layout(); plt.show()\n", + "\n", + "\n", + "plot_top_tokens_relative_position_histogram()" + ] + }, + { + "cell_type": "markdown", + "id": "a0ed1989", + "metadata": {}, + "source": [ + "### Per-token relative position (mean +/- std)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "d774e2c8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_top_tokens_position_errorbars(vocab_size: int):\n", + " rows = per_vocab_size[str(vocab_size)][\"top_tokens_by_frequency_train\"]\n", + " sorted_rows = sorted(rows, key=lambda r: r[\"mean_relative_position\"])\n", + " fig, ax = plt.subplots(figsize=(9, max(4, len(sorted_rows) * 0.18)))\n", + " y_positions = range(len(sorted_rows))\n", + " means = [r[\"mean_relative_position\"] for r in sorted_rows]\n", + " stds = [r[\"std_relative_position\"] for r in sorted_rows]\n", + " labels = [f\"{r['token']!r} (n={r['count']})\" for r in sorted_rows]\n", + " ax.errorbar(means, y_positions, xerr=stds, fmt=\"o\", color=\"tab:purple\", ecolor=\"lightgray\", capsize=2)\n", + " ax.axvline(0.5, color=\"gray\", linestyle=\"--\", linewidth=1, label=\"sequence midpoint\")\n", + " ax.set_yticks(list(y_positions)); ax.set_yticklabels(labels, fontsize=7)\n", + " ax.set_xlabel(\"relative position in sequence (0 = start, 1 = end)\")\n", + " ax.set_title(f\"Top-{len(sorted_rows)} token relative positions, vocab_size={vocab_size} (mean +/- std)\")\n", + " ax.legend(); fig.tight_layout(); plt.show()\n", + "\n", + "\n", + "# change this to inspect a different vocab_size from the grid\n", + "plot_top_tokens_position_errorbars(vocab_sizes[len(vocab_sizes) // 2])" + ] + }, + { + "cell_type": "markdown", + "id": "04a95b22", + "metadata": {}, + "source": [ + "## 6. Tokenization examples" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "id": "21711059", "metadata": {}, "outputs": [ From ceaaf678a888df86a7620c482c983cfcf2d1a1a7 Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Wed, 29 Jul 2026 11:38:47 +0300 Subject: [PATCH 15/70] Saved the splits in data, summary contains with info. Ran and cached log10 Pgen --- benchmark/__init__.py | 1 + benchmark/prepare_splits.py | 336 ++++++++++++++++++++++++ data/benchmark/trb/dataset_summary.json | 115 ++++++++ 3 files changed, 452 insertions(+) create mode 100644 benchmark/__init__.py create mode 100644 benchmark/prepare_splits.py create mode 100644 data/benchmark/trb/dataset_summary.json diff --git a/benchmark/__init__.py b/benchmark/__init__.py new file mode 100644 index 0000000..6e25b91 --- /dev/null +++ b/benchmark/__init__.py @@ -0,0 +1 @@ +"""Baseline benchmark for IRRM-CODEC on reconstruction and pgen prediction.""" diff --git a/benchmark/prepare_splits.py b/benchmark/prepare_splits.py new file mode 100644 index 0000000..1026f46 --- /dev/null +++ b/benchmark/prepare_splits.py @@ -0,0 +1,336 @@ +"""Issue 1: build the common human TRB dataset shared by all benchmark experiments. + +Steps: + 1. load the AIRR table and drop invalid / duplicate CDR3 amino-acid sequences + 2. match sequences to their TCRemP embeddings and verify the alignment + 3. compute and cache log10(pgen) and log10(pgen_1mm) + 4. build one reproducible 80/10/10 split keyed on the unique CDR3 sequence + 5. emit nested 1k / 10k / all training subsets + 6. write split manifests and a dataset summary +""" + +import argparse +import json +import subprocess +import sys +from pathlib import Path + +import numpy as np +import pandas as pd +import pyarrow.parquet as pq + +from irrm_codec.dataio import normalize_locus_name +from irrm_codec.tokenization import VALID_AA +from irrm_codec.utils import setup_logging + +SUBSET_SIZES = (1_000, 10_000) + +PGEN_COLUMNS = ("log10_pgen", "log10_pgen_1mm") + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--airr-path", default="data/zenodo/trb_background_100k.tsv") + p.add_argument("--embeddings-path", default="data/zenodo/trb_background_embeddings.parquet") + p.add_argument("--output-dir", default="data/benchmark/trb") + p.add_argument("--locus", default="beta") + p.add_argument("--chain", default="TRB") + p.add_argument("--species", default="human") + p.add_argument("--max-len", type=int, default=40, help="Maximum CDR3 length the models can encode.") + p.add_argument("--min-len", type=int, default=1) + p.add_argument("--train-fraction", type=float, default=0.8) + p.add_argument("--val-fraction", type=float, default=0.1) + p.add_argument("--seed", type=int, default=42, help="Seed for the split permutation.") + p.add_argument("--pgen-threads", type=int, default=8) + p.add_argument("--pgen-chunk-size", type=int, default=1000) + p.add_argument("--skip-pgen", action="store_true", help="Reuse a cached pgen table only; never compute.") + p.add_argument("--alignment-min-corr", type=float, default=0.3) + return p.parse_args() + + +def clean_sequences(df, cdr3_col, locus, min_len, max_len, log): + """Drop rows the models cannot consume, then de-duplicate on the CDR3 sequence.""" + report = {"rows_input": int(len(df))} + + locus_norm = normalize_locus_name(locus) + locus_series = df["locus"].astype(str).str.strip().str.lower().map(normalize_locus_name) + df = df[locus_series == locus_norm].copy() + report["rows_after_locus_filter"] = int(len(df)) + + df[cdr3_col] = df[cdr3_col].astype(str).str.strip().str.upper() + + checks = { + "dropped_missing": df[cdr3_col].isin(["", "NAN", "NONE"]), + "dropped_invalid_chars": ~df[cdr3_col].map(lambda s: bool(s) and set(s) <= VALID_AA), + "dropped_too_short": df[cdr3_col].str.len() < min_len, + "dropped_too_long": df[cdr3_col].str.len() > max_len, + } + drop = pd.Series(False, index=df.index) + for name, mask in checks.items(): + mask = mask & ~drop + report[name] = int(mask.sum()) + drop |= mask + df = df[~drop].copy() + + duplicated = df[cdr3_col].duplicated(keep="first") + report["dropped_duplicate_cdr3"] = int(duplicated.sum()) + df = df[~duplicated].copy() + + report["rows_kept"] = int(len(df)) + if df.empty: + raise ValueError("No sequences left after cleaning.") + log.info("cleaning: %s", json.dumps(report)) + return df.reset_index(drop=True), df.index.copy(), report + + +def load_embeddings(path, keep_positions, n_source_rows, log): + parquet = pq.ParquetFile(path) + n_emb = parquet.metadata.num_rows + if n_emb != n_source_rows: + raise ValueError( + f"Embeddings have {n_emb} rows but the AIRR table had {n_source_rows} before cleaning; " + "row-order alignment is unsafe. Provide a clone_id column to merge by id instead." + ) + log.info("reading embeddings rows=%d cols=%d", n_emb, parquet.metadata.num_columns) + matrix = parquet.read().to_pandas().to_numpy(dtype=np.float32) + if not np.isfinite(matrix).all(): + raise ValueError("Embeddings contain NaN or infinite values.") + return matrix[keep_positions] + + +def check_alignment(emb, sequences, min_corr, log): + lengths = np.array([len(s) for s in sequences], dtype=np.float64) + probe = emb[:, : min(600, emb.shape[1])].mean(axis=1) + corr = float(np.corrcoef(probe, lengths)[0, 1]) + shuffled = float( + np.corrcoef(probe, np.random.default_rng(0).permutation(lengths))[0, 1] + ) + log.info("alignment check corr=%.4f shuffled_corr=%.4f", corr, shuffled) + if not np.isfinite(corr) or abs(corr) < min_corr: + raise ValueError( + f"Embedding/sequence alignment check failed: |corr|={corr:.4f} < {min_corr}. " + "The embedding rows are probably not aligned with the AIRR rows." + ) + return {"length_corr": corr, "shuffled_length_corr": shuffled, "min_corr_threshold": min_corr} + + +def ensure_pgen(df, args, output_dir, log): + cache_path = output_dir / "pgen.tsv" + clean_airr_path = output_dir / "cleaned_airr.tsv" + df.to_csv(clean_airr_path, sep="\t", index=False) + + if cache_path.exists(): + cached = pd.read_csv(cache_path, sep="\t") + same_rows = len(cached) == len(df) + same_seqs = same_rows and np.array_equal( + cached["junction_aa"].astype(str).to_numpy(), df["junction_aa"].to_numpy() + ) + if same_seqs and all(c in cached.columns for c in PGEN_COLUMNS): + log.info("reusing cached pgen table %s", cache_path) + return cached, {"source": "cache", "path": str(cache_path)} + log.warning("cached pgen table does not match the cleaned data; recomputing") + + if args.skip_pgen: + raise FileNotFoundError( + f"--skip-pgen was set but no matching pgen cache exists at {cache_path}." + ) + + cmd = [ + sys.executable, "-m", "irrm_codec.calc_pgen_1mm", + "--airr-path", str(clean_airr_path), + "--output-path", str(cache_path), + "--chain", args.chain, + "--species", args.species, + "--locus", args.locus, + "--threads", str(args.pgen_threads), + "--chunk-size", str(args.pgen_chunk_size), + ] + log.info("computing pgen: %s", " ".join(cmd)) + subprocess.run(cmd, check=True, cwd=Path.cwd()) + + table = pd.read_csv(cache_path, sep="\t") + if not np.array_equal(table["junction_aa"].astype(str).to_numpy(), df["junction_aa"].to_numpy()): + raise ValueError("pgen output rows do not line up with the cleaned AIRR rows.") + return table, {"source": "computed", "path": str(cache_path)} + + +def make_splits(n, train_fraction, val_fraction, seed): + """One reproducible permutation shared by every experiment. + + Splitting on de-duplicated sequences means a CDR3 can appear in only one split. + """ + if not 0 < train_fraction < 1 or not 0 <= val_fraction < 1: + raise ValueError("Fractions must lie in (0, 1) and [0, 1).") + if train_fraction + val_fraction >= 1: + raise ValueError("train_fraction + val_fraction must be < 1.") + order = np.random.default_rng(seed).permutation(n) + train_end = int(n * train_fraction) + val_end = train_end + int(n * val_fraction) + return order[:train_end], order[train_end:val_end], order[val_end:] + + +def summarize_target(values): + finite = values[np.isfinite(values)] + if finite.size == 0: + return {"n_finite": 0} + return { + "n_finite": int(finite.size), + "n_non_finite": int(values.size - finite.size), + "mean": float(finite.mean()), + "std": float(finite.std()), + "min": float(finite.min()), + "max": float(finite.max()), + } + + +def main(): + args = parse_args() + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "prepare_splits.log") + + raw = pd.read_csv(args.airr_path, sep="\t") + n_source_rows = len(raw) + log.info("loaded AIRR rows=%d from %s", n_source_rows, args.airr_path) + + clean, clean_index, clean_report = clean_sequences( + raw, "junction_aa", args.locus, args.min_len, args.max_len, log + ) + keep_positions = raw.index.get_indexer(clean_index) + if (keep_positions < 0).any() or len(keep_positions) != len(clean): + raise ValueError("Internal error: kept-row bookkeeping disagrees with the cleaned table.") + + emb = load_embeddings(args.embeddings_path, keep_positions, n_source_rows, log) + alignment = check_alignment(emb, clean["junction_aa"].tolist(), args.alignment_min_corr, log) + + pgen_table, pgen_meta = ensure_pgen(clean, args, output_dir, log) + for column in PGEN_COLUMNS: + clean[column] = pgen_table[column].to_numpy(dtype=np.float64) + + # OLGA returns pgen=0 for a few sequences its generative model cannot account for, + # which becomes -inf after the log. Such a target has no finite loss or gradient and + # would turn every model weight into NaN, so the rows are dropped before splitting. + # They are removed for both targets at once to keep one row set shared by every + # model and target, as the benchmark requires. + finite = np.ones(len(clean), dtype=bool) + for column in PGEN_COLUMNS: + finite &= np.isfinite(clean[column].to_numpy()) + dropped_non_finite = int((~finite).sum()) + if dropped_non_finite: + log.warning( + "dropping %d row(s) with non-finite pgen targets: %s", + dropped_non_finite, + clean.loc[~finite, ["junction_aa", *PGEN_COLUMNS]].to_dict("records"), + ) + clean = clean[finite].reset_index(drop=True) + emb = emb[finite] + clean_report["dropped_non_finite_pgen"] = dropped_non_finite + clean_report["rows_kept"] = int(len(clean)) + + train_idx, val_idx, test_idx = make_splits( + len(clean), args.train_fraction, args.val_fraction, args.seed + ) + + clean["split"] = "" + clean.loc[clean.index[train_idx], "split"] = "train" + clean.loc[clean.index[val_idx], "split"] = "val" + clean.loc[clean.index[test_idx], "split"] = "test" + if (clean["split"] == "").any(): + raise ValueError("Some rows were not assigned to a split.") + + clean.insert(0, "row_index", np.arange(len(clean), dtype=np.int64)) + + subset_sizes = [s for s in SUBSET_SIZES if s < len(train_idx)] + [len(train_idx)] + subsets = {} + for size in subset_sizes: + name = "all" if size == len(train_idx) else f"{size // 1000}k" + subsets[name] = train_idx[:size] + + np.save(output_dir / "embeddings.npy", emb) + clean.to_parquet(output_dir / "dataset.parquet", index=False) + + manifest_dir = output_dir / "manifests" + manifest_dir.mkdir(exist_ok=True) + for name, idx in (("train", train_idx), ("val", val_idx), ("test", test_idx)): + clean.iloc[np.sort(idx)][["row_index", "junction_aa", "v_call", "j_call", *PGEN_COLUMNS]].to_csv( + manifest_dir / f"{name}.tsv", sep="\t", index=False + ) + for name, idx in subsets.items(): + pd.DataFrame({"row_index": np.sort(idx)}).to_csv( + manifest_dir / f"train_{name}.tsv", sep="\t", index=False + ) + + overlaps = { + "train_val": len(set(clean.iloc[train_idx].junction_aa) & set(clean.iloc[val_idx].junction_aa)), + "train_test": len(set(clean.iloc[train_idx].junction_aa) & set(clean.iloc[test_idx].junction_aa)), + "val_test": len(set(clean.iloc[val_idx].junction_aa) & set(clean.iloc[test_idx].junction_aa)), + } + if any(overlaps.values()): + raise ValueError(f"CDR3 sequences leak across splits: {overlaps}") + + for name, idx in subsets.items(): + if not set(idx).issubset(set(train_idx)): + raise ValueError(f"Training subset {name} is not contained in the train split.") + ordered = [subsets[n] for n in subsets] + for smaller, larger in zip(ordered, ordered[1:]): + if not set(smaller).issubset(set(larger)): + raise ValueError("Training subsets are not nested.") + + summary = { + "airr_path": str(Path(args.airr_path).resolve()), + "embeddings_path": str(Path(args.embeddings_path).resolve()), + "locus": args.locus, + "chain": args.chain, + "species": args.species, + "seed": args.seed, + "max_len": args.max_len, + "cleaning": clean_report, + "embedding_dim": int(emb.shape[1]), + "embedding_alignment": alignment, + "alignment_mode": "row_order", + "pgen": pgen_meta, + "split_sizes": { + "train": int(len(train_idx)), + "val": int(len(val_idx)), + "test": int(len(test_idx)), + }, + "split_fractions": { + "train": args.train_fraction, + "val": args.val_fraction, + "test": round(1.0 - args.train_fraction - args.val_fraction, 6), + }, + "train_subsets": {name: int(len(idx)) for name, idx in subsets.items()}, + "cdr3_overlap_between_splits": overlaps, + "targets": { + column: { + split: summarize_target(clean.loc[clean.split == split, column].to_numpy()) + for split in ("train", "val", "test") + } + for column in PGEN_COLUMNS + }, + "cdr3_length": { + "min": int(clean.junction_aa.str.len().min()), + "median": float(clean.junction_aa.str.len().median()), + "max": int(clean.junction_aa.str.len().max()), + }, + "outputs": { + "dataset": str((output_dir / "dataset.parquet").resolve()), + "embeddings": str((output_dir / "embeddings.npy").resolve()), + "manifests": str(manifest_dir.resolve()), + }, + } + (output_dir / "dataset_summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8") + + log.info("=" * 60) + log.info("kept %d unique CDR3 sequences (embedding_dim=%d)", len(clean), emb.shape[1]) + log.info( + "split train=%d val=%d test=%d", + len(train_idx), len(val_idx), len(test_idx), + ) + log.info("train subsets: %s", ", ".join(f"{k}={len(v)}" for k, v in subsets.items())) + log.info("no CDR3 overlap between splits: %s", overlaps) + log.info("wrote %s", output_dir / "dataset_summary.json") + + +if __name__ == "__main__": + main() diff --git a/data/benchmark/trb/dataset_summary.json b/data/benchmark/trb/dataset_summary.json new file mode 100644 index 0000000..1c46115 --- /dev/null +++ b/data/benchmark/trb/dataset_summary.json @@ -0,0 +1,115 @@ +{ + "airr_path": "C:\\Users\\Smoki\\irrm-codec\\data\\zenodo\\trb_background_100k.tsv", + "embeddings_path": "C:\\Users\\Smoki\\irrm-codec\\data\\zenodo\\trb_background_embeddings.parquet", + "locus": "beta", + "chain": "TRB", + "species": "human", + "seed": 42, + "max_len": 40, + "cleaning": { + "rows_input": 100000, + "rows_after_locus_filter": 100000, + "dropped_missing": 0, + "dropped_invalid_chars": 0, + "dropped_too_short": 0, + "dropped_too_long": 0, + "dropped_duplicate_cdr3": 0, + "rows_kept": 99998, + "dropped_non_finite_pgen": 2 + }, + "embedding_dim": 9000, + "embedding_alignment": { + "length_corr": 0.5274442408242208, + "shuffled_length_corr": 0.0008568142944854723, + "min_corr_threshold": 0.3 + }, + "alignment_mode": "row_order", + "pgen": { + "source": "cache", + "path": "data\\benchmark\\trb\\pgen.tsv" + }, + "split_sizes": { + "train": 79998, + "val": 9999, + "test": 10001 + }, + "split_fractions": { + "train": 0.8, + "val": 0.1, + "test": 0.1 + }, + "train_subsets": { + "1k": 1000, + "10k": 10000, + "all": 79998 + }, + "cdr3_overlap_between_splits": { + "train_val": 0, + "train_test": 0, + "val_test": 0 + }, + "targets": { + "log10_pgen": { + "train": { + "n_finite": 79998, + "n_non_finite": 0, + "mean": -8.34572029024153, + "std": 1.8845455361342092, + "min": -28.06169119699202, + "max": -5.092073042426336 + }, + "val": { + "n_finite": 9999, + "n_non_finite": 0, + "mean": -8.351515526786393, + "std": 1.909456406125435, + "min": -23.09528585214532, + "max": -5.365645796309452 + }, + "test": { + "n_finite": 10001, + "n_non_finite": 0, + "mean": -8.34374768827681, + "std": 1.8479154152116826, + "min": -21.193822220414155, + "max": -5.3048644505016 + } + }, + "log10_pgen_1mm": { + "train": { + "n_finite": 79998, + "n_non_finite": 0, + "mean": -6.52977416306943, + "std": 1.6300446772117814, + "min": -25.268624790379345, + "max": -3.967721318105829 + }, + "val": { + "n_finite": 9999, + "n_non_finite": 0, + "mean": -6.532824795313865, + "std": 1.6590462485672821, + "min": -20.17601369470008, + "max": -4.055332526062316 + }, + "test": { + "n_finite": 10001, + "n_non_finite": 0, + "mean": -6.522161324076908, + "std": 1.5951257276034596, + "min": -18.745888024917427, + "max": -4.127677056652921 + } + } + }, + "cdr3_length": { + "min": 6, + "median": 14.0, + "max": 25 + }, + "outputs": { + "dataset": "C:\\Users\\Smoki\\irrm-codec\\data\\benchmark\\trb\\dataset.parquet", + "embeddings": "C:\\Users\\Smoki\\irrm-codec\\data\\benchmark\\trb\\embeddings.npy", + "manifests": "C:\\Users\\Smoki\\irrm-codec\\data\\benchmark\\trb\\manifests" + } +} \ No newline at end of file From d13a4dac602c131b4302ba1a772f8f5f8a9f20be Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 19:59:04 +0300 Subject: [PATCH 16/70] Match special-token numbering between char and WordPiece tokenizers PAD/UNK/BOS/EOS now use the same ids in both tokenizers, and decoding no longer depends on their numeric order. --- irrm_codec/tokenization.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/irrm_codec/tokenization.py b/irrm_codec/tokenization.py index f8638d0..413f362 100644 --- a/irrm_codec/tokenization.py +++ b/irrm_codec/tokenization.py @@ -1,8 +1,8 @@ AA_VOCAB = { "": 0, - "": 1, - "": 2, - "": 3, + "": 1, + "": 2, + "": 3, "-": 4, "A": 5, "C": 6, @@ -32,6 +32,7 @@ BOS_ID = AA_VOCAB[""] EOS_ID = AA_VOCAB[""] UNK_ID = AA_VOCAB[""] +SPECIAL_IDS = {PAD_ID, BOS_ID, EOS_ID, UNK_ID} GAP_TOKEN = "-" VALID_AA = set("ACDEFGHIKLMNPQRSTVWY") @@ -86,10 +87,11 @@ def decode(tokens, stop_at_eos=True, remove_gaps=False): for token in tokens: if token == EOS_ID and stop_at_eos: break - if token <= UNK_ID: + if token in SPECIAL_IDS: continue decoded.append(ID2AA[token]) sequence = "".join(decoded) if remove_gaps: return strip_gaps(sequence) return sequence + From e1c5bc60cbd21048046fc7f5917ac4fdae9f8717 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 20:06:44 +0300 Subject: [PATCH 17/70] Add WordPiece tokenizer as an alternative to the char one Same PAD/UNK/BOS/EOS ids as the char tokenizer, so both can be used interchangeably without touching the dataset or model code. --- irrm_codec/wordpiece_tokenization.py | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 irrm_codec/wordpiece_tokenization.py diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py new file mode 100644 index 0000000..9ea553f --- /dev/null +++ b/irrm_codec/wordpiece_tokenization.py @@ -0,0 +1,63 @@ +"""WordPiece tokenizer for CDR3 sequences, as an alternative to the char-level one. + +Requires: pip install tokenizers +Requires a tokenizer.json with special tokens at [PAD]=0, [UNK]=1, [BOS]=2, [EOS]=3 — +same ids irrm_codec.tokenization uses. A mismatched file raises ValueError. +""" +from pathlib import Path + +from tokenizers import Tokenizer + +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID + +_EXPECTED_SPECIAL_IDS = {"[PAD]": PAD_ID, "[UNK]": UNK_ID, "[BOS]": BOS_ID, "[EOS]": EOS_ID} + + +def _validate_special_ids(tokenizer, tokenizer_path): + """Check PAD/UNK/BOS/EOS ids match, since ForwardModel/InverseModel assume padding_idx=0.""" + for token, expected_id in _EXPECTED_SPECIAL_IDS.items(): + actual_id = tokenizer.token_to_id(token) + if actual_id != expected_id: + raise ValueError( + f"Tokenizer at {tokenizer_path} has {token}={actual_id}, expected {expected_id}." + ) + + +def load_wordpiece_tokenizer(path) -> Tokenizer: + """Load and validate a tokenizer.json. Returns the Tokenizer itself — it's picklable, + so it can go straight into a DataLoader worker.""" + tokenizer = Tokenizer.from_file(str(Path(path))) + _validate_special_ids(tokenizer, path) + return tokenizer + + +def encode_wordpiece(seq, tokenizer, max_len): + """Encode a CDR3 sequence into exactly max_len ids: truncated or PAD-padded.""" + seq = "" if seq is None else str(seq).strip().upper() + if not seq: + raise ValueError("Sequence must not be empty.") + ids = tokenizer.encode(seq).ids[:max_len] + return ids + [PAD_ID] * (max_len - len(ids)) + + +def decode_wordpiece(token_ids, tokenizer, stop_at_eos=True): + """Decode ids back to an amino-acid string, stopping at the first EOS by default.""" + ids = list(token_ids) + if stop_at_eos and EOS_ID in ids: + ids = ids[: ids.index(EOS_ID)] + return tokenizer.decode(ids, skip_special_tokens=True) + + +def wordpiece_vocab_size(tokenizer) -> int: + """Vocab size, for ForwardModel/InverseModel(vocab_size=...).""" + return tokenizer.get_vocab_size() + + +class WordpieceEncodeFn: + """Binds a tokenizer to encode_wordpiece so it matches datasets.py's encode_fn(seq, max_len).""" + + def __init__(self, tokenizer): + self.tokenizer = tokenizer + + def __call__(self, seq, max_len): + return encode_wordpiece(seq, self.tokenizer, max_len) From c409174b9b30c4430f92a309d5e30ad75dfd591e Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 20:28:12 +0300 Subject: [PATCH 18/70] Add missing __len__ to ForwardDataset and InverseDataset DataLoader(shuffle=True) requires len(dataset) to build a RandomSampler. Without __len__ this raised TypeError before any training could start. --- irrm_codec/datasets.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/irrm_codec/datasets.py b/irrm_codec/datasets.py index 06f1adf..8f217ec 100644 --- a/irrm_codec/datasets.py +++ b/irrm_codec/datasets.py @@ -192,6 +192,9 @@ def __getitem__(self, idx): "length": len(tokens), } + def __len__(self): + return len(self.seqs) + class InverseDataset(Dataset): def __init__(self, df, emb_array, max_len=40, encode_fn=None): @@ -210,6 +213,9 @@ def __getitem__(self, idx): "length": len(tokens), } + def __len__(self): + return len(self.seqs) + class PgenDataset(Dataset): def __init__(self, df, target_array, max_len=40): From 44aaa0e512817023de428726683a7e558fce5f30 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 20:34:23 +0300 Subject: [PATCH 19/70] Let train_forward pick char or WordPiece from the command line Adds --tokenizer-type/--tokenizer-path/--vocab-size and wires the chosen tokenizer's vocab size into the model instead of the old hardcoded default. Char stays the default, so existing runs don't change. --- irrm_codec/train_forward.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/irrm_codec/train_forward.py b/irrm_codec/train_forward.py index fd5b391..63e5876 100644 --- a/irrm_codec/train_forward.py +++ b/irrm_codec/train_forward.py @@ -13,6 +13,7 @@ from irrm_codec.datasets import collate_forward from irrm_codec.forward_model import ForwardModel from irrm_codec.losses import forward_loss, forward_metrics +from irrm_codec.tokenizer_cli import add_tokenizer_args, resolve_tokenizer from irrm_codec.utils import ( choose_device, move_to_device, @@ -32,6 +33,7 @@ def parse_args(): parser.add_argument("--locus", default="alpha") parser.add_argument("--clone-id-col", default="clone_id") parser.add_argument("--embedding-column", default="tcremp_emb") + add_tokenizer_args(parser) parser.add_argument("--max-len", type=int, default=40) parser.add_argument("--batch-size", type=int, default=256) parser.add_argument("--epochs", type=int, default=20) @@ -127,11 +129,14 @@ def main(): args.log_interval, ) + encode_fn, vocab_size, tokenizer_info = resolve_tokenizer(args, logger) + prepared = prepare_cached_training_data( args, logger, task="forward", collate_fn=collate_forward, + encode_fn=encode_fn, ) manifest = prepared["manifest"] mean = prepared["mean"] @@ -144,7 +149,11 @@ def main(): val_loader = prepared["val_loader"] test_loader = prepared["test_loader"] - model = ForwardModel(output_dim=merge_stats["embedding_dim"], max_len=args.max_len).to(device) + model = ForwardModel( + vocab_size=vocab_size, + output_dim=merge_stats["embedding_dim"], + max_len=args.max_len, + ).to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) num_parameters = sum(param.numel() for param in model.parameters()) num_trainable_parameters = sum(param.numel() for param in model.parameters() if param.requires_grad) @@ -172,7 +181,7 @@ def main(): save_training_metadata( output_dir, args, - data_stats, + {**data_stats, **tokenizer_info}, merge_stats, split_row_counts, manifest, @@ -266,4 +275,4 @@ def main(): if __name__ == "__main__": - main() + main() \ No newline at end of file From 52c2bde8ed0fbb1bf0f48a11eedbfad63cacdcf8 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 20:37:10 +0300 Subject: [PATCH 20/70] Add one shared place to resolve char vs WordPiece Both training scripts will call into this instead of each reimplementing the same validation, so they can't quietly diverge. --- irrm_codec/tokenizer_cli.py | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 irrm_codec/tokenizer_cli.py diff --git a/irrm_codec/tokenizer_cli.py b/irrm_codec/tokenizer_cli.py new file mode 100644 index 0000000..c9c1ac0 --- /dev/null +++ b/irrm_codec/tokenizer_cli.py @@ -0,0 +1,67 @@ +"""Shared --tokenizer-type/--tokenizer-path/--vocab-size CLI wiring for training scripts. + +Kept in one place so train_forward.py and train_inverse.py can't drift apart on how a +tokenizer is chosen and validated. +""" +from irrm_codec.tokenization import AA_VOCAB +from irrm_codec.wordpiece_tokenization import ( + WordpieceEncodeFn, + load_wordpiece_tokenizer, + wordpiece_vocab_size, +) + + +def add_tokenizer_args(parser): + parser.add_argument("--tokenizer-type", choices=["char", "wordpiece"], default="char") + parser.add_argument( + "--tokenizer-path", + default=None, + help="Path to a WordPiece tokenizer.json. Required when --tokenizer-type=wordpiece.", + ) + parser.add_argument( + "--vocab-size", + type=int, + default=None, + help="Optional explicit vocab size. If given, must match the tokenizer's actual " + "vocab size (25 for char, tokenizer.json's own size for wordpiece) — this is a " + "sanity check, not an override, since the embedding table must match the tokenizer.", + ) + + +def resolve_tokenizer(args, logger): + """Validate args and build (encode_fn, vocab_size, tokenizer_info) for the chosen tokenizer. + + encode_fn is None for the char tokenizer (ForwardDataset/InverseDataset already default + to char encode() when encode_fn=None) or a WordpieceEncodeFn for wordpiece. + """ + if args.tokenizer_type == "wordpiece": + if not args.tokenizer_path: + raise ValueError("--tokenizer-path is required when --tokenizer-type=wordpiece.") + tokenizer = load_wordpiece_tokenizer(args.tokenizer_path) + vocab_size = wordpiece_vocab_size(tokenizer) + if args.vocab_size is not None and args.vocab_size != vocab_size: + raise ValueError( + f"--vocab-size={args.vocab_size} does not match tokenizer's actual " + f"vocab_size={vocab_size} ({args.tokenizer_path})." + ) + encode_fn = WordpieceEncodeFn(tokenizer) + else: + if args.tokenizer_path: + raise ValueError("--tokenizer-path was given but --tokenizer-type=char ignores it.") + vocab_size = len(AA_VOCAB) + if args.vocab_size is not None and args.vocab_size != vocab_size: + raise ValueError(f"--vocab-size={args.vocab_size} does not match char vocab_size={vocab_size}.") + encode_fn = None + + tokenizer_info = { + "tokenizer_type": args.tokenizer_type, + "tokenizer_path": args.tokenizer_path, + "vocab_size": vocab_size, + } + logger.info( + "tokenizer_type=%s vocab_size=%d tokenizer_path=%s", + tokenizer_info["tokenizer_type"], + tokenizer_info["vocab_size"], + tokenizer_info["tokenizer_path"], + ) + return encode_fn, vocab_size, tokenizer_info From 65ccee40f3b867bd374da2ccab3fb8e2e7807508 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 20:55:07 +0300 Subject: [PATCH 21/70] Note where WordPiece support and the length_logits bug need fixing. --- irrm_codec/train_inverse.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/irrm_codec/train_inverse.py b/irrm_codec/train_inverse.py index 4fc7693..511e811 100644 --- a/irrm_codec/train_inverse.py +++ b/irrm_codec/train_inverse.py @@ -30,6 +30,11 @@ def parse_args(): parser.add_argument("--locus", default="alpha") parser.add_argument("--clone-id-col", default="clone_id") parser.add_argument("--embedding-column", default="tcremp_emb") + # TODO: add --tokenizer-type/--tokenizer-path/--vocab-size (see irrm_codec/tokenizer_cli.py, + # already wired into train_forward.py) and pass encode_fn/vocab_size through to + # prepare_cached_training_data()/InverseModel() below. Deferred: blocked on the + # length_logits bug noted further down, and this script still imports batch_cache.py, + # whose CachedBatchDataset doesn't accept a custom encode_fn at all. parser.add_argument("--max-len", type=int, default=40) parser.add_argument("--batch-size", type=int, default=128) parser.add_argument("--epochs", type=int, default=20) @@ -48,6 +53,8 @@ def parse_args(): def exact_match_rate(pred_tokens, target_tokens): + # TODO: decode() here is the char tokenizer. Once wordpiece support is wired in, + # swap for decode_wordpiece(ids, tokenizer) when --tokenizer-type=wordpiece. exact_matches = 0 total = pred_tokens.size(0) for pred_row, target_row in zip(pred_tokens.tolist(), target_tokens.tolist()): @@ -85,6 +92,12 @@ def run_epoch(model, loader, optimizer, device, stage, epoch, num_epochs, log_in for step, batch in enumerate(progress, start=1): emb, decoder_input, target, lengths, unk_fraction = move_to_device(batch, device) with torch.set_grad_enabled(is_train): + # TODO(pre-existing bug, unrelated to tokenizer integration): expects + # InverseModel.forward() to return (logits, length_logits) and inverse_loss/ + # inverse_metrics to accept length_logits/lengths. Neither inverse_model.py + # nor losses.py define that today -> raises ValueError on any run. Same issue + # in model.generate() below (returns one tensor, not a (tokens, lengths) pair). + # Needs its own fix; deliberately left as-is here. logits, length_logits = model(emb, decoder_input) loss = inverse_loss(logits, target, length_logits, lengths) metrics = inverse_metrics(logits, target, length_logits, lengths) @@ -289,4 +302,4 @@ def main(): if __name__ == "__main__": - main() + main() \ No newline at end of file From 412a1716d4872ed079684340c17295c98f48137c Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 22:30:32 +0300 Subject: [PATCH 22/70] Add a harness to compare char vs WordPiece on the forward task Trains each (tokenizer, seed) combo in-process, times training and inference, and writes per-run results plus mean +/- std across seeds into one table. --- scripts/compare_forward_tokenizers.py | 250 ++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 scripts/compare_forward_tokenizers.py diff --git a/scripts/compare_forward_tokenizers.py b/scripts/compare_forward_tokenizers.py new file mode 100644 index 0000000..23f8087 --- /dev/null +++ b/scripts/compare_forward_tokenizers.py @@ -0,0 +1,250 @@ +"""Compare char vs WordPiece tokenizers on the forward task (CDR3 -> TCRemP embedding). + +Runs training in-process (reusing irrm_codec.train_forward.run_epoch and +irrm_codec.batch_nocache.prepare_cached_training_data) for each (tokenizer config, seed) +pair, times training and inference wall-clock, and writes per-run results plus a +mean +/- std summary across seeds. + +Usage: + python -m irrm_codec.compare_forward_tokenizers \ + --airr-path data/processed/trb_1M.tsv \ + --embeddings-path data/embeddings/trb_1M.parquet \ + --locus beta --max-len 40 \ + --output-root artifacts/compare_forward_tokenizers \ + --seeds 1 42 777 \ + --configs char \ + wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_20000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_30000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_40000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_50000/tokenizer.json + +Each --configs entry is "char" or "wordpiece:". Output: + /raw_results.csv one row per (config, seed) run + /summary_table.md one row per config, mean +/- std over seeds +""" +import argparse +import csv +import statistics +import time +from pathlib import Path + +import torch + +from irrm_codec.batch_nocache import prepare_cached_training_data +from irrm_codec.datasets import collate_forward +from irrm_codec.forward_model import ForwardModel +from irrm_codec.tokenizer_cli import resolve_tokenizer +from irrm_codec.train_forward import run_epoch +from irrm_codec.utils import choose_device, save_json, set_seed, setup_logging + +RESULT_FIELDS = [ + "tokenizer", "vocab_size", "max_len", "seed", + "test_loss", "test_cosine", "best_val_loss", "epochs_to_best_val", + "train_time_sec", "inference_time_sec", "num_parameters", "tokenizer_path", +] + + +def parse_args(): + parser = argparse.ArgumentParser(description="Benchmark char vs WordPiece on the forward task.") + parser.add_argument("--airr-path", required=True) + parser.add_argument("--embeddings-path", required=True) + parser.add_argument("--locus", default="alpha") + parser.add_argument("--clone-id-col", default="clone_id") + parser.add_argument("--embedding-column", default="tcremp_emb") + parser.add_argument("--max-len", type=int, default=40) + parser.add_argument("--batch-size", type=int, default=256) + parser.add_argument("--epochs", type=int, default=20) + parser.add_argument("--lr", type=float, default=1e-3) + parser.add_argument("--weight-decay", type=float, default=1e-4) + parser.add_argument("--train-fraction", type=float, default=0.8) + parser.add_argument("--val-fraction", type=float, default=0.1) + parser.add_argument("--num-workers", type=int, default=0) + parser.add_argument("--log-interval", type=int, default=10) + parser.add_argument("--inference-repeats", type=int, default=3, help="Repeats to average inference wall-clock over.") + parser.add_argument("--seeds", type=int, nargs="+", default=[1, 42, 777]) + parser.add_argument( + "--configs", + nargs="+", + required=True, + help="'char' or 'wordpiece:', one per tokenizer to compare.", + ) + parser.add_argument("--output-root", default="artifacts/compare_forward_tokenizers") + return parser.parse_args() + + +def _tokenizer_args_from_spec(spec): + """'char' / 'wordpiece:' -> the (tokenizer_type, tokenizer_path) resolve_tokenizer needs.""" + if spec == "char": + return argparse.Namespace(tokenizer_type="char", tokenizer_path=None, vocab_size=None) + if spec.startswith("wordpiece:"): + path = spec.split(":", 1)[1] + return argparse.Namespace(tokenizer_type="wordpiece", tokenizer_path=path, vocab_size=None) + raise ValueError(f"Unrecognized --configs entry {spec!r}; expected 'char' or 'wordpiece:'.") + + +def _count_parameters(model): + return sum(p.numel() for p in model.parameters()) + + +def _benchmark_inference(model, test_loader, device, repeats): + """Average wall-clock seconds for one full forward pass over the test set.""" + model.eval() + with torch.no_grad(): + for tokens, mask, _target, _lengths in test_loader: # warm-up, excluded from timing + model(tokens.to(device), mask.to(device)) + break + durations = [] + for _ in range(repeats): + start = time.perf_counter() + for tokens, mask, _target, _lengths in test_loader: + model(tokens.to(device), mask.to(device)) + durations.append(time.perf_counter() - start) + return statistics.mean(durations) + + +def run_one(spec, seed, args, logger): + """Train one (tokenizer config, seed) combination in-process and return its metrics row.""" + set_seed(seed) + device = choose_device() + + tokenizer_args = _tokenizer_args_from_spec(spec) + encode_fn, vocab_size, tokenizer_info = resolve_tokenizer(tokenizer_args, logger) + + data_args = argparse.Namespace( + airr_path=args.airr_path, + embeddings_path=args.embeddings_path, + locus=args.locus, + clone_id_col=args.clone_id_col, + embedding_column=args.embedding_column, + max_len=args.max_len, + batch_size=args.batch_size, + train_fraction=args.train_fraction, + val_fraction=args.val_fraction, + seed=seed, + num_workers=args.num_workers, + ) + prepared = prepare_cached_training_data( + data_args, logger, task="forward", collate_fn=collate_forward, encode_fn=encode_fn + ) + model = ForwardModel( + vocab_size=vocab_size, + output_dim=prepared["merge_stats"]["embedding_dim"], + max_len=args.max_len, + ).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + + best_val_loss = float("inf") + epochs_to_best_val = None + train_start = time.perf_counter() + for epoch in range(1, args.epochs + 1): + run_epoch(model, prepared["train_loader"], optimizer, device, "train", epoch, args.epochs, args.log_interval, False) + val_metrics = run_epoch(model, prepared["val_loader"], None, device, "val", epoch, args.epochs, args.log_interval, False) + if val_metrics["loss"] < best_val_loss: + best_val_loss = val_metrics["loss"] + epochs_to_best_val = epoch + train_time_sec = time.perf_counter() - train_start + + test_metrics = run_epoch(model, prepared["test_loader"], None, device, "test", args.epochs, args.epochs, args.log_interval, False) + inference_time_sec = _benchmark_inference(model, prepared["test_loader"], device, args.inference_repeats) + + return { + "tokenizer": tokenizer_info["tokenizer_type"], + "vocab_size": tokenizer_info["vocab_size"], + "max_len": args.max_len, + "seed": seed, + "test_loss": test_metrics["loss"], + "test_cosine": test_metrics["cosine"], + "best_val_loss": best_val_loss, + "epochs_to_best_val": epochs_to_best_val, + "train_time_sec": train_time_sec, + "inference_time_sec": inference_time_sec, + "num_parameters": _count_parameters(model), + "tokenizer_path": tokenizer_info["tokenizer_path"], + } + + +def _mean_std(values): + values = [v for v in values if v is not None] + if not values: + return float("nan"), float("nan") + if len(values) == 1: + return values[0], 0.0 + return statistics.mean(values), statistics.stdev(values) + + +def summarize(rows): + """One aggregated row per (tokenizer, vocab_size), mean +/- std across seeds.""" + groups = {} + for row in rows: + key = (row["tokenizer"], row["vocab_size"]) + groups.setdefault(key, []).append(row) + + summary = [] + for (tokenizer, vocab_size), group_rows in sorted(groups.items(), key=lambda kv: (kv[0][0], kv[0][1] or 0)): + summary.append({ + "tokenizer": tokenizer, + "vocab_size": vocab_size, + "max_len": group_rows[0]["max_len"], + "n_seeds": len(group_rows), + "test_loss": _mean_std([r["test_loss"] for r in group_rows]), + "test_cosine": _mean_std([r["test_cosine"] for r in group_rows]), + "best_val_loss": _mean_std([r["best_val_loss"] for r in group_rows]), + "epochs_to_best_val": _mean_std([r["epochs_to_best_val"] for r in group_rows]), + "train_time_sec": _mean_std([r["train_time_sec"] for r in group_rows]), + "inference_time_sec": _mean_std([r["inference_time_sec"] for r in group_rows]), + "num_parameters": group_rows[0]["num_parameters"], + }) + return summary + + +def _fmt(mean_std, precision=4): + mean, std = mean_std + return f"{mean:.{precision}f} +/- {std:.{precision}f}" + + +def write_markdown_table(summary, path): + lines = [ + "| tokenizer | vocab_size | max_len | test_loss | test_cosine | best_val_loss | " + "epochs_to_best_val | train_time_sec | inference_time_sec | num_parameters | notes |", + "|---|---|---|---|---|---|---|---|---|---|---|", + ] + for row in summary: + notes = f"n={row['n_seeds']} seeds" + lines.append( + f"| {row['tokenizer']} | {row['vocab_size']} | {row['max_len']} | " + f"{_fmt(row['test_loss'])} | {_fmt(row['test_cosine'])} | {_fmt(row['best_val_loss'])} | " + f"{_fmt(row['epochs_to_best_val'], precision=1)} | {_fmt(row['train_time_sec'], precision=1)} | " + f"{_fmt(row['inference_time_sec'], precision=3)} | {row['num_parameters']} | {notes} |" + ) + Path(path).write_text("\n".join(lines) + "\n", encoding="utf-8") + + +def main(): + args = parse_args() + output_root = Path(args.output_root) + output_root.mkdir(parents=True, exist_ok=True) + logger = setup_logging(output_root / "benchmark.log") + + rows = [] + for spec in args.configs: + for seed in args.seeds: + logger.info("running config=%s seed=%d", spec, seed) + row = run_one(spec, seed, args, logger) + rows.append(row) + logger.info("done config=%s seed=%d test_loss=%.4f test_cosine=%.4f", spec, seed, row["test_loss"], row["test_cosine"]) + + with open(output_root / "raw_results.csv", "w", newline="", encoding="utf-8") as f: + writer = csv.DictWriter(f, fieldnames=RESULT_FIELDS) + writer.writeheader() + writer.writerows(rows) + + summary = summarize(rows) + save_json(output_root / "summary.json", summary) + write_markdown_table(summary, output_root / "summary_table.md") + logger.info("wrote raw_results.csv, summary.json, summary_table.md to %s", output_root) + + +if __name__ == "__main__": + main() From 08011f1c6210c0ffa5fd78c1ba6430c43268e1d9 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 22:30:38 +0300 Subject: [PATCH 23/70] Add a harness to compare char vs WordPiece on the forward task Trains each (tokenizer, seed) combo in-process, times training and inference, and writes per-run results plus mean +/- std across seeds into one table. --- scripts/compare_forward_tokenizers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/compare_forward_tokenizers.py b/scripts/compare_forward_tokenizers.py index 23f8087..01dbe57 100644 --- a/scripts/compare_forward_tokenizers.py +++ b/scripts/compare_forward_tokenizers.py @@ -6,7 +6,7 @@ mean +/- std summary across seeds. Usage: - python -m irrm_codec.compare_forward_tokenizers \ + python scripts/compare_forward_tokenizers.py \ --airr-path data/processed/trb_1M.tsv \ --embeddings-path data/embeddings/trb_1M.parquet \ --locus beta --max-len 40 \ @@ -247,4 +247,4 @@ def main(): if __name__ == "__main__": - main() + main() \ No newline at end of file From 2fba211267167bf5f0e9d8940f77e9bc238e327f Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 29 Jul 2026 23:33:11 +0300 Subject: [PATCH 24/70] Actually apply the computed embedding standardizer before training mean/std were computed from the train split but never used - the model was training against raw, unstandardized embedding targets. Now the same train-derived transform is applied to train/val/test before the data reaches the model. --- irrm_codec/batch_nocache.py | 1 + 1 file changed, 1 insertion(+) diff --git a/irrm_codec/batch_nocache.py b/irrm_codec/batch_nocache.py index bdde2ab..e4c97d7 100644 --- a/irrm_codec/batch_nocache.py +++ b/irrm_codec/batch_nocache.py @@ -80,6 +80,7 @@ def prepare_cached_training_data(args, logger=None, *, task, collate_fn, encode_ logger.info("computing train-only standardizer") mean, std = compute_train_standardizer(emb, train_idx) + emb = (emb - mean) / std # apply once, before slicing, so train/val/test share the same transform logger.info("building dataloaders task=%s", task) train_loader = build_dataloader( From 7ec484e1ce89ccb6309f5762594f74dc664ac9d0 Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 30 Jul 2026 00:05:18 +0300 Subject: [PATCH 25/70] Save results incrementally and make runs resumable raw_results.csv now gets one row appended (and flushed) right after each (tokenizer, seed) run finishes, instead of everything being written in one go at the very end. Re-running with the same --output-root skips whatever's already in the CSV, so a long overnight run can be safely interrupted and picked back up. --- scripts/compare_forward_tokenizers.py | 75 +++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/scripts/compare_forward_tokenizers.py b/scripts/compare_forward_tokenizers.py index 01dbe57..25c5f8c 100644 --- a/scripts/compare_forward_tokenizers.py +++ b/scripts/compare_forward_tokenizers.py @@ -221,24 +221,77 @@ def write_markdown_table(summary, path): Path(path).write_text("\n".join(lines) + "\n", encoding="utf-8") +def _load_completed_runs(csv_path): + """(tokenizer_path or None, seed) pairs already present in an existing raw_results.csv.""" + if not csv_path.exists(): + return set(), [] + with open(csv_path, newline="", encoding="utf-8") as f: + existing_rows = list(csv.DictReader(f)) + completed = { + (row["tokenizer_path"] or None, int(row["seed"])) + for row in existing_rows + } + # csv.DictReader gives strings back; downstream code (summarize()) expects numeric fields + for row in existing_rows: + row["vocab_size"] = int(row["vocab_size"]) + row["max_len"] = int(row["max_len"]) + row["seed"] = int(row["seed"]) + row["test_loss"] = float(row["test_loss"]) + row["test_cosine"] = float(row["test_cosine"]) + row["best_val_loss"] = float(row["best_val_loss"]) + row["epochs_to_best_val"] = int(row["epochs_to_best_val"]) if row["epochs_to_best_val"] else None + row["train_time_sec"] = float(row["train_time_sec"]) + row["inference_time_sec"] = float(row["inference_time_sec"]) + row["num_parameters"] = int(row["num_parameters"]) + row["tokenizer_path"] = row["tokenizer_path"] or None + return completed, existing_rows + + +def _spec_key(spec): + """(tokenizer_path or None) identity used to match a --configs entry against a CSV row.""" + if spec == "char": + return None + return spec.split(":", 1)[1] + + def main(): args = parse_args() output_root = Path(args.output_root) output_root.mkdir(parents=True, exist_ok=True) logger = setup_logging(output_root / "benchmark.log") - rows = [] - for spec in args.configs: - for seed in args.seeds: - logger.info("running config=%s seed=%d", spec, seed) - row = run_one(spec, seed, args, logger) - rows.append(row) - logger.info("done config=%s seed=%d test_loss=%.4f test_cosine=%.4f", spec, seed, row["test_loss"], row["test_cosine"]) - - with open(output_root / "raw_results.csv", "w", newline="", encoding="utf-8") as f: - writer = csv.DictWriter(f, fieldnames=RESULT_FIELDS) + csv_path = output_root / "raw_results.csv" + completed, rows = _load_completed_runs(csv_path) + if rows: + logger.info("resuming: %d run(s) already completed in %s", len(rows), csv_path) + + # Open once in append mode (or fresh with header) and flush after every row, so a + # killed/interrupted process only loses the run currently in flight, not prior ones. + write_header = not csv_path.exists() + csv_file = open(csv_path, "a", newline="", encoding="utf-8") + writer = csv.DictWriter(csv_file, fieldnames=RESULT_FIELDS) + if write_header: writer.writeheader() - writer.writerows(rows) + csv_file.flush() + + try: + for spec in args.configs: + key_path = _spec_key(spec) + for seed in args.seeds: + if (key_path, seed) in completed: + logger.info("skipping already-completed config=%s seed=%d", spec, seed) + continue + logger.info("running config=%s seed=%d", spec, seed) + row = run_one(spec, seed, args, logger) + rows.append(row) + writer.writerow(row) + csv_file.flush() + logger.info( + "done config=%s seed=%d test_loss=%.4f test_cosine=%.4f", + spec, seed, row["test_loss"], row["test_cosine"], + ) + finally: + csv_file.close() summary = summarize(rows) save_json(output_root / "summary.json", summary) From 978f8d0e7dd880dc3db66d28a99b44afc70f081a Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 30 Jul 2026 21:12:29 +0300 Subject: [PATCH 26/70] Add a notebook to visualize the char vs WordPiece comparison --- .../compare_forward_tokenizers_report.ipynb | 1117 +++++++++++++++++ 1 file changed, 1117 insertions(+) create mode 100644 notebooks/compare_forward_tokenizers_report.ipynb diff --git a/notebooks/compare_forward_tokenizers_report.ipynb b/notebooks/compare_forward_tokenizers_report.ipynb new file mode 100644 index 0000000..70561a1 --- /dev/null +++ b/notebooks/compare_forward_tokenizers_report.ipynb @@ -0,0 +1,1117 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d4b91ee9", + "metadata": {}, + "source": [ + "# Compare Forward Tokenizers — char vs WordPiece\n", + "\n", + "Reads the output of `scripts/compare_forward_tokenizers.py` (`raw_results.csv` +\n", + "`summary.json`) and, optionally, `scripts/calc_tokenization_stats.py`'s output for the\n", + "same AIRR file, and renders the comparison as tables and plots.\n", + "\n", + "Interpretation notes live in markdown cells next to each plot, not on the plots\n", + "themselves — the plots only show data (axes, legend identifying which series is which)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "25047bb7", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:29.527950Z", + "iopub.status.busy": "2026-07-30T17:10:29.527800Z", + "iopub.status.idle": "2026-07-30T17:10:29.533251Z", + "shell.execute_reply": "2026-07-30T17:10:29.532239Z" + }, + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "# parameters\n", + "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_background100k\"\n", + "# Optional: output of calc_tokenization_stats.py run on the SAME AIRR file used above,\n", + "# with --tokenizers-dir pointing at the same WordPiece tokenizers. Leave as-is if you\n", + "# haven't run that diagnostic yet - the relevant section below will just note that.\n", + "DOMAIN_TOKENIZATION_STATS_PATH = \"../artifacts/tokenizers_1M_integ_on_background100k/tokenization_stats.json\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b314dd93", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:29.535656Z", + "iopub.status.busy": "2026-07-30T17:10:29.534957Z", + "iopub.status.idle": "2026-07-30T17:10:34.312793Z", + "shell.execute_reply": "2026-07-30T17:10:34.311678Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 24 individual runs across 8 tokenizer configs from ../artifacts/compare_forward_tokenizers_background100k\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizemax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_path
0char254010.1998620.8650320.1995651939705.2415650.56450810850856NaN
1char2540420.2017430.8642500.19846320561.3526140.54877810850856NaN
2char25407770.2056140.8620150.20403219560.5015620.54793410850856NaN
3wordpiece50004010.3011740.7928560.30171620570.4419420.55197011169256artifacts/tokenizers_1M_integ/wordpiece_vocab_...
4wordpiece500040420.3028970.7934630.29744119820.3054570.56868511169256artifacts/tokenizers_1M_integ/wordpiece_vocab_...
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size max_len seed test_loss test_cosine \\\n", + "0 char 25 40 1 0.199862 0.865032 \n", + "1 char 25 40 42 0.201743 0.864250 \n", + "2 char 25 40 777 0.205614 0.862015 \n", + "3 wordpiece 5000 40 1 0.301174 0.792856 \n", + "4 wordpiece 5000 40 42 0.302897 0.793463 \n", + "\n", + " best_val_loss epochs_to_best_val train_time_sec inference_time_sec \\\n", + "0 0.199565 19 39705.241565 0.564508 \n", + "1 0.198463 20 561.352614 0.548778 \n", + "2 0.204032 19 560.501562 0.547934 \n", + "3 0.301716 20 570.441942 0.551970 \n", + "4 0.297441 19 820.305457 0.568685 \n", + "\n", + " num_parameters tokenizer_path \n", + "0 10850856 NaN \n", + "1 10850856 NaN \n", + "2 10850856 NaN \n", + "3 11169256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", + "4 11169256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import json\n", + "from pathlib import Path\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "results_dir = Path(RESULTS_DIR)\n", + "raw = pd.read_csv(results_dir / \"raw_results.csv\")\n", + "with open(results_dir / \"summary.json\") as f:\n", + " summary = json.load(f)\n", + "\n", + "wp = sorted((r for r in summary if r[\"tokenizer\"] == \"wordpiece\"), key=lambda r: r[\"vocab_size\"])\n", + "char_row = next(r for r in summary if r[\"tokenizer\"] == \"char\")\n", + "vocab_sizes = [r[\"vocab_size\"] for r in wp]\n", + "\n", + "print(f\"Loaded {len(raw)} individual runs across {len(summary)} tokenizer configs from {results_dir}\")\n", + "raw.head()" + ] + }, + { + "cell_type": "markdown", + "id": "a1f9d58c", + "metadata": {}, + "source": [ + "## Summary table (mean ± std across seeds)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "41f68c7f", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:34.314620Z", + "iopub.status.busy": "2026-07-30T17:10:34.314442Z", + "iopub.status.idle": "2026-07-30T17:10:34.327971Z", + "shell.execute_reply": "2026-07-30T17:10:34.327073Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizetest_losstest_cosinebest_val_lossepochs_to_best_valnum_parametersn_seeds
0char250.2024 ± 0.00290.8638 ± 0.00160.2007 ± 0.002919.3 ± 0.6108508563
1wordpiece50000.2990 ± 0.00540.7951 ± 0.00330.2973 ± 0.004419.7 ± 0.6111692563
2wordpiece100000.3426 ± 0.00110.7636 ± 0.00070.3426 ± 0.001319.3 ± 0.6114892563
3wordpiece200000.3831 ± 0.00140.7342 ± 0.00150.3809 ± 0.000919.7 ± 0.6121292563
4wordpiece300000.4061 ± 0.00890.7168 ± 0.00710.4057 ± 0.009119.7 ± 0.6127692563
5wordpiece400000.4343 ± 0.00800.6963 ± 0.00700.4321 ± 0.004519.7 ± 0.6134092563
6wordpiece500000.4473 ± 0.00250.6855 ± 0.00040.4453 ± 0.002419.7 ± 0.6140492563
7wordpiece1000000.4858 ± 0.01560.6556 ± 0.01270.4838 ± 0.015320.0 ± 0.0172492563
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size test_loss test_cosine best_val_loss \\\n", + "0 char 25 0.2024 ± 0.0029 0.8638 ± 0.0016 0.2007 ± 0.0029 \n", + "1 wordpiece 5000 0.2990 ± 0.0054 0.7951 ± 0.0033 0.2973 ± 0.0044 \n", + "2 wordpiece 10000 0.3426 ± 0.0011 0.7636 ± 0.0007 0.3426 ± 0.0013 \n", + "3 wordpiece 20000 0.3831 ± 0.0014 0.7342 ± 0.0015 0.3809 ± 0.0009 \n", + "4 wordpiece 30000 0.4061 ± 0.0089 0.7168 ± 0.0071 0.4057 ± 0.0091 \n", + "5 wordpiece 40000 0.4343 ± 0.0080 0.6963 ± 0.0070 0.4321 ± 0.0045 \n", + "6 wordpiece 50000 0.4473 ± 0.0025 0.6855 ± 0.0004 0.4453 ± 0.0024 \n", + "7 wordpiece 100000 0.4858 ± 0.0156 0.6556 ± 0.0127 0.4838 ± 0.0153 \n", + "\n", + " epochs_to_best_val num_parameters n_seeds \n", + "0 19.3 ± 0.6 10850856 3 \n", + "1 19.7 ± 0.6 11169256 3 \n", + "2 19.3 ± 0.6 11489256 3 \n", + "3 19.7 ± 0.6 12129256 3 \n", + "4 19.7 ± 0.6 12769256 3 \n", + "5 19.7 ± 0.6 13409256 3 \n", + "6 19.7 ± 0.6 14049256 3 \n", + "7 20.0 ± 0.0 17249256 3 " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def fmt(mean_std, precision=4):\n", + " mean, std = mean_std\n", + " return f\"{mean:.{precision}f} \\u00b1 {std:.{precision}f}\"\n", + "\n", + "summary_df = pd.DataFrame([\n", + " {\n", + " \"tokenizer\": row[\"tokenizer\"],\n", + " \"vocab_size\": row[\"vocab_size\"],\n", + " \"test_loss\": fmt(row[\"test_loss\"]),\n", + " \"test_cosine\": fmt(row[\"test_cosine\"]),\n", + " \"best_val_loss\": fmt(row[\"best_val_loss\"]),\n", + " \"epochs_to_best_val\": fmt(row[\"epochs_to_best_val\"], precision=1),\n", + " \"num_parameters\": row[\"num_parameters\"],\n", + " \"n_seeds\": row[\"n_seeds\"],\n", + " }\n", + " for row in summary\n", + "])\n", + "summary_df" + ] + }, + { + "cell_type": "markdown", + "id": "a0525716", + "metadata": {}, + "source": [ + "## 1. test_loss vs vocab_size" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "e9fac0c5", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:34.329706Z", + "iopub.status.busy": "2026-07-30T17:10:34.329556Z", + "iopub.status.idle": "2026-07-30T17:10:34.500172Z", + "shell.execute_reply": "2026-07-30T17:10:34.498906Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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wc3NrdT1SqUSNjY2Og8iIiKiYgafViAsLAwrV67E6tWrcebMGYwfPx7Z2dkYPXo0AGDEiBGYNm2a1P6TTz7BzJkzsWrVKnh5eSEpKQlJSUnIysoCAGRlZeGdd97B/v37cfnyZcTExCA0NBS+vr4ICQkxyHskIiKix5vBxzANGTIEN2/eRHh4OJKSkhAQEIDo6GhpIHhCQgLk8nu5btmyZcjPz8dzzz2ns5+IiAjMmjULCoUCx48fx+rVq5Geng53d3f06dMHc+bMgVKprNH3RkRERLWDwedhMkach4mIiKh2eiznYSIiIiJ6HDAwEREREenBwERERESkBwMTERERkR4MTERERER6MDARERER6cHARERERKQHAxMRERGRHgxMRERERHowMBERERHpwcBEREREpAcDExEREZEeDExEREREejAwEREREenBwERERESkBwMTERERkR4MTERERER6MDARERER6cHARERERKQHAxMRERGRHgxMRERERHowMBERERHpwcBEREREpAcDExEREZEeDExEREREejAwEREREenBwERERESkBwMTERERkR4MTERERER6MDARERER6cHARERERKQHAxMRERGRHgxMRERERHowMBERERHpwcBEREREpAcDExEREZEeDExEREREejAwEREREenBwERERESkBwMTERERkR4mhi7AmBUWFqKwsNDQZRAREVEVqez3OgNTOZKTk5GTk2PoMoiIiKiKZGZmVmo7owhMS5cuxaeffoqkpCS0bt0aixcvRmBgYKltV65ciTVr1uDkyZMAgHbt2uGjjz7SaS+EQEREBFauXIn09HR06dIFy5Ytg5+f30PVpdVqIZPJSiyXyWQwMbl36AoKCsrcR3W1BQBTU9NKtS0sLIQQwqjbmpiYSMdeo9FAq9UadVuFQgG5XG40bbVaLTQaTZlt5XI5FAqF0bQVQpT7f33G0NYYfu/5N+IeY/i959+Immtblb/LlWXwwLRhwwaEhYVh+fLlCAoKwsKFCxESEoK4uDg4OzuXaB8bG4thw4ahc+fOUKlU+OSTT9CnTx+cOnUKHh4eAIC5c+fi888/x+rVq+Ht7Y2ZM2ciJCQEp0+fhkqlqnBta9euLbV9w4YNMWDAAOn5ypUry/xw3N3dMWjQIOn5N998g9zc3FLbOjs7Y/DgwTqvX1YSdnBwwAsvvCA9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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "loss_means = [r[\"test_loss\"][0] for r in wp]\n", + "loss_stds = [r[\"test_loss\"][1] for r in wp]\n", + "\n", + "fig, ax = plt.subplots(figsize=(6, 4.5))\n", + "ax.errorbar(vocab_sizes, loss_means, yerr=loss_stds, marker=\"o\", capsize=3, label=\"wordpiece\")\n", + "ax.axhline(char_row[\"test_loss\"][0], color=\"gray\", linestyle=\"--\", label=\"char\")\n", + "ax.axhspan(char_row[\"test_loss\"][0] - char_row[\"test_loss\"][1],\n", + " char_row[\"test_loss\"][0] + char_row[\"test_loss\"][1], color=\"gray\", alpha=0.15)\n", + "ax.set_xlabel(\"vocab_size\")\n", + "ax.set_ylabel(\"test_loss\")\n", + "ax.set_title(\"test_loss vs vocab_size\")\n", + "ax.legend()\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "a27ed78f", + "metadata": {}, + "source": [ + "*Notes: lower `test_loss` is better. `char` has no `vocab_size` position of its own — it's\n", + "drawn as a horizontal reference (line + shaded std band), not a point on the WordPiece\n", + "ablation grid.*" + ] + }, + { + "cell_type": "markdown", + "id": "075d220b", + "metadata": {}, + "source": [ + "## 2. test_cosine vs vocab_size" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f24dbe8c", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:34.502628Z", + "iopub.status.busy": "2026-07-30T17:10:34.501710Z", + "iopub.status.idle": "2026-07-30T17:10:34.621402Z", + "shell.execute_reply": "2026-07-30T17:10:34.620208Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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JUwiIiIiDihhEhEREXFACZOIiIiIA0qYRERERBxQwiQiIiLigBImEREREQeUMImIiIg4oIRJRERExAElTCIiIiIOKGESERERcUAJk4iIiIgDSphEREREHFDCJCIiIuKAEiYRERERB5QwiYiIiDighElERETEASVMIiIiIg4oYRIRERFxQAmTiIiIiANKmEREREQcUMIkIiIi4oASJhEREREHlDCJiIiIOKCESURERMQBJUwiIiIiDihhEhEREXFACZOIiIiIA0qYRERERBxQwiQiIiLigBImEREREQeUMImIiIg4oIRJRERExAElTCIiIiIOKGESERERcUAJk4iIiIgDSphEREREHFDCJCIiIuKAEiYRERERB5QwiYiIiDighElERETEASVMIiIiIg4oYRIRERFxQAmTiIiIiANKmEREREQcUMIkIiIi4oASJhEREREHlDCJiIiIOKCESURERMQBJUwiIiIiDihhEhEREXFACZOIiIiIA0qYRERERBxQwiQiIiLiQL5ImN5//33Kly+Pp6cnjRs3ZuPGjZnWnz59OlWrVsXLy4vQ0FCGDh3KlStXbuucIiIiIhlxesI0d+5chg0bxrhx49iyZQt16tShbdu2nDp1Kt3633zzDaNGjWLcuHFERUXx6aefMnfuXF555ZVsn1NEREQkMybDMAxnBtC4cWPuvvtu3nvvPQAsFguhoaG88MILjBo1Kk39QYMGERUVxfLly21lw4cPZ8OGDaxevTpb57xZfHw8fn5+nD9/Hl9f35y4TBEREckHsvsb79QWpqSkJDZv3kxERIStzMXFhYiICNatW5fuMU2bNmXz5s22LraDBw+yZMkSHnjggWyfMzExkfj4eLtNREREJJWrMz/8zJkzpKSkEBQUZFceFBTE7t270z3miSee4MyZMzRv3hzDMEhOTubZZ5+1dcll55yTJk1iwoQJOXBFIiIiUhA5fQzTrVq5ciUTJ05k5syZbNmyhYULF7J48WJef/31bJ9z9OjRnD9/3rYdO3YsByMGEqLhxLaMt4TonP08ERERyVFObWEKCAjAbDYTExNjVx4TE0NwcHC6x4wZM4annnqK/v37A1CrVi0uXrzIgAEDePXVV7N1Tg8PDzw8PHLgijKw6XNY9WbG+8NHQevRuff5IiIicluc2sLk7u5OgwYN7AZwWywWli9fTpMmTdI9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W5nuf+47fvw4Tz75JCVKlMDLy4tatWqxadMm237DMBg7diylSpXCy8uLiIgI9u3bZ3eOs2fP0qNHD3x9ffH396dfv35cuHDBrs4///xDixYt8PT0JDQ0lMmTJ6eJZf78+VSrVg1PT09q1arFkiVLcuei84mUlBTGjBlDWFgYXl5eVKxYkddff91u6Qvd/5z1xx9/0LFjR0JCQjCZTPz44492+/PT/c5KLFliiNymtm3bGp9//rmxY8cOY9u2bcYDDzxglC1b1rhw4YKtzrPPPmuEhoYay5cvNzZt2mTcc889RtOmTW37k5OTjZo1axoRERHG1q1bjSVLlhgBAQHG6NGjbXUOHjxoeHt7G8OGDTN27dplvPvuu4bZbDYiIyNtdb777jvD3d3d+Oyzz4ydO3caTz/9tOHv72/ExMTkzc1wso0bNxrly5c3ateubbz44ou2ct3/3HX27FmjXLlyRu/evY0NGzYYBw8eNJYuXWrs37/fVufNN980/Pz8jB9//NH4+++/jYceesgICwszLl++bKvTrl07o06dOsb69euNP//806hUqZLRvXt32/7z588bQUFBRo8ePYwdO3YY3377reHl5WV89NFHtjpr1qwxzGazMXnyZGPXrl3Ga6+9Zri5uRnbt2/Pm5vhBG+88YZRokQJY9GiRcahQ4eM+fPnG0WLFjVmzJhhq6P7n7OWLFlivPrqq8bChQsNwPjhhx/s9uen+52VWLJCCZPkuFOnThmAsWrVKsMwDCMuLs5wc3Mz5s+fb6sTFRVlAMa6desMw7D+4XNxcTGio6NtdT744APD19fXSExMNAzDMEaOHGncdddddp/VtWtXo23btrb3jRo1MgYOHGh7n5KSYoSEhBiTJk3K+QvNZxISEozKlSsbv/32mxEeHm5LmHT/c9/LL79sNG/ePMP9FovFCA4ONqZMmWIri4uLMzw8PIxvv/3WMAzD2LVrlwEYf/31l63O//73P8NkMhnHjx83DMMwZs6caRQrVsz2naR+dtWqVW3vu3TpYnTo0MHu8xs3bmw888wzt3eR+ViHDh2Mvn372pV17tzZ6NGjh2EYuv+57eaEKT/d76zEklXqkpMcd/78eQCKFy8OwObNm7l69SoRERG2OtWqVaNs2bKsW7cOgHXr1lGrVi2CgoJsddq2bUt8fDw7d+601bnxHKl1Us+RlJTE5s2b7eq4uLgQERFhq1OQDRw4kA4dOqS5R7r/ue/nn3+mYcOGPP744wQGBlKvXj1mzZpl23/o0CGio6Pt7o2fnx+NGze2+w78/f1p2LChrU5ERAQuLi5s2LDBVqdly5a4u7vb6rRt25Y9e/Zw7tw5W53MvqeCqGnTpixfvpy9e/cC8Pfff7N69Wrat28P6P7ntfx0v7MSS1YpYZIcZbFYGDJkCM2aNaNmzZoAREdH4+7ujr+/v13doKAgoqOjbXVu/LFO3Z+6L7M68fHxXL58mTNnzpCSkpJundRzFFTfffcdW7ZsYdKkSWn26f7nvoMHD/LBBx9QuXJlli5dynPPPcfgwYOZM2cOcP0eZnZvoqOjCQwMtNvv6upK8eLFc+R7KsjfwahRo+jWrRvVqlXDzc2NevXqMWTIEHr06AHo/ue1/HS/sxJLVmnxXclRAwcOZMeOHaxevdrZoRQax44d48UXX+S3337D09PT2eEUShaLhYYNGzJx4kQA6tWrx44dO/jwww/p1auXk6Mr+ObNm8fXX3/NN998w1133cW2bdsYMmQIISEhuv+SY9TCJDlm0KBBLFq0iN9//50yZcrYyoODg0lKSiIuLs6ufkxMDMHBwbY6Nz+1lfreUR1fX1+8vLwICAjAbDanWyf1HAXR5s2bOXXqFPXr18fV1RVXV1dWrVrFO++8g6urK0FBQbr/uaxUqVLUqFHDrqx69eocPXoUuH4PM7s3wcHBnDp1ym5/cnIyZ8+ezZHvqSB/ByNGjLC1MtWqVYunnnqKoUOH2lpcdf/zVn6631mJJauUMMltMwyDQYMG8cMPP7BixQrCwsLs9jdo0AA3NzeWL19uK9uzZw9Hjx6lSZMmADRp0oTt27fb/QH67bff8PX1tf0QNWnSxO4cqXVSz+Hu7k6DBg3s6lgsFpYvX26rUxC1adOG7du3s23bNtvWsGFDevToYXut+5+7mjVrlmYqjb1791KuXDkAwsLCCA4Otrs38fHxbNiwwe47iIuLY/PmzbY6K1aswGKx0LhxY1udP/74g6tXr9rq/Pbbb1StWpVixYrZ6mT2PRVEly5dwsXF/ufMbDZjsVgA3f+8lp/ud1ZiybJbGiIuko7nnnvO8PPzM1auXGmcPHnStl26dMlW59lnnzXKli1rrFixwti0aZPRpEkTo0mTJrb9qY+133///ca2bduMyMhIo2TJkuk+1j5ixAgjKirKeP/999N9rN3Dw8OYPXu2sWvXLmPAgAGGv7+/3dNfhcGNT8kZhu5/btu4caPh6upqvPHGG8a+ffuMr7/+2vD29ja++uorW50333zT8Pf3N3766Sfjn3/+MTp16pTuY9b16tUzNmzYYKxevdqoXLmy3WPWcXFxRlBQkPHUU08ZO3bsML777jvD29s7zWPWrq6uxtSpU42oqChj3LhxBfKx9hv16tXLKF26tG1agYULFxoBAQHGyJEjbXV0/3NWQkKCsXXrVmPr1q0GYEybNs3YunWrceTIEcMw8tf9zkosWaGESW4bkO72+eef2+pcvnzZeP75541ixYoZ3t7exiOPPGKcPHnS7jyHDx822rdvb3h5eRkBAQHG8OHDjatXr9rV+f333426desa7u7uRoUKFew+I9W7775rlC1b1nB3dzcaNWpkrF+/PjcuO1+7OWHS/c99v/zyi1GzZk3Dw8PDqFatmvHxxx/b7bdYLMaYMWOMoKAgw8PDw2jTpo2xZ88euzqxsbFG9+7djaJFixq+vr5Gnz59jISEBLs6f//9t9G8eXPDw8PDKF26tPHmm2+miWXevHlGlSpVDHd3d+Ouu+4yFi9enPMXnI/Ex8cbL774olG2bFnD09PTqFChgvHqq6/aPY6u+5+zfv/993T/3u/Vq5dhGPnrfmcllqwwGcYNU6GKiIiISBoawyQiIiLigBImEREREQeUMImIiIg4oIRJRERExAElTCIiIiIOKGESERERcUAJk4iIiIgDSphEREREHFDCJCKFTqtWrRgyZMgdd24RcR5XZwcgIlKQLFy4EDc3N2eHISI5TAmTiEgOKl68uLNDEJFcoC45EclTH3/8MSEhIVgsFrvyTp060bdvXwA++OADKlasiLu7O1WrVuXLL7+0qxsXF8czzzxDUFAQnp6e1KxZk0WLFgEQGxtL9+7dKV26NN7e3tSqVYtvv/02TRzJyckMGjQIPz8/AgICGDNmDFldWnPmzJlUrlwZT09PgoKCeOyxx2z7buySW7lyJSaTKc3Wu3dvW/2ffvqJ+vXr4+npSYUKFZgwYQLJyclZikNE8o5amEQkTz3++OO88MIL/P7777Rp0waAs2fPEhkZyZIlS/jhhx948cUXmT59OhERESxatIg+ffpQpkwZWrdujcVioX379iQkJPDVV19RsWJFdu3ahdlsBuDKlSs0aNCAl19+GV9fXxYvXsxTTz1FxYoVadSokS2OOXPm0K9fPzZu3MimTZsYMGAAZcuW5emnn840/k2bNjF48GC+/PJLmjZtytmzZ/nzzz/Trdu0aVNOnjxpex8VFcUDDzxAy5YtAfjzzz/p2bMn77zzDi1atODAgQMMGDAAgHHjxmX/JotIzjNERPJYp06djL59+9ref/TRR0ZISIiRkpJiNG3a1Hj66aft6j/++OPGAw88YBiGYSxdutRwcXEx9uzZk+XP69ChgzF8+HDb+/DwcKN69eqGxWKxlb388stG9erVHZ7r+++/N3x9fY34+Ph094eHhxsvvvhimvIzZ84YFSpUMJ5//nlbWZs2bYyJEyfa1fvyyy+NUqVKOYxDRPKWuuREJM/16NGD77//nsTERAC+/vprunXrhouLC1FRUTRr1syufrNmzYiKigJg27ZtlClThipVqqR77pSUFF5//XVq1apF8eLFKVq0KEuXLuXo0aN29e655x5MJpPtfZMmTdi3bx8pKSmZxn7fffdRrlw5KlSowFNPPcXXX3/NpUuXMj3m6tWrPProo5QrV44ZM2bYyv/++2/+7//+j6JFi9q2p59+mpMnTzo8p4jkLSVMIpLnOnbsiGEYLF68mGPHjvHnn3/So0ePLB3r5eWV6f4pU6YwY8YMXn75ZX7//Xe2bdtG27ZtSUpKyonQ8fHxYcuWLXz77beUKlWKsWPHUqdOHeLi4jI85rnnnuPYsWPMnz8fV9frIyEuXLjAhAkT2LZtm23bvn07+/btw9PTM0fiFZGcoTFMIpLnPD096dy5M19//TX79++natWq1K9fH4Dq1auzZs0aevXqZau/Zs0aatSoAUDt2rX5999/2bt3b7qtTGvWrKFTp048+eSTAFgsFvbu3Ws7PtWGDRvs3q9fv57KlSvbxkJlxtXVlYiICCIiIhg3bhz+/v6sWLGCzp07p6k7bdo05s2bx9q1aylRooTdvvr167Nnzx4qVark8DNFxLmUMImIU/To0YMHH3yQnTt32pIbgBEjRtClSxfq1atHREQEv/zyCwsXLmTZsmUAhIeH07JlSx599FGmTZtGpUqV2L17NyaTiXbt2lG5cmUWLFjA2rVrKVasGNOmTSMmJiZNwnT06FGGDRvGM888w5YtW3j33Xd5++23Hca9aNEiDh48SMuWLSlWrBhLlizBYrFQtWrVNHWXLVvGyJEjef/99wkICCA6OhqwtpL5+fkxduxYHnzwQcqWLctjjz2Gi4sLf//9Nzt27OA///nP7dxeEclpzh5EJSKFU0pKilGqVCkDMA4cOGC3b+bMmUaFChUMNzc3o0qVKsYXX3xhtz82Ntbo06ePUaJECcPT09OoWbOmsWjRItu+Tp06GUWLFjUCAwON1157zejZs6fRqVMn2/Hh4eHG888/bzz77LOGr6+vUaxYMeOVV16xGwSekT///NMIDw83ihUrZnh5eRm1a9c25s6da3fu1EHf48aNM4A0W69evWz1IyMjjaZNmxpeXl6Gr6+v0ahRI+Pjjz++xbspIrnNZBhZnHhEREREpJDSoG8RERERB5QwiYjc4M8//7R7zP/mTUQKJ3XJiYjc4PLlyxw/fjzD/XqiTaRwUsIkIiIi4oC65EREREQcUMIkIiIi4oASJhEREREHlDCJiIiIOKCESURERMQBJUwiIiIiDihhEhEREXFACZOIiIiIA/8Pzdm+shQ9njsAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cos_means = [r[\"test_cosine\"][0] for r in wp]\n", + "cos_stds = [r[\"test_cosine\"][1] for r in wp]\n", + "\n", + "fig, ax = plt.subplots(figsize=(6, 4.5))\n", + "ax.errorbar(vocab_sizes, cos_means, yerr=cos_stds, marker=\"o\", capsize=3, color=\"tab:orange\", label=\"wordpiece\")\n", + "ax.axhline(char_row[\"test_cosine\"][0], color=\"gray\", linestyle=\"--\", label=\"char\")\n", + "ax.axhspan(char_row[\"test_cosine\"][0] - char_row[\"test_cosine\"][1],\n", + " char_row[\"test_cosine\"][0] + char_row[\"test_cosine\"][1], color=\"gray\", alpha=0.15)\n", + "ax.set_xlabel(\"vocab_size\")\n", + "ax.set_ylabel(\"test_cosine\")\n", + "ax.set_title(\"test_cosine vs vocab_size\")\n", + "ax.legend()\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "7a623e51", + "metadata": {}, + "source": [ + "*Notes: higher `test_cosine` is better.*" + ] + }, + { + "cell_type": "markdown", + "id": "82b9a86a", + "metadata": {}, + "source": [ + "## 3. Per-seed spread of test_loss" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a718abe6", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:34.623103Z", + "iopub.status.busy": "2026-07-30T17:10:34.622904Z", + "iopub.status.idle": "2026-07-30T17:10:34.858709Z", + "shell.execute_reply": "2026-07-30T17:10:34.857746Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAG4CAYAAABYaIRGAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAU25JREFUeJzt3XlYlXX+//HXOQiHRVYRDhgqamm4UToQU6YlCY1jOk5XaovmZE1W88uhcnSaXLIGs6Zs1bJcyu+MNWU1bbQw2uKgTC6paZSGW7EoxGqCcT6/PxxPnQBZ5HAAn4/rOtflue/3/Tnvm08QL+7NYowxAgAAAAAALc7q6QYAAAAAAOioCN0AAAAAALgJoRsAAAAAADchdAMAAAAA4CaEbgAAAAAA3ITQDQAAAACAmxC6AQAAAABwE0I3AAAAAABuQugGAAAAAMBNCN0AAMBpxIgRGjFihKfbOG3z5s2TxWLxdBsAABC6AQBYuXKlLBaL8+Xr66tzzjlHt912mwoKCjzdXpv017/+Va+99ppbP+M///mP5s2bp5KSErd+DgAA7kToBgDgf+6991698MILeuKJJ/TLX/5SS5YsUVJSko4ePerp1tqc1grd8+fPJ3QDANq1Tp5uAACAtuLyyy/X0KFDJUnTpk1Tly5d9PDDD+v111/XpEmTTmvso0ePyt/fvyXaBAAA7QhHugEAqMell14qScrNzXUuW716tYYMGSI/Pz+FhYVp4sSJOnjwoMt2I0aM0IABA7R582ZdfPHF8vf315///Od6P+f999/XRRddpJCQEHXu3Fl9+/atVV9VVaW5c+eqT58+stlsiomJ0cyZM1VVVVVrvMb0KEnPPPOMevfuLT8/PyUkJOjjjz9u1NfFYrGosrJSq1atcp6Sf/311zvXf/PNN/rd736nyMhI2Ww29e/fX8uXL681zuOPP67+/fvL399foaGhGjp0qP7+979LOnFN9l133SVJio2NdX7Ovn37GtVjXX744QctWLBAvXv3ls1mU8+ePfXnP/+51tfw008/VUpKisLDw+Xn56fY2Fj97ne/c6lZs2aNhgwZosDAQAUFBWngwIF69NFHm90bAKDj4kg3AAD12Lt3rySpS5cukqT7779f99xzj6666ipNmzZNhw8f1uOPP66LL75YW7duVUhIiHPboqIiXX755Zo4caKuvfZaRUZG1vkZn3/+uX79619r0KBBuvfee2Wz2bRnzx5t2LDBWeNwOHTFFVfok08+0U033aRzzz1XO3bs0COPPKIvv/zS5TTvxvb43HPP6fe//71++ctfasaMGfr66691xRVXKCwsTDExMaf8urzwwguaNm2aEhISdNNNN0mSevfuLUkqKCjQBRdcIIvFottuu01du3bVO++8oxtuuEFlZWWaMWOGJGnZsmX6f//v/+nKK6/U7bffrmPHjmn79u3atGmTrr76ao0fP15ffvml/vGPf+iRRx5ReHi4JKlr166Nm7w6TJs2TatWrdKVV16pO+64Q5s2bVJ6erp2796tV199VZJUWFioUaNGqWvXrpo1a5ZCQkK0b98+rV271jnO+++/r0mTJmnkyJF64IEHJEm7d+/Whg0bdPvttze7PwBAB2UAADjDrVixwkgyH3zwgTl8+LA5ePCgWbNmjenSpYvx8/Mzhw4dMvv27TNeXl7m/vvvd9l2x44dplOnTi7Lhw8fbiSZpUuXNvjZjzzyiJFkDh8+XG/NCy+8YKxWq/n4449dli9dutRIMhs2bDDGmEb3WF1dbSIiIkx8fLypqqpy1j3zzDNGkhk+fHiDfQcEBJgpU6bUWn7DDTeYqKgoc+TIEZflEydONMHBwebo0aPGGGPGjh1r+vfvf8rPePDBB40kk5ub22A/Pzd37lzz019ztm3bZiSZadOmudTdeeedRpL597//bYwx5tVXXzWSzH//+996x7799ttNUFCQ+eGHH5rcFwDgzMPp5QAA/E9ycrK6du2qmJgYTZw4UZ07d9arr76qbt26ae3atXI4HLrqqqt05MgR58tut+vss8/WunXrXMay2WyaOnVqg5958sjz66+/LofDUWfNP//5T5177rnq16+fy2efPP395Gc3tsdPP/1UhYWFuvnmm+Xj4+P8nOuvv17BwcFN/rqdZIzRK6+8ojFjxsgY49JDSkqKSktLtWXLFud+Hzp0SP/973+b/XlN8fbbb0uS0tLSXJbfcccdkqS33nrL2Zckvfnmmzp+/HidY4WEhKiyslLvv/++m7oFAHQknF4OAMD/PPnkkzrnnHPUqVMnRUZGqm/fvrJaT/x9+quvvpIxRmeffXad23p7e7u879atm0ugLS0t1ffff+987+Pjo7CwME2YMEHPPvuspk2bplmzZmnkyJEaP368rrzySpfP3r17d72nVhcWFjapx/3790tSrTpvb2/16tWr7i9OIxw+fFglJSV65pln9Mwzz5yy1z/96U/64IMPlJCQoD59+mjUqFG6+uqrdeGFFzb7809l//79slqt6tOnj8tyu92ukJAQ59dk+PDh+u1vf6v58+frkUce0YgRIzRu3DhdffXVstlskqRbbrlFL730ki6//HJ169ZNo0aN0lVXXaXU1FS39A4AaN8I3QAA/E9CQoLz7uU/53A4ZLFY9M4778jLy6vW+s6dO7u89/Pzc3l/++23a9WqVc73w4cP1/r16+Xn56ePPvpI69at01tvvaWMjAy9+OKLuvTSS/Xee+/Jy8tLDodDAwcO1MMPP1xnbyevwW5qjy3t5JH6a6+9VlOmTKmzZtCgQZKkc889Vzk5OXrzzTeVkZGhV155RU899ZTmzJmj+fPnu61Hi8XS4PqXX35ZGzdu1BtvvKF3331Xv/vd7/S3v/1NGzduVOfOnRUREaFt27bp3Xff1TvvvKN33nlHK1as0OTJk13mGAAAidANAECj9O7dW8YYxcbG6pxzzmny9jNnztS1117rfB8aGur8t9Vq1ciRIzVy5Eg9/PDD+utf/6q7775b69atU3Jysnr37q3PPvtMI0eOPGVobGyPPXr0kHTiyPjJU9Ql6fjx48rNzdXgwYMb3J+6+ujatasCAwNVU1Oj5OTkBscICAjQhAkTNGHCBFVXV2v8+PG6//77NXv2bPn6+jYYkJuiR48ecjgc+uqrr3Tuuec6lxcUFKikpMT5NTnpggsu0AUXXKD7779ff//733XNNddozZo1mjZtmqQTZyqMGTNGY8aMkcPh0C233KKnn35a99xzT62j6QCAMxvXdAMA0Ajjx4+Xl5eX5s+fL2OMyzpjjIqKik65fVxcnJKTk52vIUOGSJKKi4tr1cbHx0uS81FWV111lb755hstW7asVu3333+vysrKJvU4dOhQde3aVUuXLlV1dbWzZuXKlSopKTnlfpwUEBBQq9bLy0u//e1v9corr2jnzp21tjl8+LDz3z//evn4+CguLk7GGOe11AEBAZLU6J5O5Ve/+pUkafHixS7LT549MHr0aEnSd999V+tr9/P5+HnvVqvVeQS/rke4AQDObBzpBgCgEXr37q377rtPs2fP1r59+zRu3DgFBgYqNzdXr776qm666SbdeeedTR733nvv1UcffaTRo0erR48eKiws1FNPPaWzzjpLF110kSTpuuuu00svvaSbb75Z69at04UXXqiamhp98cUXeumll/Tuu+9q6NChje7R29tb9913n37/+9/r0ksv1YQJE5Sbm6sVK1Y0+pruIUOG6IMPPtDDDz+s6OhoxcbGKjExUQsXLtS6deuUmJioG2+8UXFxcSouLtaWLVv0wQcfOP/IMGrUKNntdl144YWKjIzU7t279cQTT2j06NEKDAx0foYk3X333Zo4caK8vb01ZswYZxhvisGDB2vKlCl65plnVFJSouHDhys7O1urVq3SuHHjdMkll0iSVq1apaeeekq/+c1v1Lt3b5WXl2vZsmUKCgpyBvdp06apuLhYl156qc466yzt379fjz/+uOLj412OogMAIIlHhgEAcPKRYad6TNRJr7zyirnoootMQECACQgIMP369TO33nqrycnJcdYMHz68wcdhnZSZmWnGjh1roqOjjY+Pj4mOjjaTJk0yX375pUtddXW1eeCBB0z//v2NzWYzoaGhZsiQIWb+/PmmtLS0yT0aY8xTTz1lYmNjjc1mM0OHDjUfffSRGT58eKMeGfbFF1+Yiy++2Pj5+RlJLo8PKygoMLfeequJiYkx3t7exm63m5EjR5pnnnnGWfP000+biy++2HTp0sXYbDbTu3dvc9ddd9XalwULFphu3boZq9XapMeH/fyRYcYYc/z4cTN//nwTGxtrvL29TUxMjJk9e7Y5duyYs2bLli1m0qRJpnv37sZms5mIiAjz61//2nz66afOmpdfftmMGjXKREREGB8fH9O9e3fz+9//3uTl5TWqNwDAmcVizM/OoQIAAAAAAC2Ca7oBAAAAAHATrukGAADtxs+fd14Xu93eSt0AANAwTi8HAADtxvXXX9/gs7D51QYA0JYQugEAQLuxa9cuffvtt6esacwzwgEAaC2EbgAAAAAA3IQbqQEAAAAA4CbcSK0ODodD3377rQIDA2WxWDzdDgAAAACgDTHGqLy8XNHR0bJaT30sm9Bdh2+//VYxMTGebgMAAAAA0IYdPHhQZ5111ilrCN11CAwMlHTiCxgUFOThbgAAAAAAbUlZWZliYmKc2fFUCN11OHlKeVBQEKEbAAAAAFCnxlyOzI3UAAAAAABwE0I3AAAAAABuQugGAAAAAMBNCN0AAAAAALgJ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OHDggEaPHi1/f39FRETorrvu0g8//OBSs379ep1//vmy2Wzq06ePVq5c2Rq7d8b46KOPNGbMGEVHR8tisei1115zWW+M0Zw5cxQVFSU/Pz8lJyfrq6++cqkpLi7WNddco6CgIIWEhOiGG25QRUWFS8327ds1bNgw+fr6KiYmRosWLarVyz//+U/169dPvr6+GjhwoN5+++0W398zRXp6un7xi18oMDBQERERGjdunHJyclxqWvN79Mknn1TPnj3l6+urxMREZWdnt/g+nwmWLFmiQYMGKSgoSEFBQUpKStI777zjXM+cdgwLFy6UxWLRjBkznMuY2/anLf2exJw2X3v6PakxvbjdaT90DICLuXPnmv79+5u8vDzn6/Dhw871N998s4mJiTGZmZnm008/NRdccIH55S9/6Vz/ww8/mAEDBpjk5GSzdetW8/bbb5vw8HAze/ZsZ83XX39t/P39TVpamtm1a5d5/PHHjZeXl8nIyGjVfe3I3n77bXP33XebtWvXGknm1VdfdVm/cOFCExwcbF577TXz2WefmSuuuMLExsaa77//3lmTmppqBg8ebDZu3Gg+/vhj06dPHzNp0iTn+tLSUhMZGWmuueYas3PnTvOPf/zD+Pn5maefftpZs2HDBuPl5WUWLVpkdu3aZf7yl78Yb29vs2PHDrd/DTqilJQUs2LFCrNz506zbds286tf/cp0797dVFRUOGta63t0zZo1xsfHxyxfvtx8/vnn5sYbbzQhISGmoKCgdb4YHci//vUv89Zbb5kvv/zS5OTkmD//+c/G29vb7Ny50xjDnHYE2dnZpmfPnmbQoEHm9ttvdy5nbtuftvJ7EnN6etrT70mN6cXdCN1AC5s7d64ZPHhwnetKSkqMt7e3+ec//+lctnv3biPJZGVlGWNO/BCzWq0mPz/fWbNkyRITFBRkqqqqjDHGzJw50/Tv399l7AkTJpiUlJQW3hsYY2r9z8ThcBi73W4efPBB57KSkhJjs9nMP/7xD2OMMbt27TKSzH//+19nzTvvvGMsFov55ptvjDHGPPXUUyY0NNQ5r8YY86c//cn07dvX+f6qq64yo0ePduknMTHR/P73v2/RfTxTFRYWGknmww8/NMa07vdoQkKCufXWW53va2pqTHR0tElPT2/5HT0DhYaGmmeffZY57QDKy8vN2Wefbd5//30zfPhwZ+hmbtuntvJ7EnPactry70mN6aU1cHo54AZfffWVoqOj1atXL11zzTU6cOCAJGnz5s06fvy4kpOTnbX9+vVT9+7dlZWVJUnKysrSwIEDFRkZ6axJSUlRWVmZPv/8c2fNT8c4WXNyDLhXbm6u8vPzXeYgODhYiYmJLvMYEhKioUOHOmuSk5NltVq1adMmZ83FF18sHx8fZ01KSopycnL03XffOWuYa/cpLS2VJIWFhUlqve/R6upqbd682aXGarUqOTmZuT1NNTU1WrNmjSorK5WUlMScdgC33nqrRo8eXevrz9y2X57+PYk5da+29HtSY3ppDYRuoIUlJiZq5cqVysjI0JIlS5Sbm6thw4apvLxc+fn58vHxUUhIiMs2kZGRys/PlyTl5+e7/I/k5PqT605VU1ZWpu+//95Ne4aTTs5DXXPw0zmKiIhwWd+pUyeFhYW1yFyfXI/mczgcmjFjhi688EINGDBAklrte/TIkSOqqalhblvQjh071LlzZ9lsNt1888169dVXFRcXx5y2c2vWrNGWLVuUnp5eax1z2z61hd+TmFP3aku/JzWml9bQqdU+CThDXH755c5/Dxo0SImJierRo4deeukl+fn5ebAzAD916623aufOnfrkk0883QpaQN++fbVt2zaVlpbq5Zdf1pQpU/Thhx96ui2choMHD+r222/X+++/L19fX0+3gxbC70k4E3GkG3CzkJAQnXPOOdqzZ4/sdruqq6tVUlLiUlNQUCC73S5Jstvtte7SefJ9QzVBQUH8D6sVnJyHuubgp3NUWFjosv6HH35QcXFxi8z1yfVonttuu01vvvmm1q1bp7POOsu5vLW+R8PDw+Xl5cXctiAfHx/16dNHQ4YMUXp6ugYPHqxHH32UOW3HNm/erMLCQp1//vnq1KmTOnXqpA8//FCPPfaYOnXqpMjISOa2A/DE70nMqXu1pd+TGtNLayB0A25WUVGhvXv3KioqSkOGDJG3t7cyMzOd63NycnTgwAElJSVJkpKSkrRjxw6XH0Tvv/++goKCFBcX56z56Rgna06OAfeKjY2V3W53mYOysjJt2rTJZR5LSkq0efNmZ82///1vORwOJSYmOms++ugjHT9+3Fnz/vvvq2/fvgoNDXXWMNctxxij2267Ta+++qr+/e9/KzY21mV9a32P+vj4aMiQIS41DodDmZmZzG0LcTgcqqqqYk7bsZEjR2rHjh3atm2b8zV06FBdc801zn8zt+2fJ35PYk7dqy39ntSYXlpFq92yDThD3HHHHWb9+vUmNzfXbNiwwSQnJ5vw8HBTWFhojDnxKIzu3bubf//73+bTTz81SUlJJikpybn9yUdhjBo1ymzbts1kZGSYrl271vkojLvuusvs3r3bPPnkkzwyrIWVl5ebrVu3mq1btxpJ5uGHHzZbt241+/fvN8acePxESEiIef3118327dvN2LFj63wUxnnnnWc2bdpkPvnkE3P22We7PAqjpKTEREZGmuuuu87s3LnTrFmzxvj7+9d6FEanTp3MQw89ZHbv3m3mzp3LI8NOw/Tp001wcLBZv369y+Nqjh496qxpre/RNWvWGJvNZlauXGl27dplbrrpJhMSEuJyR140zqxZs8yHH35ocnNzzfbt282sWbOMxWIx7733njGGOe1Ifnr3cmOY2/aorfyexJyenvb0e1JjenE3QjfQwiZMmGCioqKMj4+P6datm5kwYYLZs2ePc/33339vbrnlFhMaGmr8/f3Nb37zG5OXl+cyxr59+8zll19u/Pz8THh4uLnjjjvM8ePHXWrWrVtn4uPjjY+Pj+nVq5dZsWJFa+zeGWPdunVGUq3XlClTjDEnHkFxzz33mMjISGOz2czIkSNNTk6OyxhFRUVm0qRJpnPnziYoKMhMnTrVlJeXu9R89tln5qKLLjI2m81069bNLFy4sFYvL730kjnnnHOMj4+P6d+/v3nrrbfctt8dXV1zKsnl+6c1v0cff/xx0717d+Pj42MSEhLMxo0b3bHbHd7vfvc706NHD+Pj42O6du1qRo4c6QzcxjCnHcnPQzdz2/60pd+TmNPma0+/JzWmF3ezGGNM6x1XBwAAAADgzME13QAAAAAAuAmhGwAAAAAANyF0AwAAAADgJoRuAAAAAADchNANAAAAAICbELoBAAAAAHATQjcAAAAAAG5C6AYAAAAAwE0I3QAAAAAAuAmhGwAAAAAANyF0AwAAAADgJoRuAAAAAADc5P8DGLlhQ7PVIlUAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 4.5))\n", + "configs = sorted(raw[[\"tokenizer\", \"vocab_size\"]].drop_duplicates().itertuples(index=False),\n", + " key=lambda c: (c.tokenizer, c.vocab_size))\n", + "labels = [f\"{c.tokenizer}\\n{c.vocab_size}\" if c.tokenizer == \"wordpiece\" else \"char\" for c in configs]\n", + "\n", + "for i, c in enumerate(configs):\n", + " subset = raw[(raw[\"tokenizer\"] == c.tokenizer) & (raw[\"vocab_size\"] == c.vocab_size)]\n", + " ax.scatter([i] * len(subset), subset[\"test_loss\"], color=\"tab:blue\", zorder=3)\n", + " ax.scatter([i], [subset[\"test_loss\"].mean()], color=\"black\", marker=\"_\", s=400, zorder=4)\n", + "\n", + "ax.set_xticks(range(len(configs)))\n", + "ax.set_xticklabels(labels)\n", + "ax.set_ylabel(\"test_loss\")\n", + "ax.set_title(\"Per-seed test_loss\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "b8ec57a6", + "metadata": {}, + "source": [ + "*Notes: each blue dot is one seed's `test_loss`; the black dash is the mean shown in the\n", + "summary table. Useful for checking whether a mean is being pulled around by a single\n", + "unusually good/bad seed rather than reflecting all three consistently.*" + ] + }, + { + "cell_type": "markdown", + "id": "3d8a58f7", + "metadata": {}, + "source": [ + "## 4. best_val_loss vs test_loss, by vocab_size" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "70921265", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:34.860502Z", + "iopub.status.busy": "2026-07-30T17:10:34.860340Z", + "iopub.status.idle": "2026-07-30T17:10:34.985922Z", + "shell.execute_reply": "2026-07-30T17:10:34.984808Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAArAAAAG4CAYAAAC9/9RGAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAlM9JREFUeJzs3Xd4FFXbx/HvbnqvpFFD6EgzFAHpJSgi2KjSFFERBRELr9JExS4IKD6oFEUBwc4jiDwEkd5FOpEOCTUV0nbn/SNkYUkCAQJL4Pe5rr1gZ86cuWfL7J0zZ84xGYZhICIiIiJSTJgdHYCIiIiIyJVQAisiIiIixYoSWBEREREpVpTAioiIiEixogRWRERERIoVJbAiIiIiUqwogRURERGRYkUJrIiIiIgUK0pgRURERKRYUQIrco1GjRqFyWTixIkTjg7FYUwmE6NGjbru28j1FRsbi8lkIjY21tGh2ClXrhz33Xefo8NwKJPJxMCBA2/Ivm7Wz4HIhZTAihRTb731Fj/++KOjw5Ar8M033zBu3Ljruo8jR44watQoNm3adF33IyLiSEpgRYopJbDFz41KYEePHq0EVq5a06ZNOXv2LE2bNnV0KCIFcnZ0ACIiInLzMJvNuLu7OzoMkUtSC6xIETlx4gSdO3fG19eXoKAgBg0aRHp6ep5yX3/9NdHR0Xh4eBAYGEjXrl05ePCgXZndu3fz0EMPERYWhru7O6VKlaJr164kJSUBOf3h0tLSmD59OiaTCZPJRJ8+fS4bY1ZWFoGBgfTt2zfPuuTkZNzd3Rk6dCgAmZmZjBgxgujoaPz8/PDy8qJJkyYsWbLkKl6dwtm4cSP33HMPvr6+eHt706pVK1atWpXnGEaPHk3FihVxd3cnKCiIu+++m0WLFtnKxMfH07dvX0qVKoWbmxvh4eF07NiRffv2Fbjv999/H5PJxP79+/OsGzZsGK6urpw+fRq4/PuTn+bNmzN//nz2799ve8/KlStnW5+RkcHIkSOpUKECbm5ulC5dmpdeeomMjAy7ehYtWsTdd9+Nv78/3t7eVK5cmf/7v/8Dcvou1qtXD4C+ffva9jNt2rQC4yqM7777zvaZDQ4O5tFHH+Xw4cN2ZQrzmq9bt46YmBiCg4Px8PAgMjKSxx57rNBx/P7779SuXRt3d3eqVavG999/b1v377//YjKZ+Oijj/Jst2LFCkwmE99++22+9SYkJODs7Mzo0aPzrNu5cycmk4mJEyfa7euRRx4hMDAQT09P7rrrLubPn59n2/T0dEaNGkWlSpVwd3cnPDycBx98kLi4OFuZ999/n0aNGhEUFISHhwfR0dHMnTu3wNdg5syZVK5cGXd3d6Kjo/nzzz8LLFuQWbNmER0djY+PD76+vtSoUYPx48fb1l/cB3batGm2z9LFj+bNm9vVXZjzm0hRUAusSBHp3Lkz5cqVY+zYsaxatYqPP/6Y06dPM2PGDFuZN998k+HDh9O5c2f69evH8ePHmTBhAk2bNmXjxo34+/uTmZlJTEwMGRkZPPvss4SFhXH48GF+/fVXEhMT8fPz46uvvqJfv37Ur1+f/v37AxAVFXXZGF1cXHjggQf4/vvv+eyzz3B1dbWt+/HHH8nIyKBr165ATkL7+eef061bN5544glSUlL44osviImJYc2aNdSuXbtIX7+tW7fSpEkTfH19eemll3BxceGzzz6jefPmLF26lAYNGgA5N82NHTvWdvzJycmsW7eODRs20KZNGwAeeughtm7dyrPPPku5cuU4duwYixYt4sCBA3ZJ44U6d+7MSy+9xJw5c3jxxRft1s2ZM4e2bdsSEBBQqPcnP6+++ipJSUkcOnTIlmR5e3sDYLVauf/++/nrr7/o378/VatWZcuWLXz00Ufs2rXL1lVk69at3HfffdSsWZPXX38dNzc39uzZw/LlywGoWrUqr7/+OiNGjKB///40adIEgEaNGl31+zJt2jT69u1LvXr1GDt2LAkJCYwfP57ly5fbPrOFec2PHTtG27ZtKVGiBK+88gr+/v7s27fPLgm9lN27d9OlSxeeeuopevfuzdSpU3nkkUdYsGABbdq0oXz58jRu3JiZM2fy/PPP2207c+ZMfHx86NixY751h4aG0qxZM+bMmcPIkSPt1s2ePRsnJyceeeQRICfZbdSoEWfOnOG5554jKCiI6dOnc//99zN37lweeOABACwWC/fddx+LFy+ma9euDBo0iJSUFBYtWsQ///xj+76OHz+e+++/nx49epCZmcmsWbN45JFH+PXXX2nfvr1dLEuXLmX27Nk899xzuLm58cknn9CuXTvWrFnDHXfcUajXcdGiRXTr1o1WrVrxzjvvALB9+3aWL1/OoEGD8t2madOmfPXVV3bL9u/fz2uvvUZI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QteuXcnMzGTevHl2o5fkKuz5TaSoaBgtkSKyd+9e7r//ftq1a8fKlSv5+uuv6d69u+2yfFRUFG+88QbDhg1j3759dOrUCR8fH/bu3csPP/xA//79GTp0KP/73/8YOHAgjzzyCJUqVSI7O5uvvvoKJycnHnroIdv+oqOj+eOPP/jwww+JiIggMjLSNtRUYXTp0oUJEyYwcuRIatSoYevDl+u+++7j+++/54EHHqB9+/bs3buXyZMnU61atSK95JvrjTfesI1xOmDAAJydnfnss8/IyMjg3XfftZWrVq0azZs3Jzo6msDAQNatW8fcuXNt88Tv2rWLVq1a0blzZ6pVq4azszM//PADCQkJtiHCLiUkJIQWLVrw4YcfkpKSkiexL+z7k5/o6Ghmz57NkCFDqFevHt7e3nTo0IGePXsyZ84cnnrqKZYsWULjxo2xWCzs2LGDOXPmsHDhQurWrcvrr7/On3/+Sfv27SlbtizHjh3jk08+oVSpUrabiqKiovD392fy5Mn4+Pjg5eVFgwYNiIyMvNK3BBcXF9555x369u1Ls2bN6Natm20YrXLlytmGqyrMaz59+nQ++eQTHnjgAaKiokhJSWHKlCn4+vpy7733XjaWSpUq8fjjj7N27VpCQ0P58ssvSUhIYOrUqXnK9urVi48//pglS5bYhooqrC5duvDoo4/yySefEBMTk2fop1deeYVvv/2We+65h+eee47AwECmT5/O3r17mTdvnq2rQq9evZgxYwZDhgxhzZo1NGnShLS0NP744w8GDBhAx44dad++PR9++CHt2rWje/fuHDt2jEmTJlGhQgW7ft257rjjDmJiYuyG0QLyHb+2IP369ePUqVO0bNmSUqVKsX//fiZMmEDt2rXznANyTZ48mf/973+2z+eFQkNDadOmTaHPbyJFxoGtvyK3hNwuBNu2bTMefvhhw8fHxwgICDAGDhxoN/RQrnnz5hl333234eXlZXh5eRlVqlQxnnnmGdult3///dd47LHHjKioKMPd3d0IDAw0WrRoYfzxxx929ezYscNo2rSp4eHhYQBX3J3AarUapUuXNgDjjTfeyHf9W2+9ZZQtW9Zwc3Mz6tSpY/z6669G7969i7wLQa4NGzYYMTExhre3t+Hp6Wm0aNHCWLFihV2ZN954w6hfv77h7+9veHh4GFWqVDHefPNN26XaEydO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adMmTCYTr7zyiq1Mv379ePTRR23P582bR/Xq1XFzc6NcuXJ88MEHdnWWK1eOMWPG0KtXL3x9fenfvz+Q02WgTJkyeHp68sADD3Dy5Em77UaNGkXt2rX57LPPKF26NJ6ennTu3JmkpCRbmYu7EFitVsaOHUtkZCQeHh7UqlWLuXPn2tW7detW7rvvPnx9ffHx8aFJkybExcXZ1n/++edUrVoVd3d3qlSpwieffFLg69WnTx+WLl3K+PHjMZlMmEwm9u3bB8A///zDPffcg7e3N6GhofTs2ZMTJ07Ytp07dy41atTAw8ODoKAgWrduTVpaGqNGjWL69On89NNPtjpjY2MLjKEgS5cupX79+ri5uREeHs4rr7xCdnb2ZfcPEBsbS/369fHy8sLf35/GjRuzf//+K46hsJRlyJXLziDrx+fg54E4WTNZZLmTMRGT+HjwozSvHOLo6EREbh2GAZlphXukJ+dM101+l8fPLVvwck65y9V1BZfYmzRpQkpKChs3bgRykqDg4GC7BGrp0qU0b94cgPXr19O5c2e6du3Kli1bGDVqFMOHD2fatGl29b7//vvUqlWLjRs3Mnz4cFavXs3jjz/OwIED2bRpEy1atOCNN97IE8+ePXuYM2cOv/zyCwsWLGDjxo0MGDCgwPjHjh3LjBkzmDx5Mlu3buX555/n0UcfZenSpQAcPnyYpk2b4ubmxv/+9z/Wr1/PY489ZkvsZs6cyYgRI3jzzTfZvn07b731FsOHD2f69On57m/8+PE0bNiQJ554gqNHj3L06FFKly5NYmIiLVu2pE6dOqxbt44FCxaQkJBA586dATh69CjdunXjscceY/v27cTGxvLggw9iGAZDhw6lc+fOtGvXzlZno0aNCvX+5Tp8+DD33nsv9erVY/PmzXz66ad88cUXttf4UvvPzs6mU6dONGvWjL///puVK1fSv3//6zvLpuFgEydONMqWLWu4ubkZ9evXN1avXl1g2Xnz5hnR0dGGn5+f4enpadSqVcuYMWOGXZnevXsb5HxTbY+YmJgriikpKckAjKSkpKs6plta4kHjzKSmhjHS17CM8DPef/Vx46PftxvZFqujIxMRKdbOnj1rbNu2zTh79uz5hRmphjHS98Y/MlKvKPY777zTeO+99wzDMIxOnToZb775puHq6mqkpKQYhw4dMgBj165dhmEYRvfu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dssHDRpEy5YtC72va3HgwAE6duyIt7c3vr6+dO7cmYSEBNv6zZs306JFC3x8fPD19SU6Opp169YBsH//fjp06EBAQABeXl5Ur16d//73v0UW263kqjKXpUuXsmrVKgIDA23LgoKCePvtt2ncuHGRBSdFIDsT84JXAFji14m2dRs6OCAREblSmZmZBa4zm804X9AQcamyJpMJFxeXS5a9mlbNYcOGMWXKFD766CPuvvtujh49yo4dO+zKvPrqq7z//vtUrFiRV199lW7durFnzx6cnZ1JT08nOjqal19+GV9fX+bPn0/Pnj2Jioqifv36tjqmT5/O008/zfLly/ONo1WrVvj7+zNv3jzbPToWi4XZs2fbEurC7utqWK1WW/K6dOlSsrOzeeaZZ+jSpQuxsbEA9OjRgzp16vDpp5/i5OTEpk2bbO/JM888Q2ZmJn/++SdeXl5s27YNb2/va4rpVnVVCaybmxspKSl5lqempqo5/ybz76/vUT77EMcNPyp2fsPR4YiIyFUYO3ZsgesqVqxI9+7dbc/ff/99srKy8i1btmxZ+vTpY3s+fvx427juuUaOHHlFsaWkpDB+/HgmTpxI794591JERUXZppvPNXToUNq3bw/A6NGjqV69Onv27KFKlSqULFmSoUOH2so+++yzLFy4kDlz5tgllRUrVuTdd98tMBYnJye6du3KN998Y0tgFy9eTGJiIg899BBAofd1NRYvXsyWLVvYu3cvpUvnTMs+Y8YMqlevztq1a6lXrx4HDhzgxRdfpEqVKrZjynXgwAEeeughatSoAUD58uWvKZ5b2VV1Ibjvvvvo378/q1evxjAMDMNg1apVPPXUU9x///1FHaNcpezEw4RtmgDAishniSwV4eCIRETkVrN9+3YyMjJo1arVJcvVrFnT9v/w8Jxpy48dOwbktJKOGTOGGjVqEBgYiLe3NwsXLuTAgQN2dURHR182nh49ehAbG8uRI0cAmDlzJu3bt8ff3/+K9nU1tm/fTunSpW3JK0C1atXw9/e33fQ+ZMgQ+vXrR+vWrXn77beJi4uzlX3uued44403aNy4MSNHjuTvv/++5phuVVfVAvvxxx/Tu3dvGjZsaGv2zsrKomPHjhpK4iZyYPaLlOcsf1OR5o+ob7KISHE1bNiwAteZzfZtURe2Ll7MZLKfT3zQoEHXFhjg4eFRqHIX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Z1f23XffNUaNGmUkJCRcddzJycmGm5ubMWXKlHzX79271wCMzz//3LZs69atBmBs3769wHrbt29vvPDCC7bnzZo1M+rUqXPZeHr37m107NjRbtlXX31lVK5c2bBarbZlGRkZhoeHh7Fw4ULj5MmTBmDExsbmW+fIkSONWrVqXXbfFwKMH374wTAMw/jPf/5jBAQE2L1/8+fPN8xmsxEfH3/Z/fv4+BjTpk27ov3frC71Ob+S/EstsMWIddVkPJL2cMLwZX/NQVSL8HV0SCIicpvbvn07GRkZtGrV6pLlatasaft/eHg4AMeOHQNyWojHjBlDjRo1CAwMxNvbm4ULF3LgwAG7OqKjo68qxs2bN7Nnzx58fHzw9vbG29ubwMBA0tPTiYuLIzAwkD59+hATE0OHDh0YP348R48evap95Wf79u3UqlULLy8v27LGjRtjtVrZuXPnZfc/ZMgQ+vXrR+vWrXn77beJi4srstiKK2dHByCFlJKAZclYzMDHdOfZe+o6OiIREblBhg0bBmB32bhx48bcddddmM32bVFDhw7NU7ZevXrceeedecoOGjQoT9kr5eHhUahyF+4j99K41WoF4L333mP8+PGMGzeOGjVq4OXlxeDBg/PcqHVhAnglUlNTiY6OZubMmXnWlShRAoCpU6fy3HPPsWDBAmbPns1rr73GokWLuOuuu65qn1fqUvsfNWoU3bt3Z/78+fz222+MHDmSWbNm8cADD9yQ2G5GaoEtJrJ/H4FLdhqbrOUJb96PEj4aNktE5Hbh6uqKq6ur3WyLTk5OuLq64uzsXKRlr1TFihXx8PBg8eLFV13H8uXL6dixI48++ii1atWifPny7Nq166rqcnV1xWKx2C2788472b17NyEhIVSoUMHu4efnZytXp04dhg0bxooVK7jjjjv45ptvCqzzSlStWpXNmzeTlpZmW7Z8+XLMZjOVK1e+7P4BKlWqxPPPP8/vv//Ogw8+yNSpU686nluBEtji4OAanLfMAuBTjyfpe3d5BwckIiKSw93dnZdffpmXXnqJGTNmEBcXx6pVq/jiiy8KXUfFihVZtGgRK1asYPv27Tz55JMkJCRcVTzlypXj77//ZufOnZw4cYKsrCx69OhBcHAwHTt2ZNmyZezdu5fY2Fiee+45Dh06xN69exk2bBgrV65k//79/P777+zevZuqVava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y+FTyd6u2t0RzqeP3snoX7axKqmabXm4nzsjO1RT8ioiIiJSACWwDtTujnDaVAtjzd5THEtJJ8THnfqRgTiZr21+YBEREZFbmRJYB3Mym2gYFeToMERERESKjWI3kYGIiIiI3N6UwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEixogRWRERERIoVJbAiIiIiUqwogRURERGRYkUJrIiIiIgUK0pgRURERKRYUQIrIiIiIsWKElgRERERKVaUwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEix4vAEdtKkSZQrVw53d3caNGjAmjVrCiw7ZcoUmjRpQkBAAAEBAbRu3TpP+T59+mAymewe7dq1u96HISIiIiI3iEMT2NmzZzNkyBBGjhzJhg0bqFWrFjExMRw7dizf8rGxsXTr1o0lS5awcuVKSpcuTdu2bTl8+LBduXbt2nH06FHb49tvv70RhyMiIiIiN4DJMAzDUTtv0KAB9erVY+LEiQBYrVZKly7Ns88+yyuvvHLZ7S0WCwEBAUycOJFevXoBOS2wiYmJ/Pjjj1cdV3JyMn5+fiQlJeHr63vV9YiIiIhI4VxJ/uWwFtjMzEzWr19P69atzwdjNtO6dWtWrlxZqDrOnDlDVlYWgYGBdstjY2MJCQmhcuXKPP3005w8ebJIYxcRERERx3F21I5PnDiBxWIhNDTUbnloaCg7duwoVB0vv/wyERERdklwu3btePDBB4mMjCQuLo7/+7//45577mHlypU4OTnlW09GRgYZGRm258nJyVdxRCIiIiJyIzgsgb1Wb7/9NrNmzSI2NhZ3d3fb8q5du9r+X6NGDWrWrElUVBSxsbG0atUq37rGjh3L6NGjr3vMIiIiInLtHNaFIDg4GCcnJxISEuyWJyQkEBYWdslt33//fd5++21+//13atasecmy5cuXJzg4mD179hRYZtiwYSQlJdkeBw8eLPyBiIiIiMgN5bAE1tXVlejoaBYvXmxbZrVaWbx4MQ0bNixwu3fffZcxY8awYMEC6tate9n9HDp0iJMnTxIeHl5gGTc3N3x9fe0eIiIiInJzcugwWkOGDGHKlClMnz6d7du38/TTT5OWlkbfvn0B6NWrF8OGDbOVf+eddxg+fDhffvkl5cqVIz4+nvj4eFJTUwFITU3lxRdfZNWqVezbt4/FixfTsWNHKlSoQExMjEOOUURERESKlkP7wHbp0oXjx48zYsQI4uPjqV27NgsWLLDd2HXgwAHM5vM59qeffkpmZiYPP/ywXT0jR45k1KhRODk58ffffzN9+nQSExOJiIigbdu2jBkzBjc3txt6bCIiIiJyfTh0HNiblcaBFREREbmxisU4sCIiIiIiV0MJrIiIiIgUK0pgRURERKRYUQIrIiIiIsWKElgRERERKVaUwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEixogRWRERERIoVJbAiIiIiUqwogRURERGRYkUJrIiIiIgUK0pgRURERKRYUQIrIiIiIsWKElgRERERKVaUwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEix4vAEdtKkSZQrVw53d3caNGjAmjVrCiw7ZcoUmjRpQkBAAAEBAbRu3TpPecMwGDFiBOHh4Xh4eNC6dWt27959VbFlZmZiGIbtucViITMzk+zs7DzlrkfZrKwsMjMzsVqttmVWq5XMzEyysrJuurLZ2dlkZmZisViuqqxhGLbX53qVze91v5Kyjnzvb+XPyY1476+krCPfe50jCi6rc8R5Okc4tqzOEdfvvS8s50KXvA5mz57NkCFDmDx5Mg0aNGDcuHHExMSwc+dOQkJC8pSPjY2lW7duNGrUCHd3d9555x3atm3L1q1bKVmyJADvvvsuH3/8MdOnTycyMpLhw4cTExPDtm3bcHd3v6L4PvjgA15++WU8PT0BWL58OX/++Se1a9emY8eOtnLvv/8+WVlZPP300/j7+wOwZs0aFi9eTPXq1Xn44YdtZceNG8fZs2fp168fJUqUAGDTpk389ttvVKpUiW7dutnKTpo0iaSkJHr37k1ERAQA//zzD7/88gvlypWjd+/etrL/+c9/OHHiBN27d6ds2bIA7Nq1i3nz5lGqVCkef/xxW9mpU6dy9OhRHnnkESpUqADA3r17mTVrFiEhITz99NO2sl9//TUHDhygU6dOVK1aFYBDhw7x1VdfERAQwHPPPWcrO2vWLOLi4mjfvj01a9YEICEhgS+//BJvb29eeOEFW9l58+axY8cO2rZtS3R0NACnTp3is88+w83NjZdffhmTyQTAL7/8wt9//02LFi246667AEhJSWHixImYzWZee+01W9kFCxawfv167r77bpo0aQJAeno6H330EQCvvvoqzs45H/s//viDVatW0aBBA1q2bAnknATeffddAF566SU8PDwAWLp0KcuWLePOO+8kJibGdhzvvPMOVquVQYMG2d77lStXsnjxYmrUqMF9991nK/vhhx+SkZHBgAEDbO/9unXrWLBgAVWqVOGBBx6wlZ0wYQKpqak88cQTtvd+8+bN/PLLL0RFRdG5c2db2cmTJ3P69Gn69Olje++3bdvGvHnzKFOmDD169LCV/eKLLzh27Bjdu3enYsWKAOzevZtZs2YRFhZG3759bWVnzJjB4cOHeeSRR6hWrRoA+/bt46uvviI4OJgnnnjCVvbbb79l3759dOzYkdq1awNw5MgRvvjiC/z8/BgwYICt7Ny5c9m9ezf33nsv9erVA+DYsWNMnjwZDw8PBg8ebCv7008/sW3bNtq0aUOjRo0ASExM5OOPP8bFxYWhQ4fayv73v/9l8+bNNGvWjObNmwOQlpbGBx98AMCwYcNsZRctWsS6deto1KgRbdq0AXJ+FN5++20AXnjhBVxdXW3v/YoVK6hXrx733nuvrY6xY8cCMGjQIJ0jdI7QOULnCJ0jiuAcMW/ePArLoQnshx9+yBNPPGH7QkyePJn5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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "val_means = [r[\"best_val_loss\"][0] for r in wp]\n", + "\n", + "fig, ax = plt.subplots(figsize=(7, 4.5))\n", + "ax.plot(vocab_sizes, val_means, marker=\"o\", label=\"wordpiece val_loss\")\n", + "ax.plot(vocab_sizes, loss_means, marker=\"o\", label=\"wordpiece test_loss\")\n", + "ax.axhline(char_row[\"best_val_loss\"][0], color=\"gray\", linestyle=\"--\", label=\"char val_loss\")\n", + "ax.axhline(char_row[\"test_loss\"][0], color=\"gray\", linestyle=\":\", label=\"char test_loss\")\n", + "ax.set_xlabel(\"vocab_size\")\n", + "ax.set_ylabel(\"loss\")\n", + "ax.set_title(\"best_val_loss vs test_loss by vocab_size\")\n", + "ax.legend()\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "c9d56c1a", + "metadata": {}, + "source": [ + "*Notes: a wide, growing gap between the val and test lines for a given tokenizer would\n", + "point to overfitting to the validation split (or a val/test distribution mismatch); lines\n", + "staying close together across `vocab_size` suggests the ranking in plots 1-2 isn't an\n", + "artifact of overfitting.*" + ] + }, + { + "cell_type": "markdown", + "id": "caa7dbcd", + "metadata": {}, + "source": [ + "## 5. epochs_to_best_val, by config" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "11901b9c", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:34.988071Z", + "iopub.status.busy": "2026-07-30T17:10:34.987841Z", + "iopub.status.idle": "2026-07-30T17:10:35.131573Z", + "shell.execute_reply": "2026-07-30T17:10:35.130491Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAXxhJREFUeJzt3Xd4FFX//vF700NJAVIIBAKEXhUEQlfyCIgIqAj58kgTUAQFUVRQuhrsqCBWigrSFCwUhUhRmrQoSJEWgkpCTwhIgOT8/uDHPCwpJNmFJPB+XddeMGfOzH7mZLK7d6aszRhjBAAAAAAOcMnvAgAAAAAUfgQLAAAAAA4jWAAAAABwGMECAAAAgMMIFgAAAAAcRrAAAAAA4DCCBQAAAACHESwAAAAAOIxgAQAAAMBhBAsAuE7GjBkjm82mY8eO5XcpThMWFqZ77703v8vIN9OnT5fNZlNcXFy2/Xr16qVixYrdmKLyQWJioh588EGVLFlSNptNEydO1MqVK2Wz2bRy5cr8Lg9APiFYAMBN4v3339f06dPzuwyn27Fjh8aMGXPND/O4cZ566in98MMPGj58uD7//HO1bds2v0sCUAC45XcBAADneP/991WqVCn16tUrv0txqh07dmjs2LFq1aqVwsLC8rscSPrpp5/UsWNHPfPMM1ZblSpV9O+//8rDwyMfKwOQnwgWAAAgV44cOSI/Pz+7NhcXF3l5eeVPQQAKBE6FAlCo/f333+rTp4+CgoLk6empmjVraurUqXZ9Lp/7PWfOHI0YMULBwcEqWrSo7rvvPh06dCjDOufNm6f69evL29tbpUqV0n//+1/9/fffGfrt2rVLDz30kAICAuTt7a2qVavqhRdeyNDv1KlT6tWrl/z8/OTr66vevXvr7Nmzdn2WLVumZs2ayc/PT8WKFVPVqlU1YsSIHI9DWFiY/vjjD61atUo2m002m02tWrWy5u/fv19dunRRiRIlVKRIETVu3FiLFi3K8fqv9uOPP6pevXry8vJSjRo19PXXX2e63UOGDFFoaKg8PT0VHh6uV199Venp6Xb9Zs+erfr166t48eLy8fFR7dq19c4770i6dE1Dly5dJEl33nmntW05OY9//vz5stlsWrVqVYZ5H374oWw2m7Zv3y5J+v3339WrVy9VrFhRXl5eCg4OVp8+fXT8+PHcDo2d/fv3q02bNipatKhCQkI0btw4GWMkScYYhYWFqWPHjhmWO3funHx9ffXoo49e8zm++OILNWzYUEWKFJG/v79atGihH3/80a7P+++/r5o1a8rT01MhISEaOHCgTp06ZdenVatWqlWrlnbs2KE777xTRYoUUZkyZfTaa69ZfS5fY2KM0eTJk62fh6Qsr7GYPHmyKlasKG9vbzVs2FA///yzWrVqZbd/Arg5cMQCQKGVmJioxo0by2azadCgQQoICNCSJUv0yCOPKDk5WUOGDLHr//LLL8tms+m5557TkSNHNHHiREVGRio2Nlbe3t6SLn1w6t27t+644w5FR0crMTFR77zzjtasWaOtW7daf6X9/fff1bx5c7m7u6t///4KCwvTvn379N133+nll1+2e96HHnpIFSpUUHR0tLZs2aJPPvlEgYGBevXVVyVJf/zxh+69917VqVNH48aNk6enp/bu3as1a9bkeCwmTpyoJ554QsWKFbPCTVBQkDVOTZo00dmzZ/Xkk0+qZMmSmjFjhu677z7Nnz9fnTt3ztW479mzR127dtVjjz2mnj17atq0aerSpYuWLl2q//znP5Kks2fPqmXLlvr777/16KOPqly5clq7dq2GDx+uw4cPa+LEiZIuBaqoqCi1bt3aGo+dO3dqzZo1Gjx4sFq0aKEnn3xS7777rkaMGKHq1atLkvVvdtq3b69ixYpp7ty5atmypd28OXPmqGbNmqpVq5ZVx/79+9W7d28FBwfrjz/+0EcffaQ//vhD69evtz4850ZaWpratm2rxo0b67XXXtPSpUs1evRoXbx4UePGjZPNZtN///tfvfbaazpx4oRKlChhLfvdd98pOTlZ//3vf7N9jrFjx2rMmDFq0qSJxo0bJw8PD23YsEE//fST7r77bkmXbiIwduxYRUZGasCAAdq9e7emTJmijRs3as2aNXJ3d7fWd/LkSbVt21b333+/HnroIc2fP1/PPfecateurXbt2qlFixb6/PPP9fDDD+s///mPevTokW19U6ZM0aBBg9S8eXM99dRTiouLU6dOneTv76+yZcvmekwBFHAGAAqpRx55xJQuXdocO3bMrr1bt27G19fXnD171hhjzIoVK4wkU6ZMGZOcnGz1mzt3rpFk3nnnHWOMMefPnzeBgYGmVq1a5t9//7X6ff/990aSGTVqlNXWokULU7x4cXPw4EG7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LZcXkZGRKlGihObMmaM5c+aoYcOG1mlO0v/+Sn/1zy4nH+6vZdKkSdb/jTGaNGmS3N3d1bp1a7t+Dz/8sHbs2KFhw4bJ1dVV3bp1u+a6O3XqJBcXF40bNy7DUZXL2xIZGSkPDw+9++67dtv36aefKikpydqnr4cGDRqoZMmS+vjjj62ftyTNnDkzT6dWASj4OGIBoNCaMGGCVqxYoUaNGqlfv36qUaOGTpw4oS1btmj58uUZPrCXKFFCzZo1U+/evZWYmKiJEycqPDxc/fr1kyS5u7vr1VdfVe/evdWyZUtFRUVZt5sNCwvTU089Za3r3XffVbNmzXT77berf//+qlChguLi4rRo0SLFxsbmajvGjRun1atXq3379ipfvryOHDmi999/X2XLlrW74Ppa6tevrylTpuill15SeHi4AgMDddddd+n555/Xl19+qXbt2unJJ59UiRIlNGPGDB04cEBfffVVhgt/r6VKlSp65JFHtHHjRgUFBWnq1KlKTEzUtGnTrD7Dhg3Tt99+q3vvvVe9evVS/fr1debMGW3btk3z589XXFycSpUqpb59++rEiRO66667VLZsWR08eFDvvfee6tWrZ10DUq9ePbm6uurVV19VUlKSPD09dddddykwMDBH9bq7u+v+++/X7NmzdebMGb3xxht28318fNSiRQu99tprunDhgsqUKaMff/xRBw4cyNW4XM3Ly0tLly5Vz5491ahRIy1ZskSLFi3SiBEjFBAQYNe3ffv2KlmypObNm6d27drlaNvCw8P1wgsvaPz48WrevLnuv/9+eXp6auPGjQoJCVF0dLQCAgI0fPhwjR07Vm3bttV9992n3bt36/3339cdd9xxzdvZOsLDw0NjxozRE088obvuuksPPfSQ4uLiNH36dFWqVMnhI1EACqD8uRkVADhHYmKiGThwoAkNDTXu7u4mODjYtG7d2nz00UdWn8u3wfzyyy/N8OHDTWBgoPH29jbt27fPcLtYY4yZM2eOue2224ynp6cpUaKE6d69u/nrr78y9Nu+fbvp3Lmz8fPzM15eXqZq1apm5MiR1vzLt5u9+jayV9+yNCYmxnTs2NGEhIQYDw8PExISYqKiojLcqvVaEhISTPv27U3x4sUz3M5z37595sEHH7Rqbdiwofn+++9ztX5jLt1utn379uaHH34wderUMZ6enqZatWpm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Pj437RvL5W3PbLuvHJcjR47Yzb948aJOnDjhlPG9PL+wGDRokL7//nutWLFCZcuWtdpv1H5YqlQpubq6Fvqx9PDwUHh4uOrXr6/o6GjVrVtX77zzDuOYC5s3b9aRI0d0++23y83NTW5ublq1apXeffddubm5KSgoiLHMo/x4j7kZx7EgvcfkpJabAcHiFlC5cmV5e3srJiYmT8uvWbNGHTt21H//+1/VrVtXFStW1J9//unkKguXlJQU7du3T6VLl1b9+vXl7u5uN767d+9WfHy8IiIiJEkRERHatm2b3YvXsmXL5OPjoxo1alh9rv4ZLVu2zFrHzahChQoKDg622+7k5GRt2LDBbuxOnTqlzZs3W31++uknpaenq1GjRlaf1atX68KFC1afZcuWqWrVqvL397f6FObxNcZo0KBBWrBggX766acMh+Vv1H7o4eGh+vXr2/VJT09XTExMoRnLzKSnpys1NZVxzIXWrVtr27Ztio2NtR4NGjRQ9+7drf8zlnmTH+8xN+M4FqT3mJzUclPI76vHcWOMGTPG+Pv7mxkzZpi9e/eadevWmU8++STT282ePHnSSDIrVqwwxhjz1FNPmdDQULNmzRqzY8cO07dvX+Pj42M6duxoLXPlnUBuRk8//bRZuXKlOXDggFmzZo2JjIw0pUqVMkeOHDHGXLoVYLly5cxPP/1kNm3aZCIiIkxERIS1/OVbAd59990mNjbWLF261AQEBGR6K8Bhw4aZnTt3msmTJ98Ut5s9ffq02bp1q9m6dauRZN566y2zdetWc/DgQWPMpdvv+fn5mW+++cb8/vvvpmPHjpneCvC2224zGzZsML/88oupXLmy3a0AT506ZYKCgszDDz9stm/fbmbPnm2KFCmS4VaAbm5u5o033jA7d+40o0ePLlS3mx0wYIDx9fU1K1eutLsl5dmzZ60+N2o/nD17tvH09DTTp083O3bsMP379zd+fn52d6QpyJ5//nmzatUqc+DAAfP777+b559/3thsNvPjjz8aYxhHR1z9XsBY5kxBeY8pjONYmN5jclJLYUewuEWkpaWZl156yZQvX964u7ubcuXKmVdeeSVHweL48eOmY8eOplixYiYwMNC8+OKLpkePHrdUsOjataspXbq08fDwMGXKlDFdu3Y1e/futeb/+++/5vHHHzf+/v6mSJEipnPnzubw4cN264iLizPt2rUz3t7eplSpUubpp582Fy5csOuzYsUKU69ePePh4WEqVqxopk2bdiM277pasWKFkZTh0bNnT2PMpVvwjRw50gQFBRlPT0/TunVrs3v3brt1HD9+3ERFRZlixYoZHx8f07t3b3P69Gm7Pr/99ptp1qyZ8fT0NGXKlDETJkzIUMvcuXNNlSpVjIeHh6lZs6ZZtGjRddtuZ8tsDCXZ7SM3cj987733TLly5YyHh4dp2LChWb9+/fXY7OuiT58+pnz58sbDw8MEBASY1q1bW6HCGMbREVe/FzCWOVOQ3mMK2zgWpveYnNRS2NmMMeZGHiEBAAAAcPPhGgsAAAAADiNYAAAAAHAYwQIAAACAwwgWAAAAABxGsAAAAADgMIIFAAAAAIcRLAAAAAA4jGABAAAAwGEECwAoAM6ePasHHnhAPj4+stlsOnXqlMLCwjRx4kSH1338+HEFBgYqLi7O4XU5y8qVK63tLEzrzm9jxoxRvXr1rsu6ly5dqnr16ik9Pf26rB/AzY9gAQAFwIwZM/Tzzz9r7dq1Onz4sHx9fbVx40b179/f4XW//PLL6tixo8LCwhwvtBBo0qSJNYbIubZt28rd3V0zZ87M71IAFFIECwAoAPbt26fq1aurVq1aCg4Ols1mU0BAgIoUKeLQes+ePatPP/1UjzzyiJMqLfg8PDysMSyojDG6ePFifpdhuXDhgiSpV69eevfdd/O5GgCFFcECAK4hPT1dr732msLDw+Xp6aly5crp5ZdftuZv27ZNd911l7y9vVWyZEn1799fKSkp1vxevXqpU6dOeuONN1S6dGmVLFlSAwcOtD7MtWrVSm+++aZWr14tm82mVq1aSVKGU6F27dqlZs2aycvLSzVq1NDy5ctls9m0cOHCLGtfvHixPD091bhxY2tbypYtqylTptj127p1q1xcXHTw4EFJUnx8vDp27KhixYrJx8dHDz30kBITE+2W+e6773THHXfIy8tLpUqVUufOna15n3/+uRo0aKDixYsrODhY//d//6cjR45kqG/NmjWqU6eOvLy81LhxY23fvj2bn8T/HDx4UB06dJC/v7+KFi2qmjVravHixZIyngrVqlUr2Wy2DI/Lp4adOnVKffv2VUBAgHx8fHTXXXfpt99+y1Edl6WmpurJJ59UYGCgvLy81KxZM23cuNGaf7mmJUuWqH79+vL09NQvv/yS6br++usvRUVFqUSJEipatKgaNGigDRs22PX5/PPPFRYWJl9fX3Xr1k2nT5+25i1dulTNmjWTn5+fSpYsqXvvvVf79u2z5sfFxclms2nOnDlq2bKlvLy8rKMUHTp00KZNm+z6A0BOESwA4BqGDx+uCRMmaOTIkdqxY4dmzZqloKAgSdKZM2fUpk0b+fv7a+PGjZo3b56WL1+uQYMG2a1jxYoV2rdvn1asWKEZM2Zo+vTpmj59uiTp66+/Vr9+/RQREaHDhw/r66+/zlBDWlqaOnXqpCJFimjDhg366KOP9MILL1yz9p9//ln169e3pl1cXBQVFaVZs2bZ9Zs5c6aaNm2q8uXLKz09XR07dtSJEye0atUqLVu2TPv371fXrl2t/osWLVLnzp11zz33aOvWrYqJiVHDhg2t+RcuXND48eP122+/aeHChYqLi1OvXr0y1Dds2DC9+eab2rhxowICAtShQwcrcGVn4MCBSk1N1erVq7Vt2za9+uqrKlasWKZ9v/76ax0+fNh63H///apatar1M+zSpYuOHDmiJUuWaPPmzbr99tvVunVrnThx4pp1XPbss8/qq6++0owZM7RlyxaFh4erTZs2Gdbx/PPPa8KECdq5c6fq1KmTYT0pKSlq2bKl/v77b3377bf67bff9Oyzz9pd97Bv3z4tXLhQ33//vb7//nutWrVKEyZMsOafOXNGQ4cO1aZNmxQTEyMXFxd17tw5w7UTzz//vAYPHqydO3eqTZs2kqRy5copKChIP//8c463HQAsBgCQpeTkZOPp6Wk+/vjjTOd/9NFHxt/f36SkpFhtixYtMi4uLiYhIcEYY0zPnj1N+fLlzcWLF60+Xbp0MV27drWmBw8ebFq2bGm37vLly5u3337bGGPMkiVLjJubmzl8+LA1f9myZUaSWbBgQZb1d+zY0fTp08eubevWrcZms5mDBw8aY4xJS0szZcqUMVOmTDHGGPPjjz8aV1dXEx8fby3zxx9/GEnm119/NcYYExERYbp3757l815t48aNRpI5ffq0McaYFStWGElm9uzZVp/jx48bb29vM2fOnGuur3bt2mbMmDGZzru87pMnT2aY99Zbbxk/Pz+ze/duY4wxP//8s/Hx8THnzp2z61epUiXz4Ycf5mjbUlJSjLu7u5k5c6bVdv78eRMSEmJee+01u5oWLlyY7bo+/PBDU7x4cXP8+PFM548ePdoUKVLEJCcnW23Dhg0zjRo1ynKdR48eNZLMtm3bjDHGHDhwwEgyEydOzLT/bbfdluXYAkB2OGIBANnYuXOnUlNT1bp16yzn161bV0WLFrXamjZtqvT0dO3evdtqq1mzplxdXa3p0qVLZ3pqUFZ2796t0NBQBQcHW21XHiHIyr///isvLy+7tnr16ql69erWUYtVq1bpyJEj6tKli7VNoaGhCg0NtZapUaOG/Pz8tHPnTklSbGxslmMiSZs3b1aHDh1Urlw5FS9eXC1btpR06RSrK0VERFj/L1GihKpWrWo9R3aefPJJvfTSS2ratKlGjx6t33///ZrLLFmyRM8//7zmzJmjKlWqSJJ+++03paSkqGTJkipWrJj1OHDgQI5PB9q3b58uXLigpk2bWm3u7u5q2LBhhm1p0KBBtuuKjY3VbbfdphIlSmTZJywsTMWLF7emr96X9uzZo6ioKFWsWFE+Pj7WRftXj31WtXh7e+vs2bPZ1gkAmSFYAEA2vL29nbIed3d3u2mbzXZDbutZqlQpnTx5MkN79+7drWAxa9YstW3bViVLlszxerMbl8unh/n4+GjmzJnauHGjFixYIEk6f/58Lrcgc3379tX+/fv18MMPa9u2bWrQoIHee++9LPvv2LFD3bp104QJE3T33Xdb7SkpKSpdurRiY2PtHrt379awYcOcUuuVrgygmcnJ/natfalDhw46ceKEPv74Y23YsMG6PuPqsc+qlhMnTiggIOCadQDA1QgWAJCNypUry9vbWzExMZnOr169un777TedOXPGaluzZo1cXFxUtWpVp9VRtWpVHTp0yO4C6isvDs7Kbbfdph07dmRo/7//+z9t375dmzdv1vz589W9e3drXvXq1XXo0CEdOnTIatuxY4dOnTqlGjVqSJLq1KmT5Zjs2rVLx48f14QJE9S8eXNVq1Yty6Mz69evt/5/8uRJ/fnnn6pevfo1t0uSQkND9dhjj+nrr7/W008/rY8//jjTfseOHVOHDh30wAMP6KmnnrKbd/vttyshIUFubm4KDw+3e5QqVSpHdVSqVEkeHh5as2aN1XbhwgVt3LjRGq+cqlOnjmJjY3N1fceVjh8/rt27d+vFF19U69atVb169UyDZVbOnTunffv26bbbbsvT8wO4tREsACAbXl5eeu655/Tss8/qs88+0759+7R+/Xp9+umnki795d/Ly0s9e/bU9u3btWLFCj3xxBN6+OGHrYuDneE///mPKlWqpJ49e+r333/XmjVr9OKLL0pStrdVbdOmjf74448MHy7DwsLUpEkTPfLII0pLS9N9991nzYuMjFTt2rXVvXt3bdmyRb/++qt69Oihli1bWqfPjB49Wl9++aVGjx6tnTt3WhdQS5cuAPbw8NB7772n/fv369tvv9X48eMzrW/cuHGKiYnR9u3b1atXL5UqVUqdOnW65ngMGTJEP/zwgw4cOKAtW7ZoxYoVWQaSBx54QEWKFNGYMWOUkJBgPdLS0hQZGamIiAh16tRJP/74o+Li4rR27Vq98MIL2rRp0zXrkC795X/AgAEaNmyYli5dqh07dqhfv346e/Zsrm/zGxUVpeDgYHXq1Elr1qzR/v379dVXX2ndunU5Wt7f318lS5bURx99pL179+qnn37S0KFDc/z869evl6enp90pagCQUwQLALiGkSNH6umnn9aoUaNUvXp1de3a1foLfJEiRfTDDz/oxIkTuuOOO/Tggw+qdevWmjRpklNrcHV11cKFC5WSkqI77rhDffv2te4KdfU1FFeqXbu2br/9ds2dOzfDvO7du+u3335T586d7U7Bsdls+uabb+Tv768WLVooMjJSFStW1Jw5c6w+rVq10rx58/Ttt9+qXr16uuuuu/Trr79KkgICAjR9+nTNmzdPNWrU0IQJE/TGG29kWt+ECRM0ePBg1a9fXwkJCfruu+/k4eFxzfFIS0vTwIEDVb16dbVt21ZVqlTR+++/n2nf1atXa/v27SpfvrxKly5tPQ4dOiSbzabFixerRYsW6t27t6pUqaJu3brp4MGDVjC8fHvWlStXZlnPhAkT9MADD+jhhx/W7bffrr179+qHH36Qv7//NbflSh4eHvrxxx8VGBioe+65R7Vr19aECRPsrs/JjouLi2bPnq3NmzerVq1aeuqpp/T666/n+Pm//PJLde/e3eHvTwFwa7IZY0x+FwEAyL01a9aoWbNm2rt3rypVqpRlv0WLFmnYsGHavn27XFz4e1JurVixQvfff7/279+f66BQmBw7dkxVq1bVpk2bVKFChfwuB0Ah5JbfBQAAcmbBggUqVqyYKleurL1792rw4MFq2rRptqFCktq3b689e/bo77//trvTE3Jm8eLFGjFixE0dKqRLR2bef/99QgWAPOOIBQAUEp999pleeuklxcfHq1SpUoqMjNSbb76Zq7s5FRbt2rXL8kvaRowYoREjRtzgigAA10KwAAAUOH///bf+/fffTOeVKFEi2+95AADkD4IFAAAAAIdxFR8AAAAAhxEsAAAAADiMYAEAAADAYQQLAAAAAA4jWAAAAABwGMECAAAAgMMIFgAAAAAcRrAAAAAA4LD/B0cCFmWiv7nAAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "inferred_total_epochs = int(raw[\"epochs_to_best_val\"].max())\n", + "\n", + "conv = (\n", + " raw.groupby([\"tokenizer\", \"vocab_size\"])[\"epochs_to_best_val\"]\n", + " .agg([\"mean\", \"std\"])\n", + " .reset_index()\n", + " .sort_values([\"tokenizer\", \"vocab_size\"])\n", + ")\n", + "conv_labels = [\"char\" if t == \"char\" else str(int(v)) for t, v in zip(conv[\"tokenizer\"], conv[\"vocab_size\"])]\n", + "\n", + "fig, ax = plt.subplots(figsize=(8, 4.5))\n", + "ax.bar(conv_labels, conv[\"mean\"], yerr=conv[\"std\"].fillna(0), capsize=3)\n", + "ax.axhline(inferred_total_epochs, color=\"gray\", linestyle=\"--\")\n", + "ax.set_xlabel(\"config (vocab_size, or char)\")\n", + "ax.set_ylabel(\"epochs_to_best_val\")\n", + "ax.set_title(\"epochs_to_best_val by config\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "9048e56d", + "metadata": {}, + "source": [ + "*Notes: the dashed line marks the last epoch of the run (`--epochs` used). A bar\n", + "reaching that line means best `val_loss` landed on the final epoch for at least some\n", + "seeds — i.e. training may not have plateaued yet for that config. See the per-seed\n", + "breakdown below for exactly how many of the 3 seeds hit that ceiling per config.*" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "305a88cc", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:35.133631Z", + "iopub.status.busy": "2026-07-30T17:10:35.133381Z", + "iopub.status.idle": "2026-07-30T17:10:35.153688Z", + "shell.execute_reply": "2026-07-30T17:10:35.152834Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizeseeds_hitting_ceilingn_seedsfraction_hitting_ceiling
7wordpiece100000331.000000
1wordpiece5000230.666667
4wordpiece30000230.666667
3wordpiece20000230.666667
5wordpiece40000230.666667
6wordpiece50000230.666667
2wordpiece10000130.333333
0char25130.333333
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size seeds_hitting_ceiling n_seeds \\\n", + "7 wordpiece 100000 3 3 \n", + "1 wordpiece 5000 2 3 \n", + "4 wordpiece 30000 2 3 \n", + "3 wordpiece 20000 2 3 \n", + "5 wordpiece 40000 2 3 \n", + "6 wordpiece 50000 2 3 \n", + "2 wordpiece 10000 1 3 \n", + "0 char 25 1 3 \n", + "\n", + " fraction_hitting_ceiling \n", + "7 1.000000 \n", + "1 0.666667 \n", + "4 0.666667 \n", + "3 0.666667 \n", + "5 0.666667 \n", + "6 0.666667 \n", + "2 0.333333 \n", + "0 0.333333 " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def summarize_convergence(group):\n", + " hit_ceiling = int((group[\"epochs_to_best_val\"] == inferred_total_epochs).sum())\n", + " return pd.Series({\"seeds_hitting_ceiling\": hit_ceiling, \"n_seeds\": len(group)})\n", + "\n", + "ceiling_df = (\n", + " raw.groupby([\"tokenizer\", \"vocab_size\"])\n", + " .apply(summarize_convergence, include_groups=False)\n", + " .reset_index()\n", + ")\n", + "ceiling_df[\"fraction_hitting_ceiling\"] = ceiling_df[\"seeds_hitting_ceiling\"] / ceiling_df[\"n_seeds\"]\n", + "ceiling_df.sort_values(\"fraction_hitting_ceiling\", ascending=False)" + ] + }, + { + "cell_type": "markdown", + "id": "7c52072b", + "metadata": {}, + "source": [ + "## 6. num_parameters vs test_loss" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "95004f13", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:35.155306Z", + "iopub.status.busy": "2026-07-30T17:10:35.155133Z", + "iopub.status.idle": "2026-07-30T17:10:35.324377Z", + "shell.execute_reply": "2026-07-30T17:10:35.323274Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAArAAAAHqCAYAAAD8uX26AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAV3hJREFUeJzt3XtcVVX+//H3AQRMOSgSNwVB8ZoKXgC1TCu8TWNaU1p+CzUdy8bKrzmpM3khbSynKUsrmy5a2UUrs5opshzNbEgrJSsNL6GgcVEMUFNUzvr94c/z9QQoEHDO1tfz8TiPR2ettdf57C3jvN2svY7NGGMEAAAAWISXuwsAAAAAqoMACwAAAEshwAIAAMBSCLAAAACwFAIsAAAALIUACwAAAEshwAIAAMBSCLAAAACwFAIsAAAALIUACwDAWfr166d+/fq5uwwA50CABQA3ee2117RgwQJ3l1GvfvrpJ82ePVsZGRl1+jkX47UFLiYEWABwk4sxZP30009KTU0lwAL4TQiwAC5ox48fl8PhcHcZ9cbhcOj48ePuLgMA6hQBFrgAzJ49WzabTbt27dLo0aPVpEkTBQYGasyYMfrll1+c4/bs2SObzaalS5eWm8Nms2n27Nnl5tyxY4duvfVWBQYG6tJLL9WMGTNkjFFOTo6GDh0qu92usLAw/eMf/6h23dHR0fr973+v1atXKz4+Xv7+/urYsaNWrlzpMu7QoUOaMmWKOnfurMaNG8tut2vw4MH65ptvXMatW7dONptNb7zxhh544AE1b95cl1xyiUpKSqo9x4oVK5SamqrmzZsrICBAN954o4qLi1VaWqpJkyYpJCREjRs31pgxY1RaWlru3JYtW6bu3burYcOGCgoK0s0336ycnBxnf79+/fTvf/9be/fulc1mk81mU3R0tLO/tLRUs2bNUmxsrPz8/BQZGan777+/3GfZbDZNnDhRr776qi677DL5+fkpLS1NkvTGG2+oe/fuCggIkN1uV+fOnfXEE09U+udx8uRJBQUFacyYMeX6SkpK5O/vrylTpjjbFi5cqMsuu0yXXHKJmjZtqh49eui1116rdP5169YpISFBkjRmzBjneZ/987hx40YNGjRIgYGBuuSSS9S3b199/vnnLvMcPnxYkyZNUnR0tPz8/BQSEqL+/ftr8+bNVbq2NVFQUKCxY8cqNDRU/v7+iouL00svvVRu3Pmu+cmTJ5Wamqo2bdrI399fzZo10xVXXKGPP/74N9UHXGx83F0AgNozfPhwxcTEaN68edq8ebOef/55hYSE6JFHHqnxnCNGjFCHDh308MMP69///rfmzp2roKAgPfvss7r66qv1yCOP6NVXX9WUKVOUkJCgK6+8slrz79y5UyNGjNCdd96pUaNGacmSJbrpppuUlpam/v37S5J+/PFHrVq1SjfddJNiYmKUn5+vZ599Vn379tW2bdsUERHhMuecOXPk6+urKVOmqLS0VL6+vtq2bVu15pg3b54aNmyoadOmadeuXVq4cKEaNGggLy8v/fzzz5o9e7a++OILLV26VDExMZo5c6bz2IceekgzZszQ8OHDNW7cOB04cEALFy7UlVdeqS1btqhJkyb661//quLiYu3bt0+PP/64JKlx48aSTt9Fve6667RhwwaNHz9eHTp00LfffqvHH39cO3bs0KpVq1xq/c9//qMVK1Zo4sSJCg4OVnR0tD7++GPdcsstuuaaa5x//tu3b9fnn3+ue++9t8I/iwYNGuj666/XypUr9eyzz8rX19fZt2rVKpWWlurmm2+WJD333HO65557dOONN+ree+/V8ePHtXXrVm3cuFEjR46scP4OHTrowQcf1MyZMzV+/Hj16dNHktS7d2/neQwePFjdu3fXrFmz5OXlpSVLlujqq6/WZ599psTEREnSnXfeqbfeeksTJ05Ux44dVVhYqA0bNmj79u3q1q3bOa9tTRw7dkz9+vXTrl27NHHiRMXExOjNN9/U6NGjVVRU5LyeVbnms2fP1rx58zRu3DglJiaqpKREX331lTZv3uz8eQdQBQaA5c2aNctIMrfffrtL+/XXX2+aNWvmfJ+VlWUkmSVLlpSbQ5KZNWtWuTnHjx/vbDt16pRp0aKFsdls5uGHH3a2//zzz6Zhw4Zm1KhR1aq7ZcuWRpJ5++23nW3FxcUmPDzcdO3a1dl2/PhxU1ZW5nJsVlaW8fPzMw8++KCzbe3atUaSadWqlfnll19cxld3jk6dOpkTJ04422+55RZjs9nM4MGDXebo1auXadmypfP9nj17jLe3t3nooYdcxn377bfGx8fHpf3aa691OfaMV155xXh5eZnPPvvMpX3x4sVGkvn888+dbZKMl5eX+f77713G3nvvvcZut5tTp06Vm/9cPvroIyPJvP/++y7tv/vd70yrVq2c74cOHWouu+yyas1tjDFffvllhT+DDofDtGnTxgwcONA4HA5n+y+//GJiYmJM//79nW2BgYHmT3/60zk/p7JrWxV9+/Y1ffv2db5fsGCBkWSWLVvmbDtx4oTp1auXady4sSkpKTHGVO2ax8XFmWuvvbZGdQH4PywhAC4gd955p8v7Pn36qLCwUCUlJTWec9y4cc7/9vb2Vo8ePWSM0dixY53tTZo0Ubt27fTjjz9We/6IiAhdf/31zvd2u10pKSnasmWL8vLyJEl+fn7y8jr911VZWZkKCwvVuHFjtWvXzvlr47ONGjVKDRs2dGmr7hwpKSlq0KCB831SUpKMMbr99ttdxiUlJSknJ0enTp2SJK1cuVIOh0PDhw/XwYMHna+wsDC1adNGa9euPe81efPNN9WhQwe1b9/eZY6rr75aksrN0bdvX3Xs2NGlrUmTJjp69Gi1fzV99dVXKzg4WMuXL3e2/fzzz/r44481YsQIl/n37dunL7/8slrzVyYjI0M7d+7UyJEjVVhY6Dzno0eP6pprrtH69euda5mbNGmijRs36qeffqqVzz6fDz74QGFhYbrlllucbQ0aNNA999yjI0eO6NNPP3XWdb5r3qRJE33//ffauXNnndcNXMgIsMAFJCoqyuV906ZNJZ0OILU1Z2BgoPz9/RUcHFyuvSafExsbK5vN5tLWtm1bSafX7Eqnf6X++OOPq02bNvLz81NwcLAuvfRSbd26VcXFxeXmjImJKddW3TkqOm9JioyMLNfucDicc+zcuVPGGLVp00aXXnqpy2v79u0qKCg47zXZuXOnvv/++3LHn7kuv56jovO966671LZtWw0ePFgtWrTQ7bff7lwbey4+Pj76wx/+oHfffde53nblypU6efKkS4CdOnWqGjdurMTERLVp00Z/+tOfyq1VrY4zgW7UqFHlzvv5559XaWmp8xrPnz9f3333nSIjI5WYmKjZs2fX6B9PVbV37161adPG+Q+gMzp06ODsl6p2zR988EEVFRWpbdu26ty5s/785z9r69atdVY7cKFiDSxwAfH29q6w3RgjSeWC4hllZWXVmvN8n1Pb/va3v2nGjBm6/fbbNWfOHAUFBcnLy0uTJk2qcIeBX999rckclZ3j+c7d4XDIZrPpww8/rHBsVdZiOhwOde7cWY899liF/b8O0RWdb0hIiDIyMvTRRx/pww8/1IcffqglS5YoJSWlwoePznbzzTfr2Wef1Ycffqhhw4ZpxYoVat++veLi4pxjOnTooMzMTP3rX/9SWlqa3n77bT399NOaOXOmUlNTz3uOFZ2zJP39739XfHx8hWPOXLvhw4erT58+euedd7R69Wr9/e9/1yOPPKKVK1dq8ODB1f7s2lKVa37llVdq9+7devfdd7V69Wo9//zzevzxx7V48WKX33YAODcCLHAROXNHtqioyKX9zB0kd9i1a5eMMS7heseOHZLkfHL8rbfe0lVXXaUXXnjB5diioqJyd4IrUxtzVEXr1q1ljFFMTIzzjmllKvsHRevWrfXNN9/ommuuqXRMVfj6+mrIkCEaMmSIHA6H7rrrLj377LOaMWOGYmNjKz3uyiuvVHh4uJYvX64rrrhC//nPf/TXv/613LhGjRppxIgRGjFihE6cOKEbbrhBDz30kKZPny5/f/8K5z7XOUunl5AkJyef99zCw8N111136a677lJBQYG6deumhx56yBlgf8t1+7WWLVtq69atcjgcLndhf/jhB2f/GVW55md2ehgzZoyOHDmiK6+8UrNnzybAAtXAEgLgImK32xUcHKz169e7tD/99NNuquj0xvbvvPOO831JSYlefvllxcfHKywsTNLpu56/vrv75ptvav/+/VX+nNqYoypuuOEGeXt7KzU1tdznGWNUWFjofN+oUaMKly8MHz5c+/fv13PPPVeu79ixYzp69Oh56zj7cyTJy8tLXbp0kaQKt/369dgbb7xR77//vl555RWdOnXKZflARfP7+vqqY8eOMsbo5MmTlc7dqFEjSeX/EdW9e3e1bt1ajz76qI4cOVLuuAMHDkg6/duCX1+zkJAQRUREuJxXZde2Jn73u98pLy/PZV3wqVOntHDhQjVu3Fh9+/aVVLVr/usxjRs3Vmxs7Hn/TAC44g4scJEZN26cHn74YY0bN049evTQ+vXrnXc83aFt27YaO3asvvzyS4WGhurFF19Ufn6+lixZ4hzz+9//Xg8++KDGjBmj3r1769tvv9Wrr76qVq1aVflzamOOqmjdurXmzp2r6dOna8+ePRo2bJgCAgKUlZWld955R+PHj3fupdq9e3ctX75ckydPVkJCgho3bqwhQ4botttu04oVK3TnnXdq7dq1uvzyy1VWVqYf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2eq5OgBwP7fegfX19VX37t21Zs0aZ5vD4dCaNWvUq1evcuPbt2+vb7/9VhkZGc7Xddddp6uuukoZGRmKjIys8HP27dunwsJChYfzKzcAnm9T1qFyd17PZiTlFh/XpqxD9VcUAHgQt38T1+TJkzVq1Cj16NFDiYmJWrBggY4ePaoxY8ZIOv293s2bN9e8efPk7++vTp06uRzfpEkTSXK2HzlyRKmpqfrDH/6gsLAw7d69W/fff79iY2M1cODAej03AKiJgsOVh9eajAOAC43bA+yIESN04MABzZw5U3l5eYqPj1daWprzwa7s7Gx5eVX9RrG3t7e2bt2ql156SUVFRYqIiNCAAQM0Z84clgkAsISQAP9aHQcAFxq3f5GBJ/KEDXoB1L0lS5bo9ttv1zvvvKNhw4apoKBAKSkp2r17t/z8/PT000/ryiuvlKQ66atMmcPoikf+o7zi4xWug7VJCgv014apV7MGFkC984ScZKldCACgtuzZs0fPPfecevbs6WybNm2aevbsqZ07d2rJkiUaOXKkTp48WWd9lfH2smnWkI6STofVs515P2tIR8IrgIsWARbARcfhcGjcuHFauHChy9KiFStW6M4775QkJSQkKCIiQp9++mmd9Z3LoE7heubWbgoLdF0mEBbor2du7cY+sAAuam5fAwsA9e2xxx7T5Zdfru7duzvbCgsLdfLkSZct/KKjo5WdnV0nfVUxqFO4+ncM06asQyo4fFwhAf5KjAniziuAix4BFsBF5bvvvtPbb7+t9evXu7uUKvH2sqlX62buLgMAPApLCABcVD777DPt2bNHbdq0UXR0tL744guNHz9eK1askI+Pj/Ly8pxj9+zZo6ioKDVr1qzW+wAANUeABXBRmTBhgnJzc7Vnzx7t2bNHPXv21D//+U9NmDBBN910kxYvXixJ+vLLL7V//3717dtXkuqkDwBQMywhAID/75FHHtFtt92mNm3ayNfXV8uWLVODBg3qrA8AUDPsA1sBT9jfDAAAwBN5Qk5iCQEAAAAshSUEAC4YZQ7DllMAcBEgwAK4IKR9l6vU97cpt/i4sy080F+zhnRk038AuMCwhACA5aV9l6sJyza7hFdJyis+rgnLNivtu1w3VQYAqAsEWACWVuYwSn1/myp6GvVMW+r721Tm4HlVALhQEGABWNqmrEPl7ryezUjKLT6uTVmH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x5VamIHHkmTeeeedKo/v27evuffee+usHiur7rU8o2PHjiY1NbX2C7Kwml7L66+/3tx66621X5CFVedajhgxwjzwwANm1qxZJi4urk7rsqKqXMu1a9caSebnn3+ul5qsrCrX88MPPzSBgYGmsLCwfoqyqJr8nfnOO+8Ym81m9uzZUzdFXQC4AwtUwuFw6PDhwwoKCnJ3KZa3ZcsW/fe//1Xfvn3dXYolLVmyRD/++KNmzZrl7lIuCPHx8QoPD1f//v31+eefu7scy3rvvffUo0cPzZ8/X82bN1fbtm01ZcoUHTt2zN2lWd4LL7yg5ORktWzZ0t2leCwfdxcAeKpHH31UR44c0fDhw91dimW1aNFCBw4c0KlTpzR79myNGzfO3SVZzs6dOzVt2jR99tln8vHhr+zfIjw8XIsXL1aPHj1UWlqq559/Xv369dPGjRvVrVs3d5dnOT/++KM2bNggf39/vfPOOzp48KDuuusuFRYWasmSJe4uz7J++uknffjhh3rttdfcXYpH429DoAKvvfaaUlNT9e6777I+7jf47LPPdOTIEX3xxReaNm2aYmNjdcstt7i7LMsoKyvTyJEjlZqaqrZt27q7HMtr166dy/rM3r17a/fu3Xr88cf1yiuvuLEya3I4HLLZbHr11VcVGBgoSXrsscd044036umnn1bDhg3dXKE1vfTSS2rSpImGDRvm7lI8GgEW+JU33nhD48aN05tvvqnk5GR3l2NpMTExkqTOnTsrPz9fs2fPJsBWw+HDh/XVV19py5YtmjhxoqTTocEYIx8fH61evVpXX321m6u0tsTERG3YsMHdZVhSeHi4mjdv7gyvktShQwcZY7Rv3z61adPGjdVZkzFGL774om677Tb5+vq6uxyPRoAFzvL666/r9ttv1xtvvKFrr73W3eVcUBwOh0pLS91dhqXY7XZ9++23Lm1PP/20/vOf/+itt95y/gMBNZeRkaHw8HB3l2FJl19+ud58800dOXJEjRs3liTt2LFDXl5eatGihZurs6ZPP/1Uu3bt0tixY91discjwHqYI0eOaNeuXc73WVlZysjIUFBQkKKiojR9+nTt379fL7/8snNMRkaG89gDBw4oIyNDvr6+6tixY32X71Gqey1fe+01jRo1Sk888YSSkpKce0M2bNjQ5Q7Dxai61/Kpp55SVFSU2rdvL+n0FmWPPvqo7rnnHrfU70mqcy29vLzUqVMnl+NDQkLk7+9frv1iVN2fywULFigmJkaXXXaZjh8/rueff17/+c9/tHr1anedgkep7vUcOXKk5syZozFjxig1NVUHDx7Un//8Z91+++0X/fKBmvx/uXT64a2kpCT+910Vbt4FAb9yZpuXX79GjRpljDFm1KhRpm/fvi7HVDS+ZcuW9V67p6nutezbt+85x1/Mqnstn3zySXPZZZeZSy65xNjtdtO1a1fz9NNPm7KyMvecgAepyf/Gz8Y2Wv+nutfykUceMa1btzb+/v4mKCjI9OvXz/znP/9xT/EeqCY/m9u3bzfJycmmYcOGpkWLFmby5Mnml19+qf/iPUxNrmVRUZFp2LCh+ec//1n/BVuQzRhj6iQZAwAAAHWAfWABAABgKQRYAAAAWAoBFgAAAJZCgAUAAIClEGABAABgKQRYAAAAWAoBFgAAAJZCgAUAAIClEGABAAAuIOvXr9eQIUMUEREhm82mVatWVev42bNny2azlXs1atSobgquAQIsAKBKoqOjtWDBAneXAeA8jh49qri4OD311FM1On7KlCnKzc11eXXs2FE33XRTLVdacwRYALAAY4xOnTrl7jJqxYkTJ9xdAnBBGzx4sObOnavrr7++wv7S0lJNmTJFzZs3V6NGjZSUlKR169Y5+xs3bqywsDDnKz8/X9u2bdPYsWPr6QzOjwALwNL69eune+65R/fff7+CgoIUFham2bNnS5L27Nkjm82mjIwM5/iioiLZbDbnX9br1q2TzWbTRx99pK5du6phw4a6+uqrVVBQoA8//FAdOnSQ3W7XyJEj9csvv1S5pokTJ2rixIkKDAxUcHCwZsyYIWOMc8wrr7yiHj16KCAgQGFhYRo5cqQKCgqc/Wfq+vDDD9W9e3f5+flpw4YN2r17t4YOHarQ0FA1btxYCQkJ+uSTT1w+Pzo6WnPnzlVKSooaN26sli1b6r333tOBAwc0dOhQNW7cWF26dNFXX33lctyGDRvUp08fNWzYUJGRkbrnnnt09OhR5znt3btX//u//+v8dWJVjjtTz5w5c5SSkiK73a7x48frxIkTmjhxosLDw+Xv76+WLVtq3rx5Vbq+AH6biRMnKj09XW+88Ya2bt2qm266SYMGDdLOnTsrHP/888+rbdu26tOnTz1Xeg4GACysb9++xm63m9mzZ5sdO3aYl156ydhsNrN69WqTlZVlJJktW7Y4x//8889Gklm7dq0xxpi1a9caSaZnz55mw4YNZvPmzSY2Ntb07dvXDBgwwGzevNmsX7/eNGvWzDz88MNVrqlx48bm3nvvNT/88INZtmyZueSSS8w///lP55gXXnjBfPDBB2b37t0mPT3d9OrVywwePNjZf6auLl26mNWrV5tdu3aZwsJCk5GRYRYvXmy+/fZbs2PHDvPAAw8Yf39/s3fvXuexLVu2NEFBQWbx4sVmx44dZsKECcZut5tBgwaZFStWmMzMTDNs2DDToUMH43A4jDHG7Nq1yzRq1Mg8/vjjZseOHebzzz83Xbt2NaNHjzbGGFNYWGhatGhhHnzwQZObm2tyc3OrdNyZeux2u3n00UfNrl27zK5du8zf//53ExkZadavX2/27NljPvvsM/Paa69V7w8fwHlJMu+8847z/d69e423t7fZv3+/y7hrrrnGTJ8+vdzxx44dM02bNjWPPPJIXZdaLQRYAJbWt29fc8UVV7i0JSQkmKlTp1YrwH7yySfOMfPmzTOSzO7du51td9xxhxk4cGCVazo7HBpjzNSpU02HDh0qPebLL780kszhw4dd6lq1atV5P++yyy4zCxcudL5v2bKlufXWW53vc3NzjSQzY8YMZ1t6erqR5AyiY8eONePHj3eZ97PPPjNeXl7m2LFjznkff/xxlzFVPW7YsGEuY+6++25z9dVXu1wjALXv1wH2X//6l5FkGjVq5PLy8fExw4cPL3f8a6+9Znx8fExeXl49Vn1+Pm646QsAtapLly4u78PDw11+HV/dOUJDQ3XJJZeoVatWLm2bNm2q8nw9e/Z0+TV7r1699I9//ENlZWXy9vbW119/rdmzZ+ubb77Rzz//LIfDIUnKzs5Wx44dncf16NHDZd4jR45o9uzZ+ve//63c3FydOnVKx44dU3Z29jnPR5I6d+5crq2goEBhYWH65ptvtHXrVr366qvOMcYYORwOZWVlqUOHDhWeZ1WP+/V5jB49Wv3791e7du00aNAg/f73v9eAAQMqu5wAasmRI0ecfwd5e3u79DVu3Ljc+Oeff16///3vnX9neAoCLADLa9Cggct7m80mh8MhL6/Ty/zNWWtPT548ed45bDZbpXPWhqNHj2rgwIEaOHCgXn31VV166aXKzs7WwIEDyz3g9Otta6ZMmaKPP/5Yjz76qGJjY9WwYUPdeOON5Y779flU1nbmnI4cOaI77rhD99xzT7l6o6KiKj2Xqh736/Po1q2bsrKy9OGHH+qTTz7R8OHDlZycrLfeeqvSzwLw23Xt2lVlZWUqKCg475rWrKwsrV27Vu+99149VVd1BFgAF6xLL71UkpSbm6uuXbtKkssDXXVp48aNLu+/+OILtWnTRt7e3vrhhx9UWFiohx9+WJGRkZJU7oGqynz++ecaPXq08+niI0eOaM+ePb+53m7dumnbtm2KjY2tdIyvr6/KysqqfVxl7Ha7RowYoREjRujGG2/UoEGDdOjQIQUFBVV7LgD/58iRI9q1a5fzfVZWljIyMhQUFKS2bdvqf/7nf5SSkqJ//OMf6tq1qw4cOKA1a9aoS5cuuvbaa53HvfjiiwoPD9fgwYPdcRrnxC4EAC5YDRs2VM+ePfXwww9r+/bt+vTTT/XAAw/Uy2dnZ2dr8uTJyszM1Ouvv66FCxfq3nvvlXT6zqSvr68WLlyoH3/8Ue+9957mzJlTpXnbtGmjlStXKiMjQ998841GjhxZK3eGp06dqv/+97+aOHGiMjIytHPnTr377ruaOHGic0x0dLTWr1+v/fv36+DBg1U+riKPPfaYXn/9df3www/asWOH3nzzTYWFhalJkya/+VyAi91XX32lrl27Ov/hPnnyZHXt2lUzZ86UJC1ZskQpKSm677771K5dOw0bNkxffvmly29NHA6Hli5dqtGjR5dbauAJuAML4IL24osvauzYserevbvatWun+fPn18tay5SUFB07dkyJiYny9vbWvffeq/Hjx0s6fWd46dKl+stf/qInn3xS3bp106OPPqrrrrvuvPM+9thjuv3229W7d28FBwdr6tSpKikp+c31dunSRZ9++qn++te/qk+fPjLGqHXr1hoxYoRzzIMPPqg77rhDrVu3VmlpqYwxVTquIgEBAZo/f7527twpb29vJSQk6IMPPnAu+wBQc/369XNZOvVrDRo0UGpqqlJTUysd4+XlpZycnLoor1bYzLnOEABQbf369VN8fDzfWgUAdYR/6gIAAMBSWEIAANXw622ufm3btm31WA0AXJxYQgAA1XDq1KlzPvUfHR0tHx/uDQBAXSLAAgAAwFJYAwsAAABLIcACAADAUgiwAAAAsBQCLAAAACyFAAsAAABLIcACAADAUgiwAAAAsBQCLAAAACzl/wF5MjTI0E5WggAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(7, 5))\n", + "for row in summary:\n", + " label = \"char\" if row[\"tokenizer\"] == \"char\" else str(row[\"vocab_size\"])\n", + " ax.scatter(row[\"num_parameters\"], row[\"test_loss\"][0],\n", + " color=\"gray\" if row[\"tokenizer\"] == \"char\" else \"tab:blue\")\n", + " ax.annotate(label, (row[\"num_parameters\"], row[\"test_loss\"][0]),\n", + " textcoords=\"offset points\", xytext=(5, 5), fontsize=8)\n", + "ax.set_xlabel(\"num_parameters\")\n", + "ax.set_ylabel(\"test_loss\")\n", + "ax.set_title(\"num_parameters vs test_loss\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "f706ed6d", + "metadata": {}, + "source": [ + "*Notes: point labels identify which config each point is (`char`, or the WordPiece\n", + "`vocab_size`) - this is identification, not an interpretive claim. `char` has fewer\n", + "parameters than every WordPiece config here (smaller embedding table), which is worth\n", + "keeping in mind when comparing this plot against plots 1-2.*" + ] + }, + { + "cell_type": "markdown", + "id": "2e3b7b11", + "metadata": {}, + "source": [ + "## 7. train_time_sec by config" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "46065c2c", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:35.326171Z", + "iopub.status.busy": "2026-07-30T17:10:35.326006Z", + "iopub.status.idle": "2026-07-30T17:10:35.337145Z", + "shell.execute_reply": "2026-07-30T17:10:35.336246Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Excluding 1 run(s) with train_time_sec > 3x the median (likely contaminated by something external, e.g. the machine sleeping mid-run):\n", + "tokenizer vocab_size seed train_time_sec time_ratio_vs_median\n", + " char 25 1 39705.241565 69.237647\n" + ] + } + ], + "source": [ + "median_time = raw[\"train_time_sec\"].median()\n", + "raw[\"time_ratio_vs_median\"] = raw[\"train_time_sec\"] / median_time\n", + "outliers = raw[raw[\"time_ratio_vs_median\"] > 3]\n", + "clean = raw[raw[\"time_ratio_vs_median\"] <= 3]\n", + "\n", + "if len(outliers):\n", + " print(f\"Excluding {len(outliers)} run(s) with train_time_sec > 3x the median \"\n", + " f\"(likely contaminated by something external, e.g. the machine sleeping mid-run):\")\n", + " print(outliers[[\"tokenizer\", \"vocab_size\", \"seed\", \"train_time_sec\", \"time_ratio_vs_median\"]].to_string(index=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "dfe53dfa", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:35.338767Z", + "iopub.status.busy": "2026-07-30T17:10:35.338616Z", + "iopub.status.idle": "2026-07-30T17:10:35.481143Z", + "shell.execute_reply": "2026-07-30T17:10:35.480036Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYcNJREFUeJzt3XlcVdX+//H3ARlFQFRACucRx8JU1NSvkmReh7JMI8WyLMOcUstb5pCp2aBZDk1X7aaZZlqZ85CmIpmJOWXOmjGUCogDKKzfH/441yOgyEEQeT0fj/N4eNZaZ+/PXmw8580ejsUYYwQAAAAAdnAo7AIAAAAAFH0ECwAAAAB2I1gAAAAAsBvBAgAAAIDdCBYAAAAA7EawAAAAAGA3ggUAAAAAuxEsAAAAANiNYAEAAADAbgQL4A5RqVIl9e7du9ist6g4evSoLBaL3nnnncIu5Zb573//q1q1asnJyUne3t6SpNatW6t169b5vq5JkyapVq1aysjIyPdl58a1+/uPP/4oi8WiH3/8sVDqKQh5mfMVK1bIw8NDf//99y2szD63Yh+9Fcu0WCwaPXq09fnMmTNVoUIFpaam5ut6gPxAsAAKyJYtWzR69GglJiYWdik3rSjXjlvr999/V+/evVW1alV98skn+vjjj2/ZupKTk/XWW2/p5ZdfloPDrXv7Yn//n7zO+YMPPqhq1appwoQJt7C64ql3795KS0vTRx99VNilAFkQLIACsmXLFo0ZM+aWfVjZv3+/Pvnkk1uy7OvVfivXi9vfjz/+qIyMDL3//vvq3bu3unXrJklatWqVVq1ala/r+s9//qPLly+rR48e+brca93M72rLli114cIFtWzZ8pbWVFjsmfPnnntOH330kc6ePXsLKiu+XF1dFRERoffee0/GmMIuB7BBsABuQxkZGbp48eJNvcbFxUVOTk63qKLbb724PSQkJEiS9RSoTM7OznJ2ds7Xdc2aNUudOnWSq6trvi7XHg4ODnJ1dc23Iyjnzp27peNvlj1z3rVrV6WmpmrhwoW3oLLirVu3bjp27JjWr19f2KUANggWQAEYPXq0hg0bJkmqXLmyLBaLLBaLjh49KunKObT9+/fX3LlzVadOHbm4uGjFihWSpHfeeUfNmjVTmTJl5ObmpuDgYH399ddZ1nHtud+zZ8+WxWLR5s2bNWTIEJUrV04lS5bUww8/fFPnPd+o9pzWu2nTJg0YMEDlypWTt7e3nnvuOaWlpSkxMVG9evVS6dKlVbp0aQ0fPjzLX90yMjI0ZcoU1alTR66urvLz89Nzzz2nM2fO5LpuSTp79qwGDRqkSpUqycXFRb6+vnrggQf066+/2oyLjo7Wgw8+KC8vL7m7u6tVq1bavHlzluWdPHlSffr0UUBAgFxcXFS5cmX169dPaWlpuapn8uTJqlixotzc3NSqVSvt3r3b2jdr1ixZLBbt2LEjy+vGjx8vR0dHnTx58rrLz019hw8f1mOPPSYfHx+5u7uradOm+uGHH2yWk3ndwIIFC/Tmm2/q7rvvlqurq9q2bauDBw9ax1WqVEmjRo2SJJUrV87mXPDszjU/duyYOnXqpJIlS8rX11eDBw/WypUrc3WNwpEjR/Tbb78pNDQ0S9+5c+f00ksvKTAwUC4uLqpZs6beeecdm/0q81qX2bNnZ3n91XXfaH+/Vk7XWORmnxo9erQsFov27t2rJ554QqVLl1aLFi1ynIPM360NGzbohRdekK+vr+6++25JV06PqVSpUpbXZK7j2u3t37+/lixZorp168rFxUV16tSx/p+T6XpzPn/+fAUHB6tUqVLy9PRUvXr19P7779uM8fX1Vf369fXtt9/muE1X+/333/Xoo4/Kx8dHrq6uatSokb777jtrf0JCgsqVK6fWrVvb/GwPHjyokiVL6vHHH7dZ3hdffKHGjRvL3d1dpUuXVsuWLa97FC1zfq/9Wef0M/74449VtWpVubm5qXHjxvrpp5+yXW5qaqpGjRqlatWqycXFRYGBgRo+fHiWayRSU1M1ePBglStXTqVKlVKnTp30559/ZrvM4OBg+fj45HpugYJSorALAIqDRx55RH/88Ye+/PJLTZ48WWXLlpV05cNYpnXr1mnBggXq37+/ypYta/2Q8P7776tTp04KDw9XWlqa5s+fr8cee0xLly5Vhw4dbrjuF198UaVLl9aoUaN09OhRTZkyRf3799dXX32Vb7XntF5/f3+NGTNGW7du1ccffyxvb29t2bJFFSpU0Pjx47Vs2TK9/fbbqlu3rnr16mV97XPPPafZs2frqaee0oABA3TkyBF9+OGH2rFjhzZv3pzrIyTPP/+8vv76a/Xv319BQUE6deqUNm3apH379unee++VdGXe27dvr+DgYI0aNUoODg6aNWuW2rRpo59++kmNGzeWJP31119q3LixEhMT1bdvX9WqVUsnT57U119/rfPnz9/wr/Off/65zp49q8jISF28eFHvv/++2rRpo127dsnPz0+PPvqoIiMjNXfuXN1zzz02r507d65at26tu+66K8fl56a++Ph4NWvWTOfPn9eAAQNUpkwZzZkzR506ddLXX3+thx9+2GaZEydOlIODg4YOHaqkpCRNmjRJ4eHhio6OliRNmTJFn3/+uRYvXqwZM2bIw8ND9evXz7a+c+fOqU2bNoqNjdXAgQPl7++vefPm5fovrlu2bJEk688tkzFGnTp10vr169WnTx81bNhQK1eu1LBhw3Ty5ElNnjw5V8vPlNf9/Wq53acyPfbYY6pevbrGjx+fq1NbXnjhBZUrV06vv/56no9YbNq0Sd98841eeOEFlSpVSlOnTlXXrl11/PhxlSlTRlLOc7569Wr16NFDbdu21VtvvSVJ2rdvnzZv3qyBAwfajA0ODtaSJUtuWM+ePXvUvHlz3XXXXXrllVdUsmRJLViwQF26dNGiRYv08MMPy9fXVzNmzNBjjz2mDz74QAMGDFBGRoZ69+6tUqVKafr06dbljRkzRqNHj1azZs00duxYOTs7Kzo6WuvWrVO7du3yNGdX++yzz/Tcc8+pWbNmGjRokA4fPqxOnTrJx8dHgYGB1nEZGRnq1KmTNm3apL59+6p27dratWuXJk+erD/++MNmbp555hl98cUXeuKJJ9SsWTOtW7fuuv/H33vvvdn+AQQoVAZAgXj77beNJHPkyJEsfZKMg4OD2bNnT5a+8+fP2zxPS0szdevWNW3atLFpr1ixoomIiLA+nzVrlpFkQkNDTUZGhrV98ODBxtHR0SQmJuZL7TmtNywszGa9ISEhxmKxmOeff97advnyZXP33XebVq1aWdt++uknI8nMnTvXZj0rVqzItv16vLy8TGRkZI79GRkZpnr16llqPX/+vKlcubJ54IEHrG29evUyDg4OZtu2bdkuJydHjhwxkoybm5v5888/re3R0dFGkhk8eLC1rUePHiYgIMCkp6db23799VcjycyaNeu625qb+gYNGmQkmZ9++snad/bsWVO5cmVTqVIl63rXr19vJJnatWub1NRU69j333/fSDK7du2yto0aNcpIMn///bfNOlu1amXzc3333XeNJLNkyRJr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orp162rNmjV6+umnre0dO3bU//3f/+nVV1/V0aNH1aBBA61atUrffvutBg0aZHPO+jPPPKOJEyfqmWeeUaNGjbRx40b98ccfWdZlz/5+M/tUfurevbtefvllPfzwwxowYIDOnz+vGTNmqEaNGrm+0cO1cprzZ555RqdPn1abNm10991369ixY/rggw/UsGFDm7+gJyQk6LffflNkZOQN1zVt2jS1aNFC9erV07PPPqsqVaooPj5eUVFR+vPPP7Vz505J0sCBA3Xq1CmtWbNGjo6OevDBB/XMM89o3Lhx6ty5sxo0aKBq1arp1Vdf1RtvvKH7779fjzzyiFxcXLRt2zYFBARowoQJ2dZQp04dNW3aVCNGjNDp06fl4+Oj+fPn6/LlyzbjnJycNG7cOD333HNq06aNHn/8cR05ckSzZs3Kco1Fz549tWDBAj3//PNav369mjdvrvT0dP3+++9asGCBVq5cqUaNGqlhw4bq0aOHpk+frqSkJDVr1kxr167N8Yje9u3bdfr0aZuL1oHbQqHciwoopt544w1z1113GQcHB5vbGkrK8baon332malevbpxcXExtWrVMrNmzcr2FpI53fb12tuPXnvrRHtrz+16c7otaUREhClZsmSW9X388ccmODjYuLm5mVKlSpl69eqZ4cOHm7/++itX9aamppphw4aZBg0amFKlSpmSJUuaBg0amOnTp2cZu2PHDvPII4+YMmXKGBcXF1OxYkXTrVs3s3btWptxx44dM7169TLlypUzLi4upkqVKiYyMtLmlpPXyrzN6dtvv23effddExgYaFxcXMz9999vdu7cme1rYmNjjaOjo6lRo0autvVm6jt06JB59NFHjbe3t3F1dTWNGzc2S5cutVlO5j6ycOHCbLfl6lu25vZ2s8YYc/jwYdOhQwfj5uZmypUrZ1566SWzaNEiI8ls3br1htv33nvvGQ8Pjyy3YD579qwZPHiwCQgIME5OTqZ69erm7bffznIb4PPnz5s+ffoYLy8vU6pUKdOtWzeTkJCQ7e08c7u/5/T7lJt9Kqe5y0lOv1uZVq1aZerWrWucnZ1NzZo1zRdffJHj7Waz+//m2m0zJvs5//rrr027du2Mr6+vcXZ2NhUqVDDPPfeciY2NtXntjBkzjLu7u0lOTs7V9h06dMj06tXL+Pv7GycnJ3PXXXeZf/3rX+br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hGjXrl02/2GtXr1anp6eCgoKso659me0evVq6zLuVJUrV5a/v7/NticnJys6Otpm/hITE7V9+3brmHXr1ikjI0NNmjSxjtm4caMuXbpkHbN69WrVrFlTpUuXto4pynNsjFH//v21ePFirVu3Lsvh+ILaF52dnRUcHGwzJiMjQ2vXri0yc5mTjIwMpaamMpc3qW3bttq1a5diYmKsj0aNGik8PNz6b+Yzbwrj/eZOnMfb6b0mN7XcMQr76nHcGqNHjzalS5c2c+bMMQcPHjRRUVHm008/zfZ2s2fOnDGSzPr1640xxgwePNgEBgaazZs3m71795pnnnnGeHp6ms6dO1tfc/XdP+5EL730kvnxxx/NkSNHzObNm01oaKgpW7asSUhIMMZcuf1fhQoVzLp168wvv/xiQkJCTEhIiPX1mbf/a9eunYmJiTErVqww5cqVy/b2f8OGDTP79u0z06ZNu2NuN3v27FmzY8cOs2PHDiPJvPfee2bHjh3m2LFjxpgrt93z9vY23377rfntt99M586ds70F4D333GOio6PNpk2bTPXq1W1uAZiYmGj8/PxMz549ze7du838+fONu7t7llsAlihRwrzzzjtm3759ZtSoUUXqdrP9+vUzXl5e5scff7S5FeX58+etYwpqX5w/f75xcXExs2fPNnv37jV9+/Y13t7eNneiud298sorZsOGDebIkSPmt99+M6+88oqxWCxm1apVxhjm0l7Xvi8wn7lzu7zfFMV5LErvNbmp5U5AsLhDpaenm3HjxpmKFSsaJycnU6FCBTN+/PhcBYtTp06Zzp07Gw8PD+Pr62tee+0106tXr2IVLB5//HFTvnx54+zsbO666y7z+OOPm4MHD1r7L1y4YF544QVTunRp4+7ubh5++GETGxtrs4yjR4+a9u3bGzc3N1O2bFnz0ksvmUuXLtmMWb9+vWnYsKFxdnY2VapUMbNmzSqIzbvl1q9fbyRleURERBhjrtx6b+TIkcbPz8+4uLiYtm3bmv3799ss49SpU6ZHjx7Gw8PDeHp6mqeeesqcPXvWZszOnTtNixYtjIuLi7nrrrvMxIkTs9SyYMECU6NGDePs7Gzq1Kljfvjhh1u23fktuzmUZLOfFOS++MEHH5gKFSoYZ2dn07hxY7N169Zbsdm3zNNPP20qVqxonJ2dTbly5Uzbtm2tocIY5tJe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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "time_stats = (\n", + " clean.groupby([\"tokenizer\", \"vocab_size\"])[\"train_time_sec\"]\n", + " .agg([\"mean\", \"std\"])\n", + " .reset_index()\n", + " .sort_values([\"tokenizer\", \"vocab_size\"])\n", + ")\n", + "time_labels = [\"char\" if t == \"char\" else str(int(v)) for t, v in zip(time_stats[\"tokenizer\"], time_stats[\"vocab_size\"])]\n", + "\n", + "fig, ax = plt.subplots(figsize=(8, 4.5))\n", + "ax.bar(time_labels, time_stats[\"mean\"], yerr=time_stats[\"std\"].fillna(0), capsize=3)\n", + "ax.set_xlabel(\"config (vocab_size, or char)\")\n", + "ax.set_ylabel(\"train_time_sec\")\n", + "ax.set_title(\"train_time_sec by config (outlier run(s) excluded)\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "2422584c", + "metadata": {}, + "source": [ + "## 8. unk_token_fraction vs vocab_size, on this AIRR file" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "b82b3da1", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-30T17:10:35.482895Z", + "iopub.status.busy": "2026-07-30T17:10:35.482730Z", + "iopub.status.idle": "2026-07-30T17:10:35.490843Z", + "shell.execute_reply": "2026-07-30T17:10:35.489975Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Not found: ../artifacts/tokenizers_1M_integ_on_background100k/tokenization_stats.json\n", + "Run scripts/calc_tokenization_stats.py on the same AIRR file used for the results above (pointed at the same --tokenizers-dir) to produce this file, then re-run this cell.\n" + ] + } + ], + "source": [ + "domain_stats_path = Path(DOMAIN_TOKENIZATION_STATS_PATH)\n", + "\n", + "if not domain_stats_path.exists():\n", + " print(f\"Not found: {domain_stats_path}\")\n", + " print(\"Run scripts/calc_tokenization_stats.py on the same AIRR file used for the \"\n", + " \"results above (pointed at the same --tokenizers-dir) to produce this file, \"\n", + " \"then re-run this cell.\")\n", + "else:\n", + " with open(domain_stats_path) as f:\n", + " domain_stats = json.load(f)\n", + " per_vocab_size = domain_stats[\"per_vocab_size\"]\n", + "\n", + " domain_vocab_sizes = [vs for vs in vocab_sizes if str(vs) in per_vocab_size]\n", + " missing = [vs for vs in vocab_sizes if str(vs) not in per_vocab_size]\n", + " if missing:\n", + " print(f\"No tokenization_stats entry for vocab_size={missing}; plotting only {domain_vocab_sizes}.\")\n", + "\n", + " unk_fractions = [per_vocab_size[str(vs)][\"splits\"][\"test\"][\"unk_token_fraction\"] for vs in domain_vocab_sizes]\n", + "\n", + " fig, ax1 = plt.subplots(figsize=(7, 4.5))\n", + " ax1.errorbar(vocab_sizes, loss_means, yerr=loss_stds, marker=\"o\", color=\"tab:blue\", label=\"test_loss\")\n", + " ax1.set_xlabel(\"vocab_size\")\n", + " ax1.set_ylabel(\"test_loss\", color=\"tab:blue\")\n", + " ax1.tick_params(axis=\"y\", labelcolor=\"tab:blue\")\n", + "\n", + " ax2 = ax1.twinx()\n", + " ax2.plot(domain_vocab_sizes, unk_fractions, marker=\"s\", color=\"tab:red\", label=\"unk_token_fraction (test split)\")\n", + " ax2.set_ylabel(\"unk_token_fraction\", color=\"tab:red\")\n", + " ax2.tick_params(axis=\"y\", labelcolor=\"tab:red\")\n", + "\n", + " fig.suptitle(\"test_loss and unk_token_fraction vs vocab_size\")\n", + " fig.tight_layout()\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "b5bd7046", + "metadata": {}, + "source": [ + "*Notes: `unk_token_fraction` here comes from running the WordPiece tokenizers on THIS\n", + "AIRR file's own test split (via `calc_tokenization_stats.py`), separately from the model\n", + "training run above. If this line rises steeply with `vocab_size` on this file - more so\n", + "than what `tokenizer_stats_report.ipynb` shows for the file the tokenizers were originally\n", + "trained on - that supports a domain-mismatch explanation for plots 1-2 rather than a\n", + "WordPiece-architecture explanation. If it stays flat/low, domain mismatch is less likely\n", + "to be the cause and the effect in plots 1-2 is more likely something else (e.g. see plot 5\n", + "for a convergence-based explanation).*" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 8790782b5fed9d7fcac573339af29ae56b00920d Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 30 Jul 2026 21:19:09 +0300 Subject: [PATCH 27/70] Save per-epoch train/val metrics for each run --- scripts/compare_forward_tokenizers.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scripts/compare_forward_tokenizers.py b/scripts/compare_forward_tokenizers.py index 25c5f8c..404bb6c 100644 --- a/scripts/compare_forward_tokenizers.py +++ b/scripts/compare_forward_tokenizers.py @@ -137,10 +137,12 @@ def run_one(spec, seed, args, logger): best_val_loss = float("inf") epochs_to_best_val = None + history = [] train_start = time.perf_counter() for epoch in range(1, args.epochs + 1): - run_epoch(model, prepared["train_loader"], optimizer, device, "train", epoch, args.epochs, args.log_interval, False) + train_metrics = run_epoch(model, prepared["train_loader"], optimizer, device, "train", epoch, args.epochs, args.log_interval, False) val_metrics = run_epoch(model, prepared["val_loader"], None, device, "val", epoch, args.epochs, args.log_interval, False) + history.append({"epoch": epoch, "train": train_metrics, "val": val_metrics}) if val_metrics["loss"] < best_val_loss: best_val_loss = val_metrics["loss"] epochs_to_best_val = epoch @@ -149,6 +151,13 @@ def run_one(spec, seed, args, logger): test_metrics = run_epoch(model, prepared["test_loader"], None, device, "test", args.epochs, args.epochs, args.log_interval, False) inference_time_sec = _benchmark_inference(model, prepared["test_loader"], device, args.inference_repeats) + tokenizer_label = "char" if tokenizer_info["tokenizer_type"] == "char" else f"wordpiece_{vocab_size}" + history_dir = Path(args.output_root) / "history" + history_dir.mkdir(parents=True, exist_ok=True) + history_path = history_dir / f"{tokenizer_label}_seed{seed}.json" + save_json(history_path, history) + logger.info("wrote per-epoch history path=%s", history_path) + return { "tokenizer": tokenizer_info["tokenizer_type"], "vocab_size": tokenizer_info["vocab_size"], From 2c137fb9f16abc7aa738acf721dae277ba1aa146 Mon Sep 17 00:00:00 2001 From: maria Date: Sat, 1 Aug 2026 13:17:54 +0300 Subject: [PATCH 28/70] Add vocab filtering by max token length New filter_vocab_by_max_token_length() drops WordPiece vocab entries longer than N amino acids --- irrm_codec/wordpiece_tokenization.py | 44 +++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py index 9ea553f..c028a38 100644 --- a/irrm_codec/wordpiece_tokenization.py +++ b/irrm_codec/wordpiece_tokenization.py @@ -7,6 +7,7 @@ from pathlib import Path from tokenizers import Tokenizer +from tokenizers.models import WordPiece from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID @@ -53,6 +54,47 @@ def wordpiece_vocab_size(tokenizer) -> int: return tokenizer.get_vocab_size() +def filter_vocab_by_max_token_length(tokenizer: Tokenizer, max_token_length: int) -> Tokenizer: + """Drop vocab entries longer than max_token_length amino acids, keeping special tokens. + + "Length" is the piece's real amino-acid count, i.e. the "##" continuation prefix isn't + counted. Remaining tokens get contiguous ids (0..k-1), with PAD/UNK/BOS/EOS staying at + 0/1/2/3 since they're always kept and sorted first. Encoding after filtering just falls + back to shorter surviving pieces (WordPiece's normal longest-match behavior) - it does + not raise or produce extra [UNK] tokens by itself. + + This does not touch the tokenizer.json file on disk or retrain anything - it only + rebuilds an in-memory Tokenizer with a smaller vocab for the current run. + """ + if max_token_length < 1: + raise ValueError(f"max_token_length must be >= 1, got {max_token_length}.") + + prefix = tokenizer.model.continuing_subword_prefix + old_vocab = tokenizer.get_vocab() + + kept_tokens = [] + for token, _old_id in sorted(old_vocab.items(), key=lambda kv: kv[1]): + if token in _EXPECTED_SPECIAL_IDS: + kept_tokens.append(token) + continue + piece = token[len(prefix):] if token.startswith(prefix) else token + if len(piece) <= max_token_length: + kept_tokens.append(token) + + new_vocab = {token: new_id for new_id, token in enumerate(kept_tokens)} + new_model = WordPiece( + new_vocab, + unk_token=tokenizer.model.unk_token, + continuing_subword_prefix=prefix, + max_input_chars_per_word=tokenizer.model.max_input_chars_per_word, + ) + filtered = Tokenizer(new_model) + filtered.normalizer = tokenizer.normalizer + filtered.pre_tokenizer = tokenizer.pre_tokenizer + filtered.decoder = tokenizer.decoder + return filtered + + class WordpieceEncodeFn: """Binds a tokenizer to encode_wordpiece so it matches datasets.py's encode_fn(seq, max_len).""" @@ -60,4 +102,4 @@ def __init__(self, tokenizer): self.tokenizer = tokenizer def __call__(self, seq, max_len): - return encode_wordpiece(seq, self.tokenizer, max_len) + return encode_wordpiece(seq, self.tokenizer, max_len) \ No newline at end of file From 8b9e4237a2ff94e8378bfb321bd21de97eded4e9 Mon Sep 17 00:00:00 2001 From: maria Date: Sat, 1 Aug 2026 13:20:01 +0300 Subject: [PATCH 29/70] Add --max-token-len to filter WordPiece vocabs by token length Off by default. Filtered and unfiltered runs are kept as separate configs, never mixed into the same average. Only affects this comparison script - the tokenizer files and real training scripts aren't touched. --- scripts/compare_forward_tokenizers.py | 87 +++++++++++++++++++++------ 1 file changed, 67 insertions(+), 20 deletions(-) diff --git a/scripts/compare_forward_tokenizers.py b/scripts/compare_forward_tokenizers.py index 404bb6c..275897f 100644 --- a/scripts/compare_forward_tokenizers.py +++ b/scripts/compare_forward_tokenizers.py @@ -20,9 +20,13 @@ wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_40000/tokenizer.json \ wordpiece:artifacts/tokenizers_1M/wordpiece_vocab_50000/tokenizer.json -Each --configs entry is "char" or "wordpiece:". Output: +Each --configs entry is "char" or "wordpiece:". Optional +--max-token-len N filters every WordPiece vocab down to tokens of <= N amino acids +(char is unaffected) - runs with and without the filter are tracked as distinct configs, +never averaged together. Output: /raw_results.csv one row per (config, seed) run /summary_table.md one row per config, mean +/- std over seeds + /history/*.json per-epoch train/val metrics, one file per run """ import argparse import csv @@ -38,9 +42,15 @@ from irrm_codec.tokenizer_cli import resolve_tokenizer from irrm_codec.train_forward import run_epoch from irrm_codec.utils import choose_device, save_json, set_seed, setup_logging +from irrm_codec.wordpiece_tokenization import ( + WordpieceEncodeFn, + filter_vocab_by_max_token_length, + load_wordpiece_tokenizer, + wordpiece_vocab_size, +) RESULT_FIELDS = [ - "tokenizer", "vocab_size", "max_len", "seed", + "tokenizer", "vocab_size", "max_token_len", "max_len", "seed", "test_loss", "test_cosine", "best_val_loss", "epochs_to_best_val", "train_time_sec", "inference_time_sec", "num_parameters", "tokenizer_path", ] @@ -63,6 +73,15 @@ def parse_args(): parser.add_argument("--num-workers", type=int, default=0) parser.add_argument("--log-interval", type=int, default=10) parser.add_argument("--inference-repeats", type=int, default=3, help="Repeats to average inference wall-clock over.") + parser.add_argument( + "--max-token-len", + type=int, + default=None, + help="Filter each WordPiece tokenizer's vocab down to tokens of at most this many " + "amino acids (special tokens always kept) before training. Default: no filtering " + "(the original vocab is used as-is). Does not touch tokenizer.json files or char " + "configs - filtering happens per-run, in this script only, not in tokenizer training.", + ) parser.add_argument("--seeds", type=int, nargs="+", default=[1, 42, 777]) parser.add_argument( "--configs", @@ -110,7 +129,24 @@ def run_one(spec, seed, args, logger): device = choose_device() tokenizer_args = _tokenizer_args_from_spec(spec) - encode_fn, vocab_size, tokenizer_info = resolve_tokenizer(tokenizer_args, logger) + if args.max_token_len is not None and tokenizer_args.tokenizer_type == "wordpiece": + tokenizer = load_wordpiece_tokenizer(tokenizer_args.tokenizer_path) + original_vocab_size = wordpiece_vocab_size(tokenizer) + tokenizer = filter_vocab_by_max_token_length(tokenizer, args.max_token_len) + vocab_size = wordpiece_vocab_size(tokenizer) + encode_fn = WordpieceEncodeFn(tokenizer) + tokenizer_info = { + "tokenizer_type": "wordpiece", + "tokenizer_path": tokenizer_args.tokenizer_path, + "vocab_size": vocab_size, + } + logger.info( + "tokenizer_type=wordpiece vocab_size=%d (filtered from %d by max_token_len=%d) tokenizer_path=%s", + vocab_size, original_vocab_size, args.max_token_len, tokenizer_args.tokenizer_path, + ) + else: + # char, or wordpiece with no --max-token-len: unfiltered, shared with train_forward.py/train_inverse.py + encode_fn, vocab_size, tokenizer_info = resolve_tokenizer(tokenizer_args, logger) data_args = argparse.Namespace( airr_path=args.airr_path, @@ -151,16 +187,20 @@ def run_one(spec, seed, args, logger): test_metrics = run_epoch(model, prepared["test_loader"], None, device, "test", args.epochs, args.epochs, args.log_interval, False) inference_time_sec = _benchmark_inference(model, prepared["test_loader"], device, args.inference_repeats) + row_max_token_len = args.max_token_len if tokenizer_info["tokenizer_type"] == "wordpiece" else None + tokenizer_label = "char" if tokenizer_info["tokenizer_type"] == "char" else f"wordpiece_{vocab_size}" + filter_suffix = f"_n{row_max_token_len}" if row_max_token_len is not None else "" history_dir = Path(args.output_root) / "history" history_dir.mkdir(parents=True, exist_ok=True) - history_path = history_dir / f"{tokenizer_label}_seed{seed}.json" + history_path = history_dir / f"{tokenizer_label}{filter_suffix}_seed{seed}.json" save_json(history_path, history) logger.info("wrote per-epoch history path=%s", history_path) return { "tokenizer": tokenizer_info["tokenizer_type"], "vocab_size": tokenizer_info["vocab_size"], + "max_token_len": row_max_token_len, "max_len": args.max_len, "seed": seed, "test_loss": test_metrics["loss"], @@ -184,17 +224,20 @@ def _mean_std(values): def summarize(rows): - """One aggregated row per (tokenizer, vocab_size), mean +/- std across seeds.""" + """One aggregated row per (tokenizer, vocab_size, max_token_len), mean +/- std across seeds.""" groups = {} for row in rows: - key = (row["tokenizer"], row["vocab_size"]) + key = (row["tokenizer"], row["vocab_size"], row["max_token_len"]) groups.setdefault(key, []).append(row) summary = [] - for (tokenizer, vocab_size), group_rows in sorted(groups.items(), key=lambda kv: (kv[0][0], kv[0][1] or 0)): + for (tokenizer, vocab_size, max_token_len), group_rows in sorted( + groups.items(), key=lambda kv: (kv[0][0], kv[0][1] or 0, kv[0][2] or 0) + ): summary.append({ "tokenizer": tokenizer, "vocab_size": vocab_size, + "max_token_len": max_token_len, "max_len": group_rows[0]["max_len"], "n_seeds": len(group_rows), "test_loss": _mean_std([r["test_loss"] for r in group_rows]), @@ -215,14 +258,15 @@ def _fmt(mean_std, precision=4): def write_markdown_table(summary, path): lines = [ - "| tokenizer | vocab_size | max_len | test_loss | test_cosine | best_val_loss | " + "| tokenizer | vocab_size | max_token_len | max_len | test_loss | test_cosine | best_val_loss | " "epochs_to_best_val | train_time_sec | inference_time_sec | num_parameters | notes |", - "|---|---|---|---|---|---|---|---|---|---|---|", + "|---|---|---|---|---|---|---|---|---|---|---|---|", ] for row in summary: notes = f"n={row['n_seeds']} seeds" + max_token_len = row["max_token_len"] if row["max_token_len"] is not None else "-" lines.append( - f"| {row['tokenizer']} | {row['vocab_size']} | {row['max_len']} | " + f"| {row['tokenizer']} | {row['vocab_size']} | {max_token_len} | {row['max_len']} | " f"{_fmt(row['test_loss'])} | {_fmt(row['test_cosine'])} | {_fmt(row['best_val_loss'])} | " f"{_fmt(row['epochs_to_best_val'], precision=1)} | {_fmt(row['train_time_sec'], precision=1)} | " f"{_fmt(row['inference_time_sec'], precision=3)} | {row['num_parameters']} | {notes} |" @@ -231,18 +275,20 @@ def write_markdown_table(summary, path): def _load_completed_runs(csv_path): - """(tokenizer_path or None, seed) pairs already present in an existing raw_results.csv.""" + """(tokenizer_path or None, max_token_len, seed) triples already present in raw_results.csv.""" if not csv_path.exists(): return set(), [] with open(csv_path, newline="", encoding="utf-8") as f: existing_rows = list(csv.DictReader(f)) + # .get(..., "") covers resuming from a CSV written before --max-token-len existed completed = { - (row["tokenizer_path"] or None, int(row["seed"])) + (row["tokenizer_path"] or None, int(row["max_token_len"]) if row.get("max_token_len") else None, int(row["seed"])) for row in existing_rows } # csv.DictReader gives strings back; downstream code (summarize()) expects numeric fields for row in existing_rows: row["vocab_size"] = int(row["vocab_size"]) + row["max_token_len"] = int(row["max_token_len"]) if row.get("max_token_len") else None row["max_len"] = int(row["max_len"]) row["seed"] = int(row["seed"]) row["test_loss"] = float(row["test_loss"]) @@ -256,11 +302,12 @@ def _load_completed_runs(csv_path): return completed, existing_rows -def _spec_key(spec): - """(tokenizer_path or None) identity used to match a --configs entry against a CSV row.""" +def _spec_key(spec, args): + """(tokenizer_path or None, max_token_len) identity matched against a CSV row.""" if spec == "char": - return None - return spec.split(":", 1)[1] + return None, None + path = spec.split(":", 1)[1] + return path, args.max_token_len def main(): @@ -285,12 +332,12 @@ def main(): try: for spec in args.configs: - key_path = _spec_key(spec) + key = _spec_key(spec, args) for seed in args.seeds: - if (key_path, seed) in completed: - logger.info("skipping already-completed config=%s seed=%d", spec, seed) + if (*key, seed) in completed: + logger.info("skipping already-completed config=%s seed=%d max_token_len=%s", spec, seed, args.max_token_len) continue - logger.info("running config=%s seed=%d", spec, seed) + logger.info("running config=%s seed=%d max_token_len=%s", spec, seed, args.max_token_len) row = run_one(spec, seed, args, logger) rows.append(row) writer.writerow(row) From 245e82328b7c4b06528e3dc4cadb04f2bea21ff7 Mon Sep 17 00:00:00 2001 From: maria Date: Sat, 1 Aug 2026 14:30:23 +0300 Subject: [PATCH 30/70] Fix PAD/UNK leaking into decode() output after filtering A rebuilt tokenizer forgot to mark special tokens as special, so skip_special_tokens quietly stopped working. Doesn't affect any results so far - nothing decodes yet, only encodes. --- irrm_codec/wordpiece_tokenization.py | 38 +++++++++++++++++++--------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py index c028a38..e8fef18 100644 --- a/irrm_codec/wordpiece_tokenization.py +++ b/irrm_codec/wordpiece_tokenization.py @@ -54,6 +54,31 @@ def wordpiece_vocab_size(tokenizer) -> int: return tokenizer.get_vocab_size() +def _rebuild_tokenizer_with_vocab(tokenizer: Tokenizer, kept_tokens: list) -> Tokenizer: + """Reassign contiguous ids (0..k-1) for kept_tokens (in their original relative order) + and build a new Tokenizer sharing everything except the vocab. + + add_special_tokens() is required here: a freshly constructed Tokenizer(model) doesn't + know which of its vocab entries are "special" (that's tracked separately from + model.vocab) - without it, tokenizer.decode(ids, skip_special_tokens=True) silently + stops skipping PAD/UNK/BOS/EOS. Registering strings already present in the model's + vocab does not create new entries or change their ids. + """ + new_vocab = {token: new_id for new_id, token in enumerate(kept_tokens)} + new_model = WordPiece( + new_vocab, + unk_token=tokenizer.model.unk_token, + continuing_subword_prefix=tokenizer.model.continuing_subword_prefix, + max_input_chars_per_word=tokenizer.model.max_input_chars_per_word, + ) + filtered = Tokenizer(new_model) + filtered.normalizer = tokenizer.normalizer + filtered.pre_tokenizer = tokenizer.pre_tokenizer + filtered.decoder = tokenizer.decoder + filtered.add_special_tokens(list(_EXPECTED_SPECIAL_IDS.keys())) + return filtered + + def filter_vocab_by_max_token_length(tokenizer: Tokenizer, max_token_length: int) -> Tokenizer: """Drop vocab entries longer than max_token_length amino acids, keeping special tokens. @@ -81,18 +106,7 @@ def filter_vocab_by_max_token_length(tokenizer: Tokenizer, max_token_length: int if len(piece) <= max_token_length: kept_tokens.append(token) - new_vocab = {token: new_id for new_id, token in enumerate(kept_tokens)} - new_model = WordPiece( - new_vocab, - unk_token=tokenizer.model.unk_token, - continuing_subword_prefix=prefix, - max_input_chars_per_word=tokenizer.model.max_input_chars_per_word, - ) - filtered = Tokenizer(new_model) - filtered.normalizer = tokenizer.normalizer - filtered.pre_tokenizer = tokenizer.pre_tokenizer - filtered.decoder = tokenizer.decoder - return filtered + return _rebuild_tokenizer_with_vocab(tokenizer, kept_tokens) class WordpieceEncodeFn: From ce7b00c1a0a58f411d13dd5c617d5392ddb5f4f0 Mon Sep 17 00:00:00 2001 From: maria Date: Sat, 1 Aug 2026 17:31:27 +0300 Subject: [PATCH 31/70] Point report notebooks at latest runs, add convergence-curves notebook, move launch scripts into scripts/ --- .../compare_forward_tokenizers_report.ipynb | 585 +------ .../convergence_curves_by_epoch_report.ipynb | 282 ++++ notebooks/tokenizer_stats_report.ipynb | 1439 +---------------- scripts/run1_default_40epochs.sh | 31 + scripts/run2_maxtokenlen9_40epochs.sh | 32 + scripts/run_both_sequential.sh | 3 + scripts/run_compare_100k.sh | 16 + scripts/run_compare_40epochs_upto30k.sh | 14 + .../run_compare_finegrid_maxlen9_40epochs.sh | 26 + .../run_compare_finegrid_maxlen9_50epochs.sh | 26 + 10 files changed, 495 insertions(+), 1959 deletions(-) create mode 100644 notebooks/convergence_curves_by_epoch_report.ipynb create mode 100644 scripts/run1_default_40epochs.sh create mode 100644 scripts/run2_maxtokenlen9_40epochs.sh create mode 100644 scripts/run_both_sequential.sh create mode 100644 scripts/run_compare_100k.sh create mode 100644 scripts/run_compare_40epochs_upto30k.sh create mode 100644 scripts/run_compare_finegrid_maxlen9_40epochs.sh create mode 100644 scripts/run_compare_finegrid_maxlen9_50epochs.sh diff --git a/notebooks/compare_forward_tokenizers_report.ipynb b/notebooks/compare_forward_tokenizers_report.ipynb index 70561a1..2159d0e 100644 --- a/notebooks/compare_forward_tokenizers_report.ipynb +++ b/notebooks/compare_forward_tokenizers_report.ipynb @@ -5,19 +5,19 @@ "id": "d4b91ee9", "metadata": {}, "source": [ - "# Compare Forward Tokenizers — char vs WordPiece\n", + "# Compare Forward Tokenizers \u2014 char vs WordPiece\n", "\n", "Reads the output of `scripts/compare_forward_tokenizers.py` (`raw_results.csv` +\n", "`summary.json`) and, optionally, `scripts/calc_tokenization_stats.py`'s output for the\n", "same AIRR file, and renders the comparison as tables and plots.\n", "\n", "Interpretation notes live in markdown cells next to each plot, not on the plots\n", - "themselves — the plots only show data (axes, legend identifying which series is which)." + "themselves \u2014 the plots only show data (axes, legend identifying which series is which)." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "25047bb7", "metadata": { "execution": { @@ -33,7 +33,7 @@ "outputs": [], "source": [ "# parameters\n", - "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_background100k\"\n", + "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_background100k_40epochs_upto30k\"\n", "# Optional: output of calc_tokenization_stats.py run on the SAME AIRR file used above,\n", "# with --tokenizers-dir pointing at the same WordPiece tokenizers. Leave as-is if you\n", "# haven't run that diagnostic yet - the relevant section below will just note that.\n", @@ -42,7 +42,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "b314dd93", "metadata": { "execution": { @@ -52,157 +52,7 @@ "shell.execute_reply": "2026-07-30T17:10:34.311678Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loaded 24 individual runs across 8 tokenizer configs from ../artifacts/compare_forward_tokenizers_background100k\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizemax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_path
0char254010.1998620.8650320.1995651939705.2415650.56450810850856NaN
1char2540420.2017430.8642500.19846320561.3526140.54877810850856NaN
2char25407770.2056140.8620150.20403219560.5015620.54793410850856NaN
3wordpiece50004010.3011740.7928560.30171620570.4419420.55197011169256artifacts/tokenizers_1M_integ/wordpiece_vocab_...
4wordpiece500040420.3028970.7934630.29744119820.3054570.56868511169256artifacts/tokenizers_1M_integ/wordpiece_vocab_...
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size max_len seed test_loss test_cosine \\\n", - "0 char 25 40 1 0.199862 0.865032 \n", - "1 char 25 40 42 0.201743 0.864250 \n", - "2 char 25 40 777 0.205614 0.862015 \n", - "3 wordpiece 5000 40 1 0.301174 0.792856 \n", - "4 wordpiece 5000 40 42 0.302897 0.793463 \n", - "\n", - " best_val_loss epochs_to_best_val train_time_sec inference_time_sec \\\n", - "0 0.199565 19 39705.241565 0.564508 \n", - "1 0.198463 20 561.352614 0.548778 \n", - "2 0.204032 19 560.501562 0.547934 \n", - "3 0.301716 20 570.441942 0.551970 \n", - "4 0.297441 19 820.305457 0.568685 \n", - "\n", - " num_parameters tokenizer_path \n", - "0 10850856 NaN \n", - "1 10850856 NaN \n", - "2 10850856 NaN \n", - "3 11169256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", - "4 11169256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... " - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import json\n", "from pathlib import Path\n", @@ -229,12 +79,12 @@ "id": "a1f9d58c", "metadata": {}, "source": [ - "## Summary table (mean ± std across seeds)" + "## Summary table (mean \u00b1 std across seeds)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "41f68c7f", "metadata": { "execution": { @@ -244,158 +94,7 @@ "shell.execute_reply": "2026-07-30T17:10:34.327073Z" } }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizetest_losstest_cosinebest_val_lossepochs_to_best_valnum_parametersn_seeds
0char250.2024 ± 0.00290.8638 ± 0.00160.2007 ± 0.002919.3 ± 0.6108508563
1wordpiece50000.2990 ± 0.00540.7951 ± 0.00330.2973 ± 0.004419.7 ± 0.6111692563
2wordpiece100000.3426 ± 0.00110.7636 ± 0.00070.3426 ± 0.001319.3 ± 0.6114892563
3wordpiece200000.3831 ± 0.00140.7342 ± 0.00150.3809 ± 0.000919.7 ± 0.6121292563
4wordpiece300000.4061 ± 0.00890.7168 ± 0.00710.4057 ± 0.009119.7 ± 0.6127692563
5wordpiece400000.4343 ± 0.00800.6963 ± 0.00700.4321 ± 0.004519.7 ± 0.6134092563
6wordpiece500000.4473 ± 0.00250.6855 ± 0.00040.4453 ± 0.002419.7 ± 0.6140492563
7wordpiece1000000.4858 ± 0.01560.6556 ± 0.01270.4838 ± 0.015320.0 ± 0.0172492563
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size test_loss test_cosine best_val_loss \\\n", - "0 char 25 0.2024 ± 0.0029 0.8638 ± 0.0016 0.2007 ± 0.0029 \n", - "1 wordpiece 5000 0.2990 ± 0.0054 0.7951 ± 0.0033 0.2973 ± 0.0044 \n", - "2 wordpiece 10000 0.3426 ± 0.0011 0.7636 ± 0.0007 0.3426 ± 0.0013 \n", - "3 wordpiece 20000 0.3831 ± 0.0014 0.7342 ± 0.0015 0.3809 ± 0.0009 \n", - "4 wordpiece 30000 0.4061 ± 0.0089 0.7168 ± 0.0071 0.4057 ± 0.0091 \n", - "5 wordpiece 40000 0.4343 ± 0.0080 0.6963 ± 0.0070 0.4321 ± 0.0045 \n", - "6 wordpiece 50000 0.4473 ± 0.0025 0.6855 ± 0.0004 0.4453 ± 0.0024 \n", - "7 wordpiece 100000 0.4858 ± 0.0156 0.6556 ± 0.0127 0.4838 ± 0.0153 \n", - "\n", - " epochs_to_best_val num_parameters n_seeds \n", - "0 19.3 ± 0.6 10850856 3 \n", - "1 19.7 ± 0.6 11169256 3 \n", - "2 19.3 ± 0.6 11489256 3 \n", - "3 19.7 ± 0.6 12129256 3 \n", - "4 19.7 ± 0.6 12769256 3 \n", - "5 19.7 ± 0.6 13409256 3 \n", - "6 19.7 ± 0.6 14049256 3 \n", - "7 20.0 ± 0.0 17249256 3 " - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "def fmt(mean_std, precision=4):\n", " mean, std = mean_std\n", @@ -427,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "e9fac0c5", "metadata": { "execution": { @@ -437,18 +136,7 @@ "shell.execute_reply": "2026-07-30T17:10:34.498906Z" } }, - "outputs": [ - { - "data": { - "image/png": "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wc3NrdT1SqUSNjY2Og8iIiKiYgafViAsLAwrV67E6tWrcebMGYwfPx7Z2dkYPXo0AGDEiBGYNm2a1P6TTz7BzJkzsWrVKnh5eSEpKQlJSUnIysoCAGRlZeGdd97B/v37cfnyZcTExCA0NBS+vr4ICQkxyHskIiKix5vBxzANGTIEN2/eRHh4OJKSkhAQEIDo6GhpIHhCQgLk8nu5btmyZcjPz8dzzz2ns5+IiAjMmjULCoUCx48fx+rVq5Geng53d3f06dMHc+bMgVKprNH3RkRERLWDwedhMkach4mIiKh2eiznYSIiIiJ6HDAwEREREenBwERERESkBwMTERERkR4MTERERER6MDARERER6cHARERERKQHAxMRERGRHgxMRERERHowMBERERHpwcBEREREpAcDExEREZEeDExEREREejAwEREREenBwERERESkBwMTERERkR4MTERERER6MDARERER6cHARERERKQHAxMRERGRHgxMRERERHowMBERERHpwcBEREREpAcDExEREZEeDExEREREejAwEREREenBwERERESkBwMTERERkR4MTERERER6MDARERER6cHARERERKQHAxMRERGRHgxMRERERHowMBERERHpwcBEREREpAcDExEREZEeDExEREREejAwEREREenBwERERESkBwMTERERkR4mhi7AmBUWFqKwsNDQZRAREVEVqez3OgNTOZKTk5GTk2PoMoiIiKiKZGZmVmo7owhMS5cuxaeffoqkpCS0bt0aixcvRmBgYKltV65ciTVr1uDkyZMAgHbt2uGjjz7SaS+EQEREBFauXIn09HR06dIFy5Ytg5+f30PVpdVqIZPJSiyXyWQwMbl36AoKCsrcR3W1BQBTU9NKtS0sLIQQwqjbmpiYSMdeo9FAq9UadVuFQgG5XG40bbVaLTQaTZlt5XI5FAqF0bQVQpT7f33G0NYYfu/5N+IeY/i959+Immtblb/LlWXwwLRhwwaEhYVh+fLlCAoKwsKFCxESEoK4uDg4OzuXaB8bG4thw4ahc+fOUKlU+OSTT9CnTx+cOnUKHh4eAIC5c+fi888/x+rVq+Ht7Y2ZM2ciJCQEp0+fhkqlqnBta9euLbV9w4YNMWDAAOn5ypUry/xw3N3dMWjQIOn5N998g9zc3FLbOjs7Y/DgwTqvX1YSdnBwwAsvvCA9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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "loss_means = [r[\"test_loss\"][0] for r in wp]\n", "loss_stds = [r[\"test_loss\"][1] for r in wp]\n", @@ -471,7 +159,7 @@ "id": "a27ed78f", "metadata": {}, "source": [ - "*Notes: lower `test_loss` is better. `char` has no `vocab_size` position of its own — it's\n", + "*Notes: lower `test_loss` is better. `char` has no `vocab_size` position of its own \u2014 it's\n", "drawn as a horizontal reference (line + shaded std band), not a point on the WordPiece\n", "ablation grid.*" ] @@ -486,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "f24dbe8c", "metadata": { "execution": { @@ -496,18 +184,7 @@ "shell.execute_reply": "2026-07-30T17:10:34.620208Z" } }, - "outputs": [ - { - "data": { - "image/png": "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JUwiIiIiDihhEhEREXFACZOIiIiIA0qYRERERBxQwiQiIiLigBImEREREQeUMImIiIg4oIRJRERExAElTCIiIiIOKGESERERcUAJk4iIiIgDSphEREREHFDCJCIiIuKAEiYRERERB5QwiYiIiDighElERETEASVMIiIiIg4oYRIRERFxQAmTiIiIiANKmEREREQcUMIkIiIi4oASJhEREREHlDCJiIiIOKCESURERMQBJUwiIiIiDihhEhEREXFACZOIiIiIA0qYRERERBxQwiQiIiLigBImEREREQeUMImIiIg4oIRJRERExAElTCIiIiIOKGESERERcUAJk4iIiIgDSphEREREHFDCJCIiIuKAEiYRERERB5QwiYiIiDighElERETEASVMIiIiIg4oYRIRERFxQAmTiIiIiANKmEREREQcUMIkIiIi4oASJhEREREHlDCJiIiIOKCESURERMQBJUwiIiIiDihhEhEREXFACZOIiIiIA0qYRERERBxQwiQiIiLiQL5ImN5//33Kly+Pp6cnjRs3ZuPGjZnWnz59OlWrVsXLy4vQ0FCGDh3KlStXbuucIiIiIhlxesI0d+5chg0bxrhx49iyZQt16tShbdu2nDp1Kt3633zzDaNGjWLcuHFERUXx6aefMnfuXF555ZVsn1NEREQkMybDMAxnBtC4cWPuvvtu3nvvPQAsFguhoaG88MILjBo1Kk39QYMGERUVxfLly21lw4cPZ8OGDaxevTpb57xZfHw8fn5+nD9/Hl9f35y4TBEREckHsvsb79QWpqSkJDZv3kxERIStzMXFhYiICNatW5fuMU2bNmXz5s22LraDBw+yZMkSHnjggWyfMzExkfj4eLtNREREJJWrMz/8zJkzpKSkEBQUZFceFBTE7t270z3miSee4MyZMzRv3hzDMEhOTubZZ5+1dcll55yTJk1iwoQJOXBFIiIiUhA5fQzTrVq5ciUTJ05k5syZbNmyhYULF7J48WJef/31bJ9z9OjRnD9/3rYdO3YsByMGEqLhxLaMt4TonP08ERERyVFObWEKCAjAbDYTExNjVx4TE0NwcHC6x4wZM4annnqK/v37A1CrVi0uXrzIgAEDePXVV7N1Tg8PDzw8PHLgijKw6XNY9WbG+8NHQevRuff5IiIicluc2sLk7u5OgwYN7AZwWywWli9fTpMmTdI9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W5nuf+47fvw4Tz75JCVKlMDLy4tatWqxadMm237DMBg7diylSpXCy8uLiIgI9u3bZ3eOs2fP0qNHD3x9ffH396dfv35cuHDBrs4///xDixYt8PT0JDQ0lMmTJ6eJZf78+VSrVg1PT09q1arFkiVLcuei84mUlBTGjBlDWFgYXl5eVKxYkddff91u6Qvd/5z1xx9/0LFjR0JCQjCZTPz44492+/PT/c5KLFliiNymtm3bGp9//rmxY8cOY9u2bcYDDzxglC1b1rhw4YKtzrPPPmuEhoYay5cvNzZt2mTcc889RtOmTW37k5OTjZo1axoRERHG1q1bjSVLlhgBAQHG6NGjbXUOHjxoeHt7G8OGDTN27dplvPvuu4bZbDYiIyNtdb777jvD3d3d+Oyzz4ydO3caTz/9tOHv72/ExMTkzc1wso0bNxrly5c3ateubbz44ou2ct3/3HX27FmjXLlyRu/evY0NGzYYBw8eNJYuXWrs37/fVufNN980/Pz8jB9//NH4+++/jYceesgICwszLl++bKvTrl07o06dOsb69euNP//806hUqZLRvXt32/7z588bQUFBRo8ePYwdO3YY3377reHl5WV89NFHtjpr1qwxzGazMXnyZGPXrl3Ga6+9Zri5uRnbt2/Pm5vhBG+88YZRokQJY9GiRcahQ4eM+fPnG0WLFjVmzJhhq6P7n7OWLFlivPrqq8bChQsNwPjhhx/s9uen+52VWLJCCZPkuFOnThmAsWrVKsMwDCMuLs5wc3Mz5s+fb6sTFRVlAMa6desMw7D+4XNxcTGio6NtdT744APD19fXSExMNAzDMEaOHGncdddddp/VtWtXo23btrb3jRo1MgYOHGh7n5KSYoSEhBiTJk3K+QvNZxISEozKlSsbv/32mxEeHm5LmHT/c9/LL79sNG/ePMP9FovFCA4ONqZMmWIri4uLMzw8PIxvv/3WMAzD2LVrlwEYf/31l63O//73P8NkMhnHjx83DMMwZs6caRQrVsz2naR+dtWqVW3vu3TpYnTo0MHu8xs3bmw888wzt3eR+ViHDh2Mvn372pV17tzZ6NGjh2EYuv+57eaEKT/d76zEklXqkpMcd/78eQCKFy8OwObNm7l69SoRERG2OtWqVaNs2bKsW7cOgHXr1lGrVi2CgoJsddq2bUt8fDw7d+601bnxHKl1Us+RlJTE5s2b7eq4uLgQERFhq1OQDRw4kA4dOqS5R7r/ue/nn3+mYcOGPP744wQGBlKvXj1mzZpl23/o0CGio6Pt7o2fnx+NGze2+w78/f1p2LChrU5ERAQuLi5s2LDBVqdly5a4u7vb6rRt25Y9e/Zw7tw5W53MvqeCqGnTpixfvpy9e/cC8Pfff7N69Wrat28P6P7ntfx0v7MSS1YpYZIcZbFYGDJkCM2aNaNmzZoAREdH4+7ujr+/v13doKAgoqOjbXVu/LFO3Z+6L7M68fHxXL58mTNnzpCSkpJundRzFFTfffcdW7ZsYdKkSWn26f7nvoMHD/LBBx9QuXJlli5dynPPPcfgwYOZM2cOcP0eZnZvoqOjCQwMtNvv6upK8eLFc+R7KsjfwahRo+jWrRvVqlXDzc2NevXqMWTIEHr06AHo/ue1/HS/sxJLVmnxXclRAwcOZMeOHaxevdrZoRQax44d48UXX+S3337D09PT2eEUShaLhYYNGzJx4kQA6tWrx44dO/jwww/p1auXk6Mr+ObNm8fXX3/NN998w1133cW2bdsYMmQIISEhuv+SY9TCJDlm0KBBLFq0iN9//50yZcrYyoODg0lKSiIuLs6ufkxMDMHBwbY6Nz+1lfreUR1fX1+8vLwICAjAbDanWyf1HAXR5s2bOXXqFPXr18fV1RVXV1dWrVrFO++8g6urK0FBQbr/uaxUqVLUqFHDrqx69eocPXoUuH4PM7s3wcHBnDp1ym5/cnIyZ8+ezZHvqSB/ByNGjLC1MtWqVYunnnqKoUOH2lpcdf/zVn6631mJJauUMMltMwyDQYMG8cMPP7BixQrCwsLs9jdo0AA3NzeWL19uK9uzZw9Hjx6lSZMmADRp0oTt27fb/QH67bff8PX1tf0QNWnSxO4cqXVSz+Hu7k6DBg3s6lgsFpYvX26rUxC1adOG7du3s23bNtvWsGFDevToYXut+5+7mjVrlmYqjb1791KuXDkAwsLCCA4Otrs38fHxbNiwwe47iIuLY/PmzbY6K1aswGKx0LhxY1udP/74g6tXr9rq/Pbbb1StWpVixYrZ6mT2PRVEly5dwsXF/ufMbDZjsVgA3f+8lp/ud1ZiybJbGiIuko7nnnvO8PPzM1auXGmcPHnStl26dMlW59lnnzXKli1rrFixwti0aZPRpEkTo0mTJrb9qY+133///ca2bduMyMhIo2TJkuk+1j5ixAgjKirKeP/999N9rN3Dw8OYPXu2sWvXLmPAgAGGv7+/3dNfhcGNT8kZhu5/btu4caPh6upqvPHGG8a+ffuMr7/+2vD29ja++uorW50333zT8Pf3N3766Sfjn3/+MTp16pTuY9b16tUzNmzYYKxevdqoXLmy3WPWcXFxRlBQkPHUU08ZO3bsML777jvD29s7zWPWrq6uxtSpU42oqChj3LhxBfKx9hv16tXLKF26tG1agYULFxoBAQHGyJEjbXV0/3NWQkKCsXXrVmPr1q0GYEybNs3YunWrceTIEcMw8tf9zkosWaGESW4bkO72+eef2+pcvnzZeP75541ixYoZ3t7exiOPPGKcPHnS7jyHDx822rdvb3h5eRkBAQHG8OHDjatXr9rV+f333426desa7u7uRoUKFew+I9W7775rlC1b1nB3dzcaNWpkrF+/PjcuO1+7OWHS/c99v/zyi1GzZk3Dw8PDqFatmvHxxx/b7bdYLMaYMWOMoKAgw8PDw2jTpo2xZ88euzqxsbFG9+7djaJFixq+vr5Gnz59jISEBLs6f//9t9G8eXPDw8PDKF26tPHmm2+miWXevHlGlSpVDHd3d+Ouu+4yFi9enPMXnI/Ex8cbL774olG2bFnD09PTqFChgvHqq6/aPY6u+5+zfv/993T/3u/Vq5dhGPnrfmcllqwwGcYNU6GKiIiISBoawyQiIiLigBImEREREQeUMImIiIg4oIRJRERExAElTCIiIiIOKGESERERcUAJk4iIiIgDSphEREREHFDCJCKFTqtWrRgyZMgdd24RcR5XZwcgIlKQLFy4EDc3N2eHISI5TAmTiEgOKl68uLNDEJFcoC45EclTH3/8MSEhIVgsFrvyTp060bdvXwA++OADKlasiLu7O1WrVuXLL7+0qxsXF8czzzxDUFAQnp6e1KxZk0WLFgEQGxtL9+7dKV26NN7e3tSqVYtvv/02TRzJyckMGjQIPz8/AgICGDNmDFldWnPmzJlUrlwZT09PgoKCeOyxx2z7buySW7lyJSaTKc3Wu3dvW/2ffvqJ+vXr4+npSYUKFZgwYQLJyclZikNE8o5amEQkTz3++OO88MIL/P7777Rp0waAs2fPEhkZyZIlS/jhhx948cUXmT59OhERESxatIg+ffpQpkwZWrdujcVioX379iQkJPDVV19RsWJFdu3ahdlsBuDKlSs0aNCAl19+GV9fXxYvXsxTTz1FxYoVadSokS2OOXPm0K9fPzZu3MimTZsYMGAAZcuW5emnn840/k2bNjF48GC+/PJLmjZtytmzZ/nzzz/Trdu0aVNOnjxpex8VFcUDDzxAy5YtAfjzzz/p2bMn77zzDi1atODAgQMMGDAAgHHjxmX/JotIzjNERPJYp06djL59+9ref/TRR0ZISIiRkpJiNG3a1Hj66aft6j/++OPGAw88YBiGYSxdutRwcXEx9uzZk+XP69ChgzF8+HDb+/DwcKN69eqGxWKxlb388stG9erVHZ7r+++/N3x9fY34+Ph094eHhxsvvvhimvIzZ84YFSpUMJ5//nlbWZs2bYyJEyfa1fvyyy+NUqVKOYxDRPKWuuREJM/16NGD77//nsTERAC+/vprunXrhouLC1FRUTRr1syufrNmzYiKigJg27ZtlClThipVqqR77pSUFF5//XVq1apF8eLFKVq0KEuXLuXo0aN29e655x5MJpPtfZMmTdi3bx8pKSmZxn7fffdRrlw5KlSowFNPPcXXX3/NpUuXMj3m6tWrPProo5QrV44ZM2bYyv/++2/+7//+j6JFi9q2p59+mpMnTzo8p4jkLSVMIpLnOnbsiGEYLF68mGPHjvHnn3/So0ePLB3r5eWV6f4pU6YwY8YMXn75ZX7//Xe2bdtG27ZtSUpKyonQ8fHxYcuWLXz77beUKlWKsWPHUqdOHeLi4jI85rnnnuPYsWPMnz8fV9frIyEuXLjAhAkT2LZtm23bvn07+/btw9PTM0fiFZGcoTFMIpLnPD096dy5M19//TX79++natWq1K9fH4Dq1auzZs0aevXqZau/Zs0aatSoAUDt2rX5999/2bt3b7qtTGvWrKFTp048+eSTAFgsFvbu3Ws7PtWGDRvs3q9fv57KlSvbxkJlxtXVlYiICCIiIhg3bhz+/v6sWLGCzp07p6k7bdo05s2bx9q1aylRooTdvvr167Nnzx4qVark8DNFxLmUMImIU/To0YMHH3yQnTt32pIbgBEjRtClSxfq1atHREQEv/zyCwsXLmTZsmUAhIeH07JlSx599FGmTZtGpUqV2L17NyaTiXbt2lG5cmUWLFjA2rVrKVasGNOmTSMmJiZNwnT06FGGDRvGM888w5YtW3j33Xd5++23Hca9aNEiDh48SMuWLSlWrBhLlizBYrFQtWrVNHWXLVvGyJEjef/99wkICCA6OhqwtpL5+fkxduxYHnzwQcqWLctjjz2Gi4sLf//9Nzt27OA///nP7dxeEclpzh5EJSKFU0pKilGqVCkDMA4cOGC3b+bMmUaFChUMNzc3o0qVKsYXX3xhtz82Ntbo06ePUaJECcPT09OoWbOmsWjRItu+Tp06GUWLFjUCAwON1157zejZs6fRqVMn2/Hh4eHG888/bzz77LOGr6+vUaxYMeOVV16xGwSekT///NMIDw83ihUrZnh5eRm1a9c25s6da3fu1EHf48aNM4A0W69evWz1IyMjjaZNmxpeXl6Gr6+v0ahRI+Pjjz++xbspIrnNZBhZnHhEREREpJDSoG8RERERB5QwiYjc4M8//7R7zP/mTUQKJ3XJiYjc4PLlyxw/fjzD/XqiTaRwUsIkIiIi4oC65EREREQcUMIkIiIi4oASJhEREREHlDCJiIiIOKCESURERMQBJUwiIiIiDihhEhEREXFACZOIiIiIA/8Pzdm+shQ9njsAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "cos_means = [r[\"test_cosine\"][0] for r in wp]\n", "cos_stds = [r[\"test_cosine\"][1] for r in wp]\n", @@ -543,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "a718abe6", "metadata": { "execution": { @@ -553,18 +230,7 @@ "shell.execute_reply": "2026-07-30T17:10:34.857746Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAG4CAYAAABYaIRGAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAU25JREFUeJzt3XlYlXX+//HXOQiHRVYRDhgqamm4UToQU6YlCY1jOk5XaovmZE1W88uhcnSaXLIGs6Zs1bJcyu+MNWU1bbQw2uKgTC6paZSGW7EoxGqCcT6/PxxPnQBZ5HAAn4/rOtflue/3/Tnvm08QL+7NYowxAgAAAAAALc7q6QYAAAAAAOioCN0AAAAAALgJoRsAAAAAADchdAMAAAAA4CaEbgAAAAAA3ITQDQAAAACAmxC6AQAAAABwE0I3AAAAAABuQugGAAAAAMBNCN0AAMBpxIgRGjFihKfbOG3z5s2TxWLxdBsAABC6AQBYuXKlLBaL8+Xr66tzzjlHt912mwoKCjzdXpv017/+Va+99ppbP+M///mP5s2bp5KSErd+DgAA7kToBgDgf+6991698MILeuKJJ/TLX/5SS5YsUVJSko4ePerp1tqc1grd8+fPJ3QDANq1Tp5uAACAtuLyyy/X0KFDJUnTpk1Tly5d9PDDD+v111/XpEmTTmvso0ePyt/fvyXaBAAA7QhHugEAqMell14qScrNzXUuW716tYYMGSI/Pz+FhYVp4sSJOnjwoMt2I0aM0IABA7R582ZdfPHF8vf315///Od6P+f999/XRRddpJCQEHXu3Fl9+/atVV9VVaW5c+eqT58+stlsiomJ0cyZM1VVVVVrvMb0KEnPPPOMevfuLT8/PyUkJOjjjz9u1NfFYrGosrJSq1atcp6Sf/311zvXf/PNN/rd736nyMhI2Ww29e/fX8uXL681zuOPP67+/fvL399foaGhGjp0qP7+979LOnFN9l133SVJio2NdX7Ovn37GtVjXX744QctWLBAvXv3ls1mU8+ePfXnP/+51tfw008/VUpKisLDw+Xn56fY2Fj97ne/c6lZs2aNhgwZosDAQAUFBWngwIF69NFHm90bAKDj4kg3AAD12Lt3rySpS5cukqT7779f99xzj6666ipNmzZNhw8f1uOPP66LL75YW7duVUhIiHPboqIiXX755Zo4caKuvfZaRUZG1vkZn3/+uX79619r0KBBuvfee2Wz2bRnzx5t2LDBWeNwOHTFFVfok08+0U033aRzzz1XO3bs0COPPKIvv/zS5TTvxvb43HPP6fe//71++ctfasaMGfr66691xRVXKCwsTDExMaf8urzwwguaNm2aEhISdNNNN0mSevfuLUkqKCjQBRdcIIvFottuu01du3bVO++8oxtuuEFlZWWaMWOGJGnZsmX6f//v/+nKK6/U7bffrmPHjmn79u3atGmTrr76ao0fP15ffvml/vGPf+iRRx5ReHi4JKlr166Nm7w6TJs2TatWrdKVV16pO+64Q5s2bVJ6erp2796tV199VZJUWFioUaNGqWvXrpo1a5ZCQkK0b98+rV271jnO+++/r0mTJmnkyJF64IEHJEm7d+/Whg0bdPvttze7PwBAB2UAADjDrVixwkgyH3zwgTl8+LA5ePCgWbNmjenSpYvx8/Mzhw4dMvv27TNeXl7m/vvvd9l2x44dplOnTi7Lhw8fbiSZpUuXNvjZjzzyiJFkDh8+XG/NCy+8YKxWq/n4449dli9dutRIMhs2bDDGmEb3WF1dbSIiIkx8fLypqqpy1j3zzDNGkhk+fHiDfQcEBJgpU6bUWn7DDTeYqKgoc+TIEZflEydONMHBwebo0aPGGGPGjh1r+vfvf8rPePDBB40kk5ub22A/Pzd37lzz019ztm3bZiSZadOmudTdeeedRpL597//bYwx5tVXXzWSzH//+996x7799ttNUFCQ+eGHH5rcFwDgzMPp5QAA/E9ycrK6du2qmJgYTZw4UZ07d9arr76qbt26ae3atXI4HLrqqqt05MgR58tut+vss8/WunXrXMay2WyaOnVqg5958sjz66+/LofDUWfNP//5T5177rnq16+fy2efPP395Gc3tsdPP/1UhYWFuvnmm+Xj4+P8nOuvv17BwcFN/rqdZIzRK6+8ojFjxsgY49JDSkqKSktLtWXLFud+Hzp0SP/973+b/XlN8fbbb0uS0tLSXJbfcccdkqS33nrL2Zckvfnmmzp+/HidY4WEhKiyslLvv/++m7oFAHQknF4OAMD/PPnkkzrnnHPUqVMnRUZGqm/fvrJaT/x9+quvvpIxRmeffXad23p7e7u879atm0ugLS0t1ffff+987+Pjo7CwME2YMEHPPvuspk2bplmzZmnkyJEaP368rrzySpfP3r17d72nVhcWFjapx/3790tSrTpvb2/16tWr7i9OIxw+fFglJSV65pln9Mwzz5yy1z/96U/64IMPlJCQoD59+mjUqFG6+uqrdeGFFzb7809l//79slqt6tOnj8tyu92ukJAQ59dk+PDh+u1vf6v58+frkUce0YgRIzRu3DhdffXVstlskqRbbrlFL730ki6//HJ169ZNo0aN0lVXXaXU1FS39A4AaN8I3QAA/E9CQoLz7uU/53A4ZLFY9M4778jLy6vW+s6dO7u89/Pzc3l/++23a9WqVc73w4cP1/r16+Xn56ePPvpI69at01tvvaWMjAy9+OKLuvTSS/Xee+/Jy8tLDodDAwcO1MMPP1xnbyevwW5qjy3t5JH6a6+9VlOmTKmzZtCgQZKkc889Vzk5OXrzzTeVkZGhV155RU899ZTmzJmj+fPnu61Hi8XS4PqXX35ZGzdu1BtvvKF3331Xv/vd7/S3v/1NGzduVOfOnRUREaFt27bp3Xff1TvvvKN33nlHK1as0OTJk13mGAAAidANAECj9O7dW8YYxcbG6pxzzmny9jNnztS1117rfB8aGur8t9Vq1ciRIzVy5Eg9/PDD+utf/6q7775b69atU3Jysnr37q3PPvtMI0eOPGVobGyPPXr0kHTiyPjJU9Ql6fjx48rNzdXgwYMb3J+6+ujatasCAwNVU1Oj5OTkBscICAjQhAkTNGHCBFVXV2v8+PG6//77NXv2bPn6+jYYkJuiR48ecjgc+uqrr3Tuuec6lxcUFKikpMT5NTnpggsu0AUXXKD7779ff//733XNNddozZo1mjZtmqQTZyqMGTNGY8aMkcPh0C233KKnn35a99xzT62j6QCAMxvXdAMA0Ajjx4+Xl5eX5s+fL2OMyzpjjIqKik65fVxcnJKTk52vIUOGSJKKi4tr1cbHx0uS81FWV111lb755hstW7asVu3333+vysrKJvU4dOhQde3aVUuXLlV1dbWzZuXKlSopKTnlfpwUEBBQq9bLy0u//e1v9corr2jnzp21tjl8+LDz3z//evn4+CguLk7GGOe11AEBAZLU6J5O5Ve/+pUkafHixS7LT549MHr0aEnSd999V+tr9/P5+HnvVqvVeQS/rke4AQDObBzpBgCgEXr37q377rtPs2fP1r59+zRu3DgFBgYqNzdXr776qm666SbdeeedTR733nvv1UcffaTRo0erR48eKiws1FNPPaWzzjpLF110kSTpuuuu00svvaSbb75Z69at04UXXqiamhp98cUXeumll/Tuu+9q6NChje7R29tb9913n37/+9/r0ksv1YQJE5Sbm6sVK1Y0+pruIUOG6IMPPtDDDz+s6OhoxcbGKjExUQsXLtS6deuUmJioG2+8UXFxcSouLtaWLVv0wQcfOP/IMGrUKNntdl144YWKjIzU7t279cQTT2j06NEKDAx0foYk3X333Zo4caK8vb01ZswYZxhvisGDB2vKlCl65plnVFJSouHDhys7O1urVq3SuHHjdMkll0iSVq1apaeeekq/+c1v1Lt3b5WXl2vZsmUKCgpyBvdp06apuLhYl156qc466yzt379fjz/+uOLj412OogMAIIlHhgEAcPKRYad6TNRJr7zyirnoootMQECACQgIMP369TO33nqrycnJcdYMHz68wcdhnZSZmWnGjh1roqOjjY+Pj4mOjjaTJk0yX375pUtddXW1eeCBB0z//v2NzWYzoaGhZsiQIWb+/PmmtLS0yT0aY8xTTz1lYmNjjc1mM0OHDjUfffSRGT58eKMeGfbFF1+Yiy++2Pj5+RlJLo8PKygoMLfeequJiYkx3t7exm63m5EjR5pnnnnGWfP000+biy++2HTp0sXYbDbTu3dvc9ddd9XalwULFphu3boZq9XapMeH/fyRYcYYc/z4cTN//nwTGxtrvL29TUxMjJk9e7Y5duyYs2bLli1m0qRJpnv37sZms5mIiAjz61//2nz66afOmpdfftmMGjXKREREGB8fH9O9e3fz+9//3uTl5TWqNwDAmcVizM/OoQIAAAAAAC2Ca7oBAAAAAHATrukGAADtxs+fd14Xu93eSt0AANAwTi8HAADtxvXXX9/gs7D51QYA0JYQugEAQLuxa9cuffvtt6esacwzwgEAaC2EbgAAAAAA3IQbqQEAAAAA4CbcSK0ODodD3377rQIDA2WxWDzdDgAAAACgDTHGqLy8XNHR0bJaT30sm9Bdh2+//VYxMTGebgMAAAAA0IYdPHhQZ5111ilrCN11CAwMlHTiCxgUFOThbgAAAAAAbUlZWZliYmKc2fFUCN11OHlKeVBQEKEbAAAAAFCnxlyOzI3UAAAAAABwE0I3AAAAAABuQugGAAAAAMBNCN0AAAAAALgJ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OHDggEaPHi1/f39FRETorrvu0g8//OBSs379ep1//vmy2Wzq06ePVq5c2Rq7d8b46KOPNGbMGEVHR8tisei1115zWW+M0Zw5cxQVFSU/Pz8lJyfrq6++cqkpLi7WNddco6CgIIWEhOiGG25QRUWFS8327ds1bNgw+fr6KiYmRosWLarVyz//+U/169dPvr6+GjhwoN5+++0W398zRXp6un7xi18oMDBQERERGjdunHJyclxqWvN79Mknn1TPnj3l6+urxMREZWdnt/g+nwmWLFmiQYMGKSgoSEFBQUpKStI777zjXM+cdgwLFy6UxWLRjBkznMuY2/anLf2exJw2X3v6PakxvbjdaT90DICLuXPnmv79+5u8vDzn6/Dhw871N998s4mJiTGZmZnm008/NRdccIH55S9/6Vz/ww8/mAEDBpjk5GSzdetW8/bbb5vw8HAze/ZsZ83XX39t/P39TVpamtm1a5d5/PHHjZeXl8nIyGjVfe3I3n77bXP33XebtWvXGknm1VdfdVm/cOFCExwcbF577TXz2WefmSuuuMLExsaa77//3lmTmppqBg8ebDZu3Gg+/vhj06dPHzNp0iTn+tLSUhMZGWmuueYas3PnTvOPf/zD+Pn5maefftpZs2HDBuPl5WUWLVpkdu3aZf7yl78Yb29vs2PHDrd/DTqilJQUs2LFCrNz506zbds286tf/cp0797dVFRUOGta63t0zZo1xsfHxyxfvtx8/vnn5sYbbzQhISGmoKCgdb4YHci//vUv89Zbb5kvv/zS5OTkmD//+c/G29vb7Ny50xjDnHYE2dnZpmfPnmbQoEHm9ttvdy5nbtuftvJ7EnN6etrT70mN6cXdCN1AC5s7d64ZPHhwnetKSkqMt7e3+ec//+lctnv3biPJZGVlGWNO/BCzWq0mPz/fWbNkyRITFBRkqqqqjDHGzJw50/Tv399l7AkTJpiUlJQW3hsYY2r9z8ThcBi73W4efPBB57KSkhJjs9nMP/7xD2OMMbt27TKSzH//+19nzTvvvGMsFov55ptvjDHGPPXUUyY0NNQ5r8YY86c//cn07dvX+f6qq64yo0ePduknMTHR/P73v2/RfTxTFRYWGknmww8/NMa07vdoQkKCufXWW53va2pqTHR0tElPT2/5HT0DhYaGmmeffZY57QDKy8vN2Wefbd5//30zfPhwZ+hmbtuntvJ7EnPactry70mN6aU1cHo54AZfffWVoqOj1atXL11zzTU6cOCAJGnz5s06fvy4kpOTnbX9+vVT9+7dlZWVJUnKysrSwIEDFRkZ6axJSUlRWVmZPv/8c2fNT8c4WXNyDLhXbm6u8vPzXeYgODhYiYmJLvMYEhKioUOHOmuSk5NltVq1adMmZ83FF18sHx8fZ01KSopycnL03XffOWuYa/cpLS2VJIWFhUlqve/R6upqbd682aXGarUqOTmZuT1NNTU1WrNmjSorK5WUlMScdgC33nqrRo8eXevrz9y2X57+PYk5da+29HtSY3ppDYRuoIUlJiZq5cqVysjI0JIlS5Sbm6thw4apvLxc+fn58vHxUUhIiMs2kZGRys/PlyTl5+e7/I/k5PqT605VU1ZWpu+//95Ne4aTTs5DXXPw0zmKiIhwWd+pUyeFhYW1yFyfXI/mczgcmjFjhi688EINGDBAklrte/TIkSOqqalhblvQjh071LlzZ9lsNt1888169dVXFRcXx5y2c2vWrNGWLVuUnp5eax1z2z61hd+TmFP3aku/JzWml9bQqdU+CThDXH755c5/Dxo0SImJierRo4deeukl+fn5ebAzAD916623aufOnfrkk0883QpaQN++fbVt2zaVlpbq5Zdf1pQpU/Thhx96ui2choMHD+r222/X+++/L19fX0+3gxbC70k4E3GkG3CzkJAQnXPOOdqzZ4/sdruqq6tVUlLiUlNQUCC73S5Jstvtte7SefJ9QzVBQUH8D6sVnJyHuubgp3NUWFjosv6HH35QcXFxi8z1yfVonttuu01vvvmm1q1bp7POOsu5vLW+R8PDw+Xl5cXctiAfHx/16dNHQ4YMUXp6ugYPHqxHH32UOW3HNm/erMLCQp1//vnq1KmTOnXqpA8//FCPPfaYOnXqpMjISOa2A/DE70nMqXu1pd+TGtNLayB0A25WUVGhvXv3KioqSkOGDJG3t7cyMzOd63NycnTgwAElJSVJkpKSkrRjxw6XH0Tvv/++goKCFBcX56z56Rgna06OAfeKjY2V3W53mYOysjJt2rTJZR5LSkq0efNmZ82///1vORwOJSYmOms++ugjHT9+3Fnz/vvvq2/fvgoNDXXWMNctxxij2267Ta+++qr+/e9/KzY21mV9a32P+vj4aMiQIS41DodDmZmZzG0LcTgcqqqqYk7bsZEjR2rHjh3atm2b8zV06FBdc801zn8zt+2fJ35PYk7dqy39ntSYXlpFq92yDThD3HHHHWb9+vUmNzfXbNiwwSQnJ5vw8HBTWFhojDnxKIzu3bubf//73+bTTz81SUlJJikpybn9yUdhjBo1ymzbts1kZGSYrl271vkojLvuusvs3r3bPPnkkzwyrIWVl5ebrVu3mq1btxpJ5uGHHzZbt241+/fvN8acePxESEiIef3118327dvN2LFj63wUxnnnnWc2bdpkPvnkE3P22We7PAqjpKTEREZGmuuuu87s3LnTrFmzxvj7+9d6FEanTp3MQw89ZHbv3m3mzp3LI8NOw/Tp001wcLBZv369y+Nqjh496qxpre/RNWvWGJvNZlauXGl27dplbrrpJhMSEuJyR140zqxZs8yHH35ocnNzzfbt282sWbOMxWIx7733njGGOe1Ifnr3cmOY2/aorfyexJyenvb0e1JjenE3QjfQwiZMmGCioqKMj4+P6datm5kwYYLZs2ePc/33339vbrnlFhMaGmr8/f3Nb37zG5OXl+cyxr59+8zll19u/Pz8THh4uLnjjjvM8ePHXWrWrVtn4uPjjY+Pj+nVq5dZsWJFa+zeGWPdunVGUq3XlClTjDEnHkFxzz33mMjISGOz2czIkSNNTk6OyxhFRUVm0qRJpnPnziYoKMhMnTrVlJeXu9R89tln5qKLLjI2m81069bNLFy4sFYvL730kjnnnHOMj4+P6d+/v3nrrbfctt8dXV1zKsnl+6c1v0cff/xx0717d+Pj42MSEhLMxo0b3bHbHd7vfvc706NHD+Pj42O6du1qRo4c6QzcxjCnHcnPQzdz2/60pd+TmNPma0+/JzWmF3ezGGNM6x1XBwAAAADgzME13QAAAAAAuAmhGwAAAAAANyF0AwAAAADgJoRuAAAAAADchNANAAAAAICbELoBAAAAAHATQjcAAAAAAG5C6AYAAAAAwE0I3QAAAAAAuAmhGwAAAAAANyF0AwAAAADgJoRuAAAAAADc5P8DGLlhQ7PVIlUAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(10, 4.5))\n", "configs = sorted(raw[[\"tokenizer\", \"vocab_size\"]].drop_duplicates().itertuples(index=False),\n", @@ -604,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "70921265", "metadata": { "execution": { @@ -614,18 +280,7 @@ "shell.execute_reply": "2026-07-30T17:10:34.984808Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAArAAAAG4CAYAAAC9/9RGAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAlM9JREFUeJzs3Xd4FFXbx/HvbnqvpFFD6EgzFAHpJSgi2KjSFFERBRELr9JExS4IKD6oFEUBwc4jiDwEkd5FOpEOCTUV0nbn/SNkYUkCAQJL4Pe5rr1gZ86cuWfL7J0zZ84xGYZhICIiIiJSTJgdHYCIiIiIyJVQAisiIiIixYoSWBEREREpVpTAioiIiEixogRWRERERIoVJbAiIiIiUqwogRURERGRYkUJrIiIiIgUK0pgRURERKRYUQIrco1GjRqFyWTixIkTjg7FYUwmE6NGjbru28j1FRsbi8lkIjY21tGh2ClXrhz33Xefo8NwKJPJxMCBA2/Ivm7Wz4HIhZTAihRTb731Fj/++KOjw5Ar8M033zBu3Ljruo8jR44watQoNm3adF33IyLiSEpgRYopJbDFz41KYEePHq0EVq5a06ZNOXv2LE2bNnV0KCIFcnZ0ACIiInLzMJvNuLu7OzoMkUtSC6xIETlx4gSdO3fG19eXoKAgBg0aRHp6ep5yX3/9NdHR0Xh4eBAYGEjXrl05ePCgXZndu3fz0EMPERYWhru7O6VKlaJr164kJSUBOf3h0tLSmD59OiaTCZPJRJ8+fS4bY1ZWFoGBgfTt2zfPuuTkZNzd3Rk6dCgAmZmZjBgxgujoaPz8/PDy8qJJkyYsWbLkKl6dwtm4cSP33HMPvr6+eHt706pVK1atWpXnGEaPHk3FihVxd3cnKCiIu+++m0WLFtnKxMfH07dvX0qVKoWbmxvh4eF07NiRffv2Fbjv999/H5PJxP79+/OsGzZsGK6urpw+fRq4/PuTn+bNmzN//nz2799ve8/KlStnW5+RkcHIkSOpUKECbm5ulC5dmpdeeomMjAy7ehYtWsTdd9+Nv78/3t7eVK5cmf/7v/8Dcvou1qtXD4C+ffva9jNt2rQC4yqM7777zvaZDQ4O5tFHH+Xw4cN2ZQrzmq9bt46YmBiCg4Px8PAgMjKSxx57rNBx/P7779SuXRt3d3eqVavG999/b1v377//YjKZ+Oijj/Jst2LFCkwmE99++22+9SYkJODs7Mzo0aPzrNu5cycmk4mJEyfa7euRRx4hMDAQT09P7rrrLubPn59n2/T0dEaNGkWlSpVwd3cnPDycBx98kLi4OFuZ999/n0aNGhEUFISHhwfR0dHMnTu3wNdg5syZVK5cGXd3d6Kjo/nzzz8LLFuQWbNmER0djY+PD76+vtSoUYPx48fb1l/cB3batGm2z9LFj+bNm9vVXZjzm0hRUAusSBHp3Lkz5cqVY+zYsaxatYqPP/6Y06dPM2PGDFuZN998k+HDh9O5c2f69evH8ePHmTBhAk2bNmXjxo34+/uTmZlJTEwMGRkZPPvss4SFhXH48GF+/fVXEhMT8fPz46uvvqJfv37Ur1+f/v37AxAVFXXZGF1cXHjggQf4/vvv+eyzz3B1dbWt+/HHH8nIyKBr165ATkL7+eef061bN5544glSUlL44osviImJYc2aNdSuXbtIX7+tW7fSpEkTfH19eemll3BxceGzzz6jefPmLF26lAYNGgA5N82NHTvWdvzJycmsW7eODRs20KZNGwAeeughtm7dyrPPPku5cuU4duwYixYt4sCBA3ZJ44U6d+7MSy+9xJw5c3jxxRft1s2ZM4e2bdsSEBBQqPcnP6+++ipJSUkcOnTIlmR5e3sDYLVauf/++/nrr7/o378/VatWZcuWLXz00Ufs2rXL1lVk69at3HfffdSsWZPXX38dNzc39uzZw/LlywGoWrUqr7/+OiNGjKB///40adIEgEaNGl31+zJt2jT69u1LvXr1GDt2LAkJCYwfP57ly5fbPrOFec2PHTtG27ZtKVGiBK+88gr+/v7s27fPLgm9lN27d9OlSxeeeuopevfuzdSpU3nkkUdYsGABbdq0oXz58jRu3JiZM2fy/PPP2207c+ZMfHx86NixY751h4aG0qxZM+bMmcPIkSPt1s2ePRsnJyceeeQRICfZbdSoEWfOnOG5554jKCiI6dOnc//99zN37lweeOABACwWC/fddx+LFy+ma9euDBo0iJSUFBYtWsQ///xj+76OHz+e+++/nx49epCZmcmsWbN45JFH+PXXX2nfvr1dLEuXLmX27Nk899xzuLm58cknn9CuXTvWrFnDHXfcUajXcdGiRXTr1o1WrVrxzjvvALB9+3aWL1/OoEGD8t2madOmfPXVV3bL9u/fz2uvvUZI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QteuXcnMzGTevHl2o5fkKuz5TaSoaBgtkSKyd+9e7r//ftq1a8fKlSv5+uuv6d69u+2yfFRUFG+88QbDhg1j3759dOrUCR8fH/bu3csPP/xA//79GTp0KP/73/8YOHAgjzzyCJUqVSI7O5uvvvoKJycnHnroIdv+oqOj+eOPP/jwww+JiIggMjLSNtRUYXTp0oUJEyYwcuRIatSoYevDl+u+++7j+++/54EHHqB9+/bs3buXyZMnU61atSK95JvrjTfesI1xOmDAAJydnfnss8/IyMjg3XfftZWrVq0azZs3Jzo6msDAQNatW8fcuXNt88Tv2rWLVq1a0blzZ6pVq4azszM//PADCQkJtiHCLiUkJIQWLVrw4YcfkpKSkiexL+z7k5/o6Ghmz57NkCFDqFevHt7e3nTo0IGePXsyZ84cnnrqKZYsWULjxo2xWCzs2LGDOXPmsHDhQurWrcvrr7/On3/+Sfv27SlbtizHjh3jk08+oVSpUrabiqKiovD392fy5Mn4+Pjg5eVFgwYNiIyMvNK3BBcXF9555x369u1Ls2bN6Natm20YrXLlytmGqyrMaz59+nQ++eQTHnjgAaKiokhJSWHKlCn4+vpy7733XjaWSpUq8fjjj7N27VpCQ0P58ssvSUhIYOrUqXnK9urVi48//pglS5bYhooqrC5duvDoo4/yySefEBMTk2fop1deeYVvv/2We+65h+eee47AwECmT5/O3r17mTdvnq2rQq9evZgxYwZDhgxhzZo1NGnShLS0NP744w8GDBhAx44dad++PR9++CHt2rWje/fuHDt2jEmTJlGhQgW7ft257rjjDmJiYuyG0QLyHb+2IP369ePUqVO0bNmSUqVKsX//fiZMmEDt2rXznANyTZ48mf/973+2z+eFQkNDadOmTaHPbyJFxoGtvyK3hNwuBNu2bTMefvhhw8fHxwgICDAGDhxoN/RQrnnz5hl333234eXlZXh5eRlVqlQxnnnmGdult3///dd47LHHjKioKMPd3d0IDAw0WrRoYfzxxx929ezYscNo2rSp4eHhYQBX3J3AarUapUuXNgDjjTfeyHf9W2+9ZZQtW9Zwc3Mz6tSpY/z6669G7969i7wLQa4NGzYYMTExhre3t+Hp6Wm0aNHCWLFihV2ZN954w6hfv77h7+9veHh4GFWqVDHefPNN26XaEydO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adMmTCYTr7zyiq1Mv379ePTRR23P582bR/Xq1XFzc6NcuXJ88MEHdnWWK1eOMWPG0KtXL3x9fenfvz+Q02WgTJkyeHp68sADD3Dy5Em77UaNGkXt2rX57LPPKF26NJ6ennTu3JmkpCRbmYu7EFitVsaOHUtkZCQeHh7UqlWLuXPn2tW7detW7rvvPnx9ffHx8aFJkybExcXZ1n/++edUrVoVd3d3qlSpwieffFLg69WnTx+WLl3K+PHjMZlMmEwm9u3bB8A///zDPffcg7e3N6GhofTs2ZMTJ07Ytp07dy41atTAw8ODoKAgWrduTVpaGqNGjWL69On89NNPtjpjY2MLjKEgS5cupX79+ri5uREeHs4rr7xCdnb2ZfcPEBsbS/369fHy8sLf35/GjRuzf//+K46hsJRlyJXLziDrx+fg54E4WTNZZLmTMRGT+HjwozSvHOLo6EREbh2GAZlphXukJ+dM101+l8fPLVvwck65y9V1BZfYmzRpQkpKChs3bgRykqDg4GC7BGrp0qU0b94cgPXr19O5c2e6du3Kli1bGDVqFMOHD2fatGl29b7//vvUqlWLjRs3Mnz4cFavXs3jjz/OwIED2bRpEy1atOCNN97IE8+ePXuYM2cOv/zyCwsWLGDjxo0MGDCgwPjHjh3LjBkzmDx5Mlu3buX555/n0UcfZenSpQAcPnyYpk2b4ubmxv/+9z/Wr1/PY489ZkvsZs6cyYgRI3jzzTfZvn07b731FsOHD2f69On57m/8+PE0bNiQJ554gqNHj3L06FFKly5NYmIiLVu2pE6dOqxbt44FCxaQkJBA586dATh69CjdunXjscceY/v27cTGxvLggw9iGAZDhw6lc+fOtGvXzlZno0aNCvX+5Tp8+DD33nsv9erVY/PmzXz66ad88cUXttf4UvvPzs6mU6dONGvWjL///puVK1fSv3//6zvLpuFgEydONMqWLWu4ubkZ9evXN1avXl1g2Xnz5hnR0dGGn5+f4enpadSqVcuYMWOGXZnevXsb5HxTbY+YmJgriikpKckAjKSkpKs6plta4kHjzKSmhjHS17CM8DPef/Vx46PftxvZFqujIxMRKdbOnj1rbNu2zTh79uz5hRmphjHS98Y/MlKvKPY777zTeO+99wzDMIxOnToZb775puHq6mqkpKQYhw4dMgBj165dhmEYRvfu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dssHDRpEy5YtC72va3HgwAE6duyIt7c3vr6+dO7cmYSEBNv6zZs306JFC3x8fPD19SU6Opp169YBsH//fjp06EBAQABeXl5Ur16d//73v0UW263kqjKXpUuXsmrVKgIDA23LgoKCePvtt2ncuHGRBSdFIDsT84JXAFji14m2dRs6OCAREblSmZmZBa4zm804X9AQcamyJpMJFxeXS5a9mlbNYcOGMWXKFD766CPuvvtujh49yo4dO+zKvPrqq7z//vtUrFiRV199lW7durFnzx6cnZ1JT08nOjqal19+GV9fX+bPn0/Pnj2Jioqifv36tjqmT5/O008/zfLly/ONo1WrVvj7+zNv3jzbPToWi4XZs2fbEurC7utqWK1WW/K6dOlSsrOzeeaZZ+jSpQuxsbEA9OjRgzp16vDpp5/i5OTEpk2bbO/JM888Q2ZmJn/++SdeXl5s27YNb2/va4rpVnVVCaybmxspKSl5lqempqo5/ybz76/vUT77EMcNPyp2fsPR4YiIyFUYO3ZsgesqVqxI9+7dbc/ff/99srKy8i1btmxZ+vTpY3s+fvx427juuUaOHHlFsaWkpDB+/HgmTpxI794591JERUXZppvPNXToUNq3bw/A6NGjqV69Onv27KFKlSqULFmSoUOH2so+++yzLFy4kDlz5tgllRUrVuTdd98tMBYnJye6du3KN998Y0tgFy9eTGJiIg899BBAofd1NRYvXsyWLVvYu3cvpUvnTMs+Y8YMqlevztq1a6lXrx4HDhzgxRdfpEqVKrZjynXgwAEeeughatSoAUD58uWvKZ5b2VV1Ibjvvvvo378/q1evxjAMDMNg1apVPPXUU9x///1FHaNcpezEw4RtmgDAishniSwV4eCIRETkVrN9+3YyMjJo1arVJcvVrFnT9v/w8Jxpy48dOwbktJKOGTOGGjVqEBgYiLe3NwsXLuTAgQN2dURHR182nh49ehAbG8uRI0cAmDlzJu3bt8ff3/+K9nU1tm/fTunSpW3JK0C1atXw9/e33fQ+ZMgQ+vXrR+vWrXn77beJi4uzlX3uued44403aNy4MSNHjuTvv/++5phuVVfVAvvxxx/Tu3dvGjZsaGv2zsrKomPHjhpK4iZyYPaLlOcsf1OR5o+ob7KISHE1bNiwAteZzfZtURe2Ll7MZLKfT3zQoEHXFhjg4eFRqHIXdl3IjcNqtQLw3nvvMX78eMaNG0eNGjXw8vJi8ODBebo4eHl5XXY/9erVIyoqilmzZvH000/zww8/MG3aNNv6wu7rehk1ahTdu3dn/vz5/Pbbb4wcOZJZs2bxwAMP0K9fP2JiYpg/fz6///47Y8eO5YMPPuDZZ5+9IbEVJ1eVwPr7+/PTTz+xZ88e218UVatWpUKFCkUanFy91N3LKH90PlbDxIGGr1PTy83RIYmIyFW6ku5516tsQSpWrIiHhweLFy+mX79+V1XH8uXL6dixI48++iiQk9ju2rWLatWqXVV9PXr0YObMmZQqVQqz2WzrunA99nWhqlWrcvDgQQ4ePGhrhd22bRuJiYl29VeqVIlKlSrx/PPP061bN6ZOncoDDzwAQOnSpXnqqad46qmnbH2LlcDmVegEdsiQIZdcv2TJEtv/P/zww6uPSK6d1ULq98/jDfzm2oZ2bTQ7moiIXB/u7u68/PLLvPTSS7i6utK4cWOOHz/O1q1b7SY7upSKFSsyd+5cVqxYQUBAAB9++CEJCQnXlMCOGjWKN998k4cffhg3t/ONOEW9rwu1bt2aGjVq0KNHD8aNG0d2djYDBgygWbNm1K1bl7Nnz/Liiy/y8MMPExkZyaFDh1i7dq2tf+7gwYO55557qFSpEqdPn2bJkiVUrVr1muO6FRU6gd24cWOhyl18eUJuvBNLPyPs7G6SDE8COozB2emqujqLiIgUyvDhw3F2dmbEiBEcOXKE8PBwnnrqqUJv/9prr/Hvv/8SExODp6cn/fv3p1OnTiQlJV1VPBUqVKB+/fqsWbMmT9fGot7XhUwmEz/99BPPPvssTZs2xWw2065dOyZMyLkfxcnJiZMnT9KrVy8SEhIIDg7mwQcfZPTo0UBO/9xnnnmGQ4cO4evrS7t27fjoo4+uOa5bkckwLp5YVJKTk/Hz8yMpKQlfX19Hh3Nlzpwi9f2aeFtT+CrgGXoOesvREYmISCGkp6ezd+9eIiMjcXd3d3Q4ItfFpT7nV5J/qWnuFhP/w6t4W1PYYS1Nwy4vOjocERERkSKnBPYWYjm8kZDdObOJrKz8ChXCAhwckYiISPG1bNkyvL29C3yI42gO0VuFYXBq7mBKYPBfGtOpU2dHRyQiIlKs1a1bl02bNjk6DMmHEthbxNn131Di9CbSDDeSm4wgwEszoomIiFwLDw8PDRF6k1IXgltBejKWhcMB+MatMw+1uLap8ERERERuZkpgbwHJC9/CO+sk/1rDqNDxZVw0bJaIiIjcwpTpFHfHd+G18T8AfB8ykObVSjk4IBEREZHrSwlscWYYJH4/BCcsLLbUocPDfTSRhIiIiNzylMAWY5btv+J/dBkZhjOb73iZymE+jg5JRERE5LpTAltcZZ3l7C8vAzDd1IHe7Vs6OCAREZG89u3bh8lkuu2GozKZTPz444+ODuOWpQS2mMpc+hHeZw9zxAjEpdmLBHm7OTokERERh+vTpw+dOnUq0jpHjRpF7dq1i7ROuTZKYIuj0/sxLR8HwH/cH6NHk6qOjUdEROQGy8zMdHQI4kBKYIuhM7++gouRwQpLNRp26Iers95GERFxHKvVyrvvvkuFChVwc3OjTJkyvPnmm3Zl/v33X1q0aIGnpye1atVi5cqVtnUnT56kW7dulCxZEk9PT2rUqMG3335rt33z5s0ZOHAggwcPJjg4mJiYmDxxjBo1iunTp/PTTz9hMpkwmUzExsYCcPDgQTp37oy/vz+BgYF07NiRffv22baNjY2lfv36eHl54e/vT+PGjdm/fz/Tpk1j9OjRbN682VbntGnTrvg12rJlCy1btsTDw4OgoCD69+9PamrqZfcPsHnzZlq0aIGPjw++vr5ER0ezbt26K47hVqLMp7iJW4Jn3H/JNsz8EDaIttXDHB2RiIhcZ5mZmWRmZmIYhm2ZxWIhMzOT7OzsIi17NYYNG8bbb7/N8OHD2bZtG9988w2hoaF2ZV599VWGDh3Kpk2bqFSpEt26dbPFk56eTnR0NPPnz+eff/6hf//+9OzZkzVr1tjVMX36dFxdXVm+fDmTJ0/OE8fQoUPp3Lkz7dq14+jRoxw9epRGjRqRlZVFTEwMPj4+LFu2jOXLl+Pt7U27du1sr0unTp1o1qwZf//9NytXrqR///6YTCa6dOnCCy+8QPXq1W11dunS5Ypen7S0NGJiYggICGDt2rV89913/PHHHwwcOBDgkvsH6NGjB6VKlWLt2rWsX7+eV155BRcXlyuK4ZZjSB5JSUkGYCQlJTk6FHvZmcaZD+80jJG+xpevPmJsPXyTxSciIlft7NmzxrZt24yzZ8/mWTdq1Chj1KhRRmpqqm3Z0qVLjVGjRhk//fSTXdk333zTGDVqlHH69GnbspUrVxqjRo0y5s2bZ1f23XffNUaNGmUkJCRcddzJycmGm5ubMWXKlHzX79271wCMzz//3LZs69atBmBs3769wHrbt29vvPDCC7bnzZo1M+rUqXPZeHr37m107NjRbtlXX31lVK5c2bBarbZlGRkZhoeHh7Fw4ULj5MmTBmDExsbmW+fIkSONWrVqXXbfFwKMH374wTAMw/jPf/5jBAQE2L1/8+fPN8xmsxEfH3/Z/fv4+BjTpk27ov3frC71Ob+S/EstsMWIddVkPJL2cMLwZX/NQVSL8HV0SCIicpvbvn07GRkZtGrV6pLlatasaft/eHg4AMeOHQNyWojHjBlDjRo1CAwMxNvbm4ULF3LgwAG7OqKjo68qxs2bN7Nnzx58fHzw9vbG29ubwMBA0tPTiYuLIzAwkD59+hATE0OHDh0YP348R48evap95Wf79u3UqlULLy8v27LGjRtjtVrZuXPnZfc/ZMgQ+vXrR+vWrXn77beJi4srstiKK2dHByCFlJKAZclYzMDHdOfZe+o6OiIREblBhg0bBmB32bhx48bcddddmM32bVFDhw7NU7ZevXrceeedecoOGjQoT9kr5eHhUahyF+4j99K41WoF4L333mP8+PGMGzeOGjVq4OXlxeDBg/PcqHVhAnglUlNTiY6OZubMmXnWlShRAoCpU6fy3HPPsWDBAmbPns1rr73GokWLuOuuu65qn1fqUvsfNWoU3bt3Z/78+fz222+MHDmSWbNm8cADD9yQ2G5GaoEtJrJ/H4FLdhqbrOUJb96PEj4aNktE5Hbh6uqKq6ur3WyLTk5OuLq64uzsXKRlr1TFihXx8PBg8eLFV13H8uXL6dixI48++ii1atWifPny7Nq166rqcnV1xWKx2C2788472b17NyEhIVSoUMHu4efnZytXp04dhg0bxooVK7jjjjv45ptvCqzzSlStWpXNmzeTlpZmW7Z8+XLMZjOVK1e+7P4BKlWqxPPPP8/vv//Ogw8+yNSpU686nluBEtji4OAanLfMAuBTjyfpe3d5BwckIiKSw93dnZdffpmXXnqJGTNmEBcXx6pVq/jiiy8KXUfFihVZtGgRK1asYPv27Tz55JMkJCRcVTzlypXj77//ZufOnZw4cYKsrCx69OhBcHAwHTt2ZNmyZezdu5fY2Fiee+45Dh06xN69exk2bBgrV65k//79/P777+zevZuqVava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y+FTyd6u2t0RzqeP3snoX7axKqmabXm4nzsjO1RT8ioiIiJSACWwDtTujnDaVAtjzd5THEtJJ8THnfqRgTiZr21+YBEREZFbmRJYB3Mym2gYFeToMERERESKjWI3kYGIiIiI3N6UwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEixogRWRERERIoVJbAiIiIiUqwogRURERGRYkUJrIiIiIgUK0pgRURERKRYUQIrIiIiIsWKElgRERERKVaUwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEix4vAEdtKkSZQrVw53d3caNGjAmjVrCiw7ZcoUmjRpQkBAAAEBAbRu3TpP+T59+mAymewe7dq1u96HISIiIiI3iEMT2NmzZzNkyBBGjhzJhg0bqFWrFjExMRw7dizf8rGxsXTr1o0lS5awcuVKSpcuTdu2bTl8+LBduXbt2nH06FHb49tvv70RhyMiIiIiN4DJMAzDUTtv0KAB9erVY+LEiQBYrVZKly7Ns88+yyuvvHLZ7S0WCwEBAUycOJFevXoBOS2wiYmJ/Pjjj1cdV3JyMn5+fiQlJeHr63vV9YiIiIhI4VxJ/uWwFtjMzEzWr19P69atzwdjNtO6dWtWrlxZqDrOnDlDVlYWgYGBdstjY2MJCQmhcuXKPP3005w8ebJIYxcRERERx3F21I5PnDiBxWIhNDTUbnloaCg7duwoVB0vv/wyERERdklwu3btePDBB4mMjCQuLo7/+7//45577mHlypU4OTnlW09GRgYZGRm258nJyVdxRCIiIiJyIzgsgb1Wb7/9NrNmzSI2NhZ3d3fb8q5du9r+X6NGDWrWrElUVBSxsbG0atUq37rGjh3L6NGjr3vMIiIiInLtHNaFIDg4GCcnJxISEuyWJyQkEBYWdslt33//fd5++21+//13atasecmy5cuXJzg4mD179hRYZtiwYSQlJdkeBw8eLPyBiIiIiMgN5bAE1tXVlejoaBYvXmxbZrVaWbx4MQ0bNixwu3fffZcxY8awYMEC6tate9n9HDp0iJMnTxIeHl5gGTc3N3x9fe0eIiIiInJzcugwWkOGDGHKlClMnz6d7du38/TTT5OWlkbfvn0B6NWrF8OGDbOVf+eddxg+fDhffvkl5cqVIz4+nvj4eFJTUwFITU3lxRdfZNWqVezbt4/FixfTsWNHKlSoQExMjEOOUURERESKlkP7wHbp0oXjx48zYsQI4uPjqV27NgsWLLDd2HXgwAHM5vM59qeffkpmZiYPP/ywXT0jR45k1KhRODk58ffffzN9+nQSExOJiIigbdu2jBkzBjc3txt6bCIiIiJyfTh0HNiblcaBFREREbmxisU4sCIiIiIiV0MJrIiIiIgUK0pgRURERKRYUQIrIiIiIsWKElgRERERKVaUwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEixogRWRERERIoVJbAiIiIiUqwogRURERGRYkUJrIiIiIgUK0pgRURERKRYUQIrIiIiIsWKElgRERERKVaUwIqIiIhIsaIEVkRERESKFSWwIiIiIlKsKIEVERERkWJFCayIiIiIFCtKYEVERESkWFECKyIiIiLFihJYERERESlWlMCKiIiISLGiBFZEREREihUlsCIiIiJSrCiBFREREZFiRQmsiIiIiBQrSmBFREREpFhRAisiIiIixYoSWBEREREpVpTAioiIiEix4vAEdtKkSZQrVw53d3caNGjAmjVrCiw7ZcoUmjRpQkBAAAEBAbRu3TpPecMwGDFiBOHh4Xh4eNC6dWt27959VbFlZmZiGIbtucViITMzk+zs7DzlrkfZrKwsMjMzsVqttmVWq5XMzEyysrJuurLZ2dlkZmZisViuqqxhGLbX53qVze91v5Kyjnzvb+XPyY1476+krCPfe50jCi6rc8R5Okc4tqzOEdfvvS8s50KXvA5mz57NkCFDmDx5Mg0aNGDcuHHExMSwc+dOQkJC8pSPjY2lW7duNGrUCHd3d9555x3atm3L1q1bKVmyJADvvvsuH3/8MdOnTycyMpLhw4cTExPDtm3bcHd3v6L4PvjgA15++WU8PT0BWL58OX/++Se1a9emY8eOtnLvv/8+WVlZPP300/j7+wOwZs0aFi9eTPXq1Xn44YdtZceNG8fZs2fp168fJUqUAGDTpk389ttvVKpUiW7dutnKTpo0iaSkJHr37k1ERAQA//zzD7/88gvlypWjd+/etrL/+c9/OHHiBN27d6ds2bIA7Nq1i3nz5lGqVCkef/xxW9mpU6dy9OhRHnnkESpUqADA3r17mTVrFiEhITz99NO2sl9//TUHDhygU6dOVK1aFYBDhw7x1VdfERAQwHPPPWcrO2vWLOLi4mjfvj01a9YEICEhgS+//BJvb29eeOEFW9l58+axY8cO2rZtS3R0NACnTp3is88+w83NjZdffhmTyQTAL7/8wt9//02LFi246667AEhJSWHixImYzWZee+01W9kFCxawfv167r77bpo0aQJAeno6H330EQCvvvoqzs45H/s//viDVatW0aBBA1q2bAnknATeffddAF566SU8PDwAWLp0KcuWLePOO+8kJibGdhzvvPMOVquVQYMG2d77lStXsnjxYmrUqMF9991nK/vhhx+SkZHBgAEDbO/9unXrWLBgAVWqVOGBBx6wlZ0wYQKpqak88cQTtvd+8+bN/PLLL0RFRdG5c2db2cmTJ3P69Gn69Olje++3bdvGvHnzKFOmDD169LCV/eKLLzh27Bjdu3enYsWKAOzevZtZs2YRFhZG3759bWVnzJjB4cOHeeSRR6hWrRoA+/bt46uvviI4OJgnnnjCVvbbb79l3759dOzYkdq1awNw5MgRvvjiC/z8/BgwYICt7Ny5c9m9ezf33nsv9erVA+DYsWNMnjwZDw8PBg8ebCv7008/sW3bNtq0aUOjRo0ASExM5OOPP8bFxYWhQ4fayv73v/9l8+bNNGvWjObNmwOQlpbGBx98AMCwYcNsZRctWsS6deto1KgRbdq0AXJ+FN5++20AXnjhBVxdXW3v/YoVK6hXrx733nuvrY6xY8cCMGjQIJ0jdI7QOULnCJ0jiuAcMW/ePArLoQnshx9+yBNPPGH7QkyePJn5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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "val_means = [r[\"best_val_loss\"][0] for r in wp]\n", "\n", @@ -663,7 +318,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "11901b9c", "metadata": { "execution": { @@ -673,18 +328,7 @@ "shell.execute_reply": "2026-07-30T17:10:35.130491Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAXxhJREFUeJzt3Xd4FFX//vF700NJAVIIBAKEXhUEQlfyCIgIqAj58kgTUAQFUVRQuhrsqCBWigrSFCwUhUhRmrQoSJEWgkpCTwhIgOT8/uDHPCwpJNmFJPB+XddeMGfOzH7mZLK7d6aszRhjBAAAAAAOcMnvAgAAAAAUfgQLAAAAAA4jWAAAAABwGMECAAAAgMMIFgAAAAAcRrAAAAAA4DCCBQAAAACHESwAAAAAOIxgAQAAAMBhBAsAuE7GjBkjm82mY8eO5XcpThMWFqZ77703v8vIN9OnT5fNZlNcXFy2/Xr16qVixYrdmKLyQWJioh588EGVLFlSNptNEydO1MqVK2Wz2bRy5cr8Lg9APiFYAMBN4v3339f06dPzuwyn27Fjh8aMGXPND/O4cZ566in98MMPGj58uD7//HO1bds2v0sCUAC45XcBAADneP/991WqVCn16tUrv0txqh07dmjs2LFq1aqVwsLC8rscSPrpp5/UsWNHPfPMM1ZblSpV9O+//8rDwyMfKwOQnwgWAAAgV44cOSI/Pz+7NhcXF3l5eeVPQQAKBE6FAlCo/f333+rTp4+CgoLk6empmjVraurUqXZ9Lp/7PWfOHI0YMULBwcEqWrSo7rvvPh06dCjDOufNm6f69evL29tbpUqV0n//+1/9/fffGfrt2rVLDz30kAICAuTt7a2qVavqhRdeyNDv1KlT6tWrl/z8/OTr66vevXvr7Nmzdn2WLVumZs2ayc/PT8WKFVPVqlU1YsSIHI9DWFiY/vjjD61atUo2m002m02tWrWy5u/fv19dunRRiRIlVKRIETVu3FiLFi3K8fqv9uOPP6pevXry8vJSjRo19PXXX2e63UOGDFFoaKg8PT0VHh6uV199Venp6Xb9Zs+erfr166t48eLy8fFR7dq19c4770i6dE1Dly5dJEl33nmntW05OY9//vz5stlsWrVqVYZ5H374oWw2m7Zv3y5J+v3339WrVy9VrFhRXl5eCg4OVp8+fXT8+PHcDo2d/fv3q02bNipatKhCQkI0btw4GWMkScYYhYWFqWPHjhmWO3funHx9ffXoo49e8zm++OILNWzYUEWKFJG/v79atGihH3/80a7P+++/r5o1a8rT01MhISEaOHCgTp06ZdenVatWqlWrlnbs2KE777xTRYoUUZkyZfTaa69ZfS5fY2KM0eTJk62fh6Qsr7GYPHmyKlasKG9vbzVs2FA///yzWrVqZbd/Arg5cMQCQKGVmJioxo0by2azadCgQQoICNCSJUv0yCOPKDk5WUOGDLHr//LLL8tms+m5557TkSNHNHHiREVGRio2Nlbe3t6SLn1w6t27t+644w5FR0crMTFR77zzjtasWaOtW7daf6X9/fff1bx5c7m7u6t///4KCwvTvn379N133+nll1+2e96HHnpIFSpUUHR0tLZs2aJPPvlEgYGBevXVVyVJf/zxh+69917VqVNH48aNk6enp/bu3as1a9bkeCwmTpyoJ554QsWKFbPCTVBQkDVOTZo00dmzZ/Xkk0+qZMmSmjFjhu677z7Nnz9fnTt3ztW479mzR127dtVjjz2mnj17atq0aerSpYuWLl2q//znP5Kks2fPqmXLlvr777/16KOPqly5clq7dq2GDx+uw4cPa+LEiZIuBaqoqCi1bt3aGo+dO3dqzZo1Gjx4sFq0aKEnn3xS7777rkaMGKHq1atLkvVvdtq3b69ixYpp7ty5atmypd28OXPmqGbNmqpVq5ZVx/79+9W7d28FBwfrjz/+0EcffaQ//vhD69evtz4850ZaWpratm2rxo0b67XXXtPSpUs1evRoXbx4UePGjZPNZtN///tfvfbaazpx4oRKlChhLfvdd98pOTlZ//3vf7N9jrFjx2rMmDFq0qSJxo0bJw8PD23YsEE//fST7r77bkmXbiIwduxYRUZGasCAAdq9e7emTJmijRs3as2aNXJ3d7fWd/LkSbVt21b333+/HnroIc2fP1/PPfecateurXbt2qlFixb6/PPP9fDDD+s///mPevTokW19U6ZM0aBBg9S8eXM99dRTiouLU6dOneTv76+yZcvmekwBFHAGAAqpRx55xJQuXdocO3bMrr1bt27G19fXnD171hhjzIoVK4wkU6ZMGZOcnGz1mzt3rpFk3nnnHWOMMefPnzeBgYGmVq1a5t9//7X6ff/990aSGTVqlNXWokULU7x4cXPw4EG7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LZcXkZGRKlGihObMmaM5c+aoYcOG1mlO0v/+Sn/1zy4nH+6vZdKkSdb/jTGaNGmS3N3d1bp1a7t+Dz/8sHbs2KFhw4bJ1dVV3bp1u+a6O3XqJBcXF40bNy7DUZXL2xIZGSkPDw+9++67dtv36aefKikpydqnr4cGDRqoZMmS+vjjj62ftyTNnDkzT6dWASj4OGIBoNCaMGGCVqxYoUaNGqlfv36qUaOGTpw4oS1btmj58uUZPrCXKFFCzZo1U+/evZWYmKiJEycqPDxc/fr1kyS5u7vr1VdfVe/evdWyZUtFRUVZt5sNCwvTU089Za3r3XffVbNmzXT77berf//+qlChguLi4rRo0SLFxsbmajvGjRun1atXq3379ipfvryOHDmi999/X2XLlrW74Ppa6tevrylTpuill15SeHi4AgMDddddd+n555/Xl19+qXbt2unJJ59UiRIlNGPGDB04cEBfffVVhgt/r6VKlSp65JFHtHHjRgUFBWnq1KlKTEzUtGnTrD7Dhg3Tt99+q3vvvVe9evVS/fr1debMGW3btk3z589XXFycSpUqpb59++rEiRO66667VLZsWR08eFDvvfee6tWrZ10DUq9ePbm6uurVV19VUlKSPD09dddddykwMDBH9bq7u+v+++/X7NmzdebMGb3xxht28318fNSiRQu99tprunDhgsqUKaMff/xRBw4cyNW4XM3Ly0tLly5Vz5491ahRIy1ZskSLFi3SiBEjFBAQYNe3ffv2KlmypObNm6d27drlaNvCw8P1wgsvaPz48WrevLnuv/9+eXp6auPGjQoJCVF0dLQCAgI0fPhwjR07Vm3bttV9992n3bt36/3339cdd9xxzdvZOsLDw0NjxozRE088obvuuksPPfSQ4uLiNH36dFWqVMnhI1EACqD8uRkVADhHYmKiGThwoAkNDTXu7u4mODjYtG7d2nz00UdWn8u3wfzyyy/N8OHDTWBgoPH29jbt27fPcLtYY4yZM2eOue2224ynp6cpUaKE6d69u/nrr78y9Nu+fbvp3Lmz8fPzM15eXqZq1apm5MiR1vzLt5u9+jayV9+yNCYmxnTs2NGEhIQYDw8PExISYqKiojLcqvVaEhISTPv27U3x4sUz3M5z37595sEHH7Rqbdiwofn+++9ztX5jLt1utn379uaHH34wderUMZ6enqZatWpm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Pj437RvL5W3PbLuvHJcjR47Yzb948aJOnDjhlPG9PL+wGDRokL7//nutWLFCZcuWtdpv1H5YqlQpubq6Fvqx9PDwUHh4uOrXr6/o6GjVrVtX77zzDuOYC5s3b9aRI0d0++23y83NTW5ublq1apXeffddubm5KSgoiLHMo/x4j7kZx7EgvcfkpJabAcHiFlC5cmV5e3srJiYmT8uvWbNGHTt21H//+1/VrVtXFStW1J9//unkKguXlJQU7du3T6VLl1b9+vXl7u5uN767d+9WfHy8IiIiJEkRERHatm2b3YvXsmXL5OPjoxo1alh9rv4ZLVu2zFrHzahChQoKDg622+7k5GRt2LDBbuxOnTqlzZs3W31++uknpaenq1GjRlaf1atX68KFC1afZcuWqWrVqvL397f6FObxNcZo0KBBWrBggX766acMh+Vv1H7o4eGh+vXr2/VJT09XTExMoRnLzKSnpys1NZVxzIXWrVtr27Ztio2NtR4NGjRQ9+7drf8zlnmTH+8xN+M4FqT3mJzUclPI76vHcWOMGTPG+Pv7mxkzZpi9e/eadevWmU8++STT282ePHnSSDIrVqwwxhjz1FNPmdDQULNmzRqzY8cO07dvX+Pj42M6duxoLXPlnUBuRk8//bRZuXKlOXDggFmzZo2JjIw0pUqVMkeOHDHGXLoVYLly5cxPP/1kNm3aZCIiIkxERIS1/OVbAd59990mNjbWLF261AQEBGR6K8Bhw4aZnTt3msmTJ98Ut5s9ffq02bp1q9m6dauRZN566y2zdetWc/DgQWPMpdvv+fn5mW+++cb8/vvvpmPHjpneCvC2224zGzZsML/88oupXLmy3a0AT506ZYKCgszDDz9stm/fbmbPnm2KFCmS4VaAbm5u5o033jA7d+40o0ePLlS3mx0wYIDx9fU1K1eutLsl5dmzZ60+N2o/nD17tvH09DTTp083O3bsMP379zd+fn52d6QpyJ5//nmzatUqc+DAAfP777+b559/3thsNvPjjz8aYxhHR1z9XsBY5kxBeY8pjONYmN5jclJLYUewuEWkpaWZl156yZQvX964u7ubcuXKmVdeeSVHweL48eOmY8eOplixYiYwMNC8+OKLpkePHrdUsOjataspXbq08fDwMGXKlDFdu3Y1e/futeb/+++/5vHHHzf+/v6mSJEipnPnzubw4cN264iLizPt2rUz3t7eplSpUubpp582Fy5csOuzYsUKU69ePePh4WEqVqxopk2bdiM277pasWKFkZTh0bNnT2PMpVvwjRw50gQFBRlPT0/TunVrs3v3brt1HD9+3ERFRZlixYoZHx8f07t3b3P69Gm7Pr/99ptp1qyZ8fT0NGXKlDETJkzIUMvcuXNNlSpVjIeHh6lZs6ZZtGjRddtuZ8tsDCXZ7SM3cj987733TLly5YyHh4dp2LChWb9+/fXY7OuiT58+pnz58sbDw8MEBASY1q1bW6HCGMbREVe/FzCWOVOQ3mMK2zgWpveYnNRS2NmMMeZGHiEBAAAAcPPhGgsAAAAADiNYAAAAAHAYwQIAAACAwwgWAAAAABxGsAAAAADgMIIFAAAAAIcRLAAAAAA4jGABAAAAwGEECwAoAM6ePasHHnhAPj4+stlsOnXqlMLCwjRx4kSH1338+HEFBgYqLi7O4XU5y8qVK63tLEzrzm9jxoxRvXr1rsu6ly5dqnr16ik9Pf26rB/AzY9gAQAFwIwZM/Tzzz9r7dq1Onz4sHx9fbVx40b179/f4XW//PLL6tixo8LCwhwvtBBo0qSJNYbIubZt28rd3V0zZ87M71IAFFIECwAoAPbt26fq1aurVq1aCg4Ols1mU0BAgIoUKeLQes+ePatPP/1UjzzyiJMqLfg8PDysMSyojDG6ePFifpdhuXDhgiSpV69eevfdd/O5GgCFFcECAK4hPT1dr732msLDw+Xp6aly5crp5ZdftuZv27ZNd911l7y9vVWyZEn1799fKSkp1vxevXqpU6dOeuONN1S6dGmVLFlSAwcOtD7MtWrVSm+++aZWr14tm82mVq1aSVKGU6F27dqlZs2aycvLSzVq1NDy5ctls9m0cOHCLGtfvHixPD091bhxY2tbypYtqylTptj127p1q1xcXHTw4EFJUnx8vDp27KhixYrJx8dHDz30kBITE+2W+e6773THHXfIy8tLpUqVUufOna15n3/+uRo0aKDixYsrODhY//d//6cjR45kqG/NmjWqU6eOvLy81LhxY23fvj2bn8T/HDx4UB06dJC/v7+KFi2qmjVravHixZIyngrVqlUr2Wy2DI/Lp4adOnVKffv2VUBAgHx8fHTXXXfpt99+y1Edl6WmpurJJ59UYGCgvLy81KxZM23cuNGaf7mmJUuWqH79+vL09NQvv/yS6br++usvRUVFqUSJEipatKgaNGigDRs22PX5/PPPFRYWJl9fX3Xr1k2nT5+25i1dulTNmjWTn5+fSpYsqXvvvVf79u2z5sfFxclms2nOnDlq2bKlvLy8rKMUHTp00KZNm+z6A0BOESwA4BqGDx+uCRMmaOTIkdqxY4dmzZqloKAgSdKZM2fUpk0b+fv7a+PGjZo3b56WL1+uQYMG2a1jxYoV2rdvn1asWKEZM2Zo+vTpmj59uiTp66+/Vr9+/RQREaHDhw/r66+/zlBDWlqaOnXqpCJFimjDhg366KOP9MILL1yz9p9//ln169e3pl1cXBQVFaVZs2bZ9Zs5c6aaNm2q8uXLKz09XR07dtSJEye0atUqLVu2TPv371fXrl2t/osWLVLnzp11zz33aOvWrYqJiVHDhg2t+RcuXND48eP122+/aeHChYqLi1OvXr0y1Dds2DC9+eab2rhxowICAtShQwcrcGVn4MCBSk1N1erVq7Vt2za9+uqrKlasWKZ9v/76ax0+fNh63H///apatar1M+zSpYuOHDmiJUuWaPPmzbr99tvVunVrnThx4pp1XPbss8/qq6++0owZM7RlyxaFh4erTZs2Gdbx/PPPa8KECdq5c6fq1KmTYT0pKSlq2bKl/v77b3377bf67bff9Oyzz9pd97Bv3z4tXLhQ33//vb7//nutWrVKEyZMsOafOXNGQ4cO1aZNmxQTEyMXFxd17tw5w7UTzz//vAYPHqydO3eqTZs2kqRy5copKChIP//8c463HQAsBgCQpeTkZOPp6Wk+/vjjTOd/9NFHxt/f36SkpFhtixYtMi4uLiYhIcEYY0zPnj1N+fLlzcWLF60+Xbp0MV27drWmBw8ebFq2bGm37vLly5u3337bGGPMkiVLjJubmzl8+LA1f9myZUaSWbBgQZb1d+zY0fTp08eubevWrcZms5mDBw8aY4xJS0szZcqUMVOmTDHGGPPjjz8aV1dXEx8fby3zxx9/GEnm119/NcYYExERYbp3757l815t48aNRpI5ffq0McaYFStWGElm9uzZVp/jx48bb29vM2fOnGuur3bt2mbMmDGZzru87pMnT2aY99Zbbxk/Pz+ze/duY4wxP//8s/Hx8THnzp2z61epUiXz4Ycf5mjbUlJSjLu7u5k5c6bVdv78eRMSEmJee+01u5oWLlyY7bo+/PBDU7x4cXP8+PFM548ePdoUKVLEJCcnW23Dhg0zjRo1ynKdR48eNZLMtm3bjDHGHDhwwEgyEydOzLT/bbfdluXYAkB2OGIBANnYuXOnUlNT1bp16yzn161bV0WLFrXamjZtqvT0dO3evdtqq1mzplxdXa3p0qVLZ3pqUFZ2796t0NBQBQcHW21XHiHIyr///isvLy+7tnr16ql69erWUYtVq1bpyJEj6tKli7VNoaGhCg0NtZapUaOG/Pz8tHPnTklSbGxslmMiSZs3b1aHDh1Urlw5FS9eXC1btpR06RSrK0VERFj/L1GihKpWrWo9R3aefPJJvfTSS2ratKlGjx6t33///ZrLLFmyRM8//7zmzJmjKlWqSJJ+++03paSkqGTJkipWrJj1OHDgQI5PB9q3b58uXLigpk2bWm3u7u5q2LBhhm1p0KBBtuuKjY3VbbfdphIlSmTZJywsTMWLF7emr96X9uzZo6ioKFWsWFE+Pj7WRftXj31WtXh7e+vs2bPZ1gkAmSFYAEA2vL29nbIed3d3u2mbzXZDbutZqlQpnTx5MkN79+7drWAxa9YstW3bViVLlszxerMbl8unh/n4+GjmzJnauHGjFixYIEk6f/58Lrcgc3379tX+/fv18MMPa9u2bWrQoIHee++9LPvv2LFD3bp104QJE3T33Xdb7SkpKSpdurRiY2PtHrt379awYcOcUuuVrgygmcnJ/natfalDhw46ceKEPv74Y23YsMG6PuPqsc+qlhMnTiggIOCadQDA1QgWAJCNypUry9vbWzExMZnOr169un777TedOXPGaluzZo1cXFxUtWpVp9VRtWpVHTp0yO4C6isvDs7Kbbfdph07dmRo/7//+z9t375dmzdv1vz589W9e3drXvXq1XXo0CEdOnTIatuxY4dOnTqlGjVqSJLq1KmT5Zjs2rVLx48f14QJE9S8eXNVq1Yty6Mz69evt/5/8uRJ/fnnn6pevfo1t0uSQkND9dhjj+nrr7/W008/rY8//jjTfseOHVOHDh30wAMP6KmnnrKbd/vttyshIUFubm4KDw+3e5QqVSpHdVSqVEkeHh5as2aN1XbhwgVt3LjRGq+cqlOnjmJjY3N1fceVjh8/rt27d+vFF19U69atVb169UyDZVbOnTunffv26bbbbsvT8wO4tREsACAbXl5eeu655/Tss8/qs88+0759+7R+/Xp9+umnki795d/Ly0s9e/bU9u3btWLFCj3xxBN6+OGHrYuDneE///mPKlWqpJ49e+r333/XmjVr9OKLL0pStrdVbdOmjf74448MHy7DwsLUpEkTPfLII0pLS9N9991nzYuMjFTt2rXVvXt3bdmyRb/++qt69Oihli1bWqfPjB49Wl9++aVGjx6tnTt3WhdQS5cuAPbw8NB7772n/fv369tvv9X48eMzrW/cuHGKiYnR9u3b1atXL5UqVUqdOnW65ngMGTJEP/zwgw4cOKAtW7ZoxYoVWQaSBx54QEWKFNGYMWOUkJBgPdLS0hQZGamIiAh16tRJP/74o+Li4rR27Vq98MIL2rRp0zXrkC795X/AgAEaNmyYli5dqh07dqhfv346e/Zsrm/zGxUVpeDgYHXq1Elr1qzR/v379dVXX2ndunU5Wt7f318lS5bURx99pL179+qnn37S0KFDc/z869evl6enp90pagCQUwQLALiGkSNH6umnn9aoUaNUvXp1de3a1foLfJEiRfTDDz/oxIkTuuOOO/Tggw+qdevWmjRpklNrcHV11cKFC5WSkqI77rhDffv2te4KdfU1FFeqXbu2br/9ds2dOzfDvO7du+u3335T586d7U7Bsdls+uabb+Tv768WLVooMjJSFStW1Jw5c6w+rVq10rx58/Ttt9+qXr16uuuuu/Trr79KkgICAjR9+nTNmzdPNWrU0IQJE/TGG29kWt+ECRM0ePBg1a9fXwkJCfruu+/k4eFxzfFIS0vTwIEDVb16dbVt21ZVqlTR+++/n2nf1atXa/v27SpfvrxKly5tPQ4dOiSbzabFixerRYsW6t27t6pUqaJu3brp4MGDVjC8fHvWlStXZlnPhAkT9MADD+jhhx/W7bffrr179+qHH36Qv7//NbflSh4eHvrxxx8VGBioe+65R7Vr19aECRPsrs/JjouLi2bPnq3NmzerVq1aeuqpp/T666/n+Pm//PJLde/e3eHvTwFwa7IZY0x+FwEAyL01a9aoWbNm2rt3rypVqpRlv0WLFmnYsGHavn27XFz4e1JurVixQvfff7/279+f66BQmBw7dkxVq1bVpk2bVKFChfwuB0Ah5JbfBQAAcmbBggUqVqyYKleurL1792rw4MFq2rRptqFCktq3b689e/bo77//trvTE3Jm8eLFGjFixE0dKqRLR2bef/99QgWAPOOIBQAUEp999pleeuklxcfHq1SpUoqMjNSbb76Zq7s5FRbt2rXL8kvaRowYoREjRtzgigAA10KwAAAUOH///bf+/fffTOeVKFEi2+95AADkD4IFAAAAAIdxFR8AAAAAhxEsAAAAADiMYAEAAADAYQQLAAAAAA4jWAAAAABwGMECAAAAgMMIFgAAAAAcRrAAAAAA4LD/B0cCFmWiv7nAAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "inferred_total_epochs = int(raw[\"epochs_to_best_val\"].max())\n", "\n", @@ -713,13 +357,13 @@ "source": [ "*Notes: the dashed line marks the last epoch of the run (`--epochs` used). A bar\n", "reaching that line means best `val_loss` landed on the final epoch for at least some\n", - "seeds — i.e. training may not have plateaued yet for that config. See the per-seed\n", + "seeds \u2014 i.e. training may not have plateaued yet for that config. See the per-seed\n", "breakdown below for exactly how many of the 3 seeds hit that ceiling per config.*" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "305a88cc", "metadata": { "execution": { @@ -729,131 +373,7 @@ "shell.execute_reply": "2026-07-30T17:10:35.152834Z" } }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizeseeds_hitting_ceilingn_seedsfraction_hitting_ceiling
7wordpiece100000331.000000
1wordpiece5000230.666667
4wordpiece30000230.666667
3wordpiece20000230.666667
5wordpiece40000230.666667
6wordpiece50000230.666667
2wordpiece10000130.333333
0char25130.333333
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size seeds_hitting_ceiling n_seeds \\\n", - "7 wordpiece 100000 3 3 \n", - "1 wordpiece 5000 2 3 \n", - "4 wordpiece 30000 2 3 \n", - "3 wordpiece 20000 2 3 \n", - "5 wordpiece 40000 2 3 \n", - "6 wordpiece 50000 2 3 \n", - "2 wordpiece 10000 1 3 \n", - "0 char 25 1 3 \n", - "\n", - " fraction_hitting_ceiling \n", - "7 1.000000 \n", - "1 0.666667 \n", - "4 0.666667 \n", - "3 0.666667 \n", - "5 0.666667 \n", - "6 0.666667 \n", - "2 0.333333 \n", - "0 0.333333 " - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "def summarize_convergence(group):\n", " hit_ceiling = int((group[\"epochs_to_best_val\"] == inferred_total_epochs).sum())\n", @@ -878,7 +398,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "95004f13", "metadata": { "execution": { @@ -888,18 +408,7 @@ "shell.execute_reply": "2026-07-30T17:10:35.323274Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAArAAAAHqCAYAAAD8uX26AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAV3hJREFUeJzt3XtcVVX+//H3AQRMOSgSNwVB8ZoKXgC1TCu8TWNaU1p+CzUdy8bKrzmpM3khbSynKUsrmy5a2UUrs5opshzNbEgrJSsNL6GgcVEMUFNUzvr94c/z9QQoEHDO1tfz8TiPR2ettdf57C3jvN2svY7NGGMEAAAAWISXuwsAAAAAqoMACwAAAEshwAIAAMBSCLAAAACwFAIsAAAALIUACwAAAEshwAIAAMBSCLAAAACwFAIsAAAALIUACwDAWfr166d+/fq5uwwA50CABQA3ee2117RgwQJ3l1GvfvrpJ82ePVsZGRl1+jkX47UFLiYEWABwk4sxZP30009KTU0lwAL4TQiwAC5ox48fl8PhcHcZ9cbhcOj48ePuLgMA6hQBFrgAzJ49WzabTbt27dLo0aPVpEkTBQYGasyYMfrll1+c4/bs2SObzaalS5eWm8Nms2n27Nnl5tyxY4duvfVWBQYG6tJLL9WMGTNkjFFOTo6GDh0qu92usLAw/eMf/6h23dHR0fr973+v1atXKz4+Xv7+/urYsaNWrlzpMu7QoUOaMmWKOnfurMaNG8tut2vw4MH65ptvXMatW7dONptNb7zxhh544AE1b95cl1xyiUpKSqo9x4oVK5SamqrmzZsrICBAN954o4qLi1VaWqpJkyYpJCREjRs31pgxY1RaWlru3JYtW6bu3burYcOGCgoK0s0336ycnBxnf79+/fTvf/9be/fulc1mk81mU3R0tLO/tLRUs2bNUmxsrPz8/BQZGan777+/3GfZbDZNnDhRr776qi677DL5+fkpLS1NkvTGG2+oe/fuCggIkN1uV+fOnfXEE09U+udx8uRJBQUFacyYMeX6SkpK5O/vrylTpjjbFi5cqMsuu0yXXHKJmjZtqh49eui1116rdP5169YpISFBkjRmzBjneZ/987hx40YNGjRIgYGBuuSSS9S3b199/vnnLvMcPnxYkyZNUnR0tPz8/BQSEqL+/ftr8+bNVbq2NVFQUKCxY8cqNDRU/v7+iouL00svvVRu3Pmu+cmTJ5Wamqo2bdrI399fzZo10xVXXKGPP/74N9UHXGx83F0AgNozfPhwxcTEaN68edq8ebOef/55hYSE6JFHHqnxnCNGjFCHDh308MMP69///rfmzp2roKAgPfvss7r66qv1yCOP6NVXX9WUKVOUkJCgK6+8slrz79y5UyNGjNCdd96pUaNGacmSJbrpppuUlpam/v37S5J+/PFHrVq1SjfddJNiYmKUn5+vZ599Vn379tW2bdsUERHhMuecOXPk6+urKVOmqLS0VL6+vtq2bVu15pg3b54aNmyoadOmadeuXVq4cKEaNGggLy8v/fzzz5o9e7a++OILLV26VDExMZo5c6bz2IceekgzZszQ8OHDNW7cOB04cEALFy7UlVdeqS1btqhJkyb661//quLiYu3bt0+PP/64JKlx48aSTt9Fve6667RhwwaNHz9eHTp00LfffqvHH39cO3bs0KpVq1xq/c9//qMVK1Zo4sSJCg4OVnR0tD7++GPdcsstuuaaa5x//tu3b9fnn3+ue++9t8I/iwYNGuj666/XypUr9eyzz8rX19fZt2rVKpWWlurmm2+WJD333HO65557dOONN+ree+/V8ePHtXXrVm3cuFEjR46scP4OHTrowQcf1MyZMzV+/Hj16dNHktS7d2/neQwePFjdu3fXrFmz5OXlpSVLlujqq6/WZ599psTEREnSnXfeqbfeeksTJ05Ux44dVVhYqA0bNmj79u3q1q3bOa9tTRw7dkz9+vXTrl27NHHiRMXExOjNN9/U6NGjVVRU5LyeVbnms2fP1rx58zRu3DglJiaqpKREX331lTZv3uz8eQdQBQaA5c2aNctIMrfffrtL+/XXX2+aNWvmfJ+VlWUkmSVLlpSbQ5KZNWtWuTnHjx/vbDt16pRp0aKFsdls5uGHH3a2//zzz6Zhw4Zm1KhR1aq7ZcuWRpJ5++23nW3FxcUmPDzcdO3a1dl2/PhxU1ZW5nJsVlaW8fPzMw8++KCzbe3atUaSadWqlfnll19cxld3jk6dOpkTJ04422+55RZjs9nM4MGDXebo1auXadmypfP9nj17jLe3t3nooYdcxn377bfGx8fHpf3aa691OfaMV155xXh5eZnPPvvMpX3x4sVGkvn888+dbZKMl5eX+f77713G3nvvvcZut5tTp06Vm/9cPvroIyPJvP/++y7tv/vd70yrVq2c74cOHWouu+yyas1tjDFffvllhT+DDofDtGnTxgwcONA4HA5n+y+//GJiYmJM//79nW2BgYHmT3/60zk/p7JrWxV9+/Y1ffv2db5fsGCBkWSWLVvmbDtx4oTp1auXady4sSkpKTHGVO2ax8XFmWuvvbZGdQH4PywhAC4gd955p8v7Pn36qLCwUCUlJTWec9y4cc7/9vb2Vo8ePWSM0dixY53tTZo0Ubt27fTjjz9We/6IiAhdf/31zvd2u10pKSnasmWL8vLyJEl+fn7y8jr911VZWZkKCwvVuHFjtWvXzvlr47ONGjVKDRs2dGmr7hwpKSlq0KCB831SUpKMMbr99ttdxiUlJSknJ0enTp2SJK1cuVIOh0PDhw/XwYMHna+wsDC1adNGa9euPe81efPNN9WhQwe1b9/eZY6rr75aksrN0bdvX3Xs2NGlrUmTJjp69Gi1fzV99dVXKzg4WMuXL3e2/fzzz/r44481YsQIl/n37dunL7/8slrzVyYjI0M7d+7UyJEjVVhY6Dzno0eP6pprrtH69euda5mbNGmijRs36qeffqqVzz6fDz74QGFhYbrlllucbQ0aNNA999yjI0eO6NNPP3XWdb5r3qRJE33//ffauXNnndcNXMgIsMAFJCoqyuV906ZNJZ0OILU1Z2BgoPz9/RUcHFyuvSafExsbK5vN5tLWtm1bSafX7Eqnf6X++OOPq02bNvLz81NwcLAuvfRSbd26VcXFxeXmjImJKddW3TkqOm9JioyMLNfucDicc+zcuVPGGLVp00aXXnqpy2v79u0qKCg47zXZuXOnvv/++3LHn7kuv56jovO966671LZtWw0ePFgtWrTQ7bff7lwbey4+Pj76wx/+oHfffde53nblypU6efKkS4CdOnWqGjdurMTERLVp00Z/+tOfyq1VrY4zgW7UqFHlzvv5559XaWmp8xrPnz9f3333nSIjI5WYmKjZs2fX6B9PVbV37161adPG+Q+gMzp06ODsl6p2zR988EEVFRWpbdu26ty5s/785z9r69atdVY7cKFiDSxwAfH29q6w3RgjSeWC4hllZWXVmvN8n1Pb/va3v2nGjBm6/fbbNWfOHAUFBcnLy0uTJk2qcIeBX999rckclZ3j+c7d4XDIZrPpww8/rHBsVdZiOhwOde7cWY899liF/b8O0RWdb0hIiDIyMvTRRx/pww8/1IcffqglS5YoJSWlwoePznbzzTfr2Wef1Ycffqhhw4ZpxYoVat++veLi4pxjOnTooMzMTP3rX/9SWlqa3n77bT399NOaOXOmUlNTz3uOFZ2zJP39739XfHx8hWPOXLvhw4erT58+euedd7R69Wr9/e9/1yOPPKKVK1dq8ODB1f7s2lKVa37llVdq9+7devfdd7V69Wo9//zzevzxx7V48WKX33YAODcCLHAROXNHtqioyKX9zB0kd9i1a5eMMS7heseOHZLkfHL8rbfe0lVXXaUXXnjB5diioqJyd4IrUxtzVEXr1q1ljFFMTIzzjmllKvsHRevWrfXNN9/ommuuqXRMVfj6+mrIkCEaMmSIHA6H7rrrLj377LOaMWOGYmNjKz3uyiuvVHh4uJYvX64rrrhC//nPf/TXv/613LhGjRppxIgRGjFihE6cOKEbbrhBDz30kKZPny5/f/8K5z7XOUunl5AkJyef99zCw8N111136a677lJBQYG6deumhx56yBlgf8t1+7WWLVtq69atcjgcLndhf/jhB2f/GVW55md2ehgzZoyOHDmiK6+8UrNnzybAAtXAEgLgImK32xUcHKz169e7tD/99NNuquj0xvbvvPOO831JSYlefvllxcfHKywsTNLpu56/vrv75ptvav/+/VX+nNqYoypuuOEGeXt7KzU1tdznGWNUWFjofN+oUaMKly8MHz5c+/fv13PPPVeu79ixYzp69Oh56zj7cyTJy8tLXbp0kaQKt/369dgbb7xR77//vl555RWdOnXKZflARfP7+vqqY8eOMsbo5MmTlc7dqFEjSeX/EdW9e3e1bt1ajz76qI4cOVLuuAMHDkg6/duCX1+zkJAQRUREuJxXZde2Jn73u98pLy/PZV3wqVOntHDhQjVu3Fh9+/aVVLVr/usxjRs3Vmxs7Hn/TAC44g4scJEZN26cHn74YY0bN049evTQ+vXrnXc83aFt27YaO3asvvzyS4WGhurFF19Ufn6+lixZ4hzz+9//Xg8++KDGjBmj3r1769tvv9Wrr76qVq1aVflzamOOqmjdurXmzp2r6dOna8+ePRo2bJgCAgKUlZWld955R+PHj3fupdq9e3ctX75ckydPVkJCgho3bqwhQ4botttu04oVK3TnnXdq7dq1uvzyy1VWVqYf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2eq5OgBwP7fegfX19VX37t21Zs0aZ5vD4dCaNWvUq1evcuPbt2+vb7/9VhkZGc7Xddddp6uuukoZGRmKjIys8HP27dunwsJChYfzKzcAnm9T1qFyd17PZiTlFh/XpqxD9VcUAHgQt38T1+TJkzVq1Cj16NFDiYmJWrBggY4ePaoxY8ZIOv293s2bN9e8efPk7++vTp06uRzfpEkTSXK2HzlyRKmpqfrDH/6gsLAw7d69W/fff79iY2M1cODAej03AKiJgsOVh9eajAOAC43bA+yIESN04MABzZw5U3l5eYqPj1daWprzwa7s7Gx5eVX9RrG3t7e2bt2ql156SUVFRYqIiNCAAQM0Z84clgkAsISQAP9aHQcAFxq3f5GBJ/KEDXoB1L0lS5bo9ttv1zvvvKNhw4apoKBAKSkp2r17t/z8/PT000/ryiuvlKQ66atMmcPoikf+o7zi4xWug7VJCgv014apV7MGFkC984ScZKldCACgtuzZs0fPPfecevbs6WybNm2aevbsqZ07d2rJkiUaOXKkTp48WWd9lfH2smnWkI6STofVs515P2tIR8IrgIsWARbARcfhcGjcuHFauHChy9KiFStW6M4775QkJSQkKCIiQp9++mmd9Z3LoE7heubWbgoLdF0mEBbor2du7cY+sAAuam5fAwsA9e2xxx7T5Zdfru7duzvbCgsLdfLkSZct/KKjo5WdnV0nfVUxqFO4+ncM06asQyo4fFwhAf5KjAniziuAix4BFsBF5bvvvtPbb7+t9evXu7uUKvH2sqlX62buLgMAPApLCABcVD777DPt2bNHbdq0UXR0tL744guNHz9eK1askI+Pj/Ly8pxj9+zZo6ioKDVr1qzW+wAANUeABXBRmTBhgnJzc7Vnzx7t2bNHPXv21D//+U9NmDBBN910kxYvXixJ+vLLL7V//3717dtXkuqkDwBQMywhAID/75FHHtFtt92mNm3ayNfXV8uWLVODBg3qrA8AUDPsA1sBT9jfDAAAwBN5Qk5iCQEAAAAshSUEAC4YZQ7DllMAcBEgwAK4IKR9l6vU97cpt/i4sy080F+zhnRk038AuMCwhACA5aV9l6sJyza7hFdJyis+rgnLNivtu1w3VQYAqAsEWACWVuYwSn1/myp6GvVMW+r721Tm4HlVALhQEGABWNqmrEPl7ryezUjKLT6uTVmH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x5VamIHHkmTeeeedKo/v27evuffee+usHiur7rU8o2PHjiY1NbX2C7Kwml7L66+/3tx66621X5CFVedajhgxwjzwwANm1qxZJi4urk7rsqKqXMu1a9caSebnn3+ul5qsrCrX88MPPzSBgYGmsLCwfoqyqJr8nfnOO+8Ym81m9uzZUzdFXQC4AwtUwuFw6PDhwwoKCnJ3KZa3ZcsW/fe//1Xfvn3dXYolLVmyRD/++KNmzZrl7lIuCPHx8QoPD1f//v31+eefu7scy3rvvffUo0cPzZ8/X82bN1fbtm01ZcoUHTt2zN2lWd4LL7yg5ORktWzZ0t2leCwfdxcAeKpHH31UR44c0fDhw91dimW1aNFCBw4c0KlTpzR79myNGzfO3SVZzs6dOzVt2jR99tln8vHhr+zfIjw8XIsXL1aPHj1UWlqq559/Xv369dPGjRvVrVs3d5dnOT/++KM2bNggf39/vfPOOzp48KDuuusuFRYWasmSJe4uz7J++uknffjhh3rttdfcXYpH429DoAKvvfaaUlNT9e6777I+7jf47LPPdOTIEX3xxReaNm2aYmNjdcstt7i7LMsoKyvTyJEjlZqaqrZt27q7HMtr166dy/rM3r17a/fu3Xr88cf1yiuvuLEya3I4HLLZbHr11VcVGBgoSXrsscd044036umnn1bDhg3dXKE1vfTSS2rSpImGDRvm7lI8GgEW+JU33nhD48aN05tvvqnk5GR3l2NpMTExkqTOnTsrPz9fs2fPJsBWw+HDh/XVV19py5YtmjhxoqTTocEYIx8fH61evVpXX321m6u0tsTERG3YsMHdZVhSeHi4mjdv7gyvktShQwcZY7Rv3z61adPGjdVZkzFGL774om677Tb5+vq6uxyPRoAFzvL666/r9ttv1xtvvKFrr73W3eVcUBwOh0pLS91dhqXY7XZ9++23Lm1PP/20/vOf/+itt95y/gMBNZeRkaHw8HB3l2FJl19+ud58800dOXJEjRs3liTt2LFDXl5eatGihZurs6ZPP/1Uu3bt0tixY91discjwHqYI0eOaNeuXc73WVlZysjIUFBQkKKiojR9+nTt379fL7/8snNMRkaG89gDBw4oIyNDvr6+6tixY32X71Gqey1fe+01jRo1Sk888YSSkpKce0M2bNjQ5Q7Dxai61/Kpp55SVFSU2rdvL+n0FmWPPvqo7rnnHrfU70mqcy29vLzUqVMnl+NDQkLk7+9frv1iVN2fywULFigmJkaXXXaZjh8/rueff17/+c9/tHr1anedgkep7vUcOXKk5syZozFjxig1NVUHDx7Un//8Z91+++0X/fKBmvx/uXT64a2kpCT+910Vbt4FAb9yZpuXX79GjRpljDFm1KhRpm/fvi7HVDS+ZcuW9V67p6nutezbt+85x1/Mqnstn3zySXPZZZeZSy65xNjtdtO1a1fz9NNPm7KyMvecgAepyf/Gz8Y2Wv+nutfykUceMa1btzb+/v4mKCjI9OvXz/znP/9xT/EeqCY/m9u3bzfJycmmYcOGpkWLFmby5Mnml19+qf/iPUxNrmVRUZFp2LCh+ec//1n/BVuQzRhj6iQZAwAAAHWAfWABAABgKQRYAAAAWAoBFgAAAJZCgAUAAIClEGABAABgKQRYAAAAWAoBFgAAAJZCgAUAAIClEGABAAAuIOvXr9eQIUMUEREhm82mVatWVev42bNny2azlXs1atSobgquAQIsAKBKoqOjtWDBAneXAeA8jh49qri4OD311FM1On7KlCnKzc11eXXs2FE33XRTLVdacwRYALAAY4xOnTrl7jJqxYkTJ9xdAnBBGzx4sObOnavrr7++wv7S0lJNmTJFzZs3V6NGjZSUlKR169Y5+xs3bqywsDDnKz8/X9u2bdPYsWPr6QzOjwALwNL69eune+65R/fff7+CgoIUFham2bNnS5L27Nkjm82mjIwM5/iioiLZbDbnX9br1q2TzWbTRx99pK5du6phw4a6+uqrVVBQoA8//FAdOnSQ3W7XyJEj9csvv1S5pokTJ2rixIkKDAxUcHCwZsyYIWOMc8wrr7yiHj16KCAgQGFhYRo5cqQKCgqc/Wfq+vDDD9W9e3f5+flpw4YN2r17t4YOHarQ0FA1btxYCQkJ+uSTT1w+Pzo6WnPnzlVKSooaN26sli1b6r333tOBAwc0dOhQNW7cWF26dNFXX33lctyGDRvUp08fNWzYUJGRkbrnnnt09OhR5znt3btX//u//+v8dWJVjjtTz5w5c5SSkiK73a7x48frxIkTmjhxosLDw+Xv76+WLVtq3rx5Vbq+AH6biRMnKj09XW+88Ya2bt2qm266SYMGDdLOnTsrHP/888+rbdu26tOnTz1Xeg4GACysb9++xm63m9mzZ5sdO3aYl156ydhsNrN69WqTlZVlJJktW7Y4x//8889Gklm7dq0xxpi1a9caSaZnz55mw4YNZvPmzSY2Ntb07dvXDBgwwGzevNmsX7/eNGvWzDz88MNVrqlx48bm3nvvNT/88INZtmyZueSSS8w///lP55gXXnjBfPDBB2b37t0mPT3d9OrVywwePNjZf6auLl26mNWrV5tdu3aZwsJCk5GRYRYvXmy+/fZbs2PHDvPAAw8Yf39/s3fvXuexLVu2NEFBQWbx4sVmx44dZsKECcZut5tBgwaZFStWmMzMTDNs2DDToUMH43A4jDHG7Nq1yzRq1Mg8/vjjZseOHebzzz83Xbt2NaNHjzbGGFNYWGhatGhhHnzwQZObm2tyc3OrdNyZeux2u3n00UfNrl27zK5du8zf//53ExkZadavX2/27NljPvvsM/Paa69V7w8fwHlJMu+8847z/d69e423t7fZv3+/y7hrrrnGTJ8+vdzxx44dM02bNjWPPPJIXZdaLQRYAJbWt29fc8UVV7i0JSQkmKlTp1YrwH7yySfOMfPmzTOSzO7du51td9xxhxk4cGCVazo7HBpjzNSpU02HDh0qPebLL780kszhw4dd6lq1atV5P++yyy4zCxcudL5v2bKlufXWW53vc3NzjSQzY8YMZ1t6erqR5AyiY8eONePHj3eZ97PPPjNeXl7m2LFjznkff/xxlzFVPW7YsGEuY+6++25z9dVXu1wjALXv1wH2X//6l5FkGjVq5PLy8fExw4cPL3f8a6+9Znx8fExeXl49Vn1+Pm646QsAtapLly4u78PDw11+HV/dOUJDQ3XJJZeoVatWLm2bNm2q8nw9e/Z0+TV7r1699I9//ENlZWXy9vbW119/rdmzZ+ubb77Rzz//LIfDIUnKzs5Wx44dncf16NHDZd4jR45o9uzZ+ve//63c3FydOnVKx44dU3Z29jnPR5I6d+5crq2goEBhYWH65ptvtHXrVr366qvOMcYYORwOZWVlqUOHDhWeZ1WP+/V5jB49Wv3791e7du00aNAg/f73v9eAAQMqu5wAasmRI0ecfwd5e3u79DVu3Ljc+Oeff16///3vnX9neAoCLADLa9Cggct7m80mh8MhL6/Ty/zNWWtPT548ed45bDZbpXPWhqNHj2rgwIEaOHCgXn31VV166aXKzs7WwIEDyz3g9Otta6ZMmaKPP/5Yjz76qGJjY9WwYUPdeOON5Y779flU1nbmnI4cOaI77rhD99xzT7l6o6KiKj2Xqh736/Po1q2bsrKy9OGHH+qTTz7R8OHDlZycrLfeeqvSzwLw23Xt2lVlZWUqKCg475rWrKwsrV27Vu+99149VVd1BFgAF6xLL71UkpSbm6uuXbtKkssDXXVp48aNLu+/+OILtWnTRt7e3vrhhx9UWFiohx9+WJGRkZJU7oGqynz++ecaPXq08+niI0eOaM+ePb+53m7dumnbtm2KjY2tdIyvr6/KysqqfVxl7Ha7RowYoREjRujGG2/UoEGDdOjQIQUFBVV7LgD/58iRI9q1a5fzfVZWljIyMhQUFKS2bdvqf/7nf5SSkqJ//OMf6tq1qw4cOKA1a9aoS5cuuvbaa53HvfjiiwoPD9fgwYPdcRrnxC4EAC5YDRs2VM+ePfXwww9r+/bt+vTTT/XAAw/Uy2dnZ2dr8uTJyszM1Ouvv66FCxfq3nvvlXT6zqSvr68WLlyoH3/8Ue+9957mzJlTpXnbtGmjlStXKiMjQ998841GjhxZK3eGp06dqv/+97+aOHGiMjIytHPnTr377ruaOHGic0x0dLTWr1+v/fv36+DBg1U+riKPPfaYXn/9df3www/asWOH3nzzTYWFhalJkya/+VyAi91XX32lrl27Ov/hPnnyZHXt2lUzZ86UJC1ZskQpKSm677771K5dOw0bNkxffvmly29NHA6Hli5dqtGjR5dbauAJuAML4IL24osvauzYserevbvatWun+fPn18tay5SUFB07dkyJiYny9vbWvffeq/Hjx0s6fWd46dKl+stf/qInn3xS3bp106OPPqrrrrvuvPM+9thjuv3229W7d28FBwdr6tSpKikp+c31dunSRZ9++qn++te/qk+fPjLGqHXr1hoxYoRzzIMPPqg77rhDrVu3VmlpqYwxVTquIgEBAZo/f7527twpb29vJSQk6IMPPnAu+wBQc/369XNZOvVrDRo0UGpqqlJTUysd4+XlpZycnLoor1bYzLnOEABQbf369VN8fDzfWgUAdYR/6gIAAMBSWEIAANXw622ufm3btm31WA0AXJxYQgAA1XDq1KlzPvUfHR0tHx/uDQBAXSLAAgAAwFJYAwsAAABLIcACAADAUgiwAAAAsBQCLAAAACyFAAsAAABLIcACAADAUgiwAAAAsBQCLAAAACzl/wF5MjTI0E5WggAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(7, 5))\n", "for row in summary:\n", @@ -936,7 +445,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "46065c2c", "metadata": { "execution": { @@ -946,17 +455,7 @@ "shell.execute_reply": "2026-07-30T17:10:35.336246Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Excluding 1 run(s) with train_time_sec > 3x the median (likely contaminated by something external, e.g. the machine sleeping mid-run):\n", - "tokenizer vocab_size seed train_time_sec time_ratio_vs_median\n", - " char 25 1 39705.241565 69.237647\n" - ] - } - ], + "outputs": [], "source": [ "median_time = raw[\"train_time_sec\"].median()\n", "raw[\"time_ratio_vs_median\"] = raw[\"train_time_sec\"] / median_time\n", @@ -971,7 +470,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "dfe53dfa", "metadata": { "execution": { @@ -981,18 +480,7 @@ "shell.execute_reply": "2026-07-30T17:10:35.480036Z" } }, - "outputs": [ - { - "data": { - "image/png": "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Dg6aNWuW2rRpo59++kmNGzeWJP31119q3LixEhMT1bdvX9WqVUsnT57U119/rfPnz9/wr/Off/65zp49q8jISF28eFHvv/++2rRpo127dsnPz0+PPvqoIiMjNXfuXN1zzz02r507d65at26tu+66K8fl56a++Ph4NWvWTOfPn9eAAQNUpkwZzZkzR506ddLXX3+thx9+2GaZEydOlIODg4YOHaqkpCRNmjRJ4eHhio6OliRNmTJFn3/+uRYvXqwZM2bIw8ND9evXz7a+c+fOqU2bNoqNjdXAgQPl7++vefPm5fovrlu2bJEk688tkzFGnTp10vr169WnTx81bNhQK1eu1LBhw3Ty5ElNnjw5V8vPlNf9/Wq53acyPfbYY6pevbrGjx+fq1NbXnjhBZUrV06vv/56no9YbNq0Sd98841eeOEFlSpVSlOnTlXXrl11/PhxlSlTRlLOc7569Wr16NFDbdu21VtvvSVJ2rdvnzZv3qyBAwfajA0ODtaSJUtuWM+ePXvUvHlz3XXXXXrllVdUsmRJLViwQF26dNGiRYv08MMPy9fXVzNmzNBjjz2mDz74QAMGDFBGRoZ69+6tUqVKafr06dbljRkzRqNHj1azZs00duxYOTs7Kzo6WuvWrVO7du3yNGdX++yzz/Tcc8+pWbNmGjRokA4fPqxOnTrJx8dHgYGB1nEZGRnq1KmTNm3apL59+6p27dratWuXJk+erD/++MNmbp555hl98cUXeuKJJ9SsWTOtW7fuuv/H33vvvdn+AQQoVAZAgXj77beNJHPkyJEsfZKMg4OD2bNnT5a+8+fP2zxPS0szdevWNW3atLFpr1ixoomIiLA+nzVrlpFkQkNDTUZGhrV98ODBxtHR0SQmJuZL7TmtNywszGa9ISEhxmKxmOeff97advnyZXP33XebVq1aWdt++uknI8nMnTvXZj0rVqzItv16vLy8TGRkZI79GRkZpnr16llqPX/+vKlcubJ54IEHrG29evUyDg4OZtu2bdkuJydHjhwxkoybm5v5888/re3R0dFGkhk8eLC1rUePHiYgIMCkp6db23799VcjycyaNeu625qb+gYNGmQkmZ9++snad/bsWVO5cmVTqVIl63rXr19vJJnatWub1NRU69j333/fSDK7du2yto0aNcpIMn///bfNOlu1amXzc3333XeNJLNkyRJr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orp162rNmjV6+umnre0dO3bU//3f/+nVV1/V0aNH1aBBA61atUrffvutBg0aZHPO+jPPPKOJEyfqmWeeUaNGjbRx40b98ccfWdZlz/5+M/tUfurevbtefvllPfzwwxowYIDOnz+vGTNmqEaNGrm+0cO1cprzZ555RqdPn1abNm10991369ixY/rggw/UsGFDm7+gJyQk6LffflNkZOQN1zVt2jS1aNFC9erV07PPPqsqVaooPj5eUVFR+vPPP7Vz505J0sCBA3Xq1CmtWbNGjo6OevDBB/XMM89o3Lhx6ty5sxo0aKBq1arp1Vdf1RtvvKH7779fjzzyiFxcXLRt2zYFBARowoQJ2dZQp04dNW3aVCNGjNDp06fl4+Oj+fPn6/LlyzbjnJycNG7cOD333HNq06aNHn/8cR05ckSzZs3Kco1Fz549tWDBAj3//PNav369mjdvrvT0dP3+++9asGCBVq5cqUaNGqlhw4bq0aOHpk+frqSkJDVr1kxr167N8Yje9u3bdfr0aZuL1oHbQqHciwoopt544w1z1113GQcHB5vbGkrK8baon332malevbpxcXExtWrVMrNmzcr2FpI53fb12tuPXnvrRHtrz+16c7otaUREhClZsmSW9X388ccmODjYuLm5mVKlSpl69eqZ4cOHm7/++itX9aamppphw4aZBg0amFKlSpmSJUuaBg0amOnTp2cZu2PHDvPII4+YMmXKGBcXF1OxYkXTrVs3s3btWptxx44dM7169TLlypUzLi4upkqVKiYyMtLmlpPXyrzN6dtvv23effddExgYaFxcXMz9999vdu7cme1rYmNjjaOjo6lRo0autvVm6jt06JB59NFHjbe3t3F1dTWNGzc2S5cutVlO5j6ycOHCbLfl6lu25vZ2s8YYc/jwYdOhQwfj5uZmypUrZ1566SWzaNEiI8ls3br1htv33nvvGQ8Pjyy3YD579qwZPHiwCQgIME5OTqZ69erm7bffznIb4PPnz5s+ffoYLy8vU6pUKdOtWzeTkJCQ7e08c7u/5/T7lJt9Kqe5y0lOv1uZVq1aZerWrWucnZ1NzZo1zRdffJHj7Waz+//m2m0zJvs5//rrr027du2Mr6+vcXZ2NhUqVDDPPfeciY2NtXntjBkzjLu7u0lOTs7V9h06dMj06tXL+Pv7GycnJ3PXXXeZf/3rX+br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hGjXrl02/2GtXr1anp6eCgoKso659me0evVq6zLuVJUrV5a/v7/NticnJys6Otpm/hITE7V9+3brmHXr1ikjI0NNmjSxjtm4caMuXbpkHbN69WrVrFlTpUuXto4pynNsjFH//v21ePFirVu3Lsvh+ILaF52dnRUcHGwzJiMjQ2vXri0yc5mTjIwMpaamMpc3qW3bttq1a5diYmKsj0aNGik8PNz6b+Yzbwrj/eZOnMfb6b0mN7XcMQr76nHcGqNHjzalS5c2c+bMMQcPHjRRUVHm008/zfZ2s2fOnDGSzPr1640xxgwePNgEBgaazZs3m71795pnnnnGeHp6ms6dO1tfc/XdP+5EL730kvnxxx/NkSNHzObNm01oaKgpW7asSUhIMMZcuf1fhQoVzLp168wvv/xiQkJCTEhIiPX1mbf/a9eunYmJiTErVqww5cqVy/b2f8OGDTP79u0z06ZNu2NuN3v27FmzY8cOs2PHDiPJvPfee2bHjh3m2LFjxpgrt93z9vY23377rfntt99M586ds70F4D333GOio6PNpk2bTPXq1W1uAZiYmGj8/PxMz549ze7du838+fONu7t7llsAlihRwrzzzjtm3759ZtSoUUXqdrP9+vUzXl5e5scff7S5FeX58+etYwpqX5w/f75xcXExs2fPNnv37jV9+/Y13t7eNneiud298sorZsOGDebIkSPmt99+M6+88oqxWCxm1apVxhjm0l7Xvi8wn7lzu7zfFMV5LErvNbmp5U5AsLhDpaenm3HjxpmKFSsaJycnU6FCBTN+/PhcBYtTp06Zzp07Gw8PD+Pr62tee+0106tXr2IVLB5//HFTvnx54+zsbO666y7z+OOPm4MHD1r7L1y4YF544QVTunRp4+7ubh5++GETGxtrs4yjR4+a9u3bGzc3N1O2bFnz0ksvmUuXLtmMWb9+vWnYsKFxdnY2VapUMbNmzSqIzbvl1q9fbyRleURERBhjrtx6b+TIkcbPz8+4uLiYtm3bmv3799ss49SpU6ZHjx7Gw8PDeHp6mqeeesqcPXvWZszOnTtNixYtjIuLi7nrrrvMxIkTs9SyYMECU6NGDePs7Gzq1Kljfvjhh1u23fktuzmUZLOfFOS++MEHH5gKFSoYZ2dn07hxY7N169Zbsdm3zNNPP20qVqxonJ2dTbly5Uzbtm2tocIY5tJe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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "time_stats = (\n", " clean.groupby([\"tokenizer\", \"vocab_size\"])[\"train_time_sec\"]\n", @@ -1021,7 +509,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "b82b3da1", "metadata": { "execution": { @@ -1031,16 +519,7 @@ "shell.execute_reply": "2026-07-30T17:10:35.489975Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Not found: ../artifacts/tokenizers_1M_integ_on_background100k/tokenization_stats.json\n", - "Run scripts/calc_tokenization_stats.py on the same AIRR file used for the results above (pointed at the same --tokenizers-dir) to produce this file, then re-run this cell.\n" - ] - } - ], + "outputs": [], "source": [ "domain_stats_path = Path(DOMAIN_TOKENIZATION_STATS_PATH)\n", "\n", @@ -1114,4 +593,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/notebooks/convergence_curves_by_epoch_report.ipynb b/notebooks/convergence_curves_by_epoch_report.ipynb new file mode 100644 index 0000000..bd12516 --- /dev/null +++ b/notebooks/convergence_curves_by_epoch_report.ipynb @@ -0,0 +1,282 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4b450bf4", + "metadata": {}, + "source": [ + "# Convergence curves \u2014 char vs every WordPiece vocab_size in the grid\n", + "\n", + "Reads the per-epoch history files `scripts/compare_forward_tokenizers.py` writes under\n", + "`/history/*.json`, and plots train/val loss vs epoch as one small subplot\n", + "per config (char + every vocab_size, and every `--max-token-len` variant present).\n", + "\n", + "Interpretation goes in markdown cells, not on the plots themselves." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11f2b459", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-01T11:40:12.339841Z", + "iopub.status.busy": "2026-08-01T11:40:12.339644Z", + "iopub.status.idle": "2026-08-01T11:40:12.344805Z", + "shell.execute_reply": "2026-08-01T11:40:12.343818Z" + }, + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "# parameters\n", + "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_background100k_40epochs_upto30k\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "379bff96", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-01T11:40:12.347155Z", + "iopub.status.busy": "2026-08-01T11:40:12.346439Z", + "iopub.status.idle": "2026-08-01T11:40:13.379434Z", + "shell.execute_reply": "2026-08-01T11:40:13.378214Z" + } + }, + "outputs": [], + "source": [ + "import json\n", + "from pathlib import Path\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "results_dir = Path(RESULTS_DIR)\n", + "raw = pd.read_csv(results_dir / \"raw_results.csv\")\n", + "if \"max_token_len\" not in raw.columns:\n", + " raw[\"max_token_len\"] = None # older raw_results.csv, from before --max-token-len existed\n", + "\n", + "print(f\"{len(raw)} runs across {raw[['tokenizer','vocab_size','max_token_len']].drop_duplicates().shape[0]} configs\")\n", + "raw.head()" + ] + }, + { + "cell_type": "markdown", + "id": "1431d8f3", + "metadata": {}, + "source": [ + "## Load per-epoch history for every run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b0dc511", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-01T11:40:13.381776Z", + "iopub.status.busy": "2026-08-01T11:40:13.381555Z", + "iopub.status.idle": "2026-08-01T11:40:13.396990Z", + "shell.execute_reply": "2026-08-01T11:40:13.395714Z" + } + }, + "outputs": [], + "source": [ + "def history_filename(row):\n", + " \"\"\"Mirrors compare_forward_tokenizers.py's run_one() naming exactly, so this stays in\n", + " sync with whatever that script actually wrote - no separate parsing of filenames.\"\"\"\n", + " label = \"char\" if row[\"tokenizer\"] == \"char\" else f\"wordpiece_{int(row['vocab_size'])}\"\n", + " max_token_len = row[\"max_token_len\"]\n", + " suffix = f\"_n{int(max_token_len)}\" if pd.notna(max_token_len) else \"\"\n", + " return f\"{label}{suffix}_seed{int(row['seed'])}.json\"\n", + "\n", + "\n", + "records = []\n", + "missing = []\n", + "for _, row in raw.iterrows():\n", + " history_path = results_dir / \"history\" / history_filename(row)\n", + " if not history_path.exists():\n", + " missing.append(history_path.name)\n", + " continue\n", + " with open(history_path) as f:\n", + " history = json.load(f)\n", + " for entry in history:\n", + " for split in (\"train\", \"val\"):\n", + " records.append({\n", + " \"tokenizer\": row[\"tokenizer\"],\n", + " \"vocab_size\": row[\"vocab_size\"],\n", + " \"max_token_len\": row[\"max_token_len\"],\n", + " \"seed\": row[\"seed\"],\n", + " \"epoch\": entry[\"epoch\"],\n", + " \"split\": split,\n", + " \"loss\": entry[split][\"loss\"],\n", + " \"cosine\": entry[split][\"cosine\"],\n", + " })\n", + "\n", + "history_df = pd.DataFrame.from_records(records)\n", + "if missing:\n", + " print(f\"Missing {len(missing)} history file(s), e.g. {missing[:5]} - those runs are skipped below.\")\n", + "print(f\"Loaded {len(history_df)} (config, seed, epoch, split) rows from history/\")" + ] + }, + { + "cell_type": "markdown", + "id": "e468bfa2", + "metadata": {}, + "source": [ + "## Loss vs epoch, one subplot per config" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a04f58e1", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-01T11:40:13.399303Z", + "iopub.status.busy": "2026-08-01T11:40:13.399078Z", + "iopub.status.idle": "2026-08-01T11:40:13.809454Z", + "shell.execute_reply": "2026-08-01T11:40:13.808202Z" + } + }, + "outputs": [], + "source": [ + "def config_label(tokenizer, vocab_size, max_token_len):\n", + " if tokenizer == \"char\":\n", + " return \"char\"\n", + " label = f\"wordpiece {int(vocab_size)}\"\n", + " if pd.notna(max_token_len):\n", + " label += f\" (max_token_len={int(max_token_len)})\"\n", + " return label\n", + "\n", + "\n", + "configs = (\n", + " history_df[[\"tokenizer\", \"vocab_size\", \"max_token_len\"]]\n", + " .drop_duplicates()\n", + " .sort_values([\"tokenizer\", \"vocab_size\", \"max_token_len\"], na_position=\"first\")\n", + " .to_records(index=False)\n", + ")\n", + "\n", + "n = len(configs)\n", + "ncols = min(4, n)\n", + "nrows = int(np.ceil(n / ncols))\n", + "fig, axes = plt.subplots(nrows, ncols, figsize=(4 * ncols, 3 * nrows), squeeze=False)\n", + "\n", + "for ax, (tokenizer, vocab_size, max_token_len) in zip(axes.flat, configs):\n", + " subset = history_df[\n", + " (history_df[\"tokenizer\"] == tokenizer)\n", + " & (history_df[\"vocab_size\"] == vocab_size)\n", + " & (history_df[\"max_token_len\"].isna() if pd.isna(max_token_len) else history_df[\"max_token_len\"] == max_token_len)\n", + " ]\n", + " for split, color in [(\"train\", \"tab:blue\"), (\"val\", \"tab:orange\")]:\n", + " split_data = subset[subset[\"split\"] == split]\n", + " per_epoch = split_data.groupby(\"epoch\")[\"loss\"].agg([\"mean\", \"std\"])\n", + " ax.plot(per_epoch.index, per_epoch[\"mean\"], color=color, label=split)\n", + " if per_epoch[\"std\"].notna().any():\n", + " ax.fill_between(per_epoch.index, per_epoch[\"mean\"] - per_epoch[\"std\"].fillna(0),\n", + " per_epoch[\"mean\"] + per_epoch[\"std\"].fillna(0), color=color, alpha=0.15)\n", + " ax.set_title(config_label(tokenizer, vocab_size, max_token_len), fontsize=9)\n", + " ax.set_xlabel(\"epoch\")\n", + " ax.set_ylabel(\"loss\")\n", + "\n", + "for ax in axes.flat[n:]:\n", + " ax.axis(\"off\")\n", + "\n", + "axes.flat[0].legend(fontsize=8)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "3109807f", + "metadata": {}, + "source": [ + "*Notes: line = mean across seeds, shaded band = std across seeds (band is flat/invisible\n", + "with only 1 seed). Train and val loss diverging within a config is the usual overfitting\n", + "signal; a val curve still trending down at the last epoch means that config likely hasn't\n", + "converged yet.*" + ] + }, + { + "cell_type": "markdown", + "id": "d1c44955", + "metadata": {}, + "source": [ + "## Loss vs epoch, all configs overlaid (val split only)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7a5eab55", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-01T11:40:13.811551Z", + "iopub.status.busy": "2026-08-01T11:40:13.811340Z", + "iopub.status.idle": "2026-08-01T11:40:14.114172Z", + "shell.execute_reply": "2026-08-01T11:40:14.112983Z" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(8, 5))\n", + "val_data = history_df[history_df[\"split\"] == \"val\"]\n", + "\n", + "for tokenizer, vocab_size, max_token_len in configs:\n", + " subset = val_data[\n", + " (val_data[\"tokenizer\"] == tokenizer)\n", + " & (val_data[\"vocab_size\"] == vocab_size)\n", + " & (val_data[\"max_token_len\"].isna() if pd.isna(max_token_len) else val_data[\"max_token_len\"] == max_token_len)\n", + " ]\n", + " per_epoch = subset.groupby(\"epoch\")[\"loss\"].mean()\n", + " style = \"--\" if tokenizer == \"char\" else \"-\"\n", + " ax.plot(per_epoch.index, per_epoch.values, style,\n", + " label=config_label(tokenizer, vocab_size, max_token_len), linewidth=1.5 if tokenizer == \"char\" else 1)\n", + "\n", + "ax.set_xlabel(\"epoch\")\n", + "ax.set_ylabel(\"val_loss\")\n", + "ax.set_title(\"val_loss vs epoch, all configs\")\n", + "ax.legend(fontsize=7, ncol=2, loc=\"upper right\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "644f5c19", + "metadata": {}, + "source": [ + "*Notes: same data as the small-multiples grid above, just overlaid for a direct\n", + "side-by-side comparison of convergence speed and final level. `char` is dashed to stand\n", + "out from the WordPiece vocab_size curves.*" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/notebooks/tokenizer_stats_report.ipynb b/notebooks/tokenizer_stats_report.ipynb index f6b4f19..8a1b93f 100644 --- a/notebooks/tokenizer_stats_report.ipynb +++ b/notebooks/tokenizer_stats_report.ipynb @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "980d96f5", "metadata": { "tags": [ @@ -30,19 +30,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "da5d5624", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loaded ..\\artifacts\\tokenizers_1M\\stats\\tokenization_stats.json\n", - "vocab_size grid: [100, 1000, 10000, 50000, 100000, 200000, 300000]\n" - ] - } - ], + "outputs": [], "source": [ "import json\n", "from pathlib import Path\n", @@ -77,361 +68,10 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "37bdd010", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
 vocab_sizevocab_size_actualsplitmean_num_tokensmedian_num_tokensmin_num_tokensmax_num_tokensp95_num_tokenscompression_ratiounk_token_fractionfraction_1_tokenfraction_le_3_tokens
0100100train7.257.022010.00.4860.0000%0.00%0.05%
1100100val7.257.032010.00.4860.0000%0.00%0.04%
2100100test7.257.021910.00.4860.0000%0.00%0.04%
310001000train4.144.02126.00.2780.0000%0.00%22.84%
410001000val4.144.02116.00.2770.0000%0.00%22.98%
510001000test4.144.02136.00.2780.0000%0.00%22.82%
61000010000train3.063.02114.00.2050.0000%0.00%76.44%
71000010000val3.073.0294.00.2060.0000%0.00%76.13%
81000010000test3.073.0294.00.2060.0000%0.00%75.94%
95000050000train2.532.01104.00.1700.0000%0.00%91.44%
105000050000val2.572.0284.00.1720.0000%0.00%90.73%
115000050000test2.572.0184.00.1720.0000%0.00%90.66%
12100000100000train2.382.0184.00.1590.0000%0.00%94.92%
13100000100000val2.442.0284.00.1630.0000%0.00%93.75%
14100000100000test2.442.0184.00.1640.0000%0.00%93.73%
15200000200000train2.242.0183.00.1500.0000%1.52%97.24%
16200000200000val2.372.0283.00.1590.0000%0.00%95.39%
17200000200000test2.372.0183.00.1590.0000%0.00%95.37%
18300000300000train2.142.0183.00.1440.0000%6.90%97.94%
19300000300000val2.352.0283.00.1580.0000%0.00%95.64%
20300000300000test2.352.0183.00.1580.0000%0.00%95.58%
\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "rows = []\n", "for vocab_size in vocab_sizes:\n", @@ -491,21 +131,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "b3873ad3", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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1atNrYW/E+IBAAAAiCx+NYUqX768mQUQAAAAAPwOLAYPHiyPPPKInDp1irMIAAAAwL+mUO+8845pCjVz5kypUKGCREVFub2/detWTi0AAACQg/gVWDz00EPBPxIAAAAAOSuwuPvuu4N/JAAAAABy5szbR48elbVr1wbvaAAAAADknMBCA4pu3bpJ0aJFpXHjxs7lN998s6xatSqYxwcAAAAgUgOLRx99VI4dOyabNm1yWz5o0CB55plngnVsAAAAACK5j8W8efNkxYoVUqVKFbfll112manJAAAAAJCz+FVjER8fLyVKlDDPXYeaPXnyZKqhZwEAAABEPr8CiyZNmphaC+UaSLz88svSokWL4B0dAAAAgMhtCvXCCy9Ix44d5ccffxSHwyGjR4+WxYsXy2+//Sbfffdd8I8SAAAAQOTVWLRu3doEEIcPH5Zq1arJ1KlTpVy5cvLTTz9RYwEAAADkQH7VWCxfvlyuuOIKmTlzZqr3JkyYIAMHDgzGsQEAAACI5BqLzp07y/r161Mtf//99+X+++8PxnEBAAAAiPTA4sknn5QOHTrItm3bnMvGjx8vw4YNkzlz5gTz+AAAAABEalOo4cOHy8GDB6V9+/amX4WOEDVixAiZO3euXHvttcE/SgAAAACRF1io559/3gQXzZs3N/NaaHChgQYAAACAnMfnwGL69OmplrVq1UoWLFggt956q+zbt8+ZplevXsE9SgAAAACREVg8+OCDab63cOFC87AQWAAAAAA5i8+Bxd69e7P2SAAAAADkrFGhAAAAACAonbcTEhJkxowZsmXLFnE4HFK3bl254447JH/+/P5uEgAAAEBOqrHYvHmz1KpVy/S7WLVqlaxevdo812X6HgAAAICcxa/AQmfXbtOmjezatUuWL18uP/74o3neunVrZt4GAAAAciC/mkLppHg7duyQggULOpfp87Fjx0q1atWCeXwAAAAAIrXGIk+ePHLs2LFUy48ePSp58+bN1La++uor6dChgzRs2FB69+4t27dvTze99udYtGiRdO3aVerUqSO//PJLqjQ7d+6Uhx56yMyzobUojz/+uBw5csQtzdNPP23Wd3107tw5U8cOAAAAIIDAolOnTiYIWLdunSno62Pt2rVm/oqOHTv6vB2dXE8DBJ2xe9y4cXLq1Cm58sor5fDhw2mu88gjj8hrr71mgpE/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ljN//y3xSckSU6KEKTzENm3idwHCbHPNr5J04IAZrSWQbcE9n85u2yYJ1atLgWbNOKc5NK9STp82Q7N6jqxkAgetdUhISHf9qLx5z9UweIysZJosaSdpj2pyAPaihUa9K231FdAg4MUXXzQFzEDWee2110w7fy2s16pVSxo0aGACC22udPHFF5u74fq/rquF9DZt2pg74Frw/PHHH02h9vXXX/e6/2XLlpnCvQYGhw8fNv0RrMBi6tSp8vjjj5u77r/++qu5Q6/prUK27l/3p3f0NaC46aabzP/a3GvkyJHSrFkzc9NF1x0/frzpN6F+//13adu2rQlEdDI3fa2F5cGDBzuPS9Pq5ypTpox8++23Mnr0aHnkkUec7+tx6WfSgGLXrl2mMP/VV1+ZwCwt999/v0ycONEEX1p21HOZntOnT5uaAde80P250sCpY8eOJkBwreXQc6n7s4wYMcKcTw22rrrqKvn777/N+VIapOhrpWVZ/ayab95o0ysNsrRvSMQGFhptaybdeOONJprVQv5HH30ky5cvT7PDjC/rBCtNODq2ZInse2GMJOldTBFxLY5Ely0rZR4bKYWvvTagbQayLXg/pyc5pxGdV46UFBOUu8/pcKEGIimjeReioszNgQszSV+Yz0EfZmhWRrkBApqNOy16l17v3PuSVr+HMTExGabNbDlC7zC73mXWmgYtQOudaS0QBrKOlnf07rxnYVL7a2hwop9d39dCqn4erQXR4//uu+/M9rTgroV4TxrETJ8+Xe655x7Tl8CVFo71Dr8OYapzI1x00UWmP4ZVIFa7d+82aQoVKmReay2EBgA///yz1KtXzyzTAr9+Rr2zX6pUKXPHX4OfmTNnmvf1eL/++mu3fWvwpPtSWq7r37+/aQakN471HI0ZM0Z++OEHUwbUeXE0ENFARwvu3n5ntaA+btw4c3waDOlwrBqcpWfz5s0muNDAKj0afFifVen50IBIP6vlkksuMdeoBlEaWJQoUcL08bA6ZetrpZ/xgQceMLUwGqBUr17d1Ni40pvoq1evlqwU0sBCL9aWLVuaqhylF0+VKlVk2rRpJpP9XSdYacKxABR3/7A0x47XgpF5/43XfS4QpbVNHUkms9sC59RuMnP9J584KYlx50dUco6spP+fCx4c6RRGlNYquHWQdu3vUKG85MqbN0s/K5CTaWEyLVr4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0kSShIQE8xmtvNFrU39ntHB68OBBZ7phw4Y5qlatam5mqY8//tgRFRVlvofhmibSaMC9c+dO5+spU6Y4cuXK5fjtt9+cy7QMoIFxet577z1HoUKFHL///rt5vWrVKkeePHkcM2fODEmaSKM3IpYvX+58vW/fPvN3+4EHHnAu++6778z1unjxYvP633//NcH96NGjwzaNvwgsbET/0OmPyieffOJcpn8M9Uv82muvhfTYIimwuPHGGx2//vqrY+vWrebunict2OodP1f16tUz64YiTU6SVmChhVktyP7xxx/OZfqHTZctW7YsLNNEsowCiwcffNDxyy+/OHbt2pXq/bi4OPMHb+7cuc5lJ06cMHfU3n333WxPkxP8888/Jr+WLl1qXuvvnt4d10DRlQbG999/f1imySn02hw3bpxbYKG1uVobqnfOz549m2qd5s2bO+666y63ZXpHXe+yhyJNTnDttdeam0mWPn36mNYmrvR3UGukwjWNv3JGg98IoW2Ttc12kyZNnMu0f0X9+vVl7dq1IT22SLJ48WK56667TBvVKlWqyIIFC5zv7d6927Qddc0DpW3+rTzIzjQ4R8+H9oXRdtcWbSsfGxvrPFfhliYne+edd2TgwIGmj1jjxo3Nb5tl3bp1pl2563Wv5/Liiy92nrvsTJMTrF692vyvbfiVttk/fPhwqt+eZs2aOc9LuKXJCX7//XfTx6xGjRqp+p7dfvvt0q5dOylTpoxMmzbN+Z5e3+vXr0/370h2polky5cvl6VLl8ro0aPNb8sDDzzgfE8/v7fzon0y9NoOxzT+IrCwkfj4ePN/iRIl3Jbra+s9BKZDhw4SFxdnCjraibtnz57SvXt306nb1zzIzjQ4R8+H53nydj7DKU1O9X//939y8OBB84dXv2va0bFr166SkJBg3uc7lr20k/2wYcOkT58+5kZKOOYBv4ViAoq+ffuaG14aQFg0MNfOtzpIhHbkfuaZZ6Rfv37y008/mfd1QALt+J3e+c3ONJHs0UcflYceekj+97//SY8ePczNJIu3vwnW6/T+boQyjb8ILGwkJibG/H/69OlUPzg6sgcCd9NNN5kRaqyRNcaMGWPO+/z5833Og+xMA3GeK8/z5O18hlOanKp3796SP39+87xgwYIyduxY2bFjh6xatcos4zuWfbQAoTdTLrroInn33Xedy8MtD3L6b+HZs2elW7duZgSfzz77zG10uWuvvdaMvGS57777TI3brFmzzGvyKXtrLH777TdzI1JbPtx7773O97z9TdDrV6X3dyOUafxFYGEj1t0kvcvnSl9Xrlw5REcV2TS40CjeOud6d1V/1NPLg+xMgwvfDR3qz/WHUn8ktUrXOlfhlgbnaNMN67q2zp3ra2/XfXamiVR6Leqdbx2yVZt7ajM9S7jlQU7OJyuo0KGBly1bJuXKlfPpO2WdKx2e1vW1t3OXnWlygrJly5obKAsXLnQu02vY23nRAr6mD8c0/iKwsBHtS6FfWuvuufrrr79ky5Yt0r59+5AeWyTQ9qFWxO46X4i2OaxXr555rX98L7/8crc80Orfb775xpkH2ZkG57Rt29bkn2t/mC+//NIsu+aaa8IyTU6k3y/tJ+ZqyZIl5n/rO6btfosXL+523Wsbcq3VsK777EwTyUGF/sYsWrTI1By5Klq0qDRt2tTtvBw9elS+++4753kJtzSRKDEx0TTF3bx5s/ms3uYZ0L8JrvSGht41t75PSs/RF1984TaHif4euZ677EwTaTzzQGnzNNemRvr59bdOm4pZ5s2bJ23atHHWKoVbGr8F3P0b2UrHsNah21599VXH7NmzHfXr1zfjxuuQgQiMjt+s4zmPHTvWjOn+/vvvm+ENmzVr5jh9+rTbMG0xMTFmiEadQ6Rdu3ZmnPHjx4+HJE1OoCMq/fjjj47/+7//cxQvXtw814cOnWkZMmSIGS5v2rRp5lGqVCnH0KFD3bYTbmkizfbt202+vPTSS2aUoYULF5rXhw4dMu+vX7/ejBqjQ1LqMIf/+9//zJw8nnPF6Kg3Or76G2+84Zg1a5b5XuooK6FKE0l0JEH9TdO5Vaz8sR779+93pluyZIkjOjra8eSTT5pRs/TvjM6l4PqdC7c0kaZ79+6OAgUKmKF1XfNJhwa16Mg+OnzzV1995fjwww8dl156qZmPxXW4ZB2dTkeP7N+/v2P+/PlmtCKdr+W///4LSZpIo0PUW3+jv/jiC/Pbnzt3brchduPj4818MTfccIM5LyNGjDBluRUrVoRtGn9F6T+BhSbIbnPnzpUPPvjAzLzdqlUr01lIRzJB4LTD9ltvvWVGTChWrJhceeWVMmDAgFQRvHaMGzdunBm1SWuStNOWZ/VhdqaJdA8++KCsXLky1fIZM2Y4q9j1Tvh7771n7o6pjh07yt133+3WHjnc0kSaN99809m225X2VdLvkjWyjZ4XrW0tX768dO7cWW6++eZU63z66afy0UcfmU7dV111lYwYMcKtuU52p4kUOmu19iXz5qmnnjJt9i3ff/+96Xuh6zRs2ND89njOKBxuaSKJ5oU1qIGrO++804yqprTfhf59WLFihem7pCNl6QAJnmUC7dyt/Zm0Bl5H/3r44YdTjS6VnWkiid71nzBhgmmqdubMGfNZNX9cO29bTY1eeuklc360SduQIUPksssuC+s0/iCwAAAAABCwyL11BgAAACDbEFgAAAAACBiBBQAAAICAEVgAAAAACBiBBQAAAICAEVgAAAAACBiBBQAAAICAEVgAAMLa33//LQsWLMiSbe/YsUPmz5+fJdsGgJyGwAIAENYWL15sZsPOCjqb87333psl2waAnIbAAgCQY1WrVk26dOkS6sMAgIgQHeoDAACEn/j4eFmyZIl07txZYmNjncsPHTokX3/9tXTq1EkKFChglm3YsEG2bt0q5cqVk8suu0xy5Up9z2rnzp2ydu1aKVOmjDRt2lRy585tlu/du1e+++478zx//vxSu3ZtqVOnjtdjSkxMlPXr10tcXJzZT9myZX3+PHrcv/76q0RHR5v9Fy5c2CyvXLmydOjQwZluzpw5cubMmVTr33LLLRITE2Oe//vvv7Ju3TopUaKENG7c2O38AEBORmABAEhFg4Z77rlHkpKSpFevXs7lkydPlnHjxsltt91m3rv11ltNYNCiRQsTYGhhf+HChVKqVCmT3uFwyP333y8TJ040wcDp06dN4f6rr74yhft9+/bJ3LlzTdqTJ0/KTz/9JNdff71Mnz5doqKinPs9cuSI2YcGHykpKaZg/8knn5jAJyO6/T59+kiTJk0kT548sm3bNhk/fry0bdvWNIV64oknnNvRYz927Jhz3d9//102bdokR48eNcc9bNgwc2x6LAcPHpQ9e/bIZ599Js2aNeMqAgAHAABe9O/f33Hddde5LWvQoIFj5MiR5vnbb7/tKF68uOPff/81r48dO+a49NJLHQMHDnSmHzdunCM2Ntaxfv1657Kff/7ZsX//fq/n/MCBA45y5co5Zs+e7Vz21ltvOTRGefnll53LRo0a5ShbtqwjISEhw7xr2rSp44UXXnC+PnTokOO7774zz6dMmeKoUKGC1/V27NjhKFmypOPhhx82r99//31H9erVHQcPHnSmee655xx16tTJ8BgAICegjwUAwCutqdBmT/v37zev9c69NkWyajC0xkCfa3MiVahQIRk6dKjMnDnTuY1p06aZ2oJLL73Uuaxly5bOGg2ridPKlSvl888/l2+++UYqVaokv/zyi9ux5M2bV4YMGeJ8/eCDD5rj+uGHHzLMPa3l+Ouvv0xtiSpevLi0bt063XW09kT7XmhNxJgxY8yyKVOmmM+xbNky+fTTT2XWrFlSsGBB+eOPP0zNBQDkdDSFAgB4pYXv8uXLm0BBC/UfffSRNGrUSOrWrevsa9CtWze3dapXr26aEh0+fFiKFSsm//33n/To0SPNM7xx40a54YYbnP0rtAmWNo+yghmL9t/Q4MKiBXoNTvQYMvLWW2/JwIEDTfrLL7/cNHsaMGCA2/ZcafOtu+66y/S1+Pjjj519Rv755x85e/aszJ492y29NgvT5QCQ0xFYAAC80j4OPXv2NAHFfffdJzNmzDA1EpaSJUuaTt6u9LV2crY6RxctWtR0nE7L448/Ltdcc42p2bBcd911pnDvSvtYuNL3dZkeQ0YaNGhgakC0VmHp0qUyevRo05dDP483zz33nKk5WbVqlRQpUsS5XD+THuv//ve/DPcJADkRTaEAAGnSpk5awNaC/65du0ygYbniiitMx2jtTG3RJkLa1Mka9enaa681NR6ud/S1mVFCQoJzVCitqbDoay30e9Igwho9SumEebpfXzpN6yhSVq2Hfh4NjrTplTfz5s2TZ555xtRU1KpVy+09DXg0yDp+/LjX7QNATkeNBQAgTfXr1zcPbQqld+u1cG7R0ZQ0kNCmTDfffLOsWLHCFMxdA4Ann3xSFi1aZIKNO++80/Rz0EK7BgY6TGvXrl1l7Nixki9fPjPqkjZb0v89aRMp7auhQYEGFC+++KJ5rv0xMqLHdskll5hRqU6dOiWvvvqqW4DkGvD07t3bNAHTQEb7kLgON/vUU0+ZGg8NZrRplR6/Bl3bt2/3qa8HAES6KO3BHeqDAACELy1ga82E9jvQu/autD+EDt2q81joULP9+vVLNQ+F3uHXYWp1iFjts6FptC+G0iBBh2/VYV+1z0PHjh1lx44dpl+DDnerdD4NnX1b96/Hsnv3blP410DFdUjatGjncK1p0MBHh5vVAEk7Zus+dL/aCVuH0NXj1IDBGz1+DSQ0MNHj1YBCgyEddlb7kHgLhgAgpyGwAAAAABAwbrEAAGxNm1p5du626ChWrn04AABZh8ACAGBr2u9h586dXt/TYWkJLAAge9AUCgAAAEDAGG4WAAAAQMAILAAAAAAEjMACAAAAQMAILAAAAAAEjMACAAAAQMAILAAAAAAEjMACAAAAQMAILAAAAAAEjMACAAAAgATq/wFO4eKa2AIcAgAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def plot_train_memorization():\n", " values = [per_vocab_size[str(vs)][\"splits\"][\"train\"][\"fraction_encoded_as_1_token\"] for vs in vocab_sizes]\n", @@ -523,21 +152,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "f630f69b", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAdWBJREFUeJzt3QecE2X+x/Ffku0LW1i20KR3EVSaoqJiQcVyoh72eojlbKdnOT17OfUs592pp/7VU1TsBe/s5RQFEbFQlS59gWV3ga3J/F+/Zzch2b7Z7Caz83n7ikkmk8lknoSdb57msizLEgAAAABoAXdLngwAAAAABAsAAAAAEUGNBQAAAIAWI1gAAAAAaDGCBQAAAIAWI1gAAAAAaDGCBQAAAIAWI1gAAAAAaDGCBQAAAIAWI1gAaNCgQYPkhBNO4CgBUfTQQw+Jy+WSjRs3ttlrPvPMM+Y1ly1bJm3tlVdekbS0NNm6dWtE9jta76Wt9uXZZ5+V7Oxs2b59e8S2CYSDYAHUMHHiRPOPfmZmppSWltY6Pvn5+ZKQkGDWueCCC2L6+I0YMcK8HwCwi7KyMrn22mvliiuukKysLHGCxx57zPxNWbVqVVjPP+OMM8yxuv322yO+b0BzECyAOiQlJUlRUZG89dZbtR57/vnnTbAAgPbsnHPOEcuypF+/fm36ui+++KKsWbNGLr74YmmPWuO4ejwemTZtmjz66KNSUFAQse0CzUWwAOqQnp4uEyZMMFXWNT399NNy0kkncdwAoJV+vT/ssMMkLy+P49sMp556qqnt+fe//81xQ9QQLIAGflX68MMPZf369YFl8+bNk59++knOPffceo/bO++8I+PHj5eOHTtKcnKyjBs3Tj744IOQdbTPglZ760V/acrJyTFhZenSpXX2b9Dl+oc2JSVFunXrZqq79RevhmRkZMgPP/wg77//fuC1evXqFbKO/rq11157mRoabfp13HHHmec05rnnnpPExES58MILpbKy0ixbt26d/O53vzP7pzU6+lo33HCD+UNXs524rquP5ebmSmpqqhxzzDHmF8pg27Ztk0suuUR69uxpjuOAAQNM04gtW7Y0uG/+19Dt6fra7rhDhw7mva1YsaLW+s3Z719//VX++Mc/SpcuXcz9+jR135vy2uqrr74ynyPdVo8ePeT++++Xjz76yOyDXvtdffXVEhcXV2t/3nvvPbPuZ599FvZ7b0qZ+bepn4s99tjDfK6GDBki9957b8g2m/q+g7377rtmP1599dVaj/3vf/8zj+nnsjnHP9ztqx9//FGOP/546dSpk3mfw4YNk3/84x+1vpeNHQ9/2fgv+h0fOXKk+QGjLuXl5U36XDemKceoZl+AHTt2hOxrzcu3337bojL2NzWdM2eOHHroobUea+6xCkdTjktz/42pqeZxve666+Siiy4yt3v37h14f/p+m7pPSr+bQ4cOlbfffjtixwNoNgtAiCOPPNLKzc21du3aZaWnp1v33HNP4LFLLrnE6t+/v1VRUaFnD9b5558f8txHHnnEcrlc1k033WT9+uuvVn5+vnX77bdbHo/HmjlzZp1HuqyszPr++++tCRMmWL169bKKiooCjw0cONA68MADrd/85jdmncLCQuuvf/2ree0XX3yx0ZIbPny4eT91ueaaa8x+PfDAA9aWLVusJUuWWIcffriVkpJizZ8/P2Qfjj/+eHPb5/NZN954o+V2u6377rsvsM6aNWusLl26WKNHj7bmzJljFRcXW59++qm1xx57BJ6rHnzwQbPv5513nvX0009bBQUF1rfffmvWO+igg0L2b9KkSdaAAQOsefPmWSUlJdaKFSvM8f3LX/7S4Hv2v8aUKVMCr6HvZ8SIEVbXrl1NmYS736eddpr11FNPWVu3brUef/zxevehKfve1Nf+7rvvrKSkJOu4446zli1bZm3evNm65ZZbrBNOOMHs04cffhhY9w9/+IMp05r++9//mnV1+61ZZqtWrTLfHf3cff755+azvHjxYuu6664z+9Cc162psrLS6t69uzVx4sRaj5199tnmu6rf2aYe/5Zs/8cff7RSU1OtQw891Fq0aJH5PPztb3+z4uLirCuvvLJZxyOYfr82btxovlv6HXv55ZfD+lw3RVOOkb6OvuYvv/xS73b089inTx8rIyPDWr9+fYvKWL3++uvmNT/++OMG12voWNW13015L009Ls0pi6buy6OPPmqWrVy5Mqx98tO/ScnJyeZvFBANBAugnmChpk6dag0ePNjcLi0ttTp16mTdeeeddQYL/WOi/6DrSUhdfxiGDh3a4LHWkxDd5quvvhpyUp+QkGBCSrBhw4ZZhxxySNjBQv/w6wmovr9geuKTmZkZ8hx/sNA/aL/97W/NCdWbb74Z8rwz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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def plot_metric_vs_vocab_size(metric_key, ylabel, title, hline=None, hline_label=\"\"):\n", " fig, ax = plt.subplots(figsize=(8, 5))\n", @@ -555,21 +173,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "1903e82a", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWsJJREFUeJzt3QmcTeX/wPHvMGPGNnbGvoXIGllSoSKVLRFFSqJFRX5aKPwSKZWUikRUtIiQStqFkCVkzZqdEY11hpk5/9f36Xfu/95Z78y5M3Pvnc/79brm3nOfs9zz3HM93/NsIZZlWQIAAAAADuRxsjIAAAAAEFgAAAAA8AlqLAAAAAA4RmABAAAAwDECCwAAAACOEVgAAAAAcIzAAgAAAIBjBBYAAAAAHCOwAAAAAOAYgQUA5IDLL79cunTp4jfnfsuWLXLDDTdIZGSkhISEyNy5c8UfzJw50xzPrl27cvpQcpWJEyea83706NFs2yd5DQQ+AgsAfiUqKkquueaaFN87ePCgKew88sgjrmXt27c3y5o0aSKWZSVbJyIiQnr27OmxTNcpVKhQsrQ7duyQypUrS+nSpWXt2rWpHmPDhg3NNoJJr169zPnbv3+/+dutW7ds2/eUKVNMHu7bty/b9gkA8D0CCwBBYd26dfLxxx9nev01a9aYgCZPnjyyfPlyE6jkFqdPn5aNGzdKx44dpWjRouJP7r33XhPoXHbZZTl9KMhi5DUQ+AgsAAQ8rWFo3LixPPPMMxIXF5fh9b/77ju5/vrrTW3JihUrpGbNmpKbREdHm7/58+fP6UMBAAQwAgsAAU+b0bz88sumKc2bb76ZoXU//fRT6dChg2netGzZMilXrlya6fWOvt7dX7JkidmvPqpUqeKRZvLkyVK/fn3TDKtYsWLSqVMns056PvzwQwkPD5cHHnhA4uPjzbJDhw5J//79pXz58pIvXz6zr+HDh3sEUHZ7eE2r75UpU0YKFiwot956q2nalJYHH3zQVRvw0EMPme2ULFnSY7sHDhyQJ598UsqWLWteq2+++cb1+fVRoEABU8szY8aMZPvQ49LPVKlSJXNO6tSpI+PHjzef4emnnzb7VVWrVnVtT7efVrv7TZs2SefOnaV48eJmm/Xq1ZO33nrLozmck/Py1VdfpdrX5JdffjHvaX6pkydPysCBA00zOg3ONDAdPHiwnDhxwifb9/bzpneuM5pv6uLFi+azlCpVyjQf1O/ynj17JKO8OUdJ8/rs2bMex5r04d5c0ZvrBEA2sADAj5QpU8Zq2bJliu8dOHBAS1HWwIEDXctuuukms4665ZZbrGLFilknT550vR8eHm716NHDYzu6TsGCBa1JkyZZefLksTp27GidP3/e62Ns0KCB2UZKnnjiCStv3rzWhAkTrBMnTljbt2+32rZtaxUoUMD6/fffXelq1aplde7c2TxPTEy0nn32WXMsL7/8sivN/v37rbJly1pNmza1Vq9ebZ05c8b66aefrEqVKrnWVa+99po5L/fdd581Y8YM69SpU9batWtNuuuuuy7dz7Nz506z/uTJkz2W29u96667rOnTp1t///239c477yRbX4//6NGj5tj1M8yZM8f13r59+0z+6DlbunSpdfr0aWvbtm3W008/bS1evNik0f3qfvbu3Zts2/p59D09RtumTZtM/l1//fXW1q1bzXG98cYbVmhoqPX444/75LzEx8dbFSpUsNq3b5/svXvuuccqUqSI6zvToUMHq2bNmta6deusCxcuWHv27DHfrZdeeskn2/f283pzrr3NN/vc9ezZ03Xu9PvbsGFDq1y5clZ0dLSVEd6co5TyOqnjx49b1apVs4oWLWodPnw4Q9cJgKxHYAEgaAKLzZs3m0L90KFD0w0sdDv6aNKkiSnkZURqgYUWcHT/AwYM8FiuBTwNeNzXsQMLLWTp8WnBccGCBR7r3X333VZkZKQp/Ln78ssvzbEvW7bMoxA4evRoj3RvvfWWWb5jxw5HgcWwYcMsb2lB+cYbb3S91oKpfja7EJiSjAYWnTp1MudFC7vu9HuhBeTdu3f75LzYwZ5+79zzUoPEBx980LWsUKFCJqDMKG+37+3n9eZce5tv9rl75plnPNLpOdN9Dh8+PEPb9+YcpRdYaKDVvHlzK1++fCZwyOh1AiDr0RQKQNC44oorTAfQSZMmyV9//ZVmWm2O0a5dO9Oc4tVXX/XJ/pcuXSoJCQnStWtXj+WFCxc2+/r5558lMTHRtVybgbRp08Y0wdLmL9rUxd2iRYvkuuuuM0143Gl/EG0Kovtzp0183NWtW9f8zUzTFXfa/CUp/RwTJkyQK6+80jQvcm/C5N5s6euvvzafUZtR+coPP/xgzkHSjuY6kpUe108//eST83LfffeZpkba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FECuQB8LAAAAAI4RWAAAAABwjMACAAAAgGMEFgAAAAAcI7AAAAAA4BiBBQAAAADHCCwAAAAAOEZgAQAAkI3Wrl1rZuH2d4sWLZKDBw9m+37//vtvmTt3riQmJjraTkxMjNnOxYsXU01z7tw5k+bChQtpbuvAgQOydOlSCURHjx6V77//Plv2RWABAACQjd588015/fXX/eqcf/311/LXX395LOvbt68sX748249l27Zt0r179zQDAm/s3bvXbOf06dOppjly5IhJo8FMWvRc7Nixw2OZbnfJkiXyww8/yPnz5706pkuXLsk333xjHqlJb7unTp2S7777Tvbv35/i5/npp588lkVGRso999yTLcEsgQUAAEAu98ADDyQrkOJf3377rWzdulXuu+8+j2WVKlWSZ599VgYPHizVqlWT3377Lc1TNnLkSJOuf//+8sgjj6SYJr3t7tu3T+rWrSvjxo2TK6+80gSE7jSAOHTokMeyAgUKyKOPPirDhw/P8iwNzfI9AAAA5BKbN2+W7du3m+fFihWTevXqSenSpR2vs2rVKgkPD5fLLrtMVq9eLSEhIXLDDTeY5kqNGjWSfPnyyaZNm6RgwYLSvHlz8742Y9q4caNUrFhR6tevn+r+9c64NgXSJlqFChWSvHnzym233eZ6/8SJE2Y7+t5VV10lefL8/31pe/+67Pfff5cKFSpIgwYNXHfWtVCsx92wYUMpWrSox35jY2PNPnXfuo2SJUsmO7adO3fK7t27zefWR1L6GTds2GDuyjdr1szsy5saES2g16pVS7ytYerdu7eEhoa6mk/16tVLHnroIVPAV3369DHLtFbD/fy40/OntQZTpkyRWbNmJXs/te3qvvU7oiZNmiSdO3eWt99+Wz766CMTrNxyyy3mvffff9/sW9Mndffdd5vAQo/P28+dGQQWAAAAPqIF8Pnz57sK5FqQfOWVV0xh0ck6+lrb+WuTnapVq5qCugYW2kTniiuuMM2YateuLStXrjSBRZs2bUwBVguRv/76qwwYMMBsIyXarEYL9xqwaHt8DVLswOLDDz80BVLdjgYOug9tr6/Bh9L9a7Chd/Q1eLn99ttNYPHuu+/KE088YQIGy7JM0KPL9H2l6W+88UYpU6aMREVFmdcjRoyQ+++/33Vcd911lwkqNM0vv/wiY8aMkaFDh7reHzVqlLz88ssm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AAAAABwjsAAAAADgGIFFEAgPD5dRo0aZv/Bf5FNgIJ/8H3kUGMinwEA++b/wACrn0XkbAAAAgGPUWAAAAABwjMACAAAAgGMEFgAAAAAcYx6LAKeTlmzdulXi4+PliiuukNBQstQXzp07J7///nuy5fXr1082hrSm3b59uxQrVkyqVauW6vayK01usGHDBklISJDGjRun+L5eD1u2bDHXQ506dVKctNLf0gSb2NhYWb9+vZQtW1aqVq3q8d4///wjmzdvTrZOkyZNJCIiwmNZTEyM7Ny5U8qUKWMmiEpJdqYJJnoN6efVeZj09yS1/z8OHjwoR48elRo1aqQ6lr2/pQkm58+flz///FNKlSol5cuXT/b+mjVrJC4uzmOZfn8rV66canmhbt26kjdv3mTbys40wTiJ3a5du8zvR0r55I/lhSwpU+jM2whMO3bssC6//HKrdOnSVsWKFa3y5ctbv/76a04fVlD4/fffdUZ6q1mzZlbLli1dj02bNnmkmz17tlW4cGGrZs2a5m+bNm2sf/75J8fSBLs333zTqlOnjlW0aFGrevXqKaZZvXq1VaFCBXNNlClTxpyvbdu2+XWaYHLixAlr6NChVrly5az8+fNbgwYNSpZm8eLF5vpyv7b0cfDgQY90b7zxhtlG7dq1zd+uXbtasbGxOZYmmIwdO9aKiooy/4dUrVrV5NeCBQs80ujn79atm+u8REREWK+99ppfpwkmR44cse655x6rSJEiVsOGDa1ixYqZ62Tv3r0e6fT//ho1anhcS5MnT/ZIo785+tujv0H6e6QP/W3KqTTB5NChQ1bPnj2tEiVKWFdeeaUVGRlp8uDAgQN+XV7IqjIFgUUAa9SokdWxY0crPj7evH7ggQfMfw4XLlzI6UMLmsAiOjo61TQ7d+60wsLCrKlTp5rXp06dsmrVqmX17ds3R9LkBkOGDLH++OMPa9SoUSkGFlrw0P/EBgwYYF4nJCRYnTp1surXr++3aYLx2hk/fry5dho3bpxqYJE3b940t7Nq1SorJCTE+uKLL1z/eevv27Bhw3IkTbAZPny4x+/b888/bwrq7sHds88+a86DvWzRokXmd3HFihV+myaY6Pfy/fffty5dumRenzlzxrruuuusa6+9NllgMWPGjFS3k5iYaH5zunTpYn6DVL9+/czNDjt4zs40wWblypXWl19+aT67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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "unk_threshold = next(iter(per_vocab_size.values()))[\"alarms\"][\"tokenizer_misconfigured\"][\"threshold\"]\n", "plot_metric_vs_vocab_size(\n", @@ -580,42 +187,20 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "05f3df0d", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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rj3CSj5BnonzWBARERGRtwYW1atXt69PmjQJY8aMQbt27VSLxYQJE1x5fJXWxXks2GJBRERERJ6vVEM4nTlzxr4+evRo1WqxefNmtGjRAgMHDnTl8VVaBmtgweRtIiIiItIDl4wN261bN7WQ6xitw/YysCAiIiIiPeAEeR7eFcpo0GAxm919OEREREREhWJg4eHDzQotO9utx0JEREREVBQGFh4+3KywZGe59ViIiIiIiFwaWPz2228ws1tOhTBYcyxENs85EREREXlTYDF8+HBERkZi5MiR+PLLL5GUlFR+R1bJGY2OXaHYYkFEREREXhRYnD59Gj/++CMaNWqEWbNmqSCjT58+ePnll7F3797yO8pKyOTr2BWKORZERERE5EWBhcFgQNeuXfH8889j+/btOHLkCG699Vb8+uuv6NSpExo3boyJEyfi559/RmZmZvkddSVL3jab2WJBRERERF6cvF27dm2MHz8ey5cvR0JCAt544w0VUNx5552oUaOG646yEjIaL7ZYIJvDzRIRERFRJZggTwQEBOCaa65Ri/j7779dtetKyejQFcrMHAsiIiIiqqzDzV566aXltetKwejjEFhY2GJBRERERJ6N81h4KJNDjgWYvE1EREREHo6BhQcza4acWwYWRERERFQZAovs7Gxs3rwZJ0+edMXuyMpsrR6LhcPNEhEREZEXBhbr169XIz/ZXHvttejevbua3+Knn35y5fFVapq1ejSOCkVERERE3jgq1OTJk/Hmm2+q9S1btqhF5rRYsWIFnn32WQwcOLDY+5JWjvnz5yM2NhZt27bF6NGj4efnV+hz/vzzT6xcuRLnzp1D69atcdNNN6lRqWy++OILNbdG7qFxn376aeiJBTldoSxmtlgQERERkRe2WPzzzz9o06aNWl+9ejVuuOEG1K9fH7fddhv27NlT7P3s27dPBRObNm1CRESEmsF7wIABqmtVQR588EE8/vjjaj0sLEw9p0OHDjh79qx9GwkqJPho166dfWnevDn0hoEFEREREXl1i0W1atWwe/dudOzYEd9++y0efvhhVR4fH4/q1asXez9PPPGEGpZ22bJlalbvsWPHomHDhvjss89w++235/scmdlbZvi2mTBhggpKfvjhB4wcOdJeLt2y5DE906wtFmCLBRERERF5Y4uFXPRLd6cuXbrg6NGj9knxvvvu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Fl577TVV1qxZM7z99tvMrygPbLEgIiIiIm8MLJYsWaICCFnMZrMqM5lM9seGDRvm2qOs5F2hDAwsiIiIiMgbA4vhw4dDs86tYAso8nuMXDTzNng+iYiIiKgSzbwdFxeH0NBQV+6yUtMM1uphiwUREREReVOLhcyund+6sFgs2L9/P/r27eu6o6vsNM68TUREREReGFh06tRJ3a5Zs8a+buPr66tGihoxYoRrj7AS0wzWwAI5eSxERERERF4RWLz00kvqtkaNGnj00UfL65jILiewMFiYY0FEREREXpJj4TghXlFBRX6T51EZJshj8jYREREReUtgMW7cOFxxxRVYunQpLly4kOfx1NRULFy4EP3791fbkivYukJx5m0iIiIi8pLAYufOnRg0aBAefvhhNfJT27ZtVQK3BBKtW7dGWFgYnnjiCQwePFhtS67LsTBw+F4iIiIi8pYcCz8/PxVUPPjgg/j999/Vcvz4cRgMBhVg9OrVCz169MgzrwWVBVssiIiIiMhLJ8iTwOGyyy5TC1XMBHlgiwURERERVaYJ8sjFrBPkGZhjQUREREQejoGFDkaFkjUiIiIiIk/GwMKDSf6Kwq5QREREROThGFjoIMeCXaGIiIiIyNO5PbD49ddfcfPNN6Nv37544IEHcPr06UK3z8zMxAcffIAbb7wRV111FSZNmoTDhw+Xeb8eyd5iwXksiIiIiMhLA4uff/5ZDTNbu3Zt1KpVS61LWUmsW7dOzYPRtGlTPPbYYzhw4AB69uypJtsryNixY7Fnzx7cfvvteOihh1RQ0blzZzX0bVn264k02IbuZY4FEREREXnZcLNi3rx5uOuuu1SLwNChQ1UuwKZNm9QEeh9//DFuu+22Yu1n6tSpquXhhRdeUPf79euHmjVrqhaJRx55JN/nfPjhhwgKCrLflwAiODgYa9asUcFGaffrsS0WmnSFYmBBRERERF7YYjF9+nQVQHz22We4//77cd9996n1jz76CC+++GKx9nHhwgVs3rwZ1157rb1MAgZp+Vi9enWBz3MMKoQENGazWc0EXpb9eibbzNvsCkVEREREXthiId2PpKUit+uvvx533313sfYhXZcsFovqRuVI7kvrQ2EkcJBuUCkpKYiJicG3336Ljh07lmm/GRkZarGRfQvZlywVLec1rXGfQXPLMVDxSN1oGutIL1hf+sG60hfWl36wrvTF4ubrjJK8bqkCC8mr+OWXX5xaBWy5DXXq1CnWPrKystStv7+/U3lgYKD9sYK0bNkSs2fPxpkzZ1QriSRnt2vXDvXq1Sv1fmfMmIFp06blKY+Pj0d6ejrcUYlmW0uFxYy4uLgKPwYqfl0lJyerL73R6PbxEKgIrC/9YF3pC+tLP1hX+mJx83VGSXKUSxVYTJw4ESNHjsS9996LLl26qLI//vgD77zzDp5//vli7aNatWrqNjEx0ak8ISEB1atXL/S5oaGh6Natm1q/+uqr0aJFC8yZMwevvvpqqfc7efJkNcKUY4tF3bp1ERERgZCQELjjQ7TX5AuYc+aziIyMrPBjoOLXldSRfFYYWHg+1pd+sK70hfWlH6wrfbG4+TojICCgfAML6YYkF/CzZs3Ca6+9psqaNWuGt99+u9iJ29I1KTo6Gn/99RcGDx5sL5cApXfv3sU+FpPJpE60tF6UZb/SwpG7lUNIBbrvYjHndSV5mxesnk2+8O79rFBJsL70g3WlL6wv/WBd6YvBjdcZJXnNUh+dBBC7du1CWlqaWmS9uEGFzR133KG6Mp08eVLdX7p0qRpKVsoduyhJ64iQ15FWCccuTd99950KIqTloiT71QODkRPkEREREZE+lKrFIneLQWk988wzao6JJk2aqG5HJ06cwFtvvaXmpbA5ePAg/v77b7UuLQpJSUmqVUKGjz179qwKNmbOnIkRI0aUaL/6YAssONwsEREREXlJYCEzWIv169fb1wsi2xSHBAqLFy/GqVOnEBsbqwKBqlWrOm3z1FNP4dy5c/amGJmb4tlnn8X+/fvV/BWSLO7j41Pi/eqCgRPkEREREZGXBRa9evXKd90VpAUi9/CwNo0aNcpT5uvri9atW5dpv7pgsOVYcKhZIiIiIvKSwMI2i7WQoV2HDRuW73ZLlixxzZGRwwR5PBlERERE5NlKlbw9fPjwUj1GJWTNwmeLBRERERF5OpeOWSWTuMkcE+QaBnvyNrtCEREREZEXjQo1YMCAfNdtk3dIQnVRid1UfJoxJ3nbkBNfEBERERF5R2DRqVMndbtmzRr7umNCtcw34TjsK5URk7eJiIiIyBsDi5deeknd1qhRA48++mh5HRNZGa1NFZzHgoiIiIi8MseCQUVFt1hwWCgiIiIi8tKZt+Pj4/Hzzz/j2LFjyM7Odnps6tSprjg2so8KxcCCiIiIiLwwsPj9999xzTXXIDo6Gv/++y8uvfRSlbidlpaGDh06MLBwGWvyNgMLIiIiIvLGrlCPPfYYnnnmGezbt0/d37FjB06ePInBgwejX79+rj7GyotdoYiIiIjImwOLnTt34q677srZgdGIjIwMhIeH46233sIXX3zh6mOstAzWrlBGzmNBRERERN4YWJw7dw4hISFqPSoqCkePHlXrUpaUlOTaI6zEDGyxICIiIqLKMvN2//798fDDD+Pbb7/FuHHjVI4FuYZFy0narmI4j+1fvIPsjAyeWiIiIiLynsDizTfftK/PmjVLzbp9++234/jx4/jggw9ceXyV1h8fPI9L4j9S67VNCWi/fzISXmyOze9Nc/ehERERERG5ZlSo+++/375es2ZNrFixojS7oQJI8ND19Guwzo9nF2FIQsTp17D5PaDbhGd5/oiIiIhI3y0WERERrj8SUqS7U8NTc9V67sDCaL3f4NRcdosiIiIiIv0HFpqmITEx0fVHQ9i59GNEGZPsQURuUh5tTFLbERERERHpOrAYNWoUZs6cqXIryLXSEk+6dDsiIiIiIo/Nsdi1axfWrFmDL7/8Ei1atICfn5/T499//72rjq/SCaxWGzhTzO2IiIiIiPQcWLRp00Yt5Hptb7wTsS/OUona+XWHsmhAnBautiMiIiIi0nVgMXv27GJtJ3NbDB06tDQvUWn5+PvjcK2xavQnCSIcgwu5L47UGotof3+3HSMRERERkcsnyCvM9ddfX56791oylOwfNSchXgtzKpf7f9acxKFmiYiIiKhyBRZUel3HPY2sO3/FliYvINkSpMoSWj3GoIKIiIiIPBIDCw/vFtXh1vuwy9JS3U85sMHdh0RERERElC8GFjqQFpKTKB+a8a+7D4WIiIiIKF8MLHQguuMgddvYdAxZqWfdfThERERERHkwsNCBFn2uQKwlDH6GbBxcudDdh0NEREREVLGBhT+HRHUJHx8T/rM0Vutn9613zU6JiIiIiPQSWKSnp5fn7iuVtJDW6jY0nXkWREREROQlE+QlJSXhueeew++//47ExMQ8j//333+uODZyULPDIGDDfJVnkZ16Fj5Vnee4ICIiIiLSXWBx9913Y/fu3bjtttsQHh7u+qOiPJr3vRIxv4Yj2piEvSsXouWwCTxLRERERKTvwOLnn3/G9u3b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60pfWF/6wbrSF9aXfrCu9CXEjdeERbVU2LDzPhERERERlRkDCyIiIiIiKjMGFh7K398fzz77rLolz8a60hfWl36wrvSF9aUfrCt98dfRNSGTt4mIiIiIqMzYYkFERERERGXGwIKIiIiIiMqMgQUREREREZUZ57HwQElJSfjvv/9Qu3ZtNRkJudb27dtx/vx5p7KaNWuicePGebbdu3cv0tPT0aZNG/j6+ua7v4rcprI4cOAAYmNj0aNHjwIn4/n3339VPcr58vPz08U23kg+s9u2bVPfoYYNGzo9dvbsWezatSvPczp16oSAgACnsuTkZFXvUVFRaiKo/FTkNt4oIyNDfU5lPPp69eoVOPnr/v37ce7cObRu3brAZFFP28YbnT59GnFxcWjUqJGarDf3Z3jnzp15ntOhQwcEBQU5lcnEZlLvERERqF+/fr6vVZHbeOukyvI51TRN1VdBn1O5tpO6a9WqFQIDA3WxTYnJzNvkOV588UXN399fa9WqlRYQEKCNHj1ay8rKcvdheZXWrVtrDRs21Hr27GlfXn75Zadtjhw5ol1yySVajRo1tAYNGmhRUVHaunXr3LZNZbFs2TKtd+/eWnh4uCZ/nlJTU/Nsc+LECa19+/ZatWrVVD3KeVu5cqVHb+ONzpw5oz366KNarVq1tMDAQG3ixIl5tlmxYoWqR8fvmixyzhy98cYbah8tW7ZUtzfccIOWnp7utm28TUpKivbggw+q75X8rZG/MW3atNG2bdvmtN3p06e1Ll26aGFhYVqjRo3UZ/r777/36G280c8//6x17NhRq1mzpqqvoKAgbdKkSZrFYrFvI/9G5PfdOnTokNO+3nvvPfX8Fi1aqNvBgwdr58+fd9s23uj999/X6tatq64tGjdurL5nUuYoPj5e69GjhxYaGqo1adJE3X799dcevU1pMbDwID/99JNmMpnsF5UHDx5Uf0hnzpzp7kPzKvLlf/311wvdplevXlr//v21zMxMdf+RRx7RqlevriUnJ7tlm8pi+vTp2vr167VvvvmmwMBiwIABKviwXQxOmTJF/VFMSEjw2G280fbt27VZs2apf6DkIqigwEL+phVm8+bNmsFg0L777jt1/+TJkypYmTx5slu28Ubyb8mcOXO0CxcuqPvyt2bEiBFavXr1nC5W5UKwa9eu9u2ef/55rUqVKlpsbKzHbuON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feyDDz5Qv2DafP3116qblNSv9Nt/5JFHVKuqI0/bxttIArCtf74j+fVf/kYK+T7J90y628j3TOpQ6liuGxzFx8erz7sMViKzYd9zzz3qb5S7tvFGMtP4u+++q1rUwsPD1b9VMjJU7hnQpYVg3rx5SElJUS2HMpBM7hnVPW2b0mBgQUREREREZcaO+0REREREVGYMLIiIiIiIqMwYWBARERERUZkxsCAiIiIiojJjYEFERERERGXGwIKIiIiIiMqMgQUREREREZUZAwsiIvIo33zzjZostDwsX74chw4dKpd9ExFVdgwsiIjIo9x9993YuHFjuexbZideu3ZtueybiKiyY2BBRESVxrXXXovGjRu7+zCIiLySj7sPgIiI3O/XX39FQEAAunTp4lT+yy+/qPKuXbuq+6mpqao1ISMjQ5VFRUXl2VdWVhb+/PNPJCUloXPnzk7brF69GmfOnIHBYEDNmjXRvn17VK1aNd9jOnXqFP7++2+EhISgR48e6jnFtW3bNpw4cQJNmzZFy5Yt7eVXXnkl6tevr9YPHDiArVu35nlu8+bN1XGJzMxMbN68GcnJyWjVqhWDEiKiQjCwICIibNq0CR9++CH+++8/+9mQi+rrr78er7zyigoi1qxZg2HDhqmL6ypVqqjg4bXXXsOECRPsz9m+fTtuuOEGGI1GtGjRQnU9ev755zFq1Ch7oCIX9JqmqVwHyaVYunQpevXq5VQLn3zyCR599FFccskl+Ouvv3DppZfihx9+gL+/f6G1JQHP1Vdfrd5Hhw4dcPDgQRVcyGtIYCLHM3XqVDRq1AiHDx/Gt99+a3+u2WxW+R0TJ05UgcWOHTswdOhQVKtWDbVr11YBxo033oj33nuPnxgiovxoRERU6R07dkwzGAza5s2b7efim2++0QICArTk5GQtLS1Nq1u3rvboo4/aH//00081f39/7dChQ+p+enq62ub222/XsrOzVZk876effirw/L744otamzZtnMqqV6+u1a9fX4uPj1f3T58+rUVHR2uvvfZakfX0/fffa+Hh4dq5c+fsZd9++61mNpvVuuz3ww8/zPe5jzzyiBYREaEdOXJEy8zM1Bo0aKC9/vrr9sfj4uK0mjVral9++WWl/7wQEeWHORZERIS6devisssuw+eff24/G7IuOQnSFen333/H8ePHMXnyZPvjt912GyIjI9Wv/EKSomWbl156CSaTSZVJN6qrrrrK6QxLK8XKlSuxaNEi+Pr6YteuXbhw4YLTNmPHjkWNGjXUenR0tHqtxYsXF1lTgYGBqtXi33//tZcNGTJEtaAU5rPPPsMbb7yBJUuWqK5S69atw9GjR9X7k7KvvvpKlUlrjdwSEVFe7ApFRETKyJEjVTch6d4kF/rff/+9uvgXcpEdFhamugXZSNci6VIkj9kCBglC8su7sJGuSHPnzlW5FxI4pKWlqfL4+Hh77oNo0KCB0/MaNmyIBQsWFFlTl19+OR588EF1K8fRv39/jBs3Du3atSvwOVu2bFEjUUlgIcGVOHLkCPz8/PDdd985bStdopo1a8ZPDBFRPhhYEBGRMnz4cHXhLwnWp0+fRnBwsMpXEBIESOJ2dnY2fHwu/tORmJhob1mQwOPcuXOqxSC/XAhJqH777bdVjoVtZCbJW5DcCcm5cCSJ37nv216nKDNmzMBzzz2nErO/+OILlZAuuR+tW7fOs21MTIzKo5AWEsdcEQmQJMfko48+UvkkRERUNHaFIiIie2AwaNAg1QVKlptuukl1VRLSwiABxbJly+xna9++fdi9e7c98bpPnz5qG8fuVLbWCNtFvHRVcmyZkG5G+XFMqpagQ7pb9ezZs8iakteQJGw57m7duqlWCBl1Kr/RnyRwkETzJk2aYM6cOU6P9e3bV7VYfPDBB07lsu/Y2Fh+YoiI8sEWCyIispPRm0aPHo309HT1q7+NDA371FNPqV/2JaCQi/VXX31V/drfr18/ey7Eyy+/jHvuuQc7d+5Uw7PK0LTS0iDl3bt3V7/+S8AyePBg/PHHHyp3IT8SsMgIVDI8rHTJklGeCgpCHEkuiBy3PLdevXoqH0K6bEnXqNwkF0RGnHr99dfVqFG5h5udPXu2asGR9yujYsnwtbLd9OnT1fETEZEzg2Rw5yojIqJKSrox3XnnnaplQYafzW358uWq65L82i8tFZJU7dg1SkgwIQGDdIvq3bu3ClRsc1DIEK/vvvuualmQC3hJrH7hhRfw5ptvIiIiQm0jORHynL1796qWBgliJFgp7sR2e/bswcKFC1UgIDkgt99+O+rUqaMek0BBWikkGJJcD0kiz01abeR9CelCJXkm0jVM9jVixAh13ERElBcDCyIiIiIiKjN2hSIiIt2QVogNGzbk+5jkVcgEdkRE5B4MLIiISDdOnjzplNjtSObMYGBBROQ+7ApFRERERERlxuFmiYiIiIiozBhYEBERERFRmTGwICIiIiKiMmNgQUREREREZcbAgoiIiIiIyoyBBRERERERlRkDCyIiIiIiKjMGFkREREREVGYMLIiIiIiICGX1fy2e3uXpFRxpAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plot_metric_vs_vocab_size(\"compression_ratio\", \"compression_ratio (tokens / amino acid)\", \"Compression ratio vs vocab_size\")" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "dcd6d085", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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MbAgIqJqqUWLFrj00ksDvRlERCEjItAbQERE/pWZmYkff/wRw4YNQ1xcnHV5RkYGfvrpJ1xyySWoUaOGWrZx40bs3LkTDRo0QK9evRAWVvZ81IEDB7B+/XqkpKSge/fuCA8PV8uPHj2KZcuWqduxsbFo27Yt2rVr53SbiouL8c8//+DQoUPqferXr+/255HtXrt2LSIiItT7JyQkqOVNmzbFoEGDrOt9/fXXKCwsLPP8K664ApGRker2vn37sGHDBtStWxddu3a12z9ERFQ+BhZERCFGgoa77roLJSUluOGGG6zL33vvPbzxxhu4+uqr1WNXXXWVCgzOOussFWBIY3/x4sVISkpS62uahrFjx+Ldd99VwUBBQYFq3H///feqcZ+amopvvvlGrXvy5EksX74cF110ET755BMYDAbr+2ZlZan3kODDZDKphv3cuXNV4FMRef0bb7wR3bp1Q1RUFHbt2oW33noL/fv3V0OhHn30UevryLbn5ORYn7t582Zs2bIF2dnZarvvv/9+tW2yLenp6Thy5Ajmz5+PHj16+HT/ExFVWxoREYWcW2+9VRs8eLDdsi5dumiTJk1St19//XWtTp062r59+9T9nJwcrXPnztrtt99uXf+NN97Q4uLitH/++ce6bMWKFVpaWprT9zx27JjWoEED7csvv7Que+211zT5p+i5556zLnviiSe0+vXra3l5eRV+ju7du2vTpk2z3s/IyNCWLVumbr///vtao0aNnD5vz549Wr169bSHH35Y3X/77be1Vq1aaenp6dZ1pk6dqrVr167CbSAiIjPmWBARhSDpqZBhT2lpaeq+nLmXoUiWHgzpMZDbMpxI1KxZE/fddx8+//xz62t8+OGHqregc+fO1mW9e/e29mhYhjitXLkSX331FX7++Wc0adIEq1evttuW6Oho3Hvvvdb748ePV9v1+++/V/g5pJdj+/btqrdE1KlTB+eee265z5HeE8m9kJ6I6dOnq2Xvv/+++hy//vorvvjiC8ybNw/x8fHYunWr6rkgIqKKcSgUEVEIksZ3w4YNVaAgjfpPP/0UZ555Jtq3b2/NNRgxYoTdc1q1aqWGEh0/fhy1a9fG/v37cc0117h8j02bNuHiiy+25lfIECwZHmUJZiwkf0OCCwtp0EtwIttQkddeew233367Wv/ss89Ww55uu+02u9ezJcO3brrpJpVr8b///c+aM7J3714UFRXhyy+/tFtfhoXJciIiqhgDCyKiECQ5Dtdee60KKO655x589tlnqkfCol69eirJ25bclyRnS3J0rVq1VOK0K5MnT8YFF1ygejYsBg8erBr3tiTHwpY8LstkGyrSpUsX1QMivQpLly7FlClTVC6HfB5npk6dqnpOVq1ahcTEROty+Uyyrc8++2yF70lERM5xKBQRUYiSoU7SwJaG/8GDB1WgYdGnTx+VGC3J1BYyREiGOlmqPg0cOFD1eNie0ZdhRnl5edaqUNJTYSH3pdHvSIIIS/UoIRPmyfu6kzQtVaQsvR7yeSQ4kqFXzixYsABPPfWU6qlo06aN3WMS8EiQlZub6/T1iYioYuyxICIKUZ06dVIXGQolZ+ulcW4h1ZQkkJChTJdffjn++usv1TC3DQAee+wxLFmyRAUbo0aNUnkO0miXwEDKtA4fPhwvvPACYmJiVNUlGbYk145kiJTkakhQIAHFjBkz1G3Jx6iIbFuHDh1UVar8/Hy8+OKLdgGSbcAzcuRINQRMAhnJIbEtN/v444+rHg8JZmRolWy/BF27d+92K9eDiIgAg2Rwc0cQEYUmaWBLz4TkHchZe1uSDyGlW2UeCyk1e8stt5SZh0LO8EuZWikRKzkbso7kYggJEqR8q5R9lZyHoUOHYs+ePSqvQcrdCplPQ2bflveXbTl8+LBq/EugYluS1hVJDpeeBgl8pNysBEiSmC3vIe8rSdhSQle2UwIGZ2T7JZCQwES2VwIKCYak7KzkkDgLhoiIqCwGFkREREREVGk8DUNEREFLhlo5JndbSBUr2xwOIiIKLAYWREQUtCTv4cCBA04fk7K0DCyIiIIHh0IREREREVGlsdwsERERERFVGgMLIiIiIiKqNAYWRERERERUaQwsiIiIiIio0hhYEBERERFRpTGwICIiIiKiSmNgQURERERElcbAgoiIiIiIKo2BBRERERERobL+D9b/7RINVVngAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def plot_fraction_short_sequences():\n", " metric_keys = (\"fraction_encoded_as_1_token\", \"fraction_encoded_as_2_tokens_or_less\", \"fraction_encoded_as_3_tokens_or_less\")\n", @@ -643,21 +228,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "b98a0711", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAN2CAYAAAAosDpEAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAzHJJREFUeJzs3QeYE9X38PGzsPSy9N6L1BWR3nuVpiCgSLGDCAKiCBbkJ1IEKSoC0gQEQRFRUBARpPfmIiBFpPfe2+Z9zn2f5J8syZLdTbIp38/zzG5mMjOZmSRzM2fuPTfMYrFYBAAAAAAAAPChJL58MQAAAAAAAEARlAIAAAAAAIDPEZQCAAAAAACAzxGUAgAAAAAAgM8RlAIAAAAAAIDPEZQCAAAAAACAzxGUAgAAAAAAgM8RlAIAAAAAAIDPEZQCAMTb66+/LmnTpuUIJoKwsDB55513bOPHjh0z0yZMmOCT13f2ert27TLTvvnmG59sg6vtADzl+PHjkiZNGlm8eLHPDmogfKadbWNct/u///6TFClSyJ9//unFLQUA+DuCUgAQYubNm2cuHNwZ9u7dm9ibG1QOHDhgjuvkyZPFX/jjNgXiNiI49e/fX8qUKSNNmjSxTePz6L7YjlWBAgXkhRdekN69e0t0dLSH3jEAQKAJT+wNAAD4Vps2bcRisThMy5Ahgzz22GPcsQ5gefLkeeB9DabX8/ftQPA5fPiwzJo1y6c1/wL5Mx2f7e7evbupWaU10Z544gmvbRsAwH9RUwoAAACIYdKkSZI6dWpp1aoVx8ZLSpcubWqi+XNTRQCAdxGUAgA4pXk+6tatK+nSpTMXZhUrVpTvv//+oUdr586dkjdvXqlUqZKcPn3aTLtz54589NFHUqJECZNDJEuWLNKhQweTg8RZPqI5c+ZIsWLFJGXKlKYG1/Lly916l27fvi0ff/yxudBJlSqV2Y5XX31VTp06ZZvnwoUL5u683tVPnjy55MuXT3r16iVXrlyxzbNkyRKzLTFzndy7d89Mf++99+K83cuWLZOiRYuaxy+//LKtiWTfvn1j3acTJ05I+/btJSIiQjJmzGiau1y7du2B+Zzlc9FaCyNHjpRSpUqZvDi5c+eW1q1bS1RUlFvbZL9vM2bMMO9feHi4We5h+WOmTJkihQsXNseifPnysnTpUofn3T3GD9tGV9vhzvuc0M+c/fIP29/4fA9iHnNnHvYex+W1Y/u8xcxhFpfvSHz23Z33w53vu7v77czChQulSpUqZt1WCfnOWI+NddDPpX5mtIngzZs33c7XFp/Pqjufk7h+nmOKud3unvO0nPn999/l1q1bD30NAEDwISgFAHiANqWoX7++uXDRi5Z///3XjLdt21a+/PJLl0ds0aJFUr16dalcubK5WM2ePbvcv3/fNMsYN26cDB48WM6cOSPr1q0zAatq1aqZ4EHMC8GtW7eaC62DBw9Kzpw5TU2FmPPFpBd8mvdl9OjR5iLv6NGjsmHDBqlQoYK5wFI3btyQWrVqmdfQC8Zz586Z2hBz586VevXqmQvY+HrYduvx279/v3msr6kXidYLRVeuX78uderUkW3btpkggDYn0mOpwRZ3fPbZZyY48L///c8c7x07dkinTp3k008/jdM2zZ8/32yDXjjqMdXmng/LW6YXuKtXr5Z9+/aZoIFu94oVKySu4nPc4vo+x/czF5f9jev3wN1j/rD3OC6vndDPmyveOAe4832P6+vau3z5sjn3aUDGXkK+Mxqcss6vw9mzZ2XMmDFmezWvkjvi+1l153Pi6e+vu8dKb3hogHHjxo1xWj8AIEhYAAAhLyIiwlKrVi3bcShZsqSlaNGilnv37jkcm0aNGlnSp09vuX79uhnv3r27JU2aNObx6NGjLUmTJrW88847lujoaNsy06dP1yQjloULFzqs69y5c5a0adNaBg4caMajoqLMfDVr1nSY759//jHTx40bF+v7NHnyZDPf/PnzXc7z2WefmXmWLl3qMP3HH3800ydNmmTGFy9ebMZXrFjhMN/du3fN9Hfffdc2LS7bvX//fofXeZixY8ea+devX+8wfcyYMWZ6v379bNOOHj1qpo0fP942rVWrVpayZcvG+hqxbZN13ypUqPDAc85ezzp/pUqVHObVz1HhwoUtFStWtE2LyzGObRudbYe773NCP3Nx2d+4fg+cHXNn3HmP3X3tuHze4vL+eeMc4M733d3XdWbXrl1mWf0seeo748rIkSMtyZIlM8fuYd+t+H5W3fmcxOXz7GwbnU1z55z3559/mnn0/QIAhB5qSgEAHGjTl927d0vLli0ladKkDyRJ1+ZPmzdvtr+5Id26dZO3337b9LA0dOhQ00TD/s6+Nhex771KZc6c2TQ9WblypcP0mMluH3nk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JUsWmTNnjlcOa4ECBWTy5MleWTcAwHO4NgDcR1AKQKwsFossW7ZMWrduLcmSJZM2bdo4nW/Xrl1Su3ZtSZUqleTMmVPee+89iY6OjvM8AAD/dObMGRk2bJgULFhQwsLCzDndWZkxaNAgyZ07tznX16hRQ3bs2OGVeQAAwX9twDVG8CMoBfi5Ll26yLFjxxLt9ffv328uQtq3by8NGzZ0Os/ly5elfv36UrhwYTl8+LB89913Mn78ePnoo4/iNA8AwLX//vtPXnrppUQ7RB9//LFcunRJPv30U5fzfPLJJzJmzBiZNWuWHDlyREqWLGnO/efPn/f4PAAQikLp2oBrjBBhAQLUiRMnLEmSJLGsWrXKYfrcuXMtqVOntly9etWMz5kzx1KiRAlLsmTJLPny5bMMGzbMEh0d7bDMn3/+aalRo4YlVapUlgIFClhGjRplm2fx4sUW/arokDJlSkuZMmUs8+fPd1j+888/txQtWtQyePBgS+HChc18TZo0sRw/ftytfTly5IilRYsWlowZM1qyZs1q6dixo+X06dPmuWnTplly585tmzdz5sy27bEfLl68aNuXqlWrmm3Q5V577TXLlStXLJ7QsmVLS+vWrR+Yrvuvx/zGjRu2aXosdH/u3r3r9jwAEB9du3a11K1b94HpJUuWtHzwwQfm8dmzZy3PPvusJUOGDOZc37BhQ8uePXsc5tfzU58+fSx58uSxpEmTxtK4cWPL/v37bc9XqlTJds7NmTOnpUuXLpZz5845rEPP0fqauj3p06c365owYYLb+6Lzanmi2/joo4+aMs0qf/78lkmTJtnOqc7KgjfeeMM8f/PmTUvv3r3Nduq5t0KFCpalS5daPGH79u3mtaKiohym379/35ItWzbLoEGDbNNu3bplSZcunWXkyJEenQcAYuLaIPiuDbjGCA3UlELA0iqedevWNXdR7el4q1atJG3atLJu3Trp0KGD9O7dW86dOycTJkyQIUOGmP9WGzZskAYNGphI/aFDh+TPP/+Uo0ePmseqcePGppqqDrqOt99+W5599lmJiop64K7BmjVrzPL//POP3Lx509xBcEf37t0ladKksmfPHrOsvubcuXOdzqvbYN2eu3fvmiqvFStWlHTp0smWLVukefPm8tprr5lmFqtXr5a9e/fKyy+/bFte59FmF7ENvXr1itN7oce5UqVK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v34ydepU+eGHH+TEiRPSp08fuXbtmnTr1s02T9euXeXxxx83jy0Wi7z88suyePFi0wtf/vz55datW2a4f/9+nNYLAAAAAACAEEx0rjp16mSCRdp0ThOUR0ZGyu+//y558uSxzZMsWTJTi0lduHBBZs2aZR5rcnN7EyZMME363F0vAAAAAAAAQjQopV577TUzuDJ+/Hjb48yZM5taUZ5YLwAAAAAAAEK49z0AAAAAAACEHoJSAAAAAAAACJzmez/99JOsXbvW5HmKafLkyQndLgBAEKMMAQBQPgAA4hWU0gTio0ePllq1aknGjBk5ivAbkdMj4zR/VOcor20LAOcoQwAAlA8AgHgHpaZOnSq//fabCUoBAEAZAgBIKK4xACD0xCsodf/+fSlfvrzntwYAEPQ8WYasWrVKxo0bJ6dPn5bIyEgZMGCA5MyZ0+X8d+7cka+//trcWLl27ZqUKlVKevToIQULFvTI9gAA4o9rDAAIPfFKdK41pPQHPQAAiVWGrFixQurVqydFixaVt956S/bv3y/VqlWTq1evulzm+eefl927d0uXLl2kV69ecujQIalQoYIcPXo0wdsDAEgYrjEAIPTEq6ZUvnz5pEOHDtKpUycpUqSIhIWFOTzft29fT20fACDIeKoMee+996R169YyePBgM16nTh1TS+qrr76SN9980+kykyZNktSpU9vGNaiVJk0a+eOPP0ygCgCQeLjGAIDQEx7fu9PFihWTjRs3miEmglIAAG+WITdu3JANGzbIa6+9Zpumwab69evLsmXLXAal7ANSav369aa5iDb9AwAkLq4xACD0xCsotWPHDs9vCQAgJHiiDNHmdtHR0ZIrVy6H6TqutZ5io8Esbbp35coVOXXqlCxYsEDKlSvncv7bt2+bwUqXAwB4HtcYABB64pVTCgCAxHT37l3zP0WKFA7TU6VKZXvOlRIlSsiYMWPkk08+kZo1a5pE50eOHHE5/9ChQyUiIsI25M2b10N7AQAAAIS2eNWUUmfPnpWJEyfKnj17xGKxSMmSJaVr166SJUsWz24hACDoJLQMyZQpk/l/4cIFh+nnz5+XzJkzx7qsBpYqV65sHjdp0kSKFy8uY8eOlU8//dTp/P3795c+ffo41JQiMAUA3sE1BgCElnjVlNIcIJqcdvLkyaZJg96V1sc6zVl+EAAAPFmGaDO9HDly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vlE+JM71QzB/bl0JtX0Otf0NxX1OH+T76075kKi973Xv3l2mTJlicnnonYXPPvtMjhw5Iq+88optnrffflvq168fp2XcmQcAENi8VYYAAAIb5QMABI5Eqyml3nzzTTl58qRUrlxZkiZNaiKEc+bMkRIlStjm0Sqwp06ditMy7swDAAhs3ipDAACBjfIBAAKIxQ/cvn3bcubMGUt0dPQDz124cMFy6tSpOC0Tl3ngnlu3blkGDhxo/iNuOHbxw3GLv1A7dt4qQxJTML+H7FtgCtb3LVj3K9j3LZTLh1B9b0Ntn0Ntf0Nxn0Ntf2MTpn8SOzAGAAAAAACA0JKoOaUAAAAAAAAQmghKAQAAAAAAwOcISgEAAAAAAMDnCErBpYsXL0qePHkeGH7++WeOWgznzp2TESNGSOnSpaVUqVJOj8/t27fl3XffNfNoT1/aM8z169dD/lju3LlTunbtKvnz55e33377geOxefNmp5/D3bt3h/SxO3jwoLz++utStmxZefzxx81j7VUuph9//FFq1KghRYoUkRYtWkhUVFSibC/cs2fPHnnllVfk0UcflfLly5vzhJ5fgommsmzXrp35Hv/2228SLH766Sdp2LChPPLII9K+fXs5dOiQBIPvv/9e6tevL0WLFpWKFSvKwIED5ebNmxJojh07Zra9WLFiZn+cuXz5svTs2VOKFy9uvoODBg2Su3fvSqCXo/pbY9SoUVK7dm2zby1btpQ1a9YkyrYiYY4cOSJ9+vSRcuXKyWOPPWbKC50WCrQn3ZIlS5qy4/79+xLM9u7dK88995w5X+n3dsmSJRLMJkyYYH6rajlTrVo1GT16tERHR0sw0M+qXjs3adIk1t89ixYtklq1aknhwoWlWbNmsn37dgklBKUQ65fo+PHjMnXqVNmwYYNtaNCgAUcthsaNG8vp06elUaNG5pg58+qrr8rs2bPl888/l0mTJsmvv/4qHTp0COljuWXLFunUqZP58Z89e3a5cOGC02CeHtOVK1c6fA614AplelGhP86+/vprU5j//fffUqdOHYdAp37G2rZta4b58+dLtmzZTIF34sSJRN12OHfjxg3zXumF/zfffCOfffaZrF271gQ67ty5EzSHbcyYMeYzqN/rQAxuODN27Fh59tlnpXXr1rZzuwZAgiHQpgG2J5980uzX4MGDZdq0adK9e3cJNNWr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/gY/3mPv0TscWqDkypVL/AHlg38Ite9cQnG8OF7B+PmifAit6wd3cb7jePH58h9X/Lx88OuglOaCSps2rezdu1caN25sm67jJUuW9NgyKkWKFGawlyFDBgkF+sEMpYsJ9jf48R57hz/UkLKifPAvofadSyiOF8cr2D5flA+hd/3gLs53HC8+X/4jvZ+WD36d6FwTlbdu3Vq+/vpruXXrlpn2119/mdxQbdu2tc03d+5cGT58eJyWAQAELsoHAADlAwAEPr8OSqlhw4bJzZs3pUKFCtKpUyepW7euPPfcc9KyZUvbPL///rvMnDkzTssAAAIb5QMAgPIBAAKbXzffUzly5JAdO3bI4sWL5fTp0/LKK69I9erVHeZp37691K5dO07L4P83WRw4cOADzRaDFfsb/HiPQwvlQ+ILte9cQnG8OF58vnyD8iHxcb7jePH58h8p/Pz3WpjFX/r3BgAAAAAAQMjw++Z7AAAAAAAACD4EpQAAAAAAAOBzBKUAAAAAAADgc36f6Bye9/fff8vSpUvl4sWLEhkZKU8++aSEh4fGR+HLL7+Uffv2yZtvvil58+aVYLZ69Wr5448/JFWqVKYzgPz580uwunLlisydO1cOHTok6dOnl/r160v58uUlWNy/f18WLVokf/75pzRq1EgaN278wDx37tyR2bNny549eyRPnjzSoUMHyZQpU6JsL0LD+vXrZeXKlXL37l3T262zzyWcn5t/+OEHadiwoTRt2pRDFMt5b8GCBbJt2zbJnTu3dOzYUdKlS8fxciI6OloWLlwo27dvN+OPPfaYtGjRQpIk4d4zEgflQ/xQPriH8iH4ygf/2hp4XZ8+feSZZ56RI0eOmEDUe++9JxUrVpRr164F/dHXH7cffvihjB071vTKGMwnny5duphg440bN+T27dvSsmVL2bVrlwQj/SwXK1ZMZsyYIWnTppWjR4+a3jY/+eQTCQZbtmyRwoULy+TJk2XmzJmyYcOGB+a5deuW1KpVS0aMGCEpU6aUefPmSZkyZeTYsWOJss0Ifk888YT07dtXLl26ZD5/es5p1aqVOf/ANS17NLgydepUWbduHYfKBb1pVq1aNXn33XclefLk5oZDjRo1TPAdD16c6c2KHj16mO+fDq+//rqZps8Bvkb5ED+UD+6hfAjS8kF730Po2L59uyU6Oto2fv78eUtERIRl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OaXAdM47QTK3FDCn6276wwHz/gNL6o2Y/sqbzlWa5mKK6Lw9//zz+ZHOUaqM7tq1qx8taoXrww/j+rBgrg8N7/oglAIAAACgcJpAAAAAAFA4oRQAAAAAhRNKAQAAAFA4oRQAAAAAhRNKAQAAAFA4oRQAAAAAhRNKAQAAAFA4oRQ0IJMmTYq+ffvGZ599VtuHAkAd4voAgOsDdZFQCuqgDz74IIdLU6dO/U7rff755/Gvf/0rZs6cWWPHBkDtcX0AwPWBhkQoBXXQl19+mcOl6dOn1/ahAFCHuD4A4PpAQ9Kstg8AanMqw69//es477zzYujQoTF+/Pho3759HHfccdG6deu8zMsvvxxnnHFG3HzzzdG06X8z3DQ17vDDD48LL7ww2rZtW97OmWeeGcOGDYvXXnstb+f444+PadOmxWWXXRYTJ06M7t27x4ABA6JZs/n/s/vqq69i4MCB+fmxxx4bLVq0iG7dusWpp56aK6CuuuqqeOKJJ/L4HnvsETvttNN8t3fjjTfG3XffnT/nKqusEhMmTIgrr7wy3nnnnVhzzTXj5z//eay77rrl5c8///xYZpllol27dnHPPffkfe65556x4447VqnIStt46aWXYqWVVor9998/unbt+oO+HwB1heuD6wOA64PfHyiGSikardJUt5/85Cfxn//8J7beeusYMWJElfAlTZ9Ly3z77bflsRTSpLG0fuXtlMKhLbfcMm644Ybo3bt3fqSAZ6uttsoh1kknnbTA41p88cVjl112yc933XXX2HffffOxVVRU5H1ceumlsfnmm8dqq60We+21V1x00UXz3NbFF1+cg60jjjgiB1IpzNpkk03yX9r79OkTs2bNymHZU089VV5n9OjRccopp+RwqkuXLjl0Ssdx7733lpfZYYcd8rnaZpttYtVVV42jjz46nnnmme/8PQCoi1wfXB8AXB/8/kBBKqCRGjt2bEX6J/D3v/+9PDZu3Lg89sYbb+TXDz30UH799ddfl5d5//3381hav/J2rr/++vIyN910Ux675ZZbymNXX311xcorr7xQx/b666/n9d9+++3y2K233lrRvHnzinfffbc8dvnll1css8wyFZ9++mmVY0nHeNppp+X9Pffcc+Xlu3XrVjF48OAq+zrhhBMq+vTpU3699957V3To0KHKZ95nn30qDjzwwPx86tSpeR+vvfZa+f20bOkYAOo714f/cn0AcH3w+wM1zfQ9Gr1UxVSyzjrr5K/vvvtu+fnCShVSJWuttVa1Y1OmTMlVV6WpgN/Fo48+Gj179swVUiU/+9nPcpXSiy++WOVzpOl/Tz/9dF6nNDXvww8/jOeeey6WW265eP7553PlVXqkaXyTJ0+usq9UiVV5mmE6F2PGjMnP0/rps6SqrzRFsUePHtG8efNYdtllv/NnAqjLXB9cHwBcH/z+QM0SStHopUClpBQWVZ6u90O2M69tf59Q6uOPP442bdpUGUtBUNpWeq+ycePGxeqrr56n7JWkXlilqXdrr712leWXWGKJeX6W0rGXzkl6PmrUqLjgggvimGOOyT2q0jTCNFVwzuMDqM9cH1wfAFwf/P5AzRJKwXwsueSS+WvqvVSqHJozAKoJTZo0mWssVSelRuqVvf322zksKlVmldx+++1xyCGHxM4775yblS+99NK5wmqxxRaLFVdcMfr27fuDjm+NNdbIoVSSQqnUn2rw4MExZMiQH7RdgPrC9aF6rg9AY+f6UD3XB+ZFo3OYjzT1LQU5Dz74YH6dprulRuM1bYUVVig3Wi/ZZ599cgXUXXfdVT6Ws88+OzbccMPo3LlzlfVbtWoV9913X3z99dc5mJo+fXq0bNkybyOtk6YnlqQphSnEWlhp3eHDh5dfp0AsNTtPdw0EaCxcH+bm+gDg+lAd1wfmRygFCwiHBg0aFP369ct35evYsWN88MEHNX7OWrduncOk1DMqTY1LQVLa97nnnpuDpXTXu06dOuUqqGuvvTYHZ3MqBVOpyqsUTP3lL3+J9ddfPzbYYIPYfvvtc4+qzTbbLAdcCytVXV111VV5CmC6S+BGG22ULzS/+c1vFvFZAKi7XB/m5voA4PpQHdcH5qdJ6nY+3yWggZo2bVrcf//9seuuu5b7hqR/Dv/6179i6623ztPcSsaPHx9vvfVWDnRSr6ZUKZR6M6Xgp7rtfPrpp/HAAw/E7rvvHosvvni56umRRx6Jvffeu9rpeXNK0/KefPLJeP/99/OxbLHFFnk8vX722WejRYsWOVRaaqml5vuZ0q3N//3vf+dqqg4dOuSx119/PV599dVYeeWVo0uXLlX6pqSG5ul1t27dymMvv/xyfPTRR/m8lKRpe6lyK/1i1r1792qDMYD6yPXB9QHA9cHvDxRDKAUAAABA4TQ6h1pw9dVX56l31dlkk03i5JNPLvyYAKh9rg8AuD7QmAiloBak6W6pb1R1UtNwABon1wcAXB9oTEzfAwAAAKBw7r4HAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUgAAAAAUTigFAAAAQOGEUjCH4cOHx+TJk2vkvNxzzz0xYcIE5xwAAIBGTygFc/j5z38ejz76aI2cl2OOOSZGjhxZq+d8+vTpMWrUqHjggQfigw8+qHaZ2bNnx+jRo2PEiBHx7rvv1otlAAAAqF+EUlCgnXfeOdq3b19r5/ziiy+ODTbYIM4444z4/e9/n4/lpJNOqrLMhx9+GN27d49+/frFkCFDYr311osLLrigTi8DAABA/dOstg8AksceeyyaN28em2yySZUTkiqWllxyyfJ4qvIZM2ZMzJo1K3784x/HiiuuONcJ/Oabb+KZZ56JTz/9NIcZlZd56KGH4uOPP44mTZrEqquuGl26dImll1662m/ClClT4sUXX4xWrVpFjx498joLK62XpgCmACU9SnbddddYZ5118vM333wznnvuubnWTcun4yp9lieffDI+//zz2HDDDWPNNdf8QT8wK620Urzyyivlz5yqpbbffvvYa6+9omfPnnnsuOOOi6ZNm8b48eNjqaWWittuuy369u0b2223Xfm46toyAAAA1D9CKeqENJ3smmuuiddee6089vXXX8fuu++eq2NSKJUCpRRGtG3bNlq2bJkDnYsuuiiOOOKI8jovvPBC7L333jnMWX/99XOQ8cc//jH233///P6///3vvI+Kiop466238vS1f/3rX7H55ptXOZ6//e1v8Zvf/CY22mijHHCl/d955505OJuf//znP/HTn/40Xn755ejWrVsOnjp37hxDhw7NoVaavnfaaafF4YcfHq+//noeL/n222/zPn75y1/mSqCxY8fGHnvskQOk1VdfPYdT++23X/z5z3+uEua9//778z2mdA4XX3zx/DytX1kKupIUeiVfffVVPh+XXnppDoCSFFittdZa8Y9//COHQHVtGQAAAOonoRR1QgqNTjnllBy8pKqk5O67786hRAqiZs6cmXs9HXLIIeWpWynEOvbYY6N37945pEiB0G677RZbb711fq9Zs2YxY8aMePjhh8v7SQFVZX/4wx9yUJTCrMrGjRuXQ69UWfTee+/FxhtvHH/9619zYDQ/qV/UU089FZMmTcrBWZJClRSCzVlpteOOO+ZHyW9/+9tYdtllY+DAgTmQS4FUOrYTTjihXLnVtWvX2GqrrWKfffYph3lPP/30AqcMlkKpZOLEifk8p0qyq666Kvbdd998DpMU4qXzmIK0ytLrVP1VF5cBAACgfhJKUSe0a9cuttxyy1z9Ugql0vNUddS6det48MEH45133olTTz21vE4KqVJvpNtvvz1+/etf52VS4JIqq1IglaTqmp122qnKvlKj7FdffTU+++yzXIWUwo0UfrVo0aK8zKGHHpoDqWS11VaLgw8+OG688cYFhlKpkiqFKKlCqlTFkyq3FiRt+8ILL4z7778/93lKFV1vv/12Pi/Dhg3LoVZ6pKl9acpdKZQ6+eST47tK5zFVaKWQK4Vn6bOl6XGVK6batGlTZZ3ll18+V3/VxWUAAACon4RS1BkHHHBAnH766bkSKvWOGj58eHl624QJE3I4lcKIklR5lPozpfdKYUvq/7TKKqvMcx8pvLriiity5dMKK6yQK7CSqVOnVunXNGcz8rXXXjuHZAuS+hyl6q0UsKVphul1ml7YqVOnea7z7LPPxmGHHZanIm6zzTZ5LAVSqbrp5ptvrrJsCspKPam+z/S9JB1beiSPP/54rixbY4018nKl6YkppKvsyy+/zL29krq2DAAAAPWTUIo642c/+1meupamwKWgJVUulaqcUhiVgojUK6pUBZV88skn5aAqhVZpmVSptMQSS8y1/TQdL919LlVJdejQIY898cQTce+99+YqpMpSFdWcr5dbbrmF+hznnXdenH322XmK3D//+c/cbP35558v92+a885yaZregQcemMOskmWWWSZP4Uu9rUrTAKvzfabvVZZ6aaVz8cgjj+RQKoVvSao4q9yvKb1Od+1L6toyAAAA1E//nbMDdUCaopUClFSRlB5pilopXEp32kthVKqeKkn9htIUrl69euXXqeJnscUWy0FQZelue0kKutJ0vsqVRulObtW54447qrxOU+hK+5mfFDKlhuXpuLfYYov4y1/+kgOm6oKjFJ6lqX2pQis18q4sVUylICn1fKosbTtVdZWk6Xu33nrrfB+laYmpv9YXX3wx17lJAU+q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AAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAAAonFAKAAAAgMIJpQAAAABoOKHU+++/HwcddFCsvfbaseyyy871AAAAAKDxalZTGz7ssMPio48+ikGDBkWbNm1qajcAAAAA1EM1FkqNGjUqXn311Vh99dVrahcAAAAA1FM1Nn1vxRVXjObNm9fU5gEAAACox2oslDr44IPjD3/4Q8yePbumdgEAAABAPVVj0/fuuuuueOaZZ2Lo0KGx1lprRZMmTaq8P2bMmJraNQAAAACNNZTaY4898gMAAAAACgulTjvttJraNAAAAAD1XI31lKqsoqIiPwAAAACgxkOpG2+8Mbp27RpLLbVUtGjRIj9PYwAAAAA0bjU2fe+SSy6J3/72t3HkkUfGySefnBudjx49Og477LD4+OOPY8CAATW1awAAAAAaayh14YUXxg033BB77bVXeaxfv36x1VZbxQknnCCUAgAAAGjEamz63uTJk6N3795zjW+//fb5PQAAAAAarxoLpdZaa60YMWLEXOPDhw/P7wEAAADQeNXY9L3UR6p///4xcuTI6NGjRx574okn8pS+yy67rKZ2CwAAAEBjDqUOPfTQWGWVVWLIkCFxxx135EbnG264Ydx+++2x884719RuAQAAAGjMoVSSwicBFAAAAACF9ZQCAAAAgEIqpTp27Ji/vvTSS+Xn85KWWViffvpp3HrrrTFlypTo1KlT7Lbbbnk64MJ44YUX4pZbbonNN99c1RYAAABAQwylDj/88Gqf/xDvvPNO9OrVK9q3bx+bbLJJDBw4MK6++uoYNmxYNG06/0KvL774IvbZZ5/44IMP4ssvvxRKAQAAADTEUOq4444rP19yySXj6KOPrna5yy+/fKG3edJJJ0Xbtm3joYceimbNmsWAAQPiRz/6Udx8882x7777znfdo446Kvr27RsjRoz4Dp8CAAAAgHrbU+qYY475Xu9V9s0338Tw4cPjoIMOyoFUss4668RWW20Vt91223zXveaaa+L111+P3/3ud9/xyAEAAACo13ffq86kSZNiueWWW6hlJ06cGDNmzIh11123yvh6660Xo0ePnud6r776apx88snx6KOPxuKLL75Q+5o1a1Z+lEybNm2h1gMAAACgDoRSXbt2rfZ58u2338aECRNi1113XahtTZ8+PX9t1apVlfHWrVuX35vTzJkzo1+/fnHWWWdFhw4dFvq4Bw8eHGeeeeZCLw8AAABAHQqlDjzwwPJd70rPS1LV0lprrRW77LLLQm2rZcuW+evnn39eZfyzzz4rvzenG264ITdHT1VWp512Wh5Ljc5TZVV6/fvf/77aBumDBg2K448/vkqlVOplBQAAAEA9CKVOOOGE/HWFFVaI/v37/6BttWvXLlq0aBGvvfZa9OnTpzyeXqdm59VJ1VmlYyhp0qRJLLbYYrn5enpenebNm+cHAAAAADWvSUVFRUVNbfzjjz+O5ZdffoFj87P//vvnhuWPP/54rrQaP358bLTRRjF06NB8Z71k2LBhuVfVwIED5xlUbbPNNnHRRRct9H5TpVSaJpiqtOacPlhfdbquU63te+whY2tt38AP1xD/mwgAADTQu+/99a9/jVNOOWWu8TR25ZVXLvR2zj333Jg6dWr06tUrjj322Nh2221jjz32iL333ru8zF133ZX3BwAAAEAjv/vekCFDYuTIkXONn3TSSbHzzjvHEUccsVDbSX2dxo4dG7fffntMmTIlrrnmmjyVr/I0vD333DN69Ogxz20MGDAg1lxzze/5SQAAAACoN9P3llpqqZg8efJcU/U++uijHDTNmDEj6rKGOFXF9D3g+2qI/00EAAAa6PS9zp07x9///ve5xq+77rro2LFjTe0WAAAAgMY8fe/000/PvZ+eeuqp2GqrrSIVZP3f//1f3HLLLXHHHXfU1G4BAAAAaMyh1C677JIbkP/xj3+ME088MfeA6tatW9x9992xww471NRuAQAAAGjMoVSSGpKnBwAAAAAU0lMKAAAAAGqlUurtt9+O4cOHx8SJE+Obb76p8t5FF11Uk7sGAAAAoDGGUvfdd1/stddeuY/UY489Ftttt128+OKLMXXq1Nh2221rarcAAAAANObpe6eeemr87//+bzz66KP59ciRI3PF1AEHHBDrr79+Te0WAAAAgMYcSo0bNy769euXny+22GIxc+bMWHLJJWPIkCFx22231dRuAQAAAGjModSMGTOiZcuW+fkqq6wSb775Zn7erFmz+PLLL2tqtwAAAAA09kbnJTvttFMcffTRccghh8TNN98cPXv2LGK3AAAAADS2Sqkbb7yx/DxN2VtrrbXinHPOiSWWWCKuuuqqmtotAAAAAI25UmrfffctP2/Tpk1cf/31NbUrAAAAAOqZGquUatq0xjYNAAAAQD1XY8nRiiuuGB9++GFNbR4AAACAeqzGQqkjjzwy/ud//idmzZpVU7sAAAAAoJ6qsZ5S99xzTzzzzDNx0003xdprr50bnFc2ZsyYmto1AAAAAI01lNpjjz3yAwAAAABqNJT605/+FCeccEJ+3r9//1hjjTUW5eYBAAAAaCAWaU+pE088sfy8bdu2i3LTAAAAADQgi7RSatVVV4177703evXqlV9/+eWX81y2ZcuWi3LXAAAAADTWUGrQoEHx05/+NGbPnp1fL7PMMvNctqKiYlHuGgAAAIDGGkoNHDgw9ttvv5gwYUL8+Mc/jtGjRy/KzQMAAADQQCzyu++tsMIK+XHJJZdEz549F/XmAQAAAGgAFmmj88oGDBhQU5sGAAAAoJ6rsVAKAAAAAOZFKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4ZpFPfDNN9/EqFGjYsqUKdGpU6fYaKONFrjOBx98EE899VQ0a9YsunfvHiuttFIhxwoAAABAAwilPvnkk+jdu3f+2rFjx3jkkUfi0EMPjYsuuqja5SsqKvL7DzzwQHTt2jW++uqrGD16dPzpT3+KY445pvDjBwAAAKAehlKnnHJKzJgxI8aOHRstW7aMJ554IjbbbLPYaaedok+fPtWGUltvvXVceeWVuUoqufrqq+Ooo46KHXfcMdq3b18LnwIAAACAetNTKgVMQ4cOzZVPKZBKNt100/z45z//We06TZs2jf79+5cDqWTXXXeN2bNnxyuvvFLYsQMAAABQTyulJk2aFJ9//vlcPaTSNL5nn312obdz77335rAqrTcvs2bNyo+SadOmfc+jBgAAAKBeV0qlQCpZdtllq4wvt9xy5fcW5I033ohf//rX8ctf/jLatWs3z+UGDx4crVu3Lj/atm37A48eAAAAgHoZSi211FL56/Tp06uMf/HFF+X35mfixImx/fbbxzbbbBPnnXfefJcdNGhQDrpKj1SlBQAAAEAjnL6XKpsWX3zxmDBhQpXx9HqdddaZ77opVEphVLdu3XJfqso9pqrTvHnz/AAAAACgkVdKLbHEEtG7d++46aabymNTpkyJBx98MH7605+Wxx5//PG44447yq8nT56cA6kuXbrEzTffnIMtAAAAAOqOJhXpFnd12EsvvRS9evWKPn36RM+ePePaa6+NpZdeOkaNGlUOmw4//PAYM2ZMXnbmzJnRuXPnPAXvrLPOqhJIpe2st956C7Xf1Og89ZZK22nVqlU0BJ2u61Rr+x57yNha2zfwwzXE/yYCAAC1q05P30vSHfNeeOGFuOaaa2L8+PFx1FFH5RBqzrBplVVWyc+/+eab2HzzzfPzxx57rMq21l577YUOpQAAAABoxJVStaUhVgWolAK+r4b430QAAKB21emeUgAAAAA0THV++h4NnwouAAAAaHxUSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIUTSgEAAABQOKEUAAAAAIVrVvwuG75O13WqtX2PPWRsre0bAAAAYGGplAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAArXLOqJSZMmxZQpU6JDhw7RqlWrGlsHSjpd16nWTsbYQ8b6RgAAANCg1flKqZkzZ8bee+8d66+/fhx00EGxyiqrxCWXXLLI1wEAAACgOHW+UurMM8+MJ598Mt58881YddVVY9iwYbHnnntGjx49YtNNN11k6wAAAABQnDpfKXXttdfG4YcfnsOlZI899oiOHTvm8UW5DgAAAADFqdOVUu+9917uCdW9e/cq46ni6bnnnltk6ySzZs3Kj5LPP/88f502bdp3Pu7ZM2ZHbZnf8TquhnG+oDZ/JisqKnwDAACAhh9KffLJJ/nr8ssvX2U8vS69tyjWSQYPHpyn/c2pbdu2UZ+0PqZ11EWOq2GcL/jiiy+idWs/nwAAQAMPpRZffPFy4/LKZsyYEUssscQiWycZNGhQHH/88eXX3377bQ6xUpjVpEmTaOwVEimcS3czdBdD58vPV+P895gqpFIgtdpqqxW2TwAAoGGr06FU+sWradOm8e6771YZT6/btWu3yNZJmjdvnh+VLbvssj/o+Bua9AuwUMr58vPVeP89qpACAAAaTaPzFi1axOabbx533nlneWz69OkxcuTI6N27d3nsjTfeKPeLWth1AAAAAKg9dTqUSs4666wYNmxYnl6XgqZ0J72VVlopjjzyyPIy55xzThx00EHfaR0AAAAAak+dD6W23nrreOihh+Kdd96Jiy++ODbaaKN49NFHo2XLluVl1ltvvdh4442/0zosvDSt8YwzzphreiPO16Lg58v5AgAAGqcmFe7vDQAAAEDB6nylFAAAAAANj1AKAAAAgMIJpQAAAAAonFCK+Uotx95444145ZVXYtasWc7WQvrkk09yc/2JEyc6Zwvw1VdfxXPPPRdTpkxxrhbiXL300kv5kZ4DAADUZ0Ip5umyyy6LtdZaK3bcccfYY489YrXVVovrrrvOGVuAb7/9Nvbee+98F8grrrjC+ZqPc845J1ZeeeU4+OCDY/PNN48jjzwyZs+e7ZxV49JLL41VV1019tlnn/xIz9MYAABAfSWUYp6mTp0ajz/+eK6UGj9+fJx77rlx2GGHxdixY521+TjrrLNi+eWXj/bt2ztP83HxxRfnc3Xffffln6k333wzevbsGf/5z3+ctzmkiruBAwfG+eefH+PGjcuPIUOG5DHVeAAAQH0llGKeTj/99Fh99dXLr1Mg1bRp0xg9erSzNg+jRo2Kq6++WoXUAqTg6Q9/+EP86le/yhVSJYceemgstdRSfr7m8NFHH+WptJtttll5rFevXnns448/dr4AAIB6qVltHwD1xwsvvBBff/11rLvuurV9KHW2j9SBBx6YQ6nllluutg+nzv8spTBl1113jQ8//DAmT56cK8vatGlT24dWJ2288cbRr1+/+MUvfhEnnHBCDqPOO++82H///aNbt261fXgAAADfi0opFkpqqpyqWLbYYovYdtttnbVqpEqyn/3sZ7H99ts7Pwvw3nvv5a9Dhw6Nzp0755+t1LPsqKOOyj25mNvRRx8d7777bg6lTjzxxHj//fdzDy4AAID6SqUUC5TuurfXXnvF9OnT45577okmTZo4a3P45z//GY899lgMGDAg33UvmTlzZkyaNCn35ao8RY2IxRdfPJ+GdFfHCRMmxJJLLpnvKLfpppvmkCpVBPH/vfzyy9G7d++49tprczVecv311+ex559/PjbccEOnCwAAqHeEUiyw908KpN566614+OGH853SmFuaTtWhQ4c444wzymNpetpDDz2Up6Y98MADTlsl6a6OSf/+/XMglXTs2DFX4qW+XEKpqu69995o0aJFOZBKDjrooByCpveEUgAAQH0klGKBgdTrr7+ew5U0vYrqHXDAAflRWeq9te++++Y7zFHVBhtsEO3atcvT0SpLr1O4R1UrrrhirlT89NNPy323Ug+zNJbeAwAAqI+EUsxTClQeeeSR3Lj77bffzo8khQnpAd9XmgI6ZMiQ3CcpVQCts846cfPNN+epfKqk5rb77rvHGmusEbvttlu50fn5559fHgMAAKiPmlSk326gGtttt13uJzWn1JQ6PVhwqJfO4RFHHOFUzcP999+fQ89UAbT++uvHcccdlwMq5jZ16tS4+OKLcw+pFOp16dIlfvWrX6mUAgAA6i2hFAAAAACFa1r8LgEAAABo7IRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRSAAAAABROKAUAAABA4YRS0IB8/vnnMXTo0Jg5c2ZtHwoAAADMl1AK6qAvv/wyh0vTp0//TutNmjQp9ttvv/jss89q7NgAAABgURBKQR30wQcf5HBp6tSptX0oAAAAUCOEUjRalae6vf7663HXXXfFSy+9VGWZDz/8MC9TUVFRHkvLp7G0/pzbGT9+fAwfPrzKdp577rm444474u23316o4/r6669jxIgR+XnaVtr2I488Un5/8uTJeXv//ve/46uvvlrg9iZOnJi3MWXKlCrHNGzYsPz122+/rbL8Y489Fk8//XSu1ho1alTez7Rp0+ba7ltvvZXP2ZNPPpmPGQAAAL6LZt9paWhASlPddttttxwYtW3bNh5++OH41a9+FX/84x/zMuPGjcvL9O3bN5o1++8/lzQ1Lo2NHTs2WrduXd7O1ltvnQOqlVdeOUaOHBknn3xyDqdSiLT88svnYOmGG27I25qfFPCkICi5//77Y+mll46uXbvm7Z977rlx5plnxmabbZarqFLQlAKqnj17VruttP8+ffrEAQccEPvuu298+umnsddee+XP26VLl3j55Zfz8d555535GJMLL7wwB1npc6677rr5eVrv0Ucfjfbt2+dlBg0aFH/5y19iyy23zO/NmjUrbr/99nwOAQAAYGGolKLRW3PNNePFF1/M1Uk333xzDBky5HtNm0vBUao8uvfee+Occ86Js88+O370ox/lqqP77rsvh1Snn376ArfTokWLuOiii/LzSy65JFc5pXVTCHbKKafELbfcEg888EA+5l122SUOPfTQ+Oabb+bazuOPP56DrOOOOy5/pmTAgAGxwgorxBtvvJHDrFdffTVatWoVp556apV1U8VXOua777477yeFTaVjShVUKRxLnzNVSqXKquuuuy5mzJjR6H+WAAAAWHhCKRq9o48+unwOttlmm5g9e3a8+eab3/m8HHXUUeXnqZKpurE0TbDyVMDvIgVmHTt2zEFUSQqTXnnllRwcVZYCox133DHOO++8OPHEE/NYapqetpGCsjR1L4Vbt912W7Rr1y4eeuihKuun6qpSVVTTpk1zRVQKqpLFFlssllhiiRySlT7LRhttFB06dPhenwsAAIDGyfQ9Gr3llluufA6aN2+ev6b+UN9VmzZt5trOnGOpoimFXqWpgN/FO++8E2uvvXaVsRQcpdAovbfxxhuXx4899tjYfffdcxVVybvvvpv3/8wzz+RwrLIttthinuekdOylc7LUUkvlyqiTTjopV36laqw0PTBNgwQAAICFJZSC+UiBT1K5Gfj3CawWhTTtLoVPlaW+T+nY0nuV3XjjjXHwwQfn3lhpyl+SpumVpvDtvPPOP+hY+vXrlx9p+l+a9rj//vvHBRdcEEceeeQP2i4AAACNh+l7MB+rr756/pp6MJXMOdWtJrRs2XKuACxVM40ZMybee++98liagpfCps6dO1dZf9NNN809oVLvp8GDB+exVVZZJTc3v/zyy+faX6qiWlipp1TpbnxpKuBvfvObPN0vHRsAAAAsLJVSMB/rrLNO9OrVK1cdpd5TqVLpH//4R42fs3RHvNRc/KyzzspVTSkcS3fNS8HUT37yk1ztlJqxpwbm6ZHuAjindEe+Um+pJk2a5GbpV1xxRQ6Q0mPPPffMAVO6w1/37t3L4dWCfPLJJ/kY0vobbrhhTJgwIe65554ckAEAAMDCUilFo7XsssvmKWipR1Ll6XppbKWVViqPpTvQpQBm9OjRscwyy+RKqbRMWn9e20k9mdJYaghekraZxkpTAucnhUip0ilVN6XpcWnfpWNJd9NLfaE++uijuPPOO2PgwIHz/EypuXoKpl544YV49tlno0ePHjFu3Ljc0D1t88MPP8xhVeVAKgVfP/7xj6scT6rESkFUkhqjP/HEE/nYRo0ale+698gjj1RpwA4AAAAL0qTi+94KDAAAAAC+J9P3oBakqqXXXnut2vfSVL0tt9yy8GMCAACAIgmloBak6XRpel51Nt54Y6EUAAAADZ7pewAAAAAUTqNzAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAAonlAIAAACgcEIpAAAAAKJo/w8XfchFn/zUpwAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import math\n", "\n", @@ -697,21 +271,10 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "ef9d6da8", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABKQAAAN2CAYAAADHclF6AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3QeYU8X7//2h915FmvRepSNIFSmKFEWpoiBFEAFRrIAFUFEBERRQUWxYaYooAgICgiLSy1d6772T5/rM/zn5JbvZ3exuNpvsvl/XFdmcnHNycnadydwzc08Kl8vlMgAAAAAAAECQpAzWGwEAAAAAAABCQAoAAAAAAABBRUAKAAAAAAAAQUVACgAAAAAAAEFFQAoAAAAAAABBRUAKAAAAAAAAQUVACgAAAAAAAEFFQAoAAAAAAABBRUAKAJCsPf744yZz5swmFOzfv9+kSJHCTJkyxYSDjRs32uudOXNmwM+t8z7zzDOJdm98vV9Cft7YXEewHThwwGTKlMn89NNPyepzh7Ldu3ebdOnSmSVLliT2pQAAEGcEpAAAYeebb76xjVV/Hlu3bk3syw1rO3futPdx2rRpJhyFw/WH+jUOHz7cVK5c2dx9991hc81JXdGiRU3Pnj3Nk08+aW7evJnYlwMAQJykjtthAAAkng4dOhiXy+W1LXv27KZKlSqMGEiiChYsGOl3npTeL1SvY8+ePeazzz4L6qiwUPjc4aB///52BJlGrrVq1SqxLwcAgFhjhBQAAAB8mjp1qsmYMaNp27YtdyjEVKhQwY5cY1ojACBcEZACACRZyq/SuHFjkyVLFtuorlmzpvn6669jPG79+vWmUKFCplatWubIkSN229WrV83LL79sypYta3O35M6d23Tu3NnmuvGVY+jLL780pUuXNunTp7cjt3777bc4f46EeG8de//995ts2bKZHDly2Ok/58+f98rd9Ouvv5qSJUvan3v16uWeBjl06NBI54vr5z148KDp1KlTpOvwJ6eQRtC8+eabpnz58jbH0a233mrat29vNmzY4Nf1e96zTz75xN7f1KlT2+NiymE0ffp0U7x4cft5b7/9drNw4UKv1xcsWGCPj5jj5/r163b7888/79c1RnUdJ0+etCNkNJIobdq0pnDhwmbQoEHm7NmzAf17nDt3rqlTp47JkCGDe1t87qvz+Z2Hrl33UdMC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aqkR0Lx5cztK7MCBA2bKlCnmpZdeMu+//37A9wEAGFO/fn3jcrls8D6xOiv69etn6tWrZ3r06BHlPpoBcunSJbN161azdOlS8+uvv5rHHnssUfZBiHIBIe7dd9913XLLLa4bN254be/YsaOrXbt29ucrV664nnzySVe+fPlc6dKlc9WoUcO1ePFir/1v3rzpevPNN10lSpRwpU+f3lWrVi3XihUr3K8/8sgjLv0voUeuXLlcrVu3du3cudPrHA0bNnT16tXL1aFDB1fu3LldOXPmdA0fPjzStUVl/vz5rqpVq7oyZszoKlmypL0e59hWrVq5nnjiCfuzrt25Fs9HkyZN3J/ljTfecBUrVsx+lnLlyrmmT5/uCoRr167Z9/riiy8ivabPr/vuqUqVKq4ePXrEah8AiK9//vnHllXbt2/32j5+/HhbZ1y/ft0+nzJliqt48eKuNGnS2H/1PKI5c+bYekPlqcrmDz/80P3aRx995C6DM2XK5KpZs6Zr0aJFXsc/99xzrrp167qGDh3qKly4sC3jVQ6eOnXKr8+yZcsWV7NmzVxZs2Z1FShQwNW3b1/XmTNn7GujR492Va9e3at8jvhQvef5WapVq2a3FSlSxPXMM8+4Ll265AoE1Zv9+/ePtF2fX9etusnx+OOP2/o20PsAQHSuXr1qv8d7luPy119/edUZ+q6tcl9lpdoPgwcPtu0JTxs2bHC1bNnSlSVLFlf+/PldTz/9tOvy5cv2tR07drjLYNUvZcqUcb333ntex//000+uVKlS2e/oZcuWtXVMnTp1XBs3bvTrl6h6oFu3bq48efK4smfP7mrTpo19X1m2bJl9b6d8V/nsq35Ys2aN+7O0aNHC1mM6X6dOnVwHDx4MyB/TkCFDXJUrV460XZ9f1+DZnvryyy9dKVOmdL93MPdBaGKEFELeAw88YI4fP25+++0397azZ8+auXPnmi5durh7kL/77js7reDQoUPmrrvustML9u7d6z7m2WefNWPHjjVvvfWWOXr0qJkwYYL57LPP3K9PmzbN9jTosXHjRpMvXz47skcRd0/qKa5du7bZuXOn+frrr+2IonfffTfGz3HmzBnTvn1706tXL3Ps2DHz888/2+vYtGlTpH3VO+xcix6K9GfLls00adLEvq4e4xkzZthpdSdPnrTvP2zYMPPNN9+4z6F7oql30T00/9xfN2/eNKtXr46UJ0XX9Mcff/i9DwAEQuXKlU2FChW8ynHR8wcffNCkSpXK1gvKzffaa6/ZeuTVV181TzzxhPn++++9RnW2a9fO1icaofPjjz+a33//3Vy4cMG+rp5fpyw+ePCg6dq1q7nnnnvsvp5Uxqn++fPPP83ff/9t6wiNFvWHRpIWKVLE/Pfff3Y0qaY+qD6LSLlIPOsGTbWuVKmSu25QvhKdS3XEiRMnzE8//WR++eUXWx94ft6Y6gblrYoNffaGDRvaYx26Jt0D1XeB3AcAopMmTRrTsWNHn3WDpgMrpYTaB2on6KFye/bs2fY7/fDhw93779mzx9xxxx2mQIEC9ru6yuYcOXLYUaNSokQJd1l87tw5265QW0PtE09qR0ycONHWRzpnsWLFTKtWrczVq1dj/EVqtsG2bdtsvbJv3z7Tt29f88knn/jcd9WqVV71Q/fu3W29Urx4cVtfqWxVearzbNiwwdYnmt6m7+5y+vTpGOsGjUCKDZXphQoVstfg0DXoPXW9wd4HISqxI2KAPzR6yHOEjXqsc+TIYXsyzp8/70qbNq3r888/9zqmQoUKNmIv586dsz0g06ZN8/uGX7hwwUbVN23a5DX6Rz0bntR7rV7omGzbts1G7g8cOBDlZ3RGSHk6ffq0q1SpUnZUlnqNdV0ZMmSINALshRdesD0fCTVC6sSJE3b7rFmzvLaPHTvW9ur7uw8ABIrKX8/RM06P9d9//+3uMe7Xr5/XMY899pjd7tCIp9iO4NSIpffff99rZI96nZ1RTU7vdYoUKVx79uyJ8Xzqrf7qq6+i/IzOCClPqg9UL6h+UD0hGqX18ssve+33888/2979hBwhpZ7/gQMHem3TCGT9Lv7999+A7gMAMVH5q+/wznduzUbQ6MsJEybY52ofVKpUyeuYTz/91LYn9D1bNGKqdOnSfs+CEH2P79q1q/u5M2pn6dKl7m1nz551Zc6c2edMhIjuu+8+14ABA6L8jJ4jpDy99dZbdqSuRhLLsGHDXHfddZfXPmob6R45+yTECCnNKtGI3Yh1l0aNOaPJgrkPQhMjpBAW1HOtngVnJQn1cqj3I23atOZ///uf7WWoVauW1zEaxbR582b7s/69cuWKadCgQZTvod4CRf7z5s1rE7dmypTJRtU9R1lJxBwaNWrUsD0eTm96VNSTotwY6p0ZOnSoTfQd08oYen/19GfIkMF8/PHHtndCvTSaH920aVPbu6FRALrel19+2fauB5t6YTx7s+O6DwDEVufOnW0doN5jp24oV66cqVq1qrvsj1g31KlTx2zZssX9fN26ddHWDRpppJGtBQsWtGWuyrK//vorUt1QqlQpkzVr1kh1hUa4xqR///7mkUcesQ99Br1nTF555RU7+kkjqTSCVnRdGh3lWTdoxLB674M9wkjlvkRX9gdqHwDwpLxGWhTBWaBn8eLFdlaCZl1EVzeoPaERmU7doPOoHI3qO7q+e6vsVx4nlVHjx4+PVDdEbDtkyZLFlClTxt1GiY7qBOV41ajc9957z6/v+cqbpFkTmkmhkcSiPIQLFy70qht0HfoMidF28LdMD+Y+SDwEpBAW7r33XvulVMNgNbRWFYszXc/5shpdECSmL7QqkFu2bGmKFi1qC20Fr65du2YL7evXrwekUFPhr+kUn376qV19TsOCNWw4usaKplloBQsNJVaAzLlWUUWma9NQYG3TZ9Sw3oSaspc9e3Zb4UZs1Oi5pjf6uw8ABIqG52tKhTM14/PPP3fXDVHxVWdEV65rioQaKCq/NV1cx6uRElPdoOdR1U8RKYikaSClS5e2q5RqmoU6YaKiOmHUqFHmiy++sMc4VBdoWnnEukGPPHnyJNiUvfz58/ss98Up+wO1DwDEROXYQw895K4b9K86hdXpLL7K5ohthZg6U5UuQwsuKOWHgl3a/+mnn45UN8SHpvbt2LHD/qsk3Zqm/txzz0W5vzpo7r//ftvG6NChg3u76gJNP/dVNyg9SUJN2fNVpqvDRdcQXbmfUPsgNBGQQljQCCEVmKpQ1NuhnmqtLuGMPNJIKaeH3KHnZcuWtT+rx1xBIOUF8UW9GZpfrZFL6lHR/HPlAImYP0oUIIr4XMc4AaPoqDBv1KiRzWOyfv1620DQyCdf1LDSqnvffvutbZw4nM+i3CDRUYPCcy65r4dzD/0NqKk3ScFAT8rtVbduXb/3AYBAUgDqq6++sgEdfXFXI8SzvIxYNyjPnVM3iEZTRVU3OHkp1EuthoCWttZoWF+5/9QhoJFInnWDynz1hPtD51evtnq3H374YZvv0Bd1RiiPlfJiKf+JJ32WmOoGNShiqhs8c075Q+W7GkuejTyV+6qfnUBYoPYBAH/rBn2X10gnBfg9OyvKly/vs25Qe8LJQVStWjWzYsUKd0ewr7pB5alG2DqjYyOe0+G5UqrqCXVGe9ZD0VEOK60Up3pOHRavv/66z6CXzqsOfF3PyJEjvV7TZ1FZGl3eKnUqx1Q3qEMjNlSmK2eVAmUOXYfaC5rJEux9EKISe84g4C/lwdDcbq1i8eyzz3q9phX2brvtNruShFY1evHFF+1KFp65OzR/WqtozJs3z87fXr16tTu3iFbMyJYtm+v555+3Oak0n1pzy/W/yNy5c71ySGmbVsdTzo7ffvvNruTx9ttvx3j9y5cvd/Xp08e1fv16O99bOU7y5s3r+uCDDyLlkNI+yhM1efJkn+dSvhJdr1aPUM6S3bt329UIX3vttQRdZU/3InXq1K6ZM2e6Tp48aVf608oi69ati9U+ABAoKvOVI1D5Kxo0aOD12rfffmvL0q+//tqWlcpvp7rhu+++c+8ze/ZsW0ZNnDjR5sHTCj0PP/ywrQtEq5uqfD527Jhr//79dvU8lZFabcmzTNa2zp07u44cOWJzBmpF1fbt28d4/VoNUPn/lixZYnN67N2711WvXj27slLEHFKqu7RSoN4nqpVclRPklVdecR0+fNh19OhR+1kDtcppVDmkdM3KifLUU0+5jh8/bq9D+Us8VzQM1D4A4C+Vw6obVK44uaFE35tVF4wcOdLWIX/++afNB6u8UY5du3bZ/Ke9e/d27du3z5btyonq5HB96aWX7GrXKu91jldffdXWAyq/I+aQ0nVs3brVnkPlt1Zjjbiiny9aAVz1l+ofvYdWYNV7+sohpZXHlT9X9UhEag8p9+7999/v+t///mfrkt9//93Wbc6qgQmRQ0r1m7Y3b97c3kOtLqg6rEuXLomyD0ITASmEDRU0Wspbhe/mzZu9XlNhqqCUAjwKWmkZ14hJv5WUUF/sFbhSJVS7dm3XH3/84X59wYIFNqGqGiZFixa1S4erkRMxIKWkeWpk5M6d2xbuCnT5k/BQgR4FmBToUgNJ1zFixAj38taeASnt52vpVjWMRMcoMaOuV59X51IiWDU+4sqpNCM+lADYk5bRdZZQV8WnAF9E/uwDAIGixK8qr5wAvyeVpyqPFCjXv76CGwraqMGgMl9JbLVwhkNLhCvQpXpDycfVkaEGR8SAlBa8GDp0qKtQoUK2jFc9oQCXv+Wv6hc1mtRxogCSAvoRA1JatttXOa3r9jyXkpvrGlQnKvG5josrNW58vWf58uUjJR9X3as6qWDBgq7XX3890rkCtQ8A+GPcuHG2vHIC/J7UTnDKGpWVakdEDBKpg1oBDgXGlRT9mWeece+jTouHHnrIBq1Udrdp08bVs2fPSAEpJdXWokrqUHfaH/4u0qCFldQJojZH9uzZbWJypzyPGJBSR7Wvslqd9bJlyxbXvffea/fTNavOUdA/PhQA8vWeCp45FBy655577D1Uu0kBPqfDJzH2QehJof8k9igtAAAAAAAAJB/kkAIAAAAAAEBQEZACAkQJCqNbmWL37t3cawBIhnLnzh1l3TBz5szEvjwAQCJo27ZtlHVDnz59+J0gWWDKHgAAAAAAAIKKEVIAAAAAAAAIKgJSAAAAAAAACCoCUgAAAAAAAAiq1MF9u/Bx8+ZNc/DgQZMlSxabWA4AkgqXy2XOnTtnChQoYFKmpF8iPqgrACRl4VpfzJ4926xYscJ+j7///vtN6dKlo91///799pi9e/eaYsWKmU6dOpls2bLF+7yeqC8AJGWuONYXJDWPpmIqVKhQoH4/ABBy9u3bZwoWLJjYlxHWqCsAJAfhVF/06tXLzJ071/67Z88eM2vWLPPjjz+axo0b+9x/+vTpZsyYMeauu+6y3/1//vlns2HDBht4KlWqVJzPGxH1BYDkYF8s6wsCUlE4c+aMyZ49u72hWbNmDdTvBwAS3dmzZ+2X7tOnT/vsAYb/qCsAJGXhVl+sXr3a1K5d2waT6tata7f17NnTrFq1ymzevNnnMVu3brWjotKmTeseyaRzFC9e3HzxxRdxPm9E1BcAkrKzcawvmLIXBWeanoJRBKQAJEVMRw7cPaSuAJCUhUt9oSl1RYsWdQeNpGvXruajjz4yO3bsMCVLlox0TJkyZbyea6pJ2bJl7fS9+Jw3IuoLAMlBiljWF+EzGRwAAAAAoqDgkEY7eXKe6zV/HDt2zMybN880bNgwXue9cuWKHTHg+QAAeCMgBQAAACDsXbp0ySYc9+TMdLh48WKMxyuI1LFjR3PLLbeYp556Kl7nHT16tJ224jzITQsAkRGQAgAAABD2MmfObPOXeDp16pT9N6YUHFevXjUdOnQwBw4csInNM2XKFK/zDh8+3OaNch7KSwsA8EZACgAAAEDYK1++vNm2bZtdftyxZcsW+6/yQkXl2rVrdmSU9l28eLG59dZb433edOnSufMLkmcQAHwjIAUAAAAg7GmE09GjR813331nnyuANHnyZJuM3Jkyd/z4cfP444+bTZs2eQWj9HzJkiU+lyv357wAgNhjlT0AAAAAYU+jlV577TXTrVs38+WXX9ppcrt27TKLFi1y76Opd5MmTTItWrSwI59GjBhhV9Fr27atGTNmjHu/PHnymJdeesnv8wIAYo8RUgCAkHf+/HnTq1cvkzNnTpvLo127dubgwYNR7n/9+nXz8ccfm9q1a9v9tVz3kCFD7Hk8lShRwi5P6/kYNGhQED4RACAhPP3002bNmjU24DR48GCzfft2U6FCBa9A08SJE93bmjZtap83adLElClTxv0oXrx4rM4LAIi9FC7PydBw09KsWhFDSQhjSoIYUcUZFUP2Tm7oviGxLwFAGJdvieXBBx8069ats9MltNJR9+7d7fWrcZAyZeS+FfVaf/bZZ+axxx5z5/7o1KmTqVq1qpk1a5ZXQGro0KGmT58+yeZeJkZ9Rd0DhKdwL+NCCfcSwaqPqXMRTmUcU/YAACFNUyO++uor88MPP5hy5crZbe+++64NNCn5rHq1I9I2z+3Vq1e3Kx4p8KSVlNKmTRvUzwAAAADAG1P2AAAhbeXKlTaB7J133unepsBUvnz5zB9//OH3eY4dO2YyZsxo0qRJ47VdgSqthqTRUpqSceHChYBePwAAAIDICEgBAELa4cOH7YimiMN/8+bNa1/zd5TVG2+8YR599FGbJ8qhXCALFy40J06cMB988IGdzte1a9coz3PlyhU7JNnzAQAAACD2CEgBAEKeZxDJoVFTvrZHpGBTy5YtbfLZV1991es1Tf2rUaOGTXzeuHFjm9j2+++/N//995/Pc40ePdrOj3ceLPcNAAAAxA0BKQBASMufP797ZFLEKXiathedkydPmmbNmpns2bObefPm2al50alY8f8lFd2xY4fP1zW9T8kanYdGXgEAAACIPQJSAICQVqdOHTsSSgnMHVu2bDFHjhwxdevWjfK4U6dO2WCU8kb99NNPdhRUTDZs+H8rkRYoUMDn6wpoaeqg5wMAAABA7BGQAgCENE2Lu//++80zzzxjA1EaldSvXz9TrVo106hRI/d+RYsWNYMGDbI/a/RS8+bNbTBqwYIFPoNRv/zyi3n22WfNtm3bzMWLF23Aa8CAAXZ1PmekFAAAAICEQUAKABDypk2bZurVq2dHRJUpU8ZOwZs7d65JmdJ3NaYRUWvXrjXLly83WbJksSOsnMfu3bvtPg0bNrSJ0du3b2/y5Mlj+vTpYzp37mx++OGHIH86AAAAIPlJndgXAABATDTCSUEpPaLiBJqkU6dO9hEdrdynEVXOqCoAAAAAwRMWI6S0DLd6xkuUKGHuu+8+O2UjOko6W7BgQa9H06ZNg3a9AAAAAAAACOMRUlp+W1MotBS3EtuOGzfOTrPYtGmTnWIRVSLbypUrm/fff9+9LU2aNEG8agAAAAAAAITtCKmXX37ZdO/e3eb2UJDpww8/NC6Xy0yePDna4zJkyOA1QiqmpcEBAAAAAAAQHCEdkDp79qxZt26dXbbbkTp1arsC0u+//x7tsUuXLjWlSpUyNWrUMIMHD7ajpgAAAAAAAJD4QnrK3oEDB+y/+fPn99qu0U7r16+P8jhN5Rs1apSd2qdzKKeUclD9/fffJn369D6PuXLlin14BsMAAAAAAAhnFWdUDNi5NnTfELBzASEdkLp586Z7VJQn5YO6ceNGlMcpGKWlvaVcuXKmQoUKpkiRIubLL780PXr08HnM6NGjzciRIwN6/QAAAAAAAAizKXtO0vLjx497bdfzqBKaixOMctxyyy02IBXd6nwaRXXmzBn3Y9++ffG+fgAAAAAAAIRZQCpv3rw2kLRixQqv7cuXLzc1a9b0+zyXLl0yhw4dMjlz5oxyn3Tp0pmsWbN6PQAAAAAAAJDMAlLSv39/M336dJszSlP4JkyYYPbu3Wt69+7t3mfYsGGmadOm9mflgRowYIA5ePCgfa7RTr169bI/d+rUKZE+BQAAAAAAAMIih5QMGTLEjm6qXbu2SZUqlR25pFxQZcuWde9z8uRJc/jwYfdIJ+WMql+/vl1ZT6OjatWqZVfd02grAAAAAAAAJK6QD0ilTJnSvPXWW2bMmDF2tFPu3Lkj5Yh64403zNWrV93PH3vsMfvQ/pkzZ7aBLAAAAAAAAISGkA9IOdKmTRtlIvMcOXL43J4tW7YEvioAAAAAAAAkuRxSAAAAAAAASFoISAEAAAAAACCoCEgBAAAAAAAgqAhIAQAAAAAAIKgISAEAAAAAACCoCEgBAAAAAAAgqAhIAQAAAAAAIKgISAEAAAAAACCoCEgBAAAAAAAgqAhIAQAAAAAAIKgISAEAAAAAACCoCEgBAAAAAAAgqAhIAQAAAAAAIKgISAEAAAAAACCoCEgBAAAAAAAgqFIH9+0AAIibs2fPmiVLlpirV6+a+vXrm/z588d4zNatW83GjRtN7ty5Te3atU369OkDcl4AAAAA8UNACgAQ8latWmVat25tihUrZrJkyWJ69OhhPvroI9OxY0ef++/Zs8d0797dHDlyxJQvX95s377dnDx50nz77bemVq1acT4vAAAAgMBgyh4AIKS5XC7TrVs306ZNG/Pnn3+aRYsWmWeffdY8+uij5tSpUz6PuXTpkhk1apTZsmWL+eabb8z69etNw4YN7Xnic14AAAAAgUFACgAQ0tasWWN27NhhnnjiCfe2fv362aDTvHnzfB5TpkwZ06BBA/fzFClSmFatWtmRUleuXInzeQEAoe3gwYOma9euduRr5cqVzbhx42wHREzTuwcNGmQKFy5sHnrooUiv79u3z07njvj49ddfE/CTAEDSx5Q9AEBIUw4oKVeunHtb9uzZza233up+zR8LFiywgap06dLF+bwKZjkBLSf/FAAgNFy7ds00a9bMFCxY0Hz//fd2+raCU5cvXzbPPfecz2MOHTpk7rvvPtO7d28bwNL07ohu3Lhhp4CvXLnSFC1a1L09R44cCfp5ACCpIyAFAAhpZ86cMRkzZjRp06b12p4zZ077mj+++uor89lnn5kffvghXucdPXq0GTlyZJw+BwAgYSlPoEY7LV682OTNm9cGmBSIeu2118xTTz0VqbyXfPny2end8tdff5njx49HeX4tkMHCFwAQOEzZAwCEtAwZMtje7Zs3b3ptP3funH0tJj/99JNNcP7222/bfFHxOe/w4cNtsMp5aBoHACA0/P777zYIpWCU46677rLltXIJ+pIypf/NIS2CUbx4cdOiRQs76hYAED8EpAAAIU1f/hU02rt3r9e0DOUJ0WvRUYOhXbt2dmTTwIED431eTffLmjWr1wMAEBoOHDhgRzx5cp6rbI+Pzp07m+nTp9scg3fccYfNS/j5559Hub+md2tat+cDAOCNgBQAIKTVr1/fZMuWzU67c8yZM8cmH2/ZsqV7m1bT02p5joULF9q8IJqq8eSTT8b5vACA8KDk5alTe2ckcZ4rD1RcFSlSxMycOdPUq1fPlC1b1k4DfOSRR6Kdwq2OENUxzqNQoUJxfn8ASKrCIoeUhtl+9913Nplg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t2xQSatT5M6dO9K86zfeeMNcvXo1VseEAw3zfemllyIN9w0nfIbQkBR+D0nlcySFz5AYNB17wYIFdm66GhNqHES0atUqkyFDhlgd488++D/J/e83uX9+4R5wD0KdOqSV7+nEiRO2TtDIJk+33XabzaGi9oG/x/i7T1IW7v/vc/2Jj98B99+XFK5wWccVAAAAAAAASULIT9kDAAAAAABA0kJACgAAAAAAAEFFQAoAAAAAAABBRUAqBN24ccPMnj3btGjRwmtZ2nCilaqeeOIJU61aNVO1alXTt29fu6JJODl//rwZPXq0qVevnl2hsW3btub333834eqLL76wf0+PPfaYCSfvvfeevW7PR+nSpU240d/TCy+8YP9/qFy5sv3bUhJtINRpJaqJEyeaxo0bmzJlypjWrVub3377zSRXEyZMsOWQ/n9ObpYuXWratGljSpYsae655x6zYcMGk5zMmDHD3HnnnaZEiRI2wbXK8WvXriX2ZQEJRqmGf/jhB/v/u7576e9/2rRp5ubNm2F51/UdWOW3vhOHk2PHjtl2VYUKFUyNGjXMBx98YMKJrrdBgwa27Kxbt64ZN26cbe+G6neejz/+2F6n/lbUpvVlypQp9neh+rBLly52oYRQcPPmTbsiaKtWrez1//jjj5H22bNnjxk0aJBtp1epUsX+f5GY109AKgS9/PLL5sMPPzQ9evTwWpY2nNx333220Jk+fbqZOnWq+d///mcLorNnz5pwMXz4cFtYvvPOO+bbb7+1QammTZuatWvXmnCj+z9s2DCTM2dOuzpMONHfTK5cuewKas5j8eLFJpxcuXLFNGrUyC4XrSWiv/76a3P58mXz5ZdfJvalATF69tlnzc6dO20ARp0l+pLWrFkzs3DhwmR39/766y+7iq9WCjp16pRJTlRuNW/e3Nxxxx32C64aR88//7xJLj755BPTq1cv0717d7sypz7722+/bZ5++unEvjQgwXz++efuv/05c+bYhuuQIUPMqFGjwu6uz5w50/z777/m8OHD5sKFCyZcHD9+3NSqVcvs2LHDtg8VGNfnWLJkiQmXjmUFP/r06WPLTrVHXnnlFTNy5EgTinr37m3bGQ8++KBth/vqPH733Xft/wd6fPXVV/b7gDrt9N0+sY0dO9ZMnjzZPPzww/b6L168GGmfdu3amWLFitngstrqe/futXX76dOnEy3yjRBz/fp1+++pU6e0AqJr7ty5rnD9DI6jR4/az/L999+7wsWNGzcibcuTJ49r7NixrnBy9epVV40aNVyffPKJq1WrVq727du7wsno0aNd1atXd4Uz/c1kyZLFdezYsRj/xoBQL8+lcePGrgceeMCVnJw9e9ZVsmRJ14IFC2yZ1L9/f1dycfHiRVeuXLlcw4cPT7ZlWI8ePVwNGzb02jZw4EBXlSpVEu2agMQo/1988UXXrbfeGlY3f/v27a5bbrnFtXPnTleqVKlcU6dOdYWLvn37uooWLeq6fPlyWJa/HTp0sO0PTz179nTVr1/fFcp/8ytXrrRt1x07dkS67/ny5XO99NJL7m0nT550pUmTxjV9+nRXqFz/pUuX7PV//fXXUe7jOHHihCtFihQ+9w0GRkiFoFSpUpmk9hmcIe1p0qQx4SJlSu//PRTVV+RYEeRw8swzz9goeNeuXU242r59ux2hpmGl6qULt+mfs2bNstNccufOHe3fGBAudZLK9HAqzwNBU89btmxp7rrrLpPcKHWARteqxzW5lmEaFahRCVu3bnVPodHU1eT494DkIymU/1evXjWdOnUyr732milevLgJx9GpDz30kB2ZG47lr8pOzS7577//7PNDhw7ZFCihWnbG1A7ftm2bOXLkiP1cjhw5cpiaNWuGRGqXVH7EESLuo1Fgmp6bWP9fh8dfMsKepr8VKFDAzj0PJ/ryqfm32bNnN+3btzefffaZqVOnjgkXP/30k/nmm2/sPOdwlSlTJvPcc8/ZoI6GyGres+Y8qzEQTgE1TWHt16+fnWuuv6HXX3/dfkkCwo2may1btsx+QU4ulE9i/fr1ZsyYMSY5UhmWMWNG26DQlE3lEuvQoYO9J8mF/t5feuklU6lSJZMnTx5zyy232ByTyiMFJBea2qPpQOFU/muKmDpmlQol3Jw8edJO2VMbSvdc3yGVAkVTrRRACAeaAqcp3spBprKzUKFCNidZuE753r9/v/03f/78Xtvz5csXdh3mnu10Xb+mHSaG1InyrkhWNJdVwQTlG1FwIZxoVI5yFmlusIJR6h0uXLiwncsd6jRHXterPEUKqIWrxx9/3KRIkcL9XMk19cVi0qRJZsSIESYcqDdR/x/oepVoUL0rqqCVQFDJooFwoQBE586dzeDBg83dd99tkkswZujQoXY0TPr06U1ypDJMAXR9aVUePOUjVP4kjRhWx03RokVNUvfdd9/ZzhE1xvW5t2zZYkfNqXGl7UBSp+/CWtSiYsWKNjgbDubPn2/zwIZr8NyZYaLZDipz9T3yzz//tLm8zpw5Y3MYhbpPP/3UBu6Vq0iLQWgxDOWTUtmp3FLhxknonzq1dxhFo4tCNVF7dJRgXm1czQTKkiWLSRSJMlEQfgnnHFKOt956y5U+fXqbcyMpUP6IcMmbonxdqVOntvP8nYd+FxkyZLA/79u3zxWumjZt6rr//vtd4aJw4cKuBg0aeG0bN26czSt18+bNRLsuIDb+/fdfV+7cuW0+i+Rk8uTJrrRp03qVpcoVkSlTJvtzxLweSdGHH35ov4/89ttv7m3Xrl1z5ciRw/Xmm2+6koOqVau6evXq5bXt3XffdaVLl87eCyCpt0mUO69OnTo2n164eOyxx1yZM2f2Kr9VlqnsipgTLlTzwOq7fLdu3by2DxgwwFWhQgVXOFDuxSeffNJr25gxY1zZsmVzhbKockj99ddfdvvatWu9tjdp0iSk2iaXoskh5ZgwYYKtw+bPn+9KTIyQQoJRL6pWZ/r+++9Ddp5wbGnKgq/VCkJRixYtzK5du7y2abiy5qC///77drpBONIQZX0uTYELF+oROn/+vNc29UJoxIF6UyL2sgChZuPGjaZJkyZ26rJGJyYnyr+nUQGetJyypg5rVdyIeT2SIpVhkjlzZvc2lVsZMmQIy5WA47paasTe46xZs9rcG3pQjiOp0kgcrbCpESCJOooiDjTNOuLUMI3o1GjPbt26mVCne666xrPsFf0OwqXsjars1HdgjTYKl1xYjnLlytkZPytWrDDVq1d3f8Y1a9aYF1980YSLSZMmmaeeesqOIFR+zMQUXn8BCBvK9aPhpQpGKTASrlPFNFdeVGBqOOMvv/xiOnbsaMKBppYo/5XnQ9vUgNDP4ZI8X8N5teS8aDlV5QLYvXt3WOUCGDBggJ3u4yzRq+mU+n9EjVoaMQh1mprkBKM0XclzCm1yoC+eEctSNRKc7cmBpq8rgaumXTidMvpbOHr0qC3HkgN1rGnZ+E2bNtnnKsffeecd07Bhw2Q7lRNJ39mzZ20wSt9Vfv75ZxtICCdKWRGx/HaSUCtnTjhQ/qWvvvrKdgyJvhPPmDHD3HvvvSZcys4PP/zQTn93cjDpO7DqlHALRonK+0ceecS89dZbtoNcHRLOFNYuXbqYcDBlyhQ73VPBqJCowxN1fBZ80rA5DSktUKCAHWqnpZb1/OWXXw6LO6alJLV0pKaHeQ6R1WPKlCmucPHpp5+6ypQp48qePbv9LBpyOm3aNFc407Kr7du3d4WTb7/91g5L1tBeDSvVtIlffvnFFW4++eQTu0yshonr7+nBBx+0y6wCoa5jx462LlKd5Fmet2zZ0pVcaepK//79XcnJsWPHbB2icljTjbUMeWItEZ0YLly4YKf/ZMyY0ZUzZ057H+65556wnv4OxGT8+PG2/Nd07Yjf6cN1unKqVKlcU6dOdYWTsWPH2u/B+g6pMqhfv352SlY4OHPmjKtHjx42ZYhTdnbo0MF1+PBhV6j+zevvO0+ePPZvP3/+/Pb5559/7t5H917TKDV9X7+P4sWLu5YsWeIKBb/++qvX9FTdc/38/PPPu/eJqp0+adKkRLnmFPpPYgfF4E1DMLW8ckQa7pgtW7awWoHAV09FxGGn4dA7pCkZSWFahv6uNLpBCWnDzblz52yvRDgtNRyRRtrpd6D7Hy4j1ACt8uNrqnLatGlN3rx5k+UN0sggff5wXjAiri5cuGCnGofbSIlA0ddm/T+h3z3lOJI6pRs4ffq0z9fCdYSoVkLTCCml4QgnGomj30WuXLnCcqSyU3bq3ofyyCi1NzRNNSJ9d4/4N6M2u+rE3Llzm1Bx+fJluzJjRGp/O99ZomqnK86QGFNyCUgBAAAAAAAgqEI3PAkAAAAAAIAkiYAUAAAAAAAAgoqAFAAAAAAAAIKKgBQAAAAAAACCioAUAAAAAAAAgoqAFAAAAAAAAIKKgBQAAAAAAACCioAUkrwRI0aY+vXrm6Qoc+bM5ocffjChIkWKFObXX39N7MsAgDhRXaE6I6lZtWqVLZ/Pnz9vQoHqCV0PAISjy5cv2zJs+fLlJql55ZVXTO3atU2oeOaZZ0zTpk0T+zKQgAhIIWyMGTPG3H777Yl9Gfj/pU+f3sybN4/7ASDk6MurvsQi8anBpoabGnAAEGroTA0dSXkQAaJGQAoAAAAAAABBRUAKYWHatGlm+PDh5q+//rI9GXpom/NayZIlTdq0aU3x4sXNe++9F+25tm/fbooWLWoGDBhgXC6XOXv2rOnTp4/JmzevyZIli43M//HHH17H6P3efPNNc+edd5ps2bKZ2267zcyYMSPa9ylRooQ9LmXKlKZQoUKmf//+5ty5c7HeJzYC9Vl0j/R6hgwZTKlSpcw777xj8ufPb7788kv7esGCBc2VK1dMmzZt7Pn03PHPP//E6j4BQCB16tTJLFq0yIwdO9ZdX+zevduWWYMGDTL58uWzIzw1JWHZsmXRnuu7774zWbNmNV999ZV9vnnzZtOyZUtbvubJk8c88MAD5uDBg5Gmon3++eemYsWKJlOmTKZGjRq27oqKrs25TtVjZcqUMe+++26s94mtQH2WuXPnmtKlS7tfnzhxoj3u+PHjZuvWreaOO+6w+6k+0fYePXq4j43NfQKAQMudO7f9t1mzZrZ80vdy2bNnj7n33nttagzVAe3btzcHDhyI8jxqTwwZMsR+l9+yZYvdppQa1apVs/WNvg8/99xzth5yaBRvgwYNbPtGr+t7c7t27cyJEyeifB+1eZy6QNememzp0qWx3ie2AvVZRo0aZdsouXLlMq1btzaDBw82VapUsa+pThs5cqRZsWKF+/pnzpxpX7t69Wqs7hPCjAsIE6NHj3ZVr17da9vs2bNd6dKlc33xxReuM2fOuGbNmuVKnz69/dfx0ksvuerVq2d//uuvv1x58uSx2+TmzZuuBg0auDp06OD677//XOfOnXNNnjzZlTlzZtfu3bvd59D/Krfeeqtr2bJlrvPnz7vef/99V+rUqV07d+6M8bpv3Ljh2rRpk6tWrVqufv36xXkfXzJlyuT6/vvvA/pZdC3lypVz3XPPPa6DBw+6du3a5brjjjvscbrPDt33uXPnel1PfO4TAARKkyZNXE8//bTXtgEDBrhuu+0215o1a1wnTpxwDR8+3JUxY0bX/v373fuornDqh6lTp7qyZs3qWrBggX1+4MABV65cuVxjxoyxxx85csTVvXt3Wy9dv37d7vPLL7/YcrBx48a23Dt9+rSra9eurpIlS/p13ZcvX7bnyJkzp+u7776L8z4RrVy50l6X6oVAfhbVNWnSpHG99tprrlOnTtmyP3/+/Pa4Y8eO2X20Tc8vXbrkPi6+9wkAAkVlkcokh8rAihUrulq1auXat2+fa8+ePbZOUfmo79qi8kzHqXy7du2aq1u3bq5SpUrZfUXfj3PkyGH/1fdhfcevUqWKa8iQIe73UR2lczz11FO2HFZ5Wr58eVffvn39um61e9555x37PV/f1+O6T0Qvv/yybY84AvVZPvroI1eWLFlc8+bNs9elOjZlypSuypUr+2yzBeo+IfQRkEJYB6RUaPXu3dtrW//+/b32cwq3xYsXu7Jly+aaOHGi+7XffvvNBrAuXrzodQ4FYPRF3aGCcNKkSV775M2b1zVz5ky/r/+nn36ywbD47hNVQCpQn0WNLwWR1EBxqPLxNyAV3/sEAIEOSJ09e9YGTjw7K9SwKFOmjNd+TkBKZaYCPgrkOJ599ll7Xk8XLlyw5eXatWu9Ai3btm1z7/Pvv//abYcPH/b7+vVF/8EHH4z3PlEFpAL1WYYOHeqqWrWq13nGjx/vd0AqvvcJAAIdkNJ3W9UXnmWRAk0Knjj7OQEpPW/Tpo1tdxw9etS9f82aNW27xdP8+fNd2bNndz9X3VOkSBF3kEveeustV4UKFWJ1/QroTJ8+Pd77RBWQCtRnURBr2LBhXufRvfMnIBWI+4TQxZQ9hDVNOahVq5bXtjp16riHyzq2bdtmWrRoYd544w3z+OOPu7evXbvWJlrVlIVUqVLZh6bPaRrHf//953UOTQv0lCNHDnPq1Kkor2327Nn22jS0VMNO7777bnPs2DGvxK7+7OOvQH0WTbHQkGMNqXWUK1fOZMyY0a/riO19AoCEtmPHDnPt2jWv+kJlrqYyqB7xNH36dDutQFMcPFcaUhn722+/mdSpU7vLV001u379erRlrMpAiaocVHvo1VdftdOjNR1C1zVu3Dizd+/eWO0TG4H6LKovIi42EpvFR2JznwAgGFQnKLWHpnc7ChcubAoUKBCpvnj44YdtObx48WI79dkpr//++287rc2zjG3VqpU5ffq0VxmnVCOeK47G9J1ZU6EfeeQRmypD59ax69ev96oL/NnHX4H8LGqLVa9ePU71RWzvE8ILASkkOf+vs8Pbrbfeauc+f/rpp17LXt+8edPccsst9kv4jRs37EPbdI7333/f6xyxWaJaFdb9999vevXqZf73v//Z86qyEr2Xv/vERqA+i/b39bqv++oLS3kDCDVRlV++yjsFrRSA/+STT7y2qzzt0qWLu4x1ylc9OnbsGOdycPLkyWbSpEnmgw8+MEePHrXn05d/z3rAn31iI1Cfxdf987euiOncABDq9YXy8CnQ4pmjSfupTP3oo498lrFO8D0uZWDv3r1tTsGff/7Ztmd0PtVZnnWBP/v4K1Cfxbmnca0vqCuSNgJSCBtp0qSxhaAnjdz5888/vbatXr3alC1b1mubkvotWLDA9pCr8rhw4YLdriDVoUOHbM9BIOmaFBx69NFHbcJE9SZEvE5/9omNQH0W3Tv1oqjR49CIs0uXLsX4+wCAUBCxfNJIHG3zLGP1RXjNmjWR6osKFSrYpOj6Av700097lbFLliyJ0wjW6GjhCdVLWgxCyXMlYl3gzz6xEajPonun0Vae1JvuSfddqC8AhCKN/PEsn8qXL28DOp7fg/ft22e/Y0esL7p27WqmTJliA/nz5s2z2/R9Xom6f/rpp4Bfq+oCdWTrGjVaVgshRZwV4s8+/grUZ1FASYtf+FNfUFckPwSkEDaKFClidu3a5bXKxbBhw+wqbrNmzbIFrlZE0nQLz0aEQ1/i1VuglRqcoFTTpk3tSnSdO3e2Bbi2bdq0yQwdOjReha9WQNq/f7+tnC5evGj/HT16dKz3iY1AfRatNKJpIVqtT5WvVhrp27evz9/HqlWr4txDDwAJReWTvug6nQ8q/1WmaSUgreSmof4vvPCCbXRoxdWIKlWqZINSqk90jGg/ldVqgOzcudPWOVoN6J577nG/T1yoLtB7afqbpkBodcBffvkl1vvERqA+S79+/cyGDRvs9Zw5c8bWPRHrMU11UWNE54/N6CkACFZ9sXLlSvf3WaXPUJmrDmO1ORSM0hS4qlWrmiZNmkQ6vnv37nYUq4JS8+fPt9teeukl2zYZM2aMDWwpHce3335rzxkfuq4vvvjCrjCn69KqpVphO7b7xEagPssTTzxhg3dqk+h61OnjBPE8fxeqkw4fPhzn60X4ISCFsKEvygqWqPdaX261rKm2TZgwwU5d0BKiTz31lHnzzTcjTTlwqFGycOFCu1Sp5j/rC/mPP/5oKxhNn9M5HnzwQTvFz1el4y/lHVHBrWGzGs6qwlyBodjuExu6J4H4LOoN+f77721FpuVVFejS0re6d+nSpXPv9/rrr5tvvvnGLuWteeoAECq0lLQCK8rpobJRgSflENQy0+qQyJ8/vw3o6IuxykhfnKCU6hotN61yTkEVTVmoUaOGPe7ZZ5+1ZbjyL8XnWtWZoCkVyt+nvH8Rv+j7s09sBOqzqI5QPaDAnfKrDBw40AwaNMi+5tQXGgmspbwV/FL+ETWOACBUqN2glB76PluiRAlbTs2dO9c9qkezMTTTQnlfo5o6pnLtvffecwel1D7ROebMmWPzUVWsWNEGdYYMGRKva1UKDnWoqAxX/iWVu565Dv3dJzYC9Vl0j1SXdevWzZ5HQa3HHnvMq23RoUMHW9cpqKZ7PXPmzDhfN8JHCmU2T+yLABDaNIVPvRbr1q2zQ3cBAPDFGVWmXnQAAKKijnOFIr788ktuUjLGCCkAkWjUmUYOKBmipoioV0OBKIJRAABP6iVXZ4VGpGlhjhEjRtgpLAAAOI4cOWJnsmjEsqaea/Tx119/zahZEJACQpXmWWu4qq+HhrompDZt2tj58Joa0rhxYzvlIiGSMwIA4k/THKKqL+KbsyQmyrei/FxaIl1T/nr27Glee+21BH1PAEDcZM+ePcr6IiFHKqmO0PTB5s2b2+mEWjlWua5atGiRYO+J8MCUPQAAAAAAAAQVU/YAAAAAAAAQVASkAAAAAAAAEFQEpAAAAAAAABBUBKQAAAAAAAAQVASkAAAAAAAAEFQEpAAAAAAAABBUBKQAAAAAAAAQVASkAAAAAAAAEFQEpAAAAAAAABBUBKQAAAAAAAAQVASkAAAAAAAAEFQEpAAAAAAAABBUBKQAAAAAAAAQVASkAAAAAAAAEFQEpID/36hRo8ysWbMS5H68/vrr5pNPPuFeA0CYUb2g+iEhzJkzxzz33HMJcm4AQHC98MIL5vvvv0+Qc7/66qvmiy++SJBzA4kpdaK+OxBCfvvtN3P16lVz//33B/zcv//+uylRooTp1q2bSQzffPONfXjKmjWr+eCDD7y27d+/37z//vtm7969plSpUqZfv34mR44cibYPACS2f//91yxfvty8+OKLAT/35s2bzc8//2wbGonl8uXL5quvvrLX0axZM/Pwww9H2ufixYtmypQp9l7kzZvXPPLII6Z06dIhvQ8ABNsvv/xi0qVLZ+67776An3vx4sXm3Llz5sEHHzSJ4caNG+a7774zy5YtMy6Xy9SuXdt06tTJpEqVymu/PXv22PaFvueXLVvW9O3b12TLli2k90HiYoQUEARPP/206d69e6Ld640bN5p//vnHtG3b1v24++67vfbZtWuXqVq1qtmwYYOtZNQ4qVmzpjl9+nSi7AMASd29995rXnvttUR7f5XBxYsXN7/++qtZvXq1+euvvyLto46aO++803z66aemRo0a5vDhw6ZatWrm77//Dtl9ACCpef75581DDz2UaO9fvXp127ldsmRJW2/oetSWUKDKsWPHDvv9ftu2bfb7vUYB69/z58+H7D5IfClcCnECieSHH36wo4feeustr+1Tp041R44csYWdrFq1ynz55Zc2YFGpUiXTu3dvkzlzZq9jdu7caWbMmGEj4JUrVzZ9+vQx6dOnt68pMq4RUJI7d25Tp04dW6inSJHCfby+4NavX98WXEuWLDE3b960PcW33367X5/lxIkTZvr06bbQu/XWW03Xrl1toe1M2cufP78dIaUecV/TPypWrOieuqEC9OOPPzYHDx40xYoVs72/BQoUMHE1YsQI2+BQL39UevToYRsna9asMSlTprQ90Hpv9SS89NJLQd8HQPK1detWM3LkSDuKUqM5HeqZVTmrh3pl1fOp+kIjLQsXLmx69eplihQp4nWuU6dOmY8++siWOYUKFbJ1g1OeLl261EyePNn+rDqlfPnytn7JlCmT+3jVQyo7x44da3uHjx8/blq1amXatWvn12dRAGXmzJk24KP3uOeee0zDhg3ta/pyrO0aIaU6x1djI23atO4p3/os06ZNM5s2bbJ1SseOHW0jIa5Onjxp/82ZM6f9kq767t133/XaR+83YMAAs2/fPlt/ihoh169ft6MBQnEfAMnH119/bdauXWvLaE/vvfeeHVGkTmFROa4p2GfPnrXf9R999FGvsl70HV7Bbn3/1j6qDzTiSSZNmmTrILUdVPbUq1fPPPDAA15tCZWjrVu3tiP/1b7Raz179rTn8sexY8dsGad2gOo0dWbfdttt9jXVE/qurBFS69evN6NHj450vILzw4YNc9ejahcpaK8AkurHfPnymbhy6lmH6qEKFSrY9kWTJk3sNo2Y0n4rVqywn133v2jRovaanN9DqO2DxMcIKSQqFaxvv/22LXgdipEqYONUEt9++61p0KCBDVzUqlXLfPbZZ6Zu3br2S75j4cKFNlD133//2ddU+KiScKgicEYGaeqcAjQK8kSkxs8777xjC9hr167ZykaFWEz0RVjBLA2n1TEZMmSwU/90PaJKyem9VSUWcaTSggULbMEuixYtsp9T0yj0uRVg0/Uo4ObQHHIVstE9VKl60j1R5Ttw4EB7D9X48fTjjz+a9u3b2/ssGTNmtJXq/PnzE2UfAMmXvjwruKAAkCcFS/SFUsEo1RvqfNiyZYst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AKDyScET1Q36V/kzXnzxRa/y0jO/RcS6QVQneOaUikijczWiSr3RDpXLEWkqmHqYnTJTz9UzHlVQKWJjRKO09FB9pLL/iSee8DlFWVM7VP+pk0KBsogjcdX5Ed0IqISYsqfRuGrkRSyv1bng1Fmhtg+A5EVBKCfPrMpPpaNwpkl7tiU8vxurvnCCOJ5tCV8jWJWfSmku9P1d07qd8/niqy2hTmZ/RjtpJK4zpU75otSW0GfTiNmI1MGhulFTBj3bDE5bSNep46MSlyl7mr2h93rmmWfcCzE5VAbrXkf3/T7U9kGI0Cp7QGL74IMPXPny5XPdc889roceesjrtTvvvNNuv379un2+Zs0aV6pUqVwLFizw2qdhw4au8+fP2+c3b950zZkzx/58/PhxTb52LVq0yP1a79697ba5c+e6z6Hj06dP79qyZYt9fvHiRVeNGjVcPXv2jPH6t2/f7lqyZIn7+Y0bN1yVKlVyvfTSS/Z5q1atXE888YT9+ezZs65y5cq57rvvPnstETVu3NhVrVo114kTJ9zb9u/f7/rpp59ccfXZZ5/Za3J88cUXkT7/qFGjXPnz53cdOnTIPt+4caMrXbp0rpkzZybKPgCwefNmW1b16tXLVaRIEa8y8/nnn3cVK1bMlvFy7Ngxu88LL7zgtY/qll27drm3qe64fPmy/bls2bKukSNHul/7+OOP7fs9/fTT7m3PPfec3fbpp5+6t/Xp08dVpkwZr3LVF72uc3ru99hjj7maNGlifx49erSrevXq7tcefPBBV4kSJVwnT56MdK4XX3zRlTVrVtemTZvc2y5cuGDL80CoVauWq3///pG2//bbb/bz//777/b5mTNnXKVKlbL3IFT3AZD8TJgwwVWoUCFXixYtIn13r1Onjqtjx47usnjFihWulClTen13r127tqtZs2b2+79oX+d78oEDB2y5o+Oc17p37263/fLLL17laKZMmVw7d+60z9UuqVy5sqtfv35+1XfO+UXtntKlS9t6QlRvOHXTqVOnXCVLlnR16tTJ57nq1q1rr+X06dPubXv27HEtXLjQFVfLli2zn03f4aPy7LPPugoWLOg6evSofb5u3TpX6tSpXd98803I7oPER0AKIUEFqwISKth//PFHr9e2bt3qKlq0qP3Cedddd9nCcNCgQV777Nu3z1W1alUb5GjZsqUtpPXl3aFgkI5r3bq1DQapoE6TJk2kgJS233rrrbYyU8NG76lKKCbaR0ExNW7uvfde21DR+xw8eDBSQErBN31ObXvggQfcj1deecW+rmN0HTlz5nTdfffdtoLU5/EMwMWW7tdtt91m742CbLoXY8aM8drn0qVL9v7myZPH1bx5c9vwefjhh70agMHcBwBEAXqVmfpi6encuXO23FXASWVl3rx5XY0aNXJ3TIgCTypfM2fObBsat99+u9332rVr9vXPP//c1j36ol+/fn37xVUBoYgBqeLFi9tyXedXXaMya+nSpTH+glSmqdFSuHBhW+arbM+VK5c7mOIZkHKCb2pEeNYNXbt2ta9fvXrVlpMZMmSwn1udF7recePGxfkPxbk/eui6VNfo56FDh3rtp3ufMWNGV9OmTe17qh6JGDQLtX0AJC8KOijYoHJUgWtPGzZssMEqfU/X906VH57lvKjjomLFiq4CBQrY8lrl/quvvurVmZAlSxZXmzZtbH2gdoOvgJTqErUlVNfoPdUeOHLkSIzXr4CRji1fvryrbdu2tg2iYJYTTPEMSCn4pvdWh71nfTF27Fh3u6hmzZqu3Llz2+/++lnBLadzPrYUgNNnz549u9f76eHZllInieom1cu6zzomYmdBqO2DxJdC/0nsUVqAkyBPOTI0b1pDbT1pGp9yNGmOt4brO8NlPWn6hBINaj64hutq2psnDfHXUFtN/dPcb+WQUi4OJ6n5b7/9Zofp6nXl4dCUPi0JG9W8bV+U10rDfZXgT7k+nES6y5Yts1P/lDxQQ4R9Lf+qY7SCkuf1al9dj/I9xTSsNiZHjhwxf//9t53yoaGqUa2coXuoocmaguhMcUzMfQAkbyqPlWRc5aOTPDViOaIpdBqar3LXFx2v8ln1gspTTyqD9B7K06fV21avXm2naTsLR2h4v1Za0mvaT/lI6tev79dUboemietYlb+qf5ypG86iHMobqHxXSkwbkfKUeK74p+v9559/7PVWq1bNK0dIbCmJu+rCiJRfQ/lHPDmrP2mlWN0Lz0TxoboPgORFiz+oLFWZGbFMUJJr5WjS66oHPFdY9WxLKL+qpldrn4jTgFX2agqeplCrvlEOqUaNGtnp0qJpfWpX6LnKfFFakth8h1cSdrVXbrnlFvsezlRx5W5y6iYtyqTv9BGpzeCsehfxevV5PJOtx4bCBc7qtRGpbePkrHX2VTtHidW16qkzLTLi+UJpHyQuAlIAAAAAAAAIKpKaA372bmuVp6ho2dOYlvEGACQ9vXv3totE+KJEtBpNBQBI3jSSV6utRkULI8VnxCsQrghIAX7Q1IjoVi7yZ+UMAEDSc/fdd5srV674fM3Xyq8AgORHwabo2hKxSRECJCVM2QMAhAXl2lGOHeWUa9KkSYx5AJQLQksUa8lfLbncrFkzryWfnR5J5a7zVKNGDXt+AAAAAAmHDJAAgJD3888/22SU8+bNMytXrrTJnBVMiooSfirx58iRI83WrVvN9OnTTbFixex5PL3xxhs2UagWTHAely5dCsInAgAAAJI3RkgBAEKaVrzU6mgdOnQwb7/9tt02adIkM3ToULN792736jaetKqMplEpiOXo27evmT9/vl2lzFGiRAl7nj59+gTp0wAAAAAQRkgBAEKaRkTt37/f9OrVy72te/fudilfjZjyRcs5ewajRMmldZ6I+X60xLMCXd988405ceJEAn0KAAAAAJ5Iah5N7hGtrKZk1ilSpIhqNwAIOwrknDt3zhQoUMCkTBn6/RJbtmyx/5YqVcq9LXPmzObWW291v+YPBZwqV67slThUn18r32hhgi+//NI89thj5vPPPzd33XWXz3MomOUZ0FJdcfLkSZubiroCQFITbvWF4+jRo2bt2rX2e3zt2rVNmjRpYvycmzdvtiNoNb27dOnSXq9fvHjR/Pjjj5GOU0dH/vz5/bom2hYAkjJXHOsLAlJRUDCK1XEAJPUk4QULFjSh7vz58yZTpkwmdWrvKit79uz2NX+89957djTVokWLIgWplGvKc1pf165d7VRAX6tnjh492ualAoDkJFzqC/nwww/NgAEDbK5BfZ9PlSqVWbhwoZ367YvyCA4cONAGjPTdX6Nmdex3331nA1pOgKtjx46mRYsWtj7yHI3rb0CKtgWA5GBfLOsLckhF4cyZM7axoxuaNWvWQP1+ACDRnT171n7pVgJvLUMc6j744AOb4+natWu2YeGZ/+nee+8148aNi/b4mTNnmp49e5oZM2aYBx98MNp9N23aZCpUqGCnCapXPaYRUqorChcuTF0BIEkKt/pCnQka3aROiEceecTWG02bNjXp06ePtKiFQ7kFFVgqV66cfa6p2wpItW3b1owfP959Xu2zY8cOW/fEBW0LAEnZ2TjW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u9dWNsrt5EnPly5dauIjderUplatWqZhw4Z26l6/fv3MF198Yb7//vtoA2SeUwXPnj0br2sAABjz6quvmhEjRkRqXIg6IH799ddY3aYLFy6Ya9eumezZs/t9zJkzZ+w0b42cjejw4cORri1Lliy2MwMAEBwq19u2bWs7pX0ZPXq0eeaZZ/h1AEASE6eA1KBBg8yjjz5qnn76aZMjR444vbET/MmYMaPXdiU0v3z5somPl19+2eu6WrdubXNVzZ4929x7771RVnRKkA4ACAx1CIwaNcrMmjXLtGjRwmTIkCFeo6w06nXRokUmZcqUplKlSuaTTz4xZcqUifKY5cuXm3fffdfMmTPHXL161WdQrH79+rZzJVOmTO5tqt8URAMABIc6jjXzYt26daZChQq2cxkAkPTFKam5htK+8MILcQ5GidP7fOrUKa/tahjEpufbl4jXpSkhGua7Zs2aaPNZqRfdeezbty9e1wAAyZ1GwlarVs3cd9998QpGSZcuXWx9oRVZ9a/K9DZt2the9ajMmDHDdkK888470Z5bHRL79+93PwhGAUBwqW2h2RdVqlQhGAUAyUicuh/UI717925Tvnz5OL9xwYIFbeDo33//NS1btnRv13P1fAeSphCeO3fOpEqVKsp90qVLZx8AgMAoVaqUXYDixo0b0Za/Mdm5c6edKv7zzz+7Oxxef/11U6xYMbu9VatWPo+bOnWq/ffjjz+O9vw3b960I7By585tUqRIEefrBADEjdoWGs0aCCrTNeJqxYoVdgr2gw8+aANdMbUVVMd89913pnTp0mbIkCFerx8/ftwMHTo00nFPPvmkqVy5ckCuGwCSoziNkOrbt6/p3r27Wbx4sR1J5NmzrIc/9KW/c+fOZvr06eb06dN2m3JHaRSTesIdU6ZMsavq+Uu95Z999pnXtnHjxtnk6+pNBwAEh6ZgN2rUyDz88MPmn3/+iVRX6Au+P/7880/7b7169dzbbrvtNpsTynktPgYMGGAT5mranuqlo0ePxvucAAD/NW7c2Pz999/2O/u2bdsi1RfqWPZX165dbb4pjaTVcTVq1DA//fRTlPurjaA64O233zZ//fWX+eWXXyLtozyEGnVbrlw5u0K489DiHACAII+Q6tWrl7vyiGtScyfZrSqfsmXL2sfq1avNs88+63XetWvXmlWrVrmfL1myxOYEuXTp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8QaAZCpdunTu+kKrIymZ+euvvx5pv+heAwAkfVmzZrUPmT59up3G3alTp0j7RfcaACAZJjVftGiRz+03b940ixcvju81AQCSAOUD+fvvv6PMHbJ+/fqgXxMAIPRo9e7s2bP7fG3btm0mT548Qb8mAECIBaR27tzp82cnGKXcIbfeemvgrg4AEHYuXbpkDhw4YA4ePGh/jlhfXL161Xz//ffUFwCQzKnj4tSpUzaHlBKbR6wvzp49a5YsWWIGDRqUaNcIAAiRgFTJkiV9/uyZD2TixImBuTIAQFhasWKFVzJzX/VFgQIFzNy5c4N8ZQCAUPLGG294JTN/8803I+1Tq1Ytc++99wb5ygAAIReQ2rVrl/33tttuc//sSJMmjcmXL59JnTpOswABAElE/fr1bR2hwNTkyZPNzJkzvV7PmDGjnX6RIkWKRLtGAEDie/rpp02fPn1sUEr5pPr27et+TXWEpvGR0BwAkq5YRY+KFi1q/z137pzJnDlzQl0TACCMabSs6otChQqZ9u3bs5oeAMCnHDly2Mf48eNtAEod3ACA5CNlXA5SviitjhSRtmmuNwAAqVKlMv/9959ZtmyZ181Qp8bnn3/ODQIAWGnTprULI0WcgbF161azdOlS7hIAJFFxCkgNGTLEXLhwIdL28+fPm2HDhgXiugAAYe769eumY8eOJn/+/F7bs2TJYmbPnm2++eabRLs2AEDo2LJli21DRFwcSSNt+/XrZ/bv359o1wYACLGA1HfffWenYUSkbXoNAIANGzbY6Xq+kppTXwAAHPPmzTN33XWXHSnlKVOmTKZevXpm4cKF3CwASILiPGVPy7RGpG1azhsAANUVJ0+e9HkjqC8AADG1LagvACBpi1NASst5Dx061E7R88wJMnjwYNO0adNAXh8AIExVqlTJXLx40bz++uvG5XK5tyuv1JgxY6gvAACW2g/KLRgx56BGTunRuHFj7hQAJPdV9hxvvPGGueOOO0yRIkVM1apVbUNj3bp1Ni8IiQcBAKLVkqZNm2bzSE2ZMsWUKVPGnD592vz111+mUaNG5pFHHuFGAQBM9erVzYABA0yDBg1s26JAgQJm7969dur3q6++akqVKsVdAoAkKE4BKQWiVEF88skn5u+//7bLtLZt29Z069bNZMuWLfBXCQAIS23atDEbN240M2fOtCOjihYtap588kmb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3HHHHS5TONppohkHABC7pGVIyeOPP26tW7e2Zs2aua621Tueeju64IILguNMmzbN5syZY/369Yt6mmjGAQDkDKrxNHLkSHcMV/FYZcHquP7CCy9YxYoVg+O9/vrr1qVLF7vwwgujmiba+QIAcgZlMunhhK77zzvvPNfkUAXJv/jii+A4Kuvx3HPPWbt27dz40UwTzTgAgBwWkKpUqZL9+OOP9sknn7inDjfeeGNYd6py+eWXW5s2bWKaJppxoqE028GDB2dIt82pctP65KZ1yW3rk5vWRVif1NC2bVsXNPrss89s//79LnP26KOPDhvn/vvvD+sFKZppohknGuwnqYvvJnXx3aSunPzd3HvvvXb++efbrFmzXH2nc845x8qWLRv8ux44DB061OrXrx/1NNGOk5e2czKwvdhW7Fu577eYL5BT+nEFAAAAAABArpAzKtoCAAAAAAAg1yAgBQAAAAAAAF8RkAIAAAAAAEDeKWqeCr755hvXk1/hwoVd70wnnnjiYZnGDzNmzLBvv/3WDh486Lozb9++fZbjqzepqVOnhg0rVaqU60Uk2dQdb3rqcvdQxemnT5/u1kndtqvnrEaNGlmyPfroo7Zx48YMw1VM84Ybbsh0mk8//dS9QqkHsEceecT8tmfPHhs7dqwtWLDAevTo4XquTE891rz11luu15ljjz3WrrzySjviiCOynG880ySCunl+++23rWjRoq5AaXrbtm2zCRMmuN5zqlSp4va7o446Kst53nXXXXbgwIGwYerpTb19Hk579+513838+fOte/fu1qRJk7C/6zg1ZcqUsGFa7yFDhmQ5X20DfTerVq2yY445xn03mi4v+/fff+29996ztLQ0tz9cccUVh9wv4pnGD//8849NmjTJdf5RpkwZO/vss10PUlkZNmyYrVy5MmxY06ZNXY9TyaTf6Ysvvphh+MCBA+3II4+MOJ1+r/puFi1a5MbTd6MOUZJpy5YtEc+/WR1P/vvf/9pvv/0WNqxx48Z29dVXm9/+/PNPe+ONN2z9+vXu3Fe8ePEM46gTgXHjxtnOnTutVatWrjD0ocQzTXapxOrnn3/uzsUtW7a0rl27ZhhnxYoVrgOdv/76y+rVq+fOF1kVeNX4zz//fIbh/fv3P+z7nzr50Xezbt06e/jhh11R7lBaLi1fKF1DXXPNNVnOV9Pou9mxY4eddtpp1qlTp8Oy/LlRMvbrnGjTpk2ZXv/26tXL/e5gtnDhQndOU5H9vn37ZrpJvvrqK9crpI5Run9t2LBhntx06sDmww8/tDlz5tjFF1+c4d5S99Pvv/9+ptdBeXFbTZo0ye1ful4899xzM/3NLV261MaPH2+7du1yndF16NAhps/J0xlSOrh17tzZ3XCvXbvWXVzrx5zoafxw1llnuQtwndS0M+gG8rLLLnMXVJGol5DJkydbrVq1gq/q1atbKlB3vPoRhC5b+oun9B5//HF3Mtf662K4efPmLvCQbFWrVg1bD/XuovVbs2ZNxGl0kPzoo4+S/t3ogK0exxTY0DIvW7Ys0xsQBaneeecdF1DSAVsXpbt3744433imSQR18awbBp2UR44cmeHvuvk46aST7Ouvv7ZixYq59VavbQr0ZkXbRsGh0O9Lwd3DSfuHlk0BWH3+zz//nGGc7777zgXXQperRo0aWc5XN1a6mX3zzTfddzN8+HA79dRT3e8qr1LwQkGbBx54wD2I0A2oLuTS37xldxo/KMio4JOOjYUKFXL7jQKZL730UpbTvfvuu+7mKf2xLNkU0Nb+H7pcemndItFDG11UDRo0yI2n31CDBg0yPb75SQ9S0q/H33//7dYvX758EadTUFoXg8n+bvr162fNmjVzD4a0zLpOSk83Q/od6MGAfiMKpN92221ZzjeeabJLv9PjjjvOXVfoxkTLkNn14Hnnned+F/qNP/XUU245dfMcia4btW10HI52f00EXR/qd+59N5kdz7We2sax7Ec6V2qdFXTX9aaCV7179z6Ma5J7JGO/zqn0AFP7ra6rQvfPvP6gzDuf6fpZ+4/2KT1MzIyuRfSgXtequg7Q8UABhLxG20jXzjrevfzyy+7BXHoapvuT9OfjvOa3335z14u6/tM56qeffnIPKV599dWw8XR9q3snnQv1IFbxh0hB0YgCedSqVasCBQsWDLzzzjvBYffee2+gYsWKgX379iVsGr/Mnz8/7P28efMUiQp8+eWXEafRsrdu3TqQirTs06ZNi3r8tWvXBgoVKhQYM2ZMcNjgwYMD5cqVC+zZsyeQSl5//fVA/vz5A7///nvEcbTsp512WiDZfvrpp8DmzZsD//zzj/tOQvd9T+/evQPHH398YO/eve69xi9btmzgySefjDjfeKZJhOnTpwe3b926dTP8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mjRpErjkkkuC77UP6neybNmyTNcv2mkOp0i97O3YscP9TcvnHS/T0zJq3/N+J9988407R3jWr18fOPLII921mx8i9bKn996xyqPrRfVGGdor53PPPRcYOXJkWO+bXbp0Cb5XL176baXfJ5FRsvfrnGTWrFmuF0vPtm3bXC9onTt3TupypZpIvezp963z9UsvvRQcpt4x69Spk/T712SK1Mte+nuwuXPnumNhXrwOHjVqlLueGDt2bMRx6tevH7jyyiuD73WO0PaKpVfMPBuQkhEjRrgfqLrh7tChQ6BEiRKBL774IuyiUCfu0B/woaZJFnXdWapUqcB//vMfd/HjvUJ/VF4Xn6Hd2Tdt2jRw3XXXuYO6uijXwSxSQMsvumBT8EldcGvZjj76aHdzHxog8AIkoQcSXcDqu7nwwgtdQEABjqlTpwZSgW4MdKGh7sYzoyBA+fLlg++7desWaNy4sVv/8847z303d9xxh+/fjXcjp/1K2/ucc85x70MPTLow0H6k7+nqq68OVKlSxQXfQm8S069fNNMcDrqY1vLrIlonIu934gXGdBDVerZt2zbsdxTanaloHC/4qe521fW19led4LWvKtilE9jh5N3o6KXl0T6vf4cGLbt37x7cj7R82o9uu+22sP1IwTlti9CbrObNm7t10Hejbsw179CbqLxI20KBDm1TBZbUZXfoTZ2CHPoe1KVwtNMkgwKoOhbpAiL9Ph5646mbJe8CQ0EevW/Xrl3ghhtucPtHuXLlkhYgD/Xss8+684WW9YorrnCBHO2vf//9d4YAiY5nHv0mdExSEKphw4buWJSsAE56ChjrO4q0PDp+XXbZZcGAho6l3nejvymg/vbbb/u81IHAxIkT3X6kAIW2t4I4eq99zqMu7bXdTz/9dLcO6j768ccfj7h+0U6TaN4DSb10ftI+on8/9thjwXG0z2k9e/ToEfY7evHFFzMEgNLS0oLnIO2v2lf10nel7y5SQCtRdHzSsunaVcujfUXvtW1F3aA3a9bMPfzT30455RR3XnjjjTfC5qMA3MUXXxx8r6CujnEafvnll7vrLnULjkNLxn6dUylYpwCU7lt0Xq1cubLbX1etWpXsRUsJTz75pPs963pPv0fvWLR79+7gOP/73/9cUoV+vzrm6EGj92A1L9F1jrd9FGhRooD+HRpoV0LDiSee6B4g6pipe8trr702ZRIc/KL7bj1g8M5/oS9dF3q+++47d+3VunXrwKWXXur2s9AEkWjk038sD1Ndoq+++so1VVHadWgvQ0qfVXFQNYNTbaVopklmobHMqOifimGLekZSUcDQmhRq5qcaIGpGovGyKoLuJzWL1DZWzSiv7W5o3SXttur95cwzz3Q91HiUIvjll1+69uX6bipXrmypQKmxU6dOtV69eoX10uhRzzyLFi1yRbQ9KnyqGiCqMaHvRj3X+E1deX744YcZhqumVdu2bcPSM1VrSSnB6hFRfwtNo85s/Q41zeEwbty4TLvkVjNK/QZ++OEHV5MgMyrgHPp7a926dbA5n+rIaX9Vb5XaX9W+OpoutrNjzZo1Nn78+AzDGzRoENbMR/ueaoCoOZLqR6Xv1Ue9ci1YsMB69+4d1lTD+27U+5qOgaTFm9s3VKdPBVa9mjEeFbBX/Rh1SBDabCeraZIh0n4jqsmhmkyiOgHlypVzx1GvKc63334b7NFU55YyZcpYKlBzbS2bUuq9OmmZHcdU9yq0DsmsWbNs4cKFbp3VTXGyvxuPfnubN29230dm3nvvPVcwVPuT992otoW+G53z1Ltu6Hr6RcugTlXS69y5s2sK7FEPiCpEvHPnTresOmZltX7RTJNo3vVfevpNqEaXqDOAzHrMVCF51TEL/b2pHpO6wRadJ9QLq/ZXNWnwrtEOJ13/ZVbvTfv9scceG7yu0vFKTS90XavtrPVNfw7VuaRTp05htUL03aj5ooq6h14vI2t+79c5mY6J+t2oR1Xts9rXuC75P6oDuXHjxgzbTNd1ofccahL69ddfu2E6t+u6JK9Rj9PqICo9XeuGHte0rXTvomt51fBV79l5zaoI94CiDrZCO1xRB1Cffvqpux/SPZB64otFng9IAQAAAAAAwF95tqg5AAAAAAAAkoOAFAAAAAAAAHxFQAoAAAAAAAC+IiAFAAAAAAAAXxGQAgAAAAAAgK8ISAEAAAAAAMBXBKQAAAAAAADgKwJSyPXGjh1rgwYNstyoe/fuNnfuXEsVl1xyiaWlpSV7MQAgLjpX6JyR2/zyyy/u+Lx3715LBTpPaHkAICf6559/3DFs6dKlltuMHz/eBg4caKnirbfesoceeijZi4HDiIAUcowJEyZYv379Yp5uyZIl9tVXX1lu9OGHH9q6deuS8tlXXHGFzZs3L8NJbMOGDUlZHgDw6OJVF7Gx0rlC54zcZvPmze74/O+///r+2bph042bbuA8Ok9oeQAgJz5MPXDggDuGbdq0yXKbn3/+2b788suUSSLQd/Ptt98mZXngDwJSyDF0UfvFF18kezHw/3zwwQf2xx9/sD0ApBxdvJKtmRp0w6YbN93AAUCq4WFq6sjNSQSIrGAWfwNShgJRetqtbCAvzb9379521lln2cqVK+2VV16xVatWWfXq1e3GG2+0unXrRpyXntIOGDDAihcvbg888IDly5fPPv/8cxdg2bNnj5100kl20003WdGiRYPT6DP79+9vc+bMsQULFli5cuXs1ltvtZo1a0b8nNtuu80FbPLnz29Vq1a1888/384888yYx4lVItZF20jb9LvvvnPb9Oqrr7ZnnnnGrrnmGjvttNPcPDXO448/bqNGjbLy5cu78WX//v32/PPPR72dACCRhg0b5oJRa9eutRUrVrhhL730klWsWNGmT59u7777rm3bts0aNWrkjmUlS5aMOC+dc5SZ26VLl2CWz5gxY9x8jjjiCGvbtq117do1OL4+98EHH7Thw4fb//73P/vtt9/shBNOsP/85z9hx+FQGzdudOczKVy4sNWpU8euu+469/9YxolVotblr7/+sueee85tb/29c+fONnjwYBs5cqTt2LEj+LRbWbU61+kcd9xxx7lhOv9Fu50AINF0HPWyal9++WWrXLmyO+YdPHjQ3Xfo/kPHrfbt29vll1/u7hkiUSBF89C9xfHHH++C8Tq+Kcii+V522WXWtGnT4Pia/6+//modO3a0999/37Zs2eLua3SsjETLo/OZlChRwho0aODODbqniWWcWCVqXebPn2+vvfaay9Y99dRTrUKFCvbNN9/YU089ZZ9++qnLkNI5xbvXu/3224PT6p4k2u2EnIUMKeQICjApuFK2bFl3QtBLw3SzoZsK/b9du3YuKHXyySe7dNPM7N692y644AKbMWOGO8jpxKKTkE5ItWvXttatW7sDYsuWLW3fvn1hT090ka3POeOMM2z58uVunJ07d0Zc5k6dOrnl1EFVy33RRRe5C/RYx4lFotZF8xgyZIg1b97cBZV0ItaNy5o1a9zftQ0LFChgrVq1csuv96HTxrKdACCRTjnlFDvqqKPcDYF3vtCF+Ntvv+0uYhWA0vFJgSkF2BVEj1R3SX8vXbq0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pUuXttWrVydiuQAAAAAAAJBLxRWQOvHEE+2NN97IMHz06NHWoEGDRCwXAAAAAAAAcqmYetnz3H///dalSxebO3eunXHGGRYIBOzbb7+1cePG2cSJExO/lAAAAAAAAMjbAalOnTrZ5MmT7bHHHrO+fftavnz57OSTT7aPP/7YOnTokPilBAAAAAAAQN4OSEnHjh3dCwAAAAAAADjsNaQAAAAAAAAA3zOkfv/9d5s0aZLrVe/ff/8N+9uwYcPiXiAAAAAAAADkbnEFpD777DO76KKLXN2omTNn2llnnWWLFi2yjRs32plnnpn4pQQAAAAAAEDeDkjde++99t///td69uzpCpp//vnntnfvXrv++uutZMmSiV9KIEkajm4Y9bhpPdIO67IAAAAAAJCna0gtWbLELrvsMvfvAgUKuGDUEUccYU8++aR98MEHiV5GAAAAAAAA5PWA1J49e6xEiRLu35UqVbJff/3V/btgwYK2c+fOxC4hAAAAAAAAcpW4i5p7zjnnHOvVq5f16NHDxo4day1btkzMkgEAAAAAACBXiitD6p133gn+W830atWqZY8//rgVLlzYXnvttUQuHwAAAAAAAHKZuAJSl19+efDfZcuWtTFjxtiKFSts8uTJVrt27ZjmNX78eGvdurXVq1fPunbtasuWLcty/AMHDtiECRPs7LPPdoGwOXPmJGS+AAAAAAAASOGAVP78cU2WwcSJE11wSwGjt956y2VYnXHGGbZp06aI0/Tv399GjhzpiqqvWrXKFVRPxHwBAAAAAADgj7giSxUrVrS//vor2x/+0EMPWffu3e3WW2+1Jk2a2KhRo1wG1MsvvxxxmiFDhriAU/v27RM6XwAAAAAAAKRwQOrGG2+0QYMG2b59++L+4B07dtj8+fOtY8eOwWGFChWys846y77++uuI06knv8MxXwAAAAAAAKRwL3uffPKJzZs3z9577z2rU6eOaxIXKlJdp1Br1651/69UqVLYcL1ftGhRPIuVrfkquBYaYNu+fXvcywAAAAAAAIAEB6S6dOniXtlx8ODBTDOelM2k5nV+z1dNAR988MG4PxcAAAAAAAAJDkg9/fTTdvfdd7t/X3PNNVatWjXLjgoVKrj/b968OWy4Co+rRpXf8x0wYID16dMnLEOqevXqcS8HAAAAAAAAsllDqm/fvsF/JyJQc9RRR1mNGjVs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VqNGDXe8Of/8823EiBFhQc1PPvnE7SulS5e2v//+2+rUqWOTJk2yypUrJ3X5AQAAACAWNNmLwg033GD58uVzgYNff/3V7rzzThds+euvv2La2LmZgjAzZswIvvJiMEoUgFLgZOrUqRHHueuuu2zNmjUug2rZsmU2dOhQu+6661wAIrdbunSpC7499thjWY43cODAsP0ptwej5JdffrG7777bBTIXLFjg9g0FOO+7777gOJs2bbLLLrvMbr/9dncs0jGpUKFC1rNnz6QuOwAAAADEioDUIWzYsMGmTJliffv2taJFiwYDCoFAwMaOHRvzBs/NWWTK7NANc1528803W+fOnS1//vwRm1q9/fbbdttttwUzyhRMUDaQsu5yu0ceecSaN29+yPG0H2l/0u8vr7jkkkusffv2YZli5513ngvIecaNG2cHDhxwxyAvO1FBrE8//dT++OOPpCw3AAAAAMSDgFQUzWgUfGrSpElwmAJTqiOlLAb8HzU1UmBFtX7UlFEBKmSkrJfdu3eH7U/KvmvatCn7U4iHHnrIrr/+etccrU2bNq7eVl6j4868efPs6KOPDg7TMef4448Pa8KnAJ/G/fHHH5O0pAAAAAAQOwJSURQYlvLly4cN13vvb3nd888/7zJaFLxbsWKFa47Wo0ePZC9WSmJ/ii4Ype2kAIuKe//zzz+umVr6wvm53TPPPBOsK+XRdsnsWOT9DQAAAAByCgJSh6D6LLJ3796w4Xv27LHChQsfvm8mB1Emi9dETT3r3X///a6GEjfIGbE/HZrqaRUs+H8dgFaoUMEeffRR1/OeaiblFWPGjHF1tEaPHm2NGjUK238yOxYJxyMAAAAAOQkBqUPwuppft25d2HC9V09YyOioo45y/1fBZbA/JWp/Sv8bzK3eeust1/x15MiRGToH0PEos2ORcDwCAAAAkJMQkDoEZScoS+Ojjz4KDvv5559dj1ihBYjzql27dmUYpuwo1dlS/R+EU6HqevXqhe1P6q1x9uzZ7E9Z7E8FChRwtZNyu3feecdliL3++ut25ZVXZvi7jjnKFFuyZElw2MSJE61cuXLWuHFjn5cWAAAAAOL3f+1iEHkDFSzomgz95z//sdKlS7smaQ888IC1bdvWOnTokOe33IQJE+zdd9+1rl27up7ivvzySxs2bJgNGTIkrPByXqFsFRXgVi0trwj1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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plot_histogram_grid(\n", " \"token_aa_length_histogram_train\", \"token aa_length\", \"Token length distribution (train usage)\",\n", @@ -729,18 +292,10 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "b512e365", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "No alarms triggered.\n" - ] - } - ], + "outputs": [], "source": [ "alarm_rows = []\n", "for vocab_size in vocab_sizes:\n", @@ -766,627 +321,10 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "4add4d20", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "vocab_size=50000 (actual=50000)\n", - "\n", - "top by frequency:\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenidcountmean_relative_positionmedian_relative_positionstd_relative_positionfraction_start_thirdfraction_middle_thirdfraction_end_third
0##G27833390.5440170.5357140.0886000.0062640.8991830.094554
1##S25209990.5551270.5666670.0849280.0083810.9079960.083623
2##ETQYF6761710.8289050.8333330.0221410.0000000.0000001.000000
3##TDTQYF7658730.8056950.8125000.0240520.0000000.0000001.000000
4##NEQFF5958500.8294400.8333330.0223140.0000000.0000001.000000
5##EQYF5357850.8552520.8571430.0188660.0000000.0000001.000000
6##DTQYF6255870.8291220.8333330.0218870.0000000.0000001.000000
7##QETQYF9652480.8011150.8000000.0238890.0000000.0000001.000000
8##EQFF5549290.8568630.8571430.0197610.0000000.0000001.000000
9##YEQYF6347720.8264850.8333330.0221540.0000000.0000001.000000
10##TQYF5045710.8547800.8571430.0201520.0000000.0000001.000000
11##YNEQFF7741440.8037500.8125000.0242590.0000000.0000001.000000
12##SYEQYF10740810.8015840.8000000.0226450.0000000.0000001.000000
13##SYNEQFF16539290.7834110.7812500.0242490.0000000.0000001.000000
14##YGYTF7936870.8241130.8333330.0231570.0000000.0002710.999729
\n", - "
" - ], - "text/plain": [ - " token id count mean_relative_position median_relative_position \\\n", - "0 ##G 27 83339 0.544017 0.535714 \n", - "1 ##S 25 20999 0.555127 0.566667 \n", - "2 ##ETQYF 67 6171 0.828905 0.833333 \n", - "3 ##TDTQYF 76 5873 0.805695 0.812500 \n", - "4 ##NEQFF 59 5850 0.829440 0.833333 \n", - "5 ##EQYF 53 5785 0.855252 0.857143 \n", - "6 ##DTQYF 62 5587 0.829122 0.833333 \n", - "7 ##QETQYF 96 5248 0.801115 0.800000 \n", - "8 ##EQFF 55 4929 0.856863 0.857143 \n", - "9 ##YEQYF 63 4772 0.826485 0.833333 \n", - "10 ##TQYF 50 4571 0.854780 0.857143 \n", - "11 ##YNEQFF 77 4144 0.803750 0.812500 \n", - "12 ##SYEQYF 107 4081 0.801584 0.800000 \n", - "13 ##SYNEQFF 165 3929 0.783411 0.781250 \n", - "14 ##YGYTF 79 3687 0.824113 0.833333 \n", - "\n", - " std_relative_position fraction_start_third fraction_middle_third \\\n", - "0 0.088600 0.006264 0.899183 \n", - "1 0.084928 0.008381 0.907996 \n", - "2 0.022141 0.000000 0.000000 \n", - "3 0.024052 0.000000 0.000000 \n", - "4 0.022314 0.000000 0.000000 \n", - "5 0.018866 0.000000 0.000000 \n", - "6 0.021887 0.000000 0.000000 \n", - "7 0.023889 0.000000 0.000000 \n", - "8 0.019761 0.000000 0.000000 \n", - "9 0.022154 0.000000 0.000000 \n", - "10 0.020152 0.000000 0.000000 \n", - "11 0.024259 0.000000 0.000000 \n", - "12 0.022645 0.000000 0.000000 \n", - "13 0.024249 0.000000 0.000000 \n", - "14 0.023157 0.000000 0.000271 \n", - "\n", - " fraction_end_third \n", - "0 0.094554 \n", - "1 0.083623 \n", - "2 1.000000 \n", - "3 1.000000 \n", - "4 1.000000 \n", - "5 1.000000 \n", - "6 1.000000 \n", - "7 1.000000 \n", - "8 1.000000 \n", - "9 1.000000 \n", - "10 1.000000 \n", - "11 1.000000 \n", - "12 1.000000 \n", - "13 1.000000 \n", - "14 0.999729 " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "top longest tokens:\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenidcountaa_length
0##PGLAGGSSYNEQFF38092214
1##RSRPNHSGANVLTF44569214
2##LAGGPSSYNEQFF13942613
3##TSGGPSSYNEQFF20968613
4##TSGGLSSYNEQFF28237413
5##RLAGGSSYNEQFF44438313
6##LAGGSSSYNEQFF35627313
7##LAGGLSSYNEQFF20962313
8##LAGGPGSYNEQFF46644213
9##LAGGRSSYNEQFF38509113
10##PGQGSSGANVLTF34381113
11##LAGGPLSYNEQFF37491113
12##LAGGSSYNEQFF57722912
13##TSGRSSYNEQFF133511512
14##TSGGSSYNEQFF155781312
\n", - "
" - ], - "text/plain": [ - " token id count aa_length\n", - "0 ##PGLAGGSSYNEQFF 38092 2 14\n", - "1 ##RSRPNHSGANVLTF 44569 2 14\n", - "2 ##LAGGPSSYNEQFF 13942 6 13\n", - "3 ##TSGGPSSYNEQFF 20968 6 13\n", - "4 ##TSGGLSSYNEQFF 28237 4 13\n", - "5 ##RLAGGSSYNEQFF 44438 3 13\n", - "6 ##LAGGSSSYNEQFF 35627 3 13\n", - "7 ##LAGGLSSYNEQFF 20962 3 13\n", - "8 ##LAGGPGSYNEQFF 46644 2 13\n", - "9 ##LAGGRSSYNEQFF 38509 1 13\n", - "10 ##PGQGSSGANVLTF 34381 1 13\n", - "11 ##LAGGPLSYNEQFF 37491 1 13\n", - "12 ##LAGGSSYNEQFF 5772 29 12\n", - "13 ##TSGRSSYNEQFF 13351 15 12\n", - "14 ##TSGGSSYNEQFF 15578 13 12" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "top non-single-amino-acid tokens:\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenidcountaa_length
0##ETQYF6761715
1##TDTQYF7658736
2##NEQFF5958505
3##EQYF5357854
4##DTQYF6255875
5##QETQYF9652486
6##EQFF5549294
7##YEQYF6347725
8##TQYF5045714
9##YNEQFF7741446
10##SYEQYF10740816
11##SYNEQFF16539297
12##YGYTF7936875
13##TEAFF8736325
14##STDTQYF20834937
\n", - "
" - ], - "text/plain": [ - " token id count aa_length\n", - "0 ##ETQYF 67 6171 5\n", - "1 ##TDTQYF 76 5873 6\n", - "2 ##NEQFF 59 5850 5\n", - "3 ##EQYF 53 5785 4\n", - "4 ##DTQYF 62 5587 5\n", - "5 ##QETQYF 96 5248 6\n", - "6 ##EQFF 55 4929 4\n", - "7 ##YEQYF 63 4772 5\n", - "8 ##TQYF 50 4571 4\n", - "9 ##YNEQFF 77 4144 6\n", - "10 ##SYEQYF 107 4081 6\n", - "11 ##SYNEQFF 165 3929 7\n", - "12 ##YGYTF 79 3687 5\n", - "13 ##TEAFF 87 3632 5\n", - "14 ##STDTQYF 208 3493 7" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def show_top_tokens(vocab_size: int) -> None:\n", " entry = per_vocab_size[str(vocab_size)]\n", @@ -1434,87 +372,10 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "63efe7a0", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
 vocab_sizestart_thirdmiddle_thirdend_third
010026.4%56.1%17.4%
110008.9%50.9%40.2%
2100000.7%35.2%64.1%
3500000.3%38.2%61.5%
41000000.2%36.5%63.4%
52000000.2%37.7%62.2%
63000000.2%40.0%59.9%
\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "position_macro_rows = []\n", "for vocab_size in vocab_sizes:\n", @@ -1540,21 +401,10 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "482a56a8", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3kAAAHqCAYAAAC5nYcRAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAiZVJREFUeJzt3Qd4FMUbx/E39N57R5rSEQQpVlCKBQUVCygqKFhQERVQ/2IHFHsXGyoiIgqCCKgggoCANAVBeu9VOuT+z2/CnpfkEpJwl+SS7+d5DnJ7c7uzs+X23ZmdifL5fD4DAAAAAGQIWdI6AwAAAACA0CHIAwAAAIAMhCAPAAAAADIQgjwAAAAAyEAI8gAAAAAgAyHIAwAAAIAMhCAPAAAAADIQgjwAAAAAyEAI8gAAAAAgAyHIw2mrX7++tWnTJqJLMioqyvr27Rv25fz5559uWZ999lnYl4X0Ze/evXbrrbdaqVKl3D7Qo0ePtM5SpqDjWuWdkezZs8et04svvmjpzRtvvOHytmXLloiYLzKWSNtPnnnmGZfff//9N+zL+uijj6xYsWK2f/9+i5Tt8eabb1rZsmXtwIEDIc9bZkCQl4lde+21lj179ngnl4MHD1qOHDncgblhw4ZYn0VHR1uRIkXs/PPPT+XcRo4VK1a4shs6dGimzoNo31I+9Hr++efjfT5u3Dj32ahRoyySpKR8n376afvuu+/s119/NZ/PZ++8845lNgMGDHDldvjw4bCkz8x0EaWyeuWVVyxSKWjVOuzYscPSi/SYJ0SWUO1Dy5Yts9tvv92qVq1qefLksTPPPDPJx7uCpEcffdQefvhhy58/f8jzFi7du3e3bNmy2eDBg9M6KxGJIC8Tu/jii+348ePuojOQ3mu6TiI///xzrM8WLFhgu3fvdt8FkmPgwIHp9ockNfzyyy/WpEkTq1atWlpnBRGuUKFC7kZBnz59LLO455573DqrJhzIjJ544glr3ry5zZw507Zu3Wq33HKLPfDAA/byyy8nqRZv165ddscdd1gkHbeqcFCg9+qrr1KblwIEeZmYF6jFDeT0vlatWnbhhRcG/UxatmyZijlFpLvkkktcDfFTTz1lmZUC3Ny5c6d1NgAAEWjEiBF22223WfHixV1tXL9+/dwNnzFjxpzyu2o5cvnll7v0kaZz587ucQetP5KHIC8Tq1GjhpUrV86mTJkSL5C76KKLggZ5SqsaPtVIxLVq1Spr3bq15c2b10qXLm3/+9//3B2cuH744QcXYBYoUMBd9J577rk2fvz4oM/5/f33326e+fLls65du7rPjh496pq+nXXWWZYzZ07Xxvymm26K17Q0mE2bNtn1119vBQsWtMKFC7sTZkJt4XXX6+6773ZlpLtJFSpUsPvvv9/27duX4Px//PFHf02N7j55TRWD3XHXCUvbIFeuXG5945Z1Stc1KXlIyroFPj/4wQcfWJUqVVxeGzVqZJMmTbLkqF69uruDqB8aNXVMrsC86I6kmqtoP7vsssts8+bNLo3yqPVWHs877zzXtCWupKy39lk1YdGNDi1DzwN07NjRFi9enOTyDaSmqPp8zZo19vXXX/vTq1Y8cL2GDRvmtrOapmgZorLS9i5ZsqTLr5arGlE1m457TDVs2NCtu7aTykLz1Ly1jMAfS617XB9//LFLq+MtUFKW7z3zpiaVKtuiRYu6CxA1Bw+sudXx++STT7q/ddwHlkMwSUn/22+/2aWXXuqOZ6VRGSTledelS5e6ctJx5x1Lar0waNAgt91VjmqWft1117nzmkfbUHnQfvzNN9/409auXdu+//77oM+j1K1b152/dE5s3769zZs375T5O9X34j6TN2vWLJdOdGffK6vkPvcZuH4jR45066Um/d9++63/c20XLUv7wxlnnOG2kcouMd4x4L20XvoNGT58eKw7/g899JD7WxexXtrp06cHfbbnyy+/dO+178elbaHPtI0C1y25eT9VnmTu3LnuPKSLZ+9cnpRm3KqJ0flD5yDtu/otUFM6tZQJlNR867dZZao8VKpUyT3LpO2m/Gr/8GifCHah720jrU9yl+89V6a89+7d25WVtvFVV13lPz/Hnad+e3Uu8o4f1dQcO3Ys2eudVOFYj59++skaN26caJknZR8SrXtSlhlozpw57lxQuXLlRNOtXr3a/vrrr3gtsE6VN688dB6/77773O+A19QzKcd0Qs/kJbecVbZax7Fjxya6ngjCh0ytS5cuvixZsvh2797t3u/Zs8eXNWtW39dff+37/fffFaH5/vnnH/fZsWPHfPnz5/ddeumlseZRr149X9OmTX1XX321b968eb69e/f63njjDffdjz76KFba999/3xcVFeV75JFHfOvWrfPt2LHDN2jQIJcHLTNw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Irq4V1qvGaWuFefPn+9Pqw4zwtmT4QMPPOBqvUQ1YKq9CszrqUyePNld27744ouu8kJd5z/33HMu6BgzZkystL169XI1dnEpWMyePbv7++qrr3Y1U0899ZR7lk3za9++fZJq8vQsmddcUZUohQsXtuHDh8dKo22jZ9DUocjFF1/sas08CqJUg+U9Q6eaKi8YVWWMnq9TjaWCKm1v1ZxpPsl9NlH5VJNIufHGG11NnwK+lC5ny8kmncWKFbPkmjhxolWrVs01yYzb8lDNP2+66Sb3fJ4CzbhUa5rU5qSZIsgLthFUSGqbnBC1K9bBEvgCAABA2tDFeGBnFmoG+MILL7i/N2zY4JotqtZKhg0b5jqx8KgmTBf6opovpfWaN+pRIDXT8/Ts2TOsHVwokAmkICnYs3kJUc2T5qFmh558+fJZ5cqV3WeBNC0YNRGMO4h23GlJqS1TByMe1TopUPLyoGtp1ezpMSttC22vb775JtYzZQ8++KCrvVJTSdWu6XOviaICLgXnqmXU82mqqdQ81LQzuTV5gWXuBaVemadkOTlOBozJ6QAyWFPNQC+99JLLi2IXBf5qWhr4vKRXpjlz5rRwCX93NWEYGFAPWwbSe939SIiqj3WXI90b8F/vSwh12e4N03zZZmHFdos8bLPIFI7txvkxvCLhWMtX3qz5ELNth8yyxR7c+c72zazjeTXNNsXUuo147QnLnzePe18uyxGb98PnVq1MNvf+5ksb2KX13/an/XjQw5YrVw73vtixYy5tlYr53fvrzj/Lmn33sT/t2wPutWzZsvrfJ0XUvpNB2vZlZpv+u748fvSI2e41see1c0Xs98cPm+3d8N803wmzXatj3pdpEG9ZClLiXvyLmlsGdgIiCV7rblpglutksLDjZGAYmKddq8x80QmXwY7l7r9Dq+dY4UPF/8vDnu2W11fWfe/1d4bZb79OsdUzv7MypWLS/O+Ft23spF/8861ZyGzFtK/s9/l/2pTf5lrv++6xd14dbBOHv2U5og9ai0Z1bOzHrySwDvPNtp3sX2PLIrOjheO/P5nPWOu76+TwCtv+NtvkS9py4qicO6ZZ7IY/frRitWtYUimAnTBhgn399dcJplGArSaln332matxVnNdjwJkBdLhElE1eV7krmr7QHof905KID33p2p875VYjz8AAAAIr9Ili1uds6r539es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5i5aalUqlrOPRo61a+98ONHmjH2eetnu6v+8FStSyPVAf95559muXbtifadPnz521113uZZyCaWJ64033rB27dq5ALFiudL24Ygx1uLq2+3YsWOnXLcGtWpY1qxZrEaVinbu2XWsYd2z/J/d+ciz9sOU39w6T5051xpfdrMdPHQowfVTObXtcq9NnjbbalWvYuVKl3CxwUXX3mEffjnWvZ+z8C+XBhFQk6e7BB988IHrgOWPP/6w6Ohoq1+/Pk01AQAAkCFce3kre+PZvu5v1VDVuugau7rNRfbC4w+4ac0a1bMml99s23bsshLFisT7/up1G+21D0fYD5+9bi3Pa2JWpoHVrVvXOnXq9F+a1avttddecy3iWrZs6abFTRPXhg0brHfv3jZ79mxr0KCB2ab5dtct11nNizrasFHj7fYbrkp0vTq1b22393nKNde8qs1FsT678tLz7c3n+rm/u990tZWo28omTp1pV7e9OMH5tWrRxD559Sn/+2FfjbNlK9famlnjrHChAm7aXf2et7eHfZVovpBOBkOXsmXLuhcAAACQkbRs0dj/d9VK5d3/FzePP23jlm1Bg7zpv8+3/PnyxAR4J3Xs2NGyZfvv8nv69OmWP39+f4AXLE1cEydOtCxZsti7777ravLswA7zmc9OnIi2BX/F7kwluRT4efLkzm3ly5S0DZu3Jfqdthc3j/VetZ8tW5zjD/Ck05WXEuRFQpC3aNEi+/zzz23QoEHxunvt0qWL1alTJ1T5AwAAAFJd7lw5/X9nyRIVZFrMU08KroLZtmO3FS1UMNa0rFmzusec/Gm2bbOiRYsmmiauHTt2WN68ea1Ro0YxE/asc/81rl/bqp9RwU5H4Pp5eVHzy8QUKpAv1nvVbAY+xydqrooICPI0VoeaasalZ/LU+cpPP/0UirwBAAAAEUm1YJu37bDjx4/7a+b+/fdf27lz539pypd3w48lliYutaLbs2ePXXvttVawYEHXXDO5AnvHD7XyZUrZqnUbYk1bu4Eh1iKi45Xff//dzj777HjTNU3tgwEAAIDMTE0fVROm8eE8r776akwTSy9Nq1YxaT74IME0wSpVChQoYP369XP9YniWLF91ysHMPUUKFbBde/ZaOHRoe7H9NH2O/fl3zDh/qgl8/aMRYVkWQlyTV7x4cddt64UXXhhruqYVKRK/TTIAAACQmRQpXNBeeqK39ez3nH07caodz5rHNbV0tW9emiJF7KWXXrKePXvat99+62r04qaJq3Dhwm7oBHXOojGq61WvYGvWb7KDhw7biLefT1Le1OHKY4Pfsmmz5lvRwgX9QyiEQqvzm9hNV7e1Flff5jplWb56rRWJ02wV6TTI03N3t912m+u+9fzzz3d3G6ZNm2Z33323+wwAAABI68HJU+q9wY9a7RpV/e9V2/b+C4+7YQc8eXLnctMqlS+d4GDh6uny/CZn2+z5i6183fPs3HPPtdGjR1vjxv914HL77be762m1hlPzzWBpXn/99f+ewTNzFS1r1qxx19/bl8+xapUr2Dn1a/mfEzyVV596yK65rKUbDiFbtqxB11me6tPDalSplOD6BfuOfPzKk/bbnA62ZsMmO7NqJddJzcjvJluRwv91xoLwivIlVh+cgKNHj1r37t3t008/9Vcnq22vAryhQ4cmaSDGtKQxSHSHRIO4q7o73RjAXY7wlW14miSwzcKM7RZ52GaRKRzbjd80y+zH2uF85W118yFWuWxxy5UtfM+ARYwyDcIz3xQ8k4d0sN0ScfjwYTe8RuXKlS1XrlwpimNSVJOXI0cO++STT+zpp5+2+fPnuwBP4+RVqHB6PfoAAAAASDkN3fDxyO8SfBZv8GP3U7yZwGmNk6egjsAOAAAASB+KFyls554dfDizvHlyp3p+EGFBngZinDFjhu3atSveZ3pWDwAAAEDqqlG1knshc0tRkPfEE0/Yc889Z82aNXM9/AAAAAAAIjjIe/fdd23ChAlubA8AAAAAQIQPhn7s2DFr2rRp6HMDAAAAAEj9IK9Fixb2888/n96SAQAAAADpo7lmjRo17IYbbnCDN1atWtUNoRDonnvuCVX+AAAAAADhDvLGjh1r5cqVcz1s6hUXQR4AAAAQ3/fff2+1a9dO8TBko0ePtubNm1vJkiUTvlaf9Is1rHOWlS1dIlnzPnDwkE34eYZd1rKF5c4dexBuZILmmn///XeiLwAAAADx3XHHHTZt2rQkFc23335rmzZtijXtuuuus/nz5yf6vZvve9xmzluU7OLfvHW7XXvnw7Zz995kfxcZaDB0AAAAINneuzB1C+2OqRaJOnfubJ999pldddVVyfpe+0svtHLJrMVDxpKimjz59ddf7dZbb7ULLrjAP+2dd96xffv2hSpvAAAAQJo4evSY/Tr7D5s49TfbsGlrvM9Hf/+Tbd2+070mT5tlcxcuMZ/PFy/dlm07bPyPv9qiRYvsxIkTSV6+hitT+pkzZ9qoUaNs3LhxsT7funWrTZ48OehyO17W0sqXKRUvr+s2brZxk6fZkuWr/J8t/WeVa6K5au2GJOcNGbQmT22Bu3TpYjfddFOs6ua9e/faiy++aE899VQo8wgAAACkmtl/LLaO3R+yEsWKWIlihW32/D+tZ5dr7Ll+9/rTXNejr7W7uLn9tXyVVT+jgs1ZsMSan1PPxnz0sj/NV99Ntpvv/5/Vr1ndjkUNs1y5ctnBgweTlIfvvvvODVumipWVK1da4cKF7fLLL3efvfXWW/bXX39Z9erVbc7sWfGWq+aaQ1/4n11zeSt/Xttc2NT+XLbS6tWsbjdd3dZqVj/DHnzyJXt72Chr2rCOrV6/yWrXqBLCUkTEBXkK4kaMGGFXXHGFvf/++/7pHTp0cAOkE+QBAAAgEqnzkatuf9Ceefguu/2GmGaSazdssvqX3mAXNmtkl17w31jR+/89aEumjLKcOXO4mrAa53ewqb/Nden27f/XevZ73p556C57sEcXszINrF+/fjZjxowk5UOB3LBhw+zhhx+O11xz//79tmTJEsuZM6etmvldrOUmZPuuPbZk6ijLkzu3ez9jzgJ7Zehwmzn2Y2vcoLarubz0xrtSVmjIGM01ly1b5oI5CRw+oXTp0rZ58+bQ5Q4AAABIRd//NN12791nhQvmt28m/Oxe8xYttTMqlLWfpv8eK233m652AZ6cUbGcVSpX2v5esca9nzxtth08dNjuve16f/q+ffvGG3osJbp37+4CvGDLTcgdN3XwB3gyYsxEu6hZIxfgSY4c2a33HZ1PO2+I4Jq8YsWK2apVq6xWrVqxdtRffvnFKlasGMr8AQAAAKlm9fqNli1rVhv+zQ+xplcuX9YqlP3vOTcpUqhArPcK+A4fOeL+Xrths5UtVdwFT56CBQtakSJFTjuPcecRuNyElClZPNZ75a9yhbKxpimQRSYO8m6++Wbr0aOHa6qpIE/P4v3www92//33M0YeAAAAIlb+vHktOtpnX74z0LJmzZri+SgA3LNvf6xp0dHRadZJYdwKxCKFCtqevbHzFze/yGTNNQcMGOAe9FRNnnr9KVSokN1www122WWX2SOPPBL6XAIAAACp4JLzm9iRo0ft01HjY00/fvy47dy1J8nzadqwru3as89+m7PQP238+PGuM5Wkypcvnx05RQ1dSqmzlp9m/G7/HvivI5hvJkwJy7IQITV52bNntw8++MB1sPLHH3+4uxL169enqSYAAAAiWtXKFezph3ranX2ftYVLlluD2mfamg2bbOR3k+3NZ/vaBU0bJmk+NapWstuub28d73jI+t7d1Y7n/dlefvll/7N0SdGwYUM3RJmGSFDA5/WuGQq3XHuF63ilVace1u3Gq23pP6tt2KjYwzQgkwV5+fPnd736lC1b1r0QGgPsAYoyTAZQsgAAIIn697rdBXOjxv1ok6bNtGqVK9iYD1+yKpXK+9N0bHexlSpeLNb3Lj3/XJfW8/bz/ezs2mfajLkLrHz1bDZp0iR79dVXk1wxMnToUHvjjTds7NixljdvXhfkdezY0UqVKpXocuMOhh4sr3pW8NfRH7hAb9qsP+zMqpVs2uih9vjgty1P7lzsKxEuyhds1MZTKF68uP39999WtGhRi0RqC60HX/UsYYECsR+YTUtqBosIK9sBBcMzX5ws373hKQm2W/iwzSJTOLYbx1l4RcCxdjhfeVvdfIhVLlvccmU7/R4lI16ZBuGZ76b54ZkvwrvdEnH48GFbvXq1Va5c2Y2tmJI4JkU1eV27drWnn37aDXyeLVuKZgEAAABkWmvWrLG5c+cG/SxPnjzWrl27VM8TMo4URWizZ8+2X3/91Q2Irg5YcuSIGR/E8+OPP4YqfwAAAECGs3LlSnctHYxayxHkIdWDvGbNmrkXAAAAgORr2bKlewHpJsi75pprrFGjRiHJwLBhw9wDqFu3brU6derYoEGDrG7dugmm//fff+2ZZ56x77//3nbv3m0VKlRwY/Z16dIlJPkBAAAAgEw3Tl6TJk1CsvCRI0dat27d7N5777WffvrJypUrZxdddJEL+BLSs2dP++qrr+zNN9+03377zT0feOutt9ro0aNDkicAAAAAyHRBnmrP1I74dD377LMuQFOgVqNGDTcOiDpyeeuttxL8jp4FVK3deeedZ+XLl7fu3bu7Qdk1HQAAAOnEyQ7ck9+PO5C5+UJw0KQoyHviiSdcDdyff/5px48fT9GC1e3nokWLrFWrVv5pWbNmtYsvvjjRgO2yyy5zTTW3b9/u3qs2TwEnD6cCAACkH9mP7DI7cdQOHkvrnACR5eDBg+7/7Nmzp+4zeQrwTpw44Z6hi4qKsixZYseKSQn8Nm3a5P4vWbJkrOl6v2DBggS/99prr1nnzp1dOnUve+zYMXvvvffskksuSfA7R44cca/A8SUAAAAQPlmPH7RCayfYthzXmFkhy5PdLCozD5d3+HB45nucqtKI3G4J1OApwNu2bZsVKlTIVYClapA3btw4C1U1ZNzMq7lmdHR0gt/r1auXG1NEz/BVqVLFJk2aZHfddZcL+tq0aRP0O88//7w9+eSTp51nAAAAJF2pf4a7/7dVbGuWNfaQW5nOgdXhme+emNZtiLDtlggFeKVKlbLTkaIgL6FgKjmKFy/u/veaXXr03vssLvWm+fbbb9vw4cNdBy1eraLG5VOvnAnlq1+/fta7d+9YNXl6ng8AAADhE2U+K/3P51Zi1Wg7lqto5q7Kuyf4wOen7Y1rwzNfhHe7JUBNNE+nBu+0grw9e/acMvo8FQVylStXtunTp9tVV13lnz5t2jTr0KFD0O+oiahqANVMM1Du3LkTbSKaM2dO9wIAAEDqy3rikGU9sCFzF32uXOGZ77/rwzNfhHe7hVmKOl4pXLhwoq+kUtPLoUOH2uzZs12QNnjwYPes3p133ulP88ADD7ieNKVYsWLWuHFjGzhwoG3evNlNU5A4atQoOl4BAAAAgJTW5M2ZMyfWez1D988//9jjjz8eq1nkqdx3333uwUL1sKmOUcqWLevGu6tevbo/zf79+10zzcCx9RQc6nk8Ua3ePffcYw899BAbFAAAAECml6Igr1GjRvGmqYatatWqLshT0JUU6pnzueees2eeecYOHDhg+fPnj5fmlVdeidUUs2LFijZmzBjXbPPQoUPxmm4CAAAAQGaWoiAvIbVr13Zj3yWXhmAIFuBJvnz5EgwQCfAAAAAAIATP5AWjJpvq+bJ06dKhmiUAAAAAIDVq8oKN27B3715Xu/bpp5+mZJYAAAAAgLQK8l588cV409Srpp7V06DkAAAAAIAICvI6d+4c+pwAAAAAANLmmTwNdzB16tR40zXt6NGjp58rAAAAAEDqBXn/+9//7Pfff483XYOaDxgwIGU5AQAAAACkTZA3bNgw69q1a7zpmqbPAAAAAAARFOT9+++/QZtlatqePXtCkS8AAAAAQGoFeS1atLCnn37ajY3n0d9PPfWU+wwAAAAAEEG9aw4aNMjOO+88mzZtmjVv3tx8Pp/NmDHDNm/ebL/++mvocwkAAAAACF9NXt26dW3hwoXWrl07W7lypa1evdouu+wyN02fAQAAAAAiqCZPKlWqZEOGDAltbgAAAAAAp4Vx8gAAAAAgA2GcPAAAAADIQBgnDwAAAAAyEMbJAwAAAIAMhHHyAAAAACADYZw8AAAAAMhAGCcPAAAAADIQxskDAAAAgAwkxUGeHDx40FauXGk+n8+qVq1qefLkCV3OAAAAAACp01zz6NGj9uCDD1rhwoWtbt26Vq9ePfe3pukzAAAAAEAE1eT17dvXvv76a/vggw/s3HPPtaioKJs5c6b179/ffT5kyJBQ5xMAAAAAEK4g7/PPP7fvvvvOGjdu7J9WpUoVq1atmrVv354gDwAAAAAiqbnmnj17XEAXV/Xq1d1nAAAAAIAICvL0DN7rr78eb/orr7zintEDAAAAAERQc83Bgwdb27ZtbfTo0f4mm7Nnz7bly5fbhAkTQp1HAAAAAEA4a/IuvPBC+/vvv61Vq1a2fv1627Bhg11yySW2bNky9xkAAAAAIMLGyatYsaK9+OKLoc0NAAAAACD1a/IAAAAAAOkTQR4AAAAAZCAEeQAAAACQgRDkAQAAAEAGkuKOV2TXrl3uFVfVqlVPZ7YAAAAAgNQM8ubNm2edO3d2wygE4/P5UpofAAAAAEBqB3k9evSwRo0a2fDhw61w4cKns3wAAAAAQFoHeUuWLLEff/zRChYsGMq8AAAAAADSouOVypUr2+7du0932QAAAACA9BDkPfLII67J5urVq0OdHwAAAABAajfXvPXWW+3EiRN2xhlnWJYsWSwqKirW58ePHz+dPAEAAAAAUjPIGzduHAUOAAAAABklyGvTpk3ocwIAAAAASJtn8iQ6OtoWLlxo33zzjX/akSNHTj9HAAAAAIDUDfI2b95sTZs2tbPPPts6dOjgn66/J06caJHir7/+ijUsxPr1693fhw8ftj/++MP279/v3m/dutUFtJ5ly5bZ2rVr3d/Hjh1zaffu3eveb9++3ebPn+9P+88///g7qNFzjErr9Uy6c+dO994bPH7Xrl3uJZqmcj548KB7f+jQIfdewbVoHvq+R58dOHDAn3+91/Jkz549tmPHDn/aLVu22L///usPzJXWe45S66F18GjdvXI4evSoS6t1ln379tm2bdv8afW3pnnlorT6jmgempdHy/DKTMtWWu8mgfKmPHqUd62DV4ZKq3UUrbPee1QmXvmqrPSZys4rX5W3V4arVq2yFStW+L+rz7xy0jz03isXbcPly5f70y5YsMC/7vuO+OyPzSfs6ImY7bhub7T9vSOm7GXR1hO25d+YZf57NCbt4eMxaTfsi7Yl2/9L++e2E7Zpf0zag8di0up/0XR97tH39H23zY/HpNX83Tb+N9ot16P8KF9uO56ISat8u+12INoWbPkv7fKdJ2z17pi0x6Nj0u4+FJN2x8Fo996zYle0rTqZNtoXk3bXybT6X+9PRMe8V7p/dv73XX22/UDMd/ccjkl77GQZrtkTbcsCylDl7e0/2se0bbz9Zd26dbZ06dL/ynvRIv8+oX1Jab19YMOGDbGO+7+2nbCNJ8vw0MnyPnCyDDfvj7bFW2OX9/q9sct7/8ky3PpvtC0MKEPlfe2emLRaJ6XdezgmrdZ5fkAZ/hNQ3ifilPfOk+XtnSNW7op2L9E0faY0sjtOea+OU97zA8p7b5zyXhunvLUuWifROgbusyqDwH1WZaSyEpVdYHlv3Lgxdnn/9ZfbBq68Dx1yab1zkbaZtp1H21TbVrStA/dZ5S1wn1Xe18Qp7z0B5R24z6pMVsUp77j7rPZlUTrt4x59tiNOeR8PKG8dOx7lT8dWxJwj/v7bX946b2vbeOdznet0DHp0LvR+13SODPxd0zlU71P9HBGwz3rlfeT4f+W9NKAMFwXss1556/j3ylvnhYg5R8S5jli5cqV7+c8Rf/zhv1bwfte8awNtQ12jeHTt4v3+h/UcEVDeG4OU94Y45e3ts5pH4D6rber9rmlbR8Q5IqHriJO/a941k45FHZMenRu96yLvd827DtI5leuIMJ8j/kjkOuKvv9xvXeDvmnc9rt+1xYsXhzzWCLymD3mQ98ADD1j16tX9C/P07dvXnnvuOYsUHTt29P99/fXX2wsvvODfgA0bNrR58+a598OGDbOLLrrIn7Zr16729NNP+wtaaadPn+7ejxw50s4991x/2p49e1r//v3d39roSqsxBuW7775z770TrgJkL0jWyfm9997znxAUkOi9F2D9/PPPNn78eP9yPvjgA/9Op5OD0noB4rRp02zMmDH+tJ988ol/R9IOqLTej/lvv/1mo0aN8qf9/PPP/eWgk7/SeoHo77//biNGjPCn1brPmjXL/2OitN6FuX48PvvsM3/a0aNH+8tMJyyl9Q4SHRAfffSRP+3YsWNt6tSp/oNCab0dXxeC77//vj/thAkT/OWriw+l9QK577//3pW3V4Z9+vSx++67z/9dffbtt9+6v6dMmeLee+Xy+OOP2x133OFP27x5c/+6z1x/whq+d8C2HYg5WTw77Yh1+SbmZCAthx20j+Yf859klNb7cX9p5lG79qv/0l4+/KC9NSfmJP/3jmiXVv+Lputzj76n74vmp7Tej5qWp+V6lB/lS5RPpVW+ZcSfx6z5hzEnJLnju8P2+JSYtPuOmEs7ZU1MsPvt38fde899Pxy2PpNifmiOnYhJ+/0/Mes6cUVM2sMn+2F65MfDds+EmLTS+P0DNnppzIfT1sak9X50B0w9YreP/S/t+eef7/ZFb7/TtvECuUGDBtlNN93kT9u6dWt3PHj7ktLq+JFXX3011o2p9iMO2hu/x5ThP7tiynDJ9pjyfnfeUWv7+X9leP2oQ/bCbzFpN+yLKcN5Jy8Mhi08Zhd98l+5dB1z2J4+Wd47Dsaknb4uZl1H/nXczv3gv7Q9xx+2/j+fvGlxLKYMf1wVk/a75THlcvI3yx6YeNi9RNP0mdKIvqP3modonpq3R8vUskV5UVrlTZRX5dmjddE6idZRabXOojJQWXhURiorUdmpvL0LxzfeeMPat2/vT6uy1zYQbROl9X4Atc207Tzaptq2om2tPPy+Maa8P198zM7/6L8y1L6ifUa0Dymt9inRPqZ9zaN9UPuiaN9UWu2ron1X77Uvi/Zt7eMefaZjQHRM6L2OEdExo2PHo2NKx1bEnCO6dLFnn33W/a0LT22bmTNnuvc61+mc59G5UOdE0TlSaXXOFJ1D9T7VzxEfHXD7hWg/UdrN/8akHTT9iN00+r8ybP3ZQfvgZHkrAFFa76L+1VlHrcPIQ5FzjohzHaHrM71E0/SZ0oh+G/XeuwDVtYmuUTy6dtHveNjPEe8dcGUpKluVsUdlr20g2iZK6wXS2mbadh5tU21b0baOiHNEQtcRM2e6beMFfToWdUx6WrZs6b8uUnCotN510EsvvcR1RLjPEQ0TuY5o39791ol++5RWwZy8++671rZt25DHGrqGTooon3f7JxmKFy/uAooSJUq4njW9WehkX7JkSX+0m14pnxrIXQGNaiRFGyR//vxWvnx5F0jofbVq1dw0BSq6g1KvXj1/dJ0rVy6rWLGiCxh0kVKlShU3TwVC2nANGjTwb/Bs2bK5sQV1wlVwpb8LFy7s7q7pIFValWOvXr3cd4oUKeLKVMvUPPPkyePKVLVZKl/1aKogSjVSRYsW9V8EFShQwPLmzevyr8+1fbJmzeq+p4CnWLFiLq3mmy9fPvfSHXIFbdqmyqcCd91J0nvRumv5KgdNV541n+zZs7ty1LK0HNHJSeWifKhctFMqfzly5HB3KhR0Kv+ictJ0rZ/ypvda75w5c7qgT69SpUq5tJqP8laoUCFXhlqOyk/L0o+V8lG6dGmXVvlT+ehzlY/yr+/pYlHruWbNGqtfv75LowNWaapWreq+q7skFSpUcOun8tNdzrp167pl62+tk25ueCfZMmXKWIm3qrk7QrqTV7tEFsuRNcrdEdKd9TOLZfXfESqRN8pK5cvi7ggt3xltNYtnsVzZotwdS32/ZvGYtLoLXyR3lJXJn8XNQxdvZxbLYnmyR7m79LqLWLtETFrduSuQM8rKFcji7qDqx7N60SyWL0eUu0uvC8q6JWPSqtZA86hQMIurTfhzW7RVLZLFfV+1DZv2+6x+qZi0qo3IniXKKhfO4u5ALtoabZULZbHCuaPcHcp1e312dumYtFrvLFFmZxTO4u5sLtgSbZUKZXHroLzqTlq9klksa5Yo94Otu6LVisZ8V3fRyheIsuJ5s7iTsj6vUyKLZc8a5b6nO2w13vjXX97axtp/tL0VuNeqVcvtL7qpof3grLPOiinvRYvc/qv02o90o0Sf5c6d2x2b2sdrfdXMf9e4UK4oK1sgi7trvHRHtNUomsXy5ohyd/F0gVOn5H/lnT9HlJUv+F95VyuSxfLnjHJ3B7f867N6J8tQdw+1fSsWyuLuKi7eFm1VCmexgrmi3F1jXQw1OFmGumuc7WR5q3wWBpS3aunW7vVZg1IxvRh7tXhVimRx54j5W6KtYsEoK5oni7trvDqgvHXX+HhAeatmoNzJ8tZd+pUB5a0AQOtU4+Q+q7v0pfJFWcl8Wdxdel2Qefus7tLvP/rfPqsfwGJ5oqx0/izuLv2ya6b6y1s3bnT+0bZy5f3XX+6YL1eunDun6SaNjimdi3QO03lAx5zoM53PdEzqPPVXr6L+fVblrR/n+gHlnTNblNv3vPLWPlnoZHmv3/ffPqvyVvmcEVDecffZ+qWyWJaomH1WN+G1XG+frVAwyooFlHfdklnc9lN5H4v2WfWT5a1gqkz+KCuRN0tknCOun+3O9Spvnev//PNPd27U+Vzn3E2bNrlzpztHLF/ufgP0W6bzt44573dN52sdk2rpYwMKhv8cUey/8i59cp/1yrtW8Sxuv1B5a988q/h/5V385D7rlfdZxbJY7uwx5a3jo9bJMkzX54hB++JdR3i1eLomceeI+fPdtYp+i73fNV3L6NpAf2v76VrHnSPmz3fHZvE3q4b3HBFQ3qrJ2xOnvFUG5QLK29tnVd7bD/63z6rmRdtBv2vaF/7aHp3+zxF3z4t/HVGihP93rXbt2u7aSMeQrpnOPPNM/++a0um6yPtdq1mzprsO0u/avufP5DoinOeIa6bGv44I+F3TdWbZsmX9v2s1atRwv1/6XdM5sU6dOiGNNXT9qr+VD52jQxrkKeP68dZK6WLZa/6mk0ujRo3S/UDpXpB3qsJJbQMGDEjrLGRYYSvbAQXDM1+cLN/YrQVChu0WPmyzyBSO7cZxFl4ca5GHbRaZBoTpWiTMcUyKmmu2aNHCX23sjZGnO3+q+r/wwgtTmmcAAAAAQFoMoaD2pArm9PyYKgI1OLra4yuyVBNIAAAAAEDaSFFNnp6Z0LNlajeqhwT1nJM6MVH7Yq/9MAAAAAAgQmryvv76axfUeT2fBXrsscfsmWeeCUXeAAAAAACpUZOn5pk//fRT0ADvrbfeSsksAQAAAABpFeRpPCONETFnzhz/tEcffdTefvvtoMEfAAAAACAdN9e89tpr3dgs7dq1cwNtf/rpp27APwV43jg6AAAAAIAICfKkR48eboC/c845xw3WR4AHAAAAABEU5CXUmUrhwoWtadOmNm7cOPfyns0DAAAAAKTjIM8L4OIqW7asrVu3zr08BHkAAAAAkM6DvFmzZoU3JwAAAACAtOldEwAAAACQwTpe2bx5s7355pu2dOlS8/l8VrNmTbv77rutdOnSoc0hAAAAACC8NXkzZsywatWq2ciRIy137tyWN29e++qrr9w0fQYAAAAAiKCavD59+rhau4EDB1pUVJSbptq8Rx55xH02c+bMUOcTAAAAABCumrw//vjD+vbt6w/wRH9r2vz581MySwAAAABAWgV5BQsWtDVr1sSbrmkFChQIRb4AAAAAAKkV5F1//fXWqVMn+/bbb23Tpk3u9c0339h1113nPgMAAAAARNAzeYMHD7bjx4/btdde6/53M8qWzbp37+4+S47Zs2fbW2+9ZVu3brU6derYww8/bMWLF0/0O4cPH7b33nvPfv75Z8uTJ49b7kUXXZSSVQEAAACADCVFNXk7duxwgdn27dvdIOkK1PS3pumzpJo+fbqdd955LqhToDZv3jxr3ry5HThwIMHv6DN95+OPP3a1iXoNGjTI5syZk5JVAQAAAIAMJUU1eeXLl3e9aRYqVMiaNGkS9LOkePTRR619+/b24osvuvetW7d24+y9//77dv/99wf9ztNPP23r16+3ZcuWuWcD5corr7RDhw6lZFUAAAAAIENJUU1eQg4ePOjGzUtqWtXkKUDz5MuXz1q1amWTJk1K8HvDhg2zLl26+AM8r2dPNdsEAAAAgMwuWTV5jz32WNC/JTo62g2tUL9+/STNa8OGDe47ZcuWjTVd76dMmRL0Ozt37rTNmzdb7dq13fLVvLNMmTJ2yy232Pnnn5/gso4cOeJenn379iUpjwAAAACQoWvyVPOmV+Df3kvPxKmppp6VS4qjR4+6/+PW/KlGzvssLq9JpgZcV4B47733Wrly5eziiy+2kSNHJris559/3tX8eS/lEwAAAAAss9fkTZ061f1/zTXX2KhRo05rwYULF/bXzgXSe++zYN9R00wFdc8995yb1q5dO1u9erUNGTLEDeEQTL9+/ax3796xavII9BAKA+wBCjKMBlC6AAAAqfNMXtwALyUBn5pllihRwjXxDKQawQYNGgT9Tt68ea1GjRrxAjS9jxssBsqZM6cbpD3wBQAAAAAZUUg6XtF4eSnRtWtXGzp0qBsjT7777jtbvHixm+554YUX7NZbb/W/79atm40ePdof1O3evdu+/vprxskDAAAAgJQOoRAqAwYMsKVLl1rVqlWtcuXK9s8//9hLL71kTZs29afRUAmBY+BpaIUlS5ZYlSpVrHr16rZ8+XJr1qyZCwYBAAAAILNL0yBPna6MHTvWVq1a5Wrz1BSzSJEisdI89NBDsXrDzJo1q33wwQduvLx169ZZhQoVXA+bAAAAAIAUBnka/kC9Wno+/fTTBD9LijPOOMO9glHgF4wCO4I7AAAAAAjBM3lxOz7p3Llzgp8BAAAAACKs4xXPwYMH4417BwAAAABIp801H3vssaB/iwYn13AI9evXD13uAAAAAADhC/KmT58e9G/Jnj27VapUyXWUAgAAAACIgCBv6tSp7v9rrrkmRQOgAwAAAADS4TN5BHgAAAAAkIGGUPD5fDZy5EibMWOG7dq1K97nn332WSjyBgAAAABIjZq8Pn362G233WZr1661bNmyxXsBAAAAANJGiiIyDX4+efJka9asWehzBAAAAABI3Zo8NdesV69eypcKAAAAAEg/Qd7FF19s48ePD31uAAAAAACp31yzePHi1qVLFxfoVa1a1aKiomJ9HnegdAAAAABAOg7y5s6daw0aNLBly5a5V1wEeQAAAAAQQUHerFmzQp8TAAAAAEDaPJMHAAAAAMhgQd64cePs6quvjtXL5osvvhh0cHQAAAAAQDoO8jROXufOna1atWq2aNEi//Ts2bPbwIEDQ5k/AAAAAEC4g7xBgwbZqFGjbPDgwbGmX3HFFTZ8+PCUzBIAAAAAkFZB3ooVK6x58+bu78DhE4oVK2bbt28PRb4AAAAAAKkV5JUqVco/dEJgkDd58mSrXLlySmYJAAAAAEirIK9bt27upaEUFOStXbvW3n33XbvjjjvszjvvDEW+AAAAAACpNU5e//79bffu3XbBBRfYiRMnrFKlSpYtWza777777P7770/JLAEAAAAAaRXkZcmSxYYMGWKPP/64LV682KKjo61OnTpWpEiRUOQJAAAAAJCaQZ6nUKFCdt55553OLAAAAAAAaR3knapJ5iuvvJLS/AAAAAAAUjvI0xAKgdRcU9P++ecfa9Wq1enkBwAAAACQ2kHeuHHj4k3z+XyuQ5bjx4+fTn4AAAAAAKk9hEIwGkrhoYcespEjR4ZqlgAAAACAtAryRMMq7N27N5SzBAAAAACEu7nmO++8EzTA++STT6x169YpmSUAAAAAIK2CvBdffDHetMKFC1u7du3sf//7XyjyBQAAAABIq941AQAAAAAZ8Jk8AAAAAEAGHAw9EAOjAwAAAEA6D/KWLl1qkyZNsqJFi1qdOnXctMWLF9vOnTvt0ksvtdy5c4c6nwAAAACAcAV5VatWtYoVK9prr71muXLlctMOHz5svXr1shw5ctgbb7yRktkCAAAAANLimbwxY8bYc8895w/wRH9rmj4DAAAAAERQkLdnzx7bsmVLvOmapvHyAAAAAAARFORdddVV1qlTJ/v+++9t+/bttm3bNvf3ddddZx06dAh9LgEAAAAA4Xsm7+2337YHHnjA2rdvb8ePH4+ZUbZs1rVrV3rTBAAAAIBIC/Ly589vQ4cOtRdeeMGWL1/uplWvXt0KFy4c6vwBAAAAAMId5HkU1DVp0uR0ZgEAAAAASOtn8mTcuHF29dVXW7169fzTXnzxRdu1a1eo8gYAAAAASI0g79NPP7XOnTtbtWrVbNGiRf7p2bNnt4EDB6ZklgAAAACAtAryBg0aZKNGjbLBgwfHmn7FFVfY8OHDQ5EvAAAAAEBqBXkrVqyw5s2bu7+joqL804sVK+aGVAAAAAAARFCQV6pUKVu2bFm8IG/y5MlWuXLl0OUOAAAAABD+IK9bt27uNWvWLBfkrV271t59912744477M4770zJLAEAAAAAaTWEQv/+/W337t12wQUX2IkTJ6xSpUpuMPT77rvP7r///lDkCwAAAACQWkFedHS0DRkyxB5//HFbvHixe1+nTh0rUqRISmYHAAAAAEjLIC9HjhwusCtUqJCdd955ocoLAAAAACAtnskrUaKEbd269XSXDQAAAABID0GeOlfRc3mHDh0KdX4AAAAAAKndXHPs2LG2YMECGzlypBsyQc03A82dO/d08gQAAAAASM0gr1OnTu4FAAAAAIjQIG/gwIHWt29f9/f111/vhk0AAAAAAEToM3l6Bs/n87m/1UQTAAAAABDBNXmlS5e28ePHW/Pmzd37PXv2JJhWQysAAAAAANJxkPfoo4/a1VdfbcePH3fvCxcunGBar8YPAAAAAJBOg7y77rrLbrjhBlu7dq01aNDA5syZE96cAQAAAADC27umau/0evvtt61Ro0bJXxoAAAAAIP0Nht6jR4/Q5wQAAAAAkDZBHgAAAAAgfSLIAwAAAIAMhCAPAAAAADJrxyufffZZktJ17tw5yfPcvHmzm+/WrVutTp06duONN1r27NmT9N1Zs2a571500UXWsWPHJC8TAAAAADKqZAV53bp1S/TzY8eOWXR0dJKDvOXLl1uzZs2scePG1qRJE3v22Wft448/th9//NGyZs2a6Hd37drlAkINyp4tWzaCPAAAAABIbnPNw4cPB31t2LDB9bipYEtBW1I98sgjVrt2bRs/frw98cQT9vPPP9tvv/1mn3/++Sm/e+utt7qgs0KFCmxIAAAAAAjFM3kHDx605557zqpUqWKTJk2yL7/80mbMmJGk76rWb8KECa42Lioqyk0rV66cXXjhhTZmzJhEv/vaa6/Z7t27rW/fvqeTfQAAAADI3M01PSdOnLAPP/zQ1b5lyZLFhgwZ4mrWTtXEMtC6devsyJEjVrly5VjTzzjjjEQDxQULFrhmnb///rtbdlJoOXp59u3bl+R8AgAAAECGDvJUy6YaNHWYouaW999/v+XOnTvZCz506JD7P3/+/LGmFyhQwNUQBnPgwAHr1KmTvfzyy1axYsUkL+v555+3J598Mtl5BAAAANKzAfZAWmchQxtgmaC5ZvPmzV2Q1bZtW1u1apX169cvRQGe5MuXz/2vjlMCqRmmAr1gvF449dzePffc414bN260qVOnur/V6UswyufevXv9r/Xr16cozwAAAACQoWryFFzp+Tk9E6dXQo4fP37KeanDFAV6S5cutTZt2vin633NmjWDfkedujzzzDOxpuXMmdMKFy5sZ555pv/ZvriURi8AAAAAyOiSFeR9+umnIVuwnqe79tpr3ZAJ6plTNYJ63k6B5MMPP+xPN3z4cFuzZo3179/fjaOnV6ChQ4davXr1XE0eAAAAAGR2yQrykjPIeVIMHDjQ9abZsGFDq1+/vv3www/WtWtXu+KKK/xpNKyCBj1XkAcAAAAACEPvmsGCPz0vl1wlSpSw+fPn28SJE92zdr169bJzzz03VpqbbrrJWrZsmeA89Lxd2bJlU5RvAAAAAMhoQhLkafDylAR5omflrrzyygQ/v+iiixL9vjqCAQBkbPQeF+7yBQBkJKc1GDoAAAAAIH0hyAMAAACADCQkzTX3798fitkAAAAgDdE0OpxlC0RIkKcx7fSSs846y70AAAAAABEW5KknzFtuucX1ipkjRw437ejRo9a2bVv75JNPrHjx4qHOJwAAAAAgXM/kde/e3fbu3euGPzh8+LB76e/du3e7zwAAAAAAEVSTN3nyZPvrr7/sjDPO8E/TYOYaSqF27dqhzB8AAIhAPNsV7vIFgBDX5JUqVcpy584db7qm6TMAAAAAQAQFeTfddJPdfffdtmPHDv80/a1p+gwAAAAAEEHNNceNG2cLFy608ePHW6VKlczn89natWtd5yurV6+2CRMm+NPOnTs3lPkFgNNGM7LwoQkZAAARGuRdf/317gUAAAAAyABBXt++fUOfEwAAAABA2jyTF+jEiRPuBQAAAACI4CDv008/dcMlqEdNvfS3pgEAAAAAIizIe/XVV61nz57Wpk0bGz58uH3xxRfu7x49erjPAAAAAAAR9EzeK6+84gY+b9++vX9ax44drUWLFta7d2+77777QplHAAAAAEA4a/I2btxoF198cbzpmrZhw4aUzBIAAAAAkFZBXuXKlW3s2LHxpo8ZM8Z9BgAAAACIoCCvf//+dtttt1nXrl3trbfecq9bbrnFbr/9dvdZpPjrr7/8fy9ZssTWr1/v/j58+LD98ccftn//fvd+69atbvB3z7Jly9zg73Ls2DGXdu/eve799u3bbf78+f60//zzjxsgXtQLqdLu3r3bvd+5c6d7r8HkZdeuXe4lmrZ582Y7ePCge3/o0CH3Pjo62r3XPPR9jz47cOCAP/967/V6umfPHtuxY4c/7ZYtW+zff/91fx85csSlPX78uHuv9dA6eLTuXjlosHul1TrLvn37bNu2bf60+lvTvHJRWn1HNA/Ny6NleGWmZSut8iLKm/LoUd61Dl4ZKq3WUbTOeu9RmXjlq7LSZyo7r3xV3l4Zrlq1ylasWOH/rj7zyknz0HuvXLQNly9f7k+7YMEC/7p7ZeiVt9YrsLy13l55e2XozVflFVjemqdX3l4ZeuWt6YHlre955e2VoVfeWl5geSs/Xnl7ZeiVt8owsLwTK0Ptj4HlrTL10nr7rJc2lPusyttbH62zto2X/3Xr1tnSpUv9aRctWuTPo8pBab08qaVB4HGf3vdZr7wj6RwRWN5q9RFY3vrba+2hNErrLUfL0LbzaJtq2wbmIdzl7ZWhV95K55W3l8eklrfy55V3JJwj/v77b395e9vR+67mqWPQo3Oh97um+Qb+rmm99D61zxGZ9Xct7nXEypUr3csrb33mlan3u+aVobahrlE8unbxyonyDs85IqHrCO93zdu3dCzqmPTo3OjtP97vmre/6JzKdUTq/a5tiHMdob/1W+dtc6X1zltaxuLFi0MeawSuV8iDPAV03333nVvRp59+2p555hm3guPGjXOfRQo9R+jR4O4vvPCC+1vr1bBhQ5s3b557P2zYMLvooov8aRXcar29glba6dOnu/cjR460c889159WHdR4ga82utL++OOP7r3KUO+9HXLixInuJTqBvPfee/4TggISvfd+iH7++WcbP368fzkffPCBf6fTyUFpvRPN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AEAEj5P36aefWu3atS137tzupb81DQAAAAAQYUHeq6++aj179rQ2bdrY8OHD7YsvvnB/q4ZPnwEAAAAAIuCZPM8rr7xin3/+ubVv394/rWPHjtaiRQvr3bu33XfffaHMIwAAAAAgnDV5GzdutIsvvjjedE3bsGFDSmYJAAAAAEirIK9y5co2duzYeNPHjBnjPgMAAAAARFBzzf79+9ttt91mkydPtsaNG7tps2fPds/mvf/++6HOIwAAAAAgnEHeLbfcYqVLl7bBgwfbxIkTLSoqymrWrGnjxo2zSy+9NCWzBAAAAACkVZAnCuYI6AAAAAAgg4yTBwAAAABIfwjyAAAAACADSXFzTYTex4fPoVjDZAAlCwAAgEyCmjwAAAAAyEAI8gAAAAAgswd5GzdutBtuuMEqVKhg+fLli/cCAAAAAETQM3m333677d2715588kkrXLhw6HMFAAAAAEi9IG/GjBm2bNkyK1OmTMqWCgAAAABIP801S5QoYdmzZw99bgAAAAAAqR/kde3a1QYMGGDHjx8/vaUDAAAAANK+uebo0aNtwYIF9uWXX1rFihUtKioq1udz584NVf4AAAAAAOEO8jp16uReAAAAAIAMEOT17ds39DkBAAAAAKT9YOgnTpxwLwAAAABABAd5n376qdWuXdty587tXvpb0wAAAAAAERbkvfrqq9azZ09r06aNDR8+3L744gv3d48ePdxnAAAAAIAIeibvlVdesc8//9zat2/vn9axY0dr0aKF9e7d2+67775Q5hEAAAAAkEQpqsnbuHGjXXzxxfGma9qGDRtSMksAAAAAQFoFeZUrV7axY8fGmz5mzBj3GQAAAAAggppr9u/f32677TabPHmyNW7c2E2bPXu2ezbv/fffD3UeAQAAAADhDPJuueUWK126tA0ePNgmTpxoUVFRVrNmTRs3bpxdeumlKZklAAAAACCtgjxRMBeKgO7o0aP2008/2datW61OnTrWsGHDU35n3bp1ruYwW7ZsriaxbNmyp50PAAAAAMgITnsw9NOxfft2F9Tdf//9Nn78eGvVqpUbhiEhPp/PbrjhBrvwwgvtq6++sg8++MCqVavmevsEAAAAACSjJu/MM890///999/+vxOiNEnRr18/9//8+fMtT548Nm/ePDvnnHPsiiuusMsuuyxokKdhGzR8Q5YsMfGpBmDv2rWr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vvS2jdiOsf3666/21ltv2eOPPx5rm+XJk8dy5coVrywDyzE9pckM1NFa37597cEHH7RPPvnEunXr5gJdLwBUZzrB9v/du3e7m/npLU1mli2tM4DIkT17dndABdLBJTly5EhyGoRv+0iw8g/cPqFIg/S/jdiOSVOhQgX38qgW7c4777QRI0bYs88+G9JzH+fQ8Elv24jfwv+oJU/79u3trrvuilUjpDLSDWBdiEdFRcUqy8ByTE9pMoOyZcu6mjxZunSpnX/++a5MHn300UR/V7Jly+bKLb2lycyoyUOSVaxY0TZu3Bhrmt6XKlXKf6AlJQ3Co2DBglaoUKGg5e9dxIYqDVKmfPnyrhleYmWbmmkQXMmSJWOVW0LnNfHKMjXTIL6Eyk0XeToW0mOazGDhwoXWqlUru+mmm+yVV16J9ZnKSK1GAodaUtNADd0TeDykpzSZzVlnnWWXX365a+0gWbNmdUFgsH1b5Zce02RmBHlIsksuucTGjx/vTnqesWPHuunJSYPw0Y/pd99953+vMX60PQLLP1RpkHxqCtSsWTN3THgOHDhgP/74o79sUzMNYsokrsmTJ1vt2rX971VeGutM4x96xowZY5UrV7YqVaqkehrEp3L7+eefY21Pldu5555r+fLlS5dpMrpFixZZy5Yt7frrr7fXX3893ufnnXeeez4v8Bz1yy+/uLHZvHNUekuTGc+HGqszsDmkykLXB15TSF3v6X3ca8H0lCbTSuueX5A+qNc2dZOvl8a16dWrl/tbY7N51q1b53revOGGG3xjx4713XbbbW4Mp7///jtZaZAyu3fvdttk6tSprgcw9dSm9ytWrPCnUe9g6u5YPWOq/DVmm3rqC+wePlRpEN/WrVvdNlG36dpGGpNO79euXetPo+2XPXt2N7yBhqRQr6XqvSywV8fUTJPZ9enTx40RqqEvVEY6d2kIg0mTJvnTqDt1da2ul7bt888/74YU+fLLL9MkTWajnka93ycNJ6GxH/V34FiG+g3TuILqUe/bb7/19evXz5Xbzz//nG7TZGQab05jzbVo0cK/7byX17umPPnkk25MyPfee89136/x2W688cZY80pvaTKypk2b+p555hnf999/74bc6dSpkxsr77fffvOnWb58uSujrl27uusDlU/hwoXdeMvpNU1mFaV/0jrQRNpbsWKFde3aNd50tcV+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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def plot_top_tokens_position_composition():\n", " fig, ax = plt.subplots(figsize=(9, 5))\n", @@ -1585,21 +435,10 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "id": "e2e97d02", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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e/asNX78eCssLMwaNmxYtO198sknHdu7bt06K3/+/GbZ+Lj7Ojt37jSv89VXX8W7zrj2NaH75c77EN9ncMGCBdbs2bPN/1OnTnU837dvXzPtxo0bca4ntn2P77MVEhJivfLKK9bhw4fNfr711ltWaGio9dNPPznWMXjwYCt16tTW5MmTzT7t2LHDHJv777/f7KezLFmymG2O6pFHHrFKlCjhMs3d19fvVt26da2HH37Y2rJli3Xp0iXrgw8+MPs1ffp0l3XWqFHDatKkiZUQcS2j77e+7++++67ZPv08tGjRwnw+9L123sYHH3zQ8fj11183+zFu3DjHtGPHjlkFChSw7rnnHvP5v3LlirVixQqraNGiLstOmDDB7Nvjjz9uffHFF+aY637rfPfdd1+8+7N7924rY8aM5v3Zs2ePde7cOevjjz+2UqVKZT377LOO+fSY58uXz6pUqZK1fPly6/Lly9a+ffvM+/Hzzz+7Pc9LL71ktjeqxYsXm+l6H3XfunTpYn322Wdm23Qf7969az5Ter7VY7Fy5UpzvO33t3PnzuY8rN8NXeaff/6xOnToYGXPnt36999/zTxnzpwx69bPmp5rDh06ZJ06dcp8P8PDw62DBw+6bJ8ur8dJP4fHjx83886cOdN64YUXHPO487qzZs0yn+Mvv/zSnAP0O7Zo0SKrffv2cb5P9va2bdvW6tmzp9le3Q79vun07777zjHvyJEjzedJX9/ZvHnzzLy6DfG9Trt27awePXqY47B3715r6dKljve3Zs2a1vr1681nctmyZVbhwoXN/DY9r+g69u/fH+NrREZGWidPnrTeeecds516LosaO6Jue0zr1c9BwYIFzXcsKj1Gen65fv26eezutsd1/tf3V7dBv2Mav6tWrWrikh4zm57vNIY2btzY8X366KOPzGfq+eefd8zXunVrq3Tp0tbmzZvN+VqPs37e33777TiPY0KOT0K2x97H3r17O/ZRz1l6fBo0aGDF58cffzTLL1myJNpzcW2z/bpdu3Y1323dvk8//TRBn5mY9jsx+/PEE0+Yc/WdO3fi3V8AcBdJKQApnpTShJPOc+3atRiTM/rDSgt7I0aMiPO13ElKjRo1KtpzcSWlRo8eHS0xoYWjN954I0WSUs2bNzeFMy0MRP0hqD+Q7Xnt7f3Pf/7jMp8menS6XbiLjbuv46mk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pqxYsUK++OILxzRttqeJqoULF8aalNKdj4smkJwTUipv3rzm/vLly25vnyakNOkFAIHiyJEjJvEPzyFWAAg0xArPI1YACDRHPFiu8FpS6vDhwxIRERFtR+zaT5703nvvSfbs2U1tqdjcunXL3Gx2BTI92JkzZ/bo9gDO/Z9pH2mlS5eW9OnTc2CQLDQhr+dWrfkJz7KPKbECyYlYgZQQLLFC+5ydOHGioz/bl19+WfLkyePWsrNmzZKPP/5YOnbsKAMHDnT7NYkVSAnECvhrrPBaUur27dvmPmpBXB/bz3mCdniuweP777+P88BpX1Xa91RUmpAiKYXkop8tuyYfkNxoipx8x5RYgeRErEBKCuRYsXLlSmnatKkMHjzYJJa0jFC3bl3TF612KRKX/fv3ywsvvGCa4h08eDBBr0usQEogVsBfY4XXOhexR9g7f/68y3TtuDy+0ffcNWfOHHniiSfks88+k4ceeijOeYcNGyaXLl1y3PSqN5ASVzS2bNli7gEAIFYAyefVV181ZQLtv7Zdu3Yyb948OX36tBnVOy7amqJTp07yzjvvSK5cuXiL4JMoV8BfeS0pVaBAAcmRI4ds377dZbpeqahSpUqS1//DDz9I9+7dZfLkyfL444/HO3+aNGkcV7q54o2UognQn3/+2dwDAECsAJKvwK5N99q2beuYliFDBlNzavHixXEu++KLL5rRvTt37szbA59FuQL+KtSb1b0ee+wx+fzzz03tKKUBQWuN9OjRwzHfhAkTZMCAAQla99y5c6Vr164yadIk6d27t8e3HQAAAID/0FYQ2vROL4w708fa121s9OKh3rQfKndpzSrtd8X5BgDwsT6l1OjRo01NqTJlypiOnrdu3SpvvPGGNGjQwDGPPr9u3TrH4yVLlsj7779vRu+zm91pjStNQulNT/pavTZLlizy448/mptNOyRs3rx5Cu8lAAAAAG+6c+eOuU+bNq3L9HTp0sXan+2xY8fkySefNC0wEtLHbGx91QIAfCwppR0KLl26VHbs2GFGwNBqsfnz53eZRxNJzjWnNIHVr18/8/+gQYMc0zWpZQcW50SUs3LlyiXTngAAAADwVToSt7JbaNj0sf1cVNrnlDb70xH6bH///becOXNGNm3aJCtWrJCwsLBoy+lFc+1MPepoVQAAH0tK2SpXruz2cwULFjS32KRKlUpa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2rVLVq1aJd9//71jvjlz5sjhw4dlyJAhpqneli1bpHbt2i59U23dulXatm3rpT0BgMBCUgrwIu2bQEeBWTD+IO8DACDOWKH3ABLv7bfflvr160utWrWkevXq8ssvv0iXLl3k4YcfdsyzaNEiWbdunUlKhYSEyCuvvCKRkZFSvnx509RPR/Br2rSpDBgwgLcCPoVYAX9FUgrwIr1KV7JkSQm1DvM+AADijBUAkiZfvnyyY8cOk4w6deqU9OjRQxo2bOgyT8eOHaVevXrm/1SpUsnSpUtlw4YNpnaUNv979dVXpUKFCrwV8DnECvgrklKAF125csV0mBkZeltCI1PzXgAAYo0VNWrUiLdDZgBxS58+vUk8xaZ58+bRptWsWdPcAF9GrIC/oqNzwIuuXr0qK1asMEkpAADiihV6DwAAsQKBhKQUAAAAAAAAgq/53q1bt+S3334z7borVapkOh70xDLnzp0zVxUvXLhghoBt1KiRhId7fXcBAAAAAADg7ZpSp0+flmrVqslLL70kS5YskZYtW8qTTz6Z5GV+/vlnKVKkiEycOFHWrFljRsfQDglPnDiRzHsEAAAAAAAAd3i16tDLL79sRrXQYVfTpUsn27ZtM514tmvXTtq0aZPoZXRUjEcffVS++uor8/j69etSokQJmTx5sowaNSpF9xGIS9q0aU1tv6NLqMUHAIg7Vug9AADECgQSr9WUioyMlO+//1569eplkkuqatWqct9998l3332XpGW0mV7WrFkdj/VHnI60QfM9+Jps2bJJ+/btJSyCggYAIO5YofcAABArEEi8Vj3jyJEjZtjKcuXKuUzXx5s2bUrSMp988olp0vfss8+aZnxLly6V8uXLy8CBA+Psp0pvtsuXLydh7wD33L1713zWLImUEMYdAADEESsyZ87MBTYAQJzlCmIF/I3Xakppckk512hSehUwtoSQu8ukSZPG1KTasWOH7NmzR/755x+zTGho7Ls7duxYyZIli+NWqFChJO0f4I4zZ87IhAkTJCL8OgcMABBnrNB7AACIFQgkXktK2c3v7ESTTZNL2tQusctERESY/qXq169vRt/78ssvTb9TWpNq2LBhsW6PPnfp0iXHTWtlAQAAAAAAIMCa7xUuXFhSp05tajE5O3jwoJQqVSrRyxw/ftwklFq0aOFSc6phw4aydu3aWLdH59EbAAAA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JoEMLTY2Vnbu3GnuAQAAAACwE7eH76lq1aol+VglJCTIvn37pH379mm3dwAAAAAAAMiQUhSU6t27t7n/448/nI8dwsLCpHjx4nLHHXek7R4CAAAAAADA3kEpnSVM5c2bV/r27Zte+wQAAAAAAIAMLkVBKQcNSJ08eVLy5MnjsjypZTfz22+/ycSJEyU6OloqV65sAl8328bWrVvlf//7n+zYsUPefvttqVq1qsvr7733nsyfP99lWYkSJeSjjz5K0b4B6S179uzSunVrcw8AAAAAgJ14FJTSgNDvv/9u7hMbMWKE3HbbbfLQQw+5tZ01a9ZIs2bNzIx9emH+4YcfSoMGDWTjxo2SNWvWJNu88sorMnPmTOnSpYssX75cTp8+fd06f/31l1y5ckVefPFF57Js2bKl+DiB9Kbfy3r16vFBAwAAAABsx6Og1BtvvCHLli27bvmzzz4r7dq1czsopUEsrUH17rvvmufa9pZbbpGPP/5YHn/88STbDBgwwASbDh48aAJUycmfP7+0bNnS7WMCfCEmJkb++ecfKVmypERERHASAAAAAAC2EexJo8OHD0tkZOR1y3PkyCH79+93+2J81apV0qlTJ+cyHcLUokULWbp06Q2DTe7QTK4OHTrIvffeK5MnT5b4+Hi32gHedObMGfn222/NPQAAAAAAduJRUKpKlSryxRdfXLf8888/l0qVKrm1jQMHDkhCQoIULlzYZbk+37dvn6RGeHi4tG/f3tS+ql27towaNUratGlj3i85sbGxcu7cOZcbAAAAAAAA/Gj4ng6f0wynDRs2SOPGjcWyLPn5559Nrae5c+e6tQ2t+aSuHbKUJUsW52ueev31111qUukwPg2WzZ49W+66664k24wePVpefvnlVL0vAAAAAAAA0jFTSutALViwQA4dOiTPPPOMDB061AzpW7hwoXnNHbly5TL3p06dum4GP8drnrq2SHr58uWlePHiZkhfcoYPHy5nz5513jSTCwAAAAAAAH6UKaV0OJzePFWoUCHJly+fCRQlDmTp81q1akla0mF7GvzKnDnzDYf86Q3wptDQUClYsKC5BwAAAADATjzKlEor9913n3zyySdy7Ngx81wzrTZv3myWO4wbN87t2fzU1atX5YMPPnAWNtehhS+99JKcP39eOnfunA5HAXhOA7MPP/ywuQcAAAAAwE48Ts/Y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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def plot_top_tokens_relative_position_histogram():\n", " ncols = 3\n", @@ -1637,21 +476,10 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "id": "d774e2c8", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "def plot_top_tokens_position_errorbars(vocab_size: int):\n", " rows = per_vocab_size[str(vocab_size)][\"top_tokens_by_frequency_train\"]\n", @@ -1683,211 +511,10 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "id": "21711059", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
original_cdr3tokens_vocab_1000tokens_vocab_10000
0CAISVQDRDTEAFF[CAIS, ##VQ, ##DRD, ##TEAFF][CAISV, ##QDR, ##DTEAFF]
1CATSEGTAGTGYEQYF[CATSE, ##G, ##TAG, ##TGY, ##EQYF][CATSEG, ##TAG, ##TGYEQYF]
2CASSESRLAGANEQFF[CASSES, ##RLAG, ##AN, ##EQFF][CASSESR, ##LAGANEQFF]
3CASSPRQDRNTEAFF[CASSPR, ##QD, ##RN, ##TEAFF][CASSPRQ, ##DRNTEAFF]
4CSARDPPTVYGYTF[CSARDP, ##P, ##TV, ##YGYTF][CSARDP, ##P, ##TVYGYTF]
5CATSDNRGGYNEQFF[CATSD, ##NRG, ##GYNEQFF][CATSDN, ##RGGYNEQFF]
6CSAIRDRDGGQYF[CSAI, ##RDR, ##DGG, ##QYF][CSAIR, ##DRDG, ##G, ##QYF]
7CASSVPILGLSNEQFF[CASSV, ##PI, ##LG, ##LS, ##NEQFF][CASSVP, ##ILG, ##LSNEQFF]
8CASSPYPTSGGANQETQYF[CASSPY, ##P, ##TSGGA, ##NQETQYF][CASSPYP, ##TSGGA, ##NQETQYF]
9CASSKRRENEKLFF[CASSK, ##RR, ##E, ##NEKLFF][CASSKR, ##RE, ##NEKLFF]
10CASTLGPRDRYNEQFF[CASTL, ##G, ##PR, ##DR, ##YNEQFF][CASTLG, ##PR, ##DRYNEQFF]
11CASKPGANPYNEQYF[CASK, ##PGA, ##NP, ##YNEQYF][CASKPG, ##ANP, ##YNEQYF]
12CASSETGANTGELFF[CASSE, ##TGA, ##NTGELFF][CASSETG, ##ANTGELFF]
13CSAKRKGPIHYNEQFF[CSAK, ##RK, ##G, ##PI, ##HYNEQFF][CSAKR, ##KGP, ##IH, ##YNEQFF]
14CASSRRRASYNEQFF[CASSRR, ##RAS, ##YNEQFF][CASSRRR, ##ASYNEQFF]
15CASSRRGTSPGNEQFF[CASSRR, ##G, ##TSP, ##G, ##NEQFF][CASSRRG, ##TSP, ##G, ##NEQFF]
16CASSYPELGTTGSDTQYF[CASSYP, ##EL, ##G, ##TTG, ##SDTQYF][CASSYP, ##EL, ##G, ##TTGS, ##DTQYF]
17CASSVGQIQPQHF[CASSVG, ##QI, ##QPQHF][CASSVGQ, ##IQPQHF]
18CSARPPGQRGTEAFF[CSARP, ##PGQ, ##RG, ##TEAFF][CSARPP, ##G, ##QRG, ##TEAFF]
19CASSITGSPSYNSPLHF[CASSI, ##TGS, ##PS, ##YNSPLHF][CASSITG, ##SPS, ##YNSPLHF]
\n", - "
" - ], - "text/plain": [ - " original_cdr3 tokens_vocab_1000 \\\n", - "0 CAISVQDRDTEAFF [CAIS, ##VQ, ##DRD, ##TEAFF] \n", - "1 CATSEGTAGTGYEQYF [CATSE, ##G, ##TAG, ##TGY, ##EQYF] \n", - "2 CASSESRLAGANEQFF [CASSES, ##RLAG, ##AN, ##EQFF] \n", - "3 CASSPRQDRNTEAFF [CASSPR, ##QD, ##RN, ##TEAFF] \n", - "4 CSARDPPTVYGYTF [CSARDP, ##P, ##TV, ##YGYTF] \n", - "5 CATSDNRGGYNEQFF [CATSD, ##NRG, ##GYNEQFF] \n", - "6 CSAIRDRDGGQYF [CSAI, ##RDR, ##DGG, ##QYF] \n", - "7 CASSVPILGLSNEQFF [CASSV, ##PI, ##LG, ##LS, ##NEQFF] \n", - "8 CASSPYPTSGGANQETQYF [CASSPY, ##P, ##TSGGA, ##NQETQYF] \n", - "9 CASSKRRENEKLFF [CASSK, ##RR, ##E, ##NEKLFF] \n", - "10 CASTLGPRDRYNEQFF [CASTL, ##G, ##PR, ##DR, ##YNEQFF] \n", - "11 CASKPGANPYNEQYF [CASK, ##PGA, ##NP, ##YNEQYF] \n", - "12 CASSETGANTGELFF [CASSE, ##TGA, ##NTGELFF] \n", - "13 CSAKRKGPIHYNEQFF [CSAK, ##RK, ##G, ##PI, ##HYNEQFF] \n", - "14 CASSRRRASYNEQFF [CASSRR, ##RAS, ##YNEQFF] \n", - "15 CASSRRGTSPGNEQFF [CASSRR, ##G, ##TSP, ##G, ##NEQFF] \n", - "16 CASSYPELGTTGSDTQYF [CASSYP, ##EL, ##G, ##TTG, ##SDTQYF] \n", - "17 CASSVGQIQPQHF [CASSVG, ##QI, ##QPQHF] \n", - "18 CSARPPGQRGTEAFF [CSARP, ##PGQ, ##RG, ##TEAFF] \n", - "19 CASSITGSPSYNSPLHF [CASSI, ##TGS, ##PS, ##YNSPLHF] \n", - "\n", - " tokens_vocab_10000 \n", - "0 [CAISV, ##QDR, ##DTEAFF] \n", - "1 [CATSEG, ##TAG, ##TGYEQYF] \n", - "2 [CASSESR, ##LAGANEQFF] \n", - "3 [CASSPRQ, ##DRNTEAFF] \n", - "4 [CSARDP, ##P, ##TVYGYTF] \n", - "5 [CATSDN, ##RGGYNEQFF] \n", - "6 [CSAIR, ##DRDG, ##G, ##QYF] \n", - "7 [CASSVP, ##ILG, ##LSNEQFF] \n", - "8 [CASSPYP, ##TSGGA, ##NQETQYF] \n", - "9 [CASSKR, ##RE, ##NEKLFF] \n", - "10 [CASTLG, ##PR, ##DRYNEQFF] \n", - "11 [CASKPG, ##ANP, ##YNEQYF] \n", - "12 [CASSETG, ##ANTGELFF] \n", - "13 [CSAKR, ##KGP, ##IH, ##YNEQFF] \n", - "14 [CASSRRR, ##ASYNEQFF] \n", - "15 [CASSRRG, ##TSP, ##G, ##NEQFF] \n", - "16 [CASSYP, ##EL, ##G, ##TTGS, ##DTQYF] \n", - "17 [CASSVGQ, ##IQPQHF] \n", - "18 [CSARPP, ##G, ##QRG, ##TEAFF] \n", - "19 [CASSITG, ##SPS, ##YNSPLHF] " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "examples = results.get(\"examples\", [])\n", "if examples:\n", diff --git a/scripts/run1_default_40epochs.sh b/scripts/run1_default_40epochs.sh new file mode 100644 index 0000000..784b2c0 --- /dev/null +++ b/scripts/run1_default_40epochs.sh @@ -0,0 +1,31 @@ +#!/bin/bash +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 \ + --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_default_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 13 \ + --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_default_40epochs diff --git a/scripts/run2_maxtokenlen9_40epochs.sh b/scripts/run2_maxtokenlen9_40epochs.sh new file mode 100644 index 0000000..3ded489 --- /dev/null +++ b/scripts/run2_maxtokenlen9_40epochs.sh @@ -0,0 +1,32 @@ +#!/bin/bash +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 \ + --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_maxtokenlen9_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 13 \ + --batch-size 512 --epochs 40 \ + --max-token-len 9 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_maxtokenlen9_40epochs diff --git a/scripts/run_both_sequential.sh b/scripts/run_both_sequential.sh new file mode 100644 index 0000000..f2d1660 --- /dev/null +++ b/scripts/run_both_sequential.sh @@ -0,0 +1,3 @@ +#!/bin/bash +bash run1_default_40epochs.sh +bash run2_maxtokenlen9_40epochs.sh diff --git a/scripts/run_compare_100k.sh b/scripts/run_compare_100k.sh new file mode 100644 index 0000000..38aee97 --- /dev/null +++ b/scripts/run_compare_100k.sh @@ -0,0 +1,16 @@ +#!/bin/bash +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 \ + --batch-size 512 --epochs 20 \ + --seeds 1 42 777 \ + --configs char \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_20000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_30000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_40000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_50000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_100000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_background100k diff --git a/scripts/run_compare_40epochs_upto30k.sh b/scripts/run_compare_40epochs_upto30k.sh new file mode 100644 index 0000000..bd6263a --- /dev/null +++ b/scripts/run_compare_40epochs_upto30k.sh @@ -0,0 +1,14 @@ +#!/bin/bash +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 \ + --batch-size 512 --epochs 40 \ + --seeds 1 42 777 \ + --configs char \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_1000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_20000/tokenizer.json \ + wordpiece:artifacts/tokenizers_1M_integ/wordpiece_vocab_30000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_background100k_40epochs_upto30k diff --git a/scripts/run_compare_finegrid_maxlen9_40epochs.sh b/scripts/run_compare_finegrid_maxlen9_40epochs.sh new file mode 100644 index 0000000..14b966b --- /dev/null +++ b/scripts/run_compare_finegrid_maxlen9_40epochs.sh @@ -0,0 +1,26 @@ +#!/bin/bash +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 \ + --batch-size 512 --epochs 50 \ + --max-token-len 9 \ + --seeds 1 42 777 \ + --configs char \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_100/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_500/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_maxlen9_40epochs diff --git a/scripts/run_compare_finegrid_maxlen9_50epochs.sh b/scripts/run_compare_finegrid_maxlen9_50epochs.sh new file mode 100644 index 0000000..0311eb8 --- /dev/null +++ b/scripts/run_compare_finegrid_maxlen9_50epochs.sh @@ -0,0 +1,26 @@ +#!/bin/bash +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 \ + --batch-size 512 --epochs 50 \ + --max-token-len 9 \ + --seeds 1 42 777 \ + --configs char \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_100/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_500/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_maxlen9_50epochs From a827d67106ef9d2519b7b1b0912037103ea8de3d Mon Sep 17 00:00:00 2001 From: maria Date: Sat, 1 Aug 2026 17:37:12 +0300 Subject: [PATCH 32/70] Ignore the reports/ folder --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 2fe8f24..9bdfba8 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,7 @@ artifacts/ # Local data data/ + +# Reports +reports/ + From f5f9d669ccd949978e28c4a66e0142cc9e0c8c2a Mon Sep 17 00:00:00 2001 From: maria Date: Sun, 2 Aug 2026 12:49:43 +0300 Subject: [PATCH 33/70] Add padding-investigation scripts: per-vocab max_len vs fixed Three variants to isolate the padding effect from the vocab_size effect: individual max_len per dict (real max_num_tokens), same plus --max-token-len 9, and a fixed max_len=10 across the whole grid. --- scripts/run3_all_sequential.sh | 4 ++ scripts/run3a_individual_maxlen.sh | 45 +++++++++++++++++ .../run3b_individual_maxlen_maxtokenlen9.sh | 48 +++++++++++++++++++ scripts/run3c_fixed_maxlen10.sh | 31 ++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 scripts/run3_all_sequential.sh create mode 100644 scripts/run3a_individual_maxlen.sh create mode 100644 scripts/run3b_individual_maxlen_maxtokenlen9.sh create mode 100644 scripts/run3c_fixed_maxlen10.sh diff --git a/scripts/run3_all_sequential.sh b/scripts/run3_all_sequential.sh new file mode 100644 index 0000000..352faa6 --- /dev/null +++ b/scripts/run3_all_sequential.sh @@ -0,0 +1,4 @@ +#!/bin/bash +bash scripts/run3a_individual_maxlen.sh +bash scripts/run3b_individual_maxlen_maxtokenlen9.sh +bash scripts/run3c_fixed_maxlen10.sh diff --git a/scripts/run3a_individual_maxlen.sh b/scripts/run3a_individual_maxlen.sh new file mode 100644 index 0000000..9a1b5a0 --- /dev/null +++ b/scripts/run3a_individual_maxlen.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -e + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 8 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 7 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_40epochs diff --git a/scripts/run3b_individual_maxlen_maxtokenlen9.sh b/scripts/run3b_individual_maxlen_maxtokenlen9.sh new file mode 100644 index 0000000..76c8382 --- /dev/null +++ b/scripts/run3b_individual_maxlen_maxtokenlen9.sh @@ -0,0 +1,48 @@ +#!/bin/bash +set -e + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --max-token-len 9 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 8 --batch-size 512 --epochs 40 \ + --max-token-len 9 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 7 --batch-size 512 --epochs 40 \ + --max-token-len 9 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_40epochs diff --git a/scripts/run3c_fixed_maxlen10.sh b/scripts/run3c_fixed_maxlen10.sh new file mode 100644 index 0000000..846ca76 --- /dev/null +++ b/scripts/run3c_fixed_maxlen10.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_fixed_maxlen10_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_fixed_maxlen10_40epochs From 29760f11e47637932f6c4ebe1090eba6199b71bb Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 00:15:17 +0300 Subject: [PATCH 34/70] Add frozen-representation caching and PCA bottleneck for reconstruction benchmark- cache_embeddings: one-hot, ESM-2 8M, TCR-BERT, SCEPTR with shared mean pooling- fit_bottleneck: train-only StandardScaler + PCA to 32/64/128 with explained variance- train_decoder: IRRM-CODEC decoder per representation, edit-distance metrics- prepare_splits: standardize V/J calls and drop the 335 non-functional rows SCEPTR cannot encode, and key the pgen cache on sequence so it survives filter changes --- benchmark/cache_embeddings.py | 207 +++++++++++++++++++ benchmark/fit_bottleneck.py | 160 +++++++++++++++ benchmark/prepare_splits.py | 56 +++-- benchmark/train_decoder.py | 259 ++++++++++++++++++++++++ data/benchmark/trb/dataset_summary.json | 68 ++++--- 5 files changed, 703 insertions(+), 47 deletions(-) create mode 100644 benchmark/cache_embeddings.py create mode 100644 benchmark/fit_bottleneck.py create mode 100644 benchmark/train_decoder.py diff --git a/benchmark/cache_embeddings.py b/benchmark/cache_embeddings.py new file mode 100644 index 0000000..5b0c982 --- /dev/null +++ b/benchmark/cache_embeddings.py @@ -0,0 +1,207 @@ +"""Issue 2/3: generate and cache frozen representations for the benchmark dataset. + +One pretrained checkpoint per encoder, no fine-tuning. Every matrix is written in the +row order of ``dataset.parquet`` so that ``row_index`` identifies the same sequence in +every representation, including the TCRemP matrix produced by ``prepare_splits``. + +Encoders: + onehot aligned one-hot from the repo tokenizer (gap-padded to 40 x vocab) + esm2_8m ESM-2 8M (esm2_t6_8M_UR50D), mean-pooled over residues + tcr_bert TCR-BERT (wukevin/tcr-bert), mean-pooled over residues + sceptr SCEPTR default variant, already one vector per receptor + +Transformer encoders are mean-pooled over real residues only, excluding BOS/EOS and +padding, so the pooling rule is identical across models. +""" + +import argparse +import json +import time +import warnings +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.tokenization import AA_VOCAB, encode +from irrm_codec.utils import setup_logging + +ENCODERS = ("onehot", "esm2_8m", "tcr_bert", "sceptr") + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--output-dir", default="data/benchmark/trb/representations") + p.add_argument("--encoders", nargs="+", default=list(ENCODERS), choices=list(ENCODERS)) + p.add_argument("--batch-size", type=int, default=64) + p.add_argument("--max-len", type=int, default=40) + p.add_argument("--threads", type=int, default=8) + p.add_argument("--overwrite", action="store_true", help="Recompute even if the cache exists.") + return p.parse_args() + + +def encode_onehot(sequences, args, log): + """Aligned one-hot: the repo's gap padding gives every sequence the same layout.""" + vocab_size = len(AA_VOCAB) + out = np.zeros((len(sequences), args.max_len * vocab_size), dtype=np.float32) + positions = np.arange(args.max_len) + for row, seq in enumerate(sequences): + block = np.zeros((args.max_len, vocab_size), dtype=np.float32) + block[positions, encode(seq, max_len=args.max_len)] = 1.0 + out[row] = block.ravel() + log.info("onehot done dim=%d", out.shape[1]) + return out + + +def _mean_pool(states, keep): + """Average hidden states over the positions flagged in ``keep``.""" + mask = keep.unsqueeze(-1).to(states.dtype) + return (states * mask).sum(1) / mask.sum(1).clamp_min(1e-9) + + +def encode_esm2(sequences, args, log): + import esm + + model, alphabet = esm.pretrained.esm2_t6_8M_UR50D() + model.eval() + batch_converter = alphabet.get_batch_converter() + last_layer = model.num_layers + chunks = [] + with torch.no_grad(): + for start in range(0, len(sequences), args.batch_size): + batch = sequences[start : start + args.batch_size] + _, _, tokens = batch_converter([(str(i), s) for i, s in enumerate(batch)]) + states = model(tokens, repr_layers=[last_layer])["representations"][last_layer] + keep = ( + (tokens != alphabet.padding_idx) + & (tokens != alphabet.cls_idx) + & (tokens != alphabet.eos_idx) + ) + chunks.append(_mean_pool(states, keep).numpy().astype(np.float32)) + if start % (args.batch_size * 100) == 0: + log.info("esm2_8m %d/%d", start, len(sequences)) + return np.concatenate(chunks) + + +def encode_tcr_bert(sequences, args, log): + from transformers import AutoModel, AutoTokenizer + + tokenizer = AutoTokenizer.from_pretrained("wukevin/tcr-bert") + model = AutoModel.from_pretrained("wukevin/tcr-bert") + model.eval() + special = set(tokenizer.all_special_ids) + chunks = [] + with torch.no_grad(): + for start in range(0, len(sequences), args.batch_size): + batch = sequences[start : start + args.batch_size] + # TCR-BERT expects residues separated by spaces. + enc = tokenizer([" ".join(s) for s in batch], return_tensors="pt", padding=True) + states = model(**enc).last_hidden_state + keep = enc["attention_mask"].bool() + for token_id in special: + keep &= enc["input_ids"] != token_id + chunks.append(_mean_pool(states, keep).numpy().astype(np.float32)) + if start % (args.batch_size * 100) == 0: + log.info("tcr_bert %d/%d", start, len(sequences)) + return np.concatenate(chunks) + + +def encode_sceptr(sequences, args, log, frame=None): + import sceptr + + # SCEPTR reads V and J gene calls in addition to the CDR3, so it needs the full table. + instances = pd.DataFrame( + { + "TRBV": frame["v_call"].to_numpy(), + "CDR3B": frame["junction_aa"].to_numpy(), + "TRBJ": frame["j_call"].to_numpy(), + } + ) + chunks = [] + stride = max(args.batch_size, 1024) + for start in range(0, len(instances), stride): + chunks.append( + sceptr.calc_vector_representations(instances.iloc[start : start + stride]).astype(np.float32) + ) + if start % (stride * 10) == 0: + log.info("sceptr %d/%d", start, len(instances)) + return np.concatenate(chunks) + + +def main(): + args = parse_args() + warnings.filterwarnings("ignore") + torch.set_num_threads(args.threads) + + dataset_dir = Path(args.dataset_dir) + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "cache_embeddings.log") + + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + sequences = frame["junction_aa"].tolist() + log.info("dataset rows=%d from %s", len(frame), dataset_dir / "dataset.parquet") + + builders = { + "onehot": lambda: encode_onehot(sequences, args, log), + "esm2_8m": lambda: encode_esm2(sequences, args, log), + "tcr_bert": lambda: encode_tcr_bert(sequences, args, log), + "sceptr": lambda: encode_sceptr(sequences, args, log, frame=frame), + } + + meta_path = output_dir / "representations.json" + meta = json.loads(meta_path.read_text(encoding="utf-8")) if meta_path.exists() else {} + + for name in args.encoders: + path = output_dir / f"{name}.npy" + if path.exists() and not args.overwrite: + cached = np.load(path, mmap_mode="r") + if cached.shape[0] == len(frame): + log.info("%s cached dim=%d, skipping", name, cached.shape[1]) + continue + log.warning("%s cache has %d rows, expected %d; recomputing", name, cached.shape[0], len(frame)) + + log.info("encoding %s", name) + started = time.perf_counter() + matrix = builders[name]() + elapsed = time.perf_counter() - started + + if matrix.shape[0] != len(frame): + raise ValueError(f"{name} produced {matrix.shape[0]} rows, expected {len(frame)}.") + if not np.isfinite(matrix).all(): + raise ValueError(f"{name} produced non-finite values.") + + np.save(path, matrix) + meta[name] = { + "dim": int(matrix.shape[1]), + "rows": int(matrix.shape[0]), + "seconds": round(elapsed, 2), + "ms_per_sequence": round(elapsed / len(frame) * 1000, 4), + "path": str(path.resolve()), + } + meta_path.write_text(json.dumps(meta, indent=2), encoding="utf-8") + log.info("%s done dim=%d in %.1f s", name, matrix.shape[1], elapsed) + + # TCRemP comes from prepare_splits and needs no encoder pass. + tcremp = dataset_dir / "embeddings.npy" + if tcremp.exists(): + matrix = np.load(tcremp, mmap_mode="r") + meta["tcremp"] = { + "dim": int(matrix.shape[1]), + "rows": int(matrix.shape[0]), + "seconds": None, + "ms_per_sequence": None, + "path": str(tcremp.resolve()), + } + meta_path.write_text(json.dumps(meta, indent=2), encoding="utf-8") + + log.info("=" * 60) + for name, info in meta.items(): + log.info("%-10s dim=%-5d rows=%d", name, info["dim"], info["rows"]) + log.info("wrote %s", meta_path) + + +if __name__ == "__main__": + main() diff --git a/benchmark/fit_bottleneck.py b/benchmark/fit_bottleneck.py new file mode 100644 index 0000000..20f7d22 --- /dev/null +++ b/benchmark/fit_bottleneck.py @@ -0,0 +1,160 @@ +"""Issue 2: reduce every representation to a common bottleneck dimension with PCA. + +The scaler and the PCA are fitted on the training split only and then applied to +validation and test, so no information from the held-out rows leaks into the +projection. Representations arrive on very different scales (TCRemP holds alignment +distances in the hundreds, transformer activations sit near zero), so each one is +standardized before the PCA. + +One PCA is fitted at the largest requested width. Principal components are ordered by +explained variance, so the narrower bottlenecks are prefixes of the same fit and cost +nothing extra. +""" + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +from joblib import dump +from sklearn.decomposition import PCA, IncrementalPCA +from sklearn.preprocessing import StandardScaler + +from irrm_codec.utils import setup_logging + +# Above this input width the full SVD needs more memory than it is worth, so the +# incremental solver streams the training split in batches instead. +INCREMENTAL_PCA_MIN_DIM = 2000 + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--representations-dir", default="data/benchmark/trb/representations") + p.add_argument("--output-dir", default="data/benchmark/trb/bottleneck") + p.add_argument("--dims", type=int, nargs="+", default=[32, 64, 128]) + p.add_argument("--representations", nargs="+") + p.add_argument("--batch-size", type=int, default=4096, help="IncrementalPCA batch size.") + p.add_argument("--seed", type=int, default=42) + p.add_argument("--overwrite", action="store_true") + return p.parse_args() + + +def fit_projection(matrix, train_rows, n_components, batch_size, seed, log): + """Standardize and fit a PCA on the training rows only.""" + scaler = StandardScaler() + incremental = matrix.shape[1] >= INCREMENTAL_PCA_MIN_DIM + + if incremental: + # Two streamed passes: one to learn the scaling, one to fit the components. + for start in range(0, len(train_rows), batch_size): + scaler.partial_fit(np.asarray(matrix[train_rows[start : start + batch_size]])) + pca = IncrementalPCA(n_components=n_components, batch_size=batch_size) + for start in range(0, len(train_rows), batch_size): + block = np.asarray(matrix[train_rows[start : start + batch_size]], dtype=np.float64) + if len(block) < n_components: + break # A trailing batch smaller than the component count cannot be fitted. + pca.partial_fit(scaler.transform(block)) + else: + train = np.asarray(matrix[train_rows], dtype=np.float64) + scaler.fit(train) + pca = PCA(n_components=n_components, random_state=seed) + pca.fit(scaler.transform(train)) + + log.info( + "fitted %s pca n_components=%d", + "incremental" if incremental else "full", + n_components, + ) + return scaler, pca + + +def transform_all(matrix, scaler, pca, batch_size): + """Project every row, streaming so the full float64 copy never materializes.""" + out = np.empty((matrix.shape[0], pca.n_components_), dtype=np.float32) + for start in range(0, matrix.shape[0], batch_size): + block = np.asarray(matrix[start : start + batch_size], dtype=np.float64) + out[start : start + batch_size] = pca.transform(scaler.transform(block)).astype(np.float32) + return out + + +def main(): + args = parse_args() + dataset_dir = Path(args.dataset_dir) + reps_dir = Path(args.representations_dir) + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "fit_bottleneck.log") + + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + train_rows = pd.read_csv(dataset_dir / "manifests" / "train.tsv", sep="\t")["row_index"].to_numpy() + log.info("dataset rows=%d train rows=%d", len(frame), len(train_rows)) + + catalog = json.loads((reps_dir / "representations.json").read_text(encoding="utf-8")) + names = args.representations or list(catalog) + max_dim = max(args.dims) + + summary_path = output_dir / "bottleneck_summary.json" + summary = json.loads(summary_path.read_text(encoding="utf-8")) if summary_path.exists() else {} + + for name in names: + source = Path(catalog[name]["path"]) + matrix = np.load(source, mmap_mode="r") + if matrix.shape[0] != len(frame): + raise ValueError(f"{name} has {matrix.shape[0]} rows, expected {len(frame)}.") + + # A representation narrower than the bottleneck cannot be reduced to it; SCEPTR + # is already 64-dimensional, so its widest projection is capped at its own width. + n_components = min(max_dim, matrix.shape[1], len(train_rows)) + if name in summary and not args.overwrite: + log.info("%s already projected, skipping", name) + continue + + log.info("fitting %s dim=%d -> %d", name, matrix.shape[1], n_components) + started = time.perf_counter() + scaler, pca = fit_projection( + matrix, train_rows, n_components, args.batch_size, args.seed, log + ) + projected = transform_all(matrix, scaler, pca, args.batch_size) + elapsed = time.perf_counter() - started + + dump({"scaler": scaler, "pca": pca}, output_dir / f"{name}_projection.joblib") + + ratios = np.asarray(pca.explained_variance_ratio_, dtype=np.float64) + explained = {} + for dim in sorted(args.dims): + if dim > n_components: + explained[str(dim)] = None + continue + np.save(output_dir / f"{name}_{dim}.npy", projected[:, :dim]) + explained[str(dim)] = round(float(ratios[:dim].sum()), 6) + + summary[name] = { + "source_dim": int(matrix.shape[1]), + "components_fitted": int(n_components), + "explained_variance": explained, + "seconds": round(elapsed, 2), + "solver": "incremental" if matrix.shape[1] >= INCREMENTAL_PCA_MIN_DIM else "full", + "capped_by_source_dim": bool(n_components < max_dim), + } + summary_path.write_text(json.dumps(summary, indent=2), encoding="utf-8") + log.info("%s done in %.1f s explained=%s", name, elapsed, explained) + + log.info("=" * 68) + header = " ".join(f"{d:>8d}" for d in sorted(args.dims)) + log.info("%-10s %6s %s", "repr", "dim", header) + for name, info in summary.items(): + cells = " ".join( + f"{info['explained_variance'][str(d)]:8.4f}" + if info["explained_variance"].get(str(d)) is not None + else " -" + for d in sorted(args.dims) + ) + log.info("%-10s %6d %s", name, info["source_dim"], cells) + log.info("wrote %s", summary_path) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_splits.py b/benchmark/prepare_splits.py index 1026f46..ceda71b 100644 --- a/benchmark/prepare_splits.py +++ b/benchmark/prepare_splits.py @@ -1,7 +1,8 @@ """Issue 1: build the common human TRB dataset shared by all benchmark experiments. Steps: - 1. load the AIRR table and drop invalid / duplicate CDR3 amino-acid sequences + 1. load the AIRR table and drop invalid / duplicate CDR3 amino-acid sequences, + then standardize V/J gene calls and drop rows no representation can encode 2. match sequences to their TCRemP embeddings and verify the alignment 3. compute and cache log10(pgen) and log10(pgen_1mm) 4. build one reproducible 80/10/10 split keyed on the unique CDR3 sequence @@ -18,6 +19,7 @@ import numpy as np import pandas as pd import pyarrow.parquet as pq +import tidytcells as tt from irrm_codec.dataio import normalize_locus_name from irrm_codec.tokenization import VALID_AA @@ -72,6 +74,19 @@ def clean_sequences(df, cdr3_col, locus, min_len, max_len, log): drop |= mask df = df[~drop].copy() + # SCEPTR consumes V/J gene calls and rejects anything non-standard or + # non-functional, while the other representations only read the CDR3. Resolving the + # gene names here keeps a single row set that every representation can encode. + for column, gene_type in (("v_call", "V"), ("j_call", "J")): + df[column] = df[column].map( + lambda value: tt.tr.standardize( + value, species="homosapiens", enforce_functional=True, log_failures=False + ) + ) + unusable = df[column].isna() + report[f"dropped_non_functional_{gene_type.lower()}_call"] = int(unusable.sum()) + df = df[~unusable].copy() + duplicated = df[cdr3_col].duplicated(keep="first") report["dropped_duplicate_cdr3"] = int(duplicated.sum()) df = df[~duplicated].copy() @@ -114,21 +129,34 @@ def check_alignment(emb, sequences, min_corr, log): return {"length_corr": corr, "shuffled_length_corr": shuffled, "min_corr_threshold": min_corr} +def _pgen_lookup(cache_path, needed): + """Return per-sequence pgen values from the cache, or None if it cannot serve them. + + Values are keyed on the CDR3 sequence rather than on row position, so tightening + the cleaning filters later reuses the cache instead of recomputing it. + """ + if not cache_path.exists(): + return None + cached = pd.read_csv(cache_path, sep="\t") + if not all(c in cached.columns for c in ("junction_aa", *PGEN_COLUMNS)): + return None + cached = cached.drop_duplicates("junction_aa").set_index("junction_aa") + if not needed.isin(cached.index).all(): + return None + return cached.loc[needed, list(PGEN_COLUMNS)].reset_index(drop=True) + + def ensure_pgen(df, args, output_dir, log): cache_path = output_dir / "pgen.tsv" clean_airr_path = output_dir / "cleaned_airr.tsv" df.to_csv(clean_airr_path, sep="\t", index=False) + hit = _pgen_lookup(cache_path, df["junction_aa"]) + if hit is not None: + log.info("reusing cached pgen values for all %d sequences from %s", len(hit), cache_path) + return hit, {"source": "cache", "path": str(cache_path)} if cache_path.exists(): - cached = pd.read_csv(cache_path, sep="\t") - same_rows = len(cached) == len(df) - same_seqs = same_rows and np.array_equal( - cached["junction_aa"].astype(str).to_numpy(), df["junction_aa"].to_numpy() - ) - if same_seqs and all(c in cached.columns for c in PGEN_COLUMNS): - log.info("reusing cached pgen table %s", cache_path) - return cached, {"source": "cache", "path": str(cache_path)} - log.warning("cached pgen table does not match the cleaned data; recomputing") + log.warning("cached pgen table does not cover the cleaned data; recomputing") if args.skip_pgen: raise FileNotFoundError( @@ -148,10 +176,10 @@ def ensure_pgen(df, args, output_dir, log): log.info("computing pgen: %s", " ".join(cmd)) subprocess.run(cmd, check=True, cwd=Path.cwd()) - table = pd.read_csv(cache_path, sep="\t") - if not np.array_equal(table["junction_aa"].astype(str).to_numpy(), df["junction_aa"].to_numpy()): - raise ValueError("pgen output rows do not line up with the cleaned AIRR rows.") - return table, {"source": "computed", "path": str(cache_path)} + hit = _pgen_lookup(cache_path, df["junction_aa"]) + if hit is None: + raise ValueError("pgen output does not cover every cleaned sequence.") + return hit, {"source": "computed", "path": str(cache_path)} def make_splits(n, train_fraction, val_fraction, seed): diff --git a/benchmark/train_decoder.py b/benchmark/train_decoder.py new file mode 100644 index 0000000..6ea2366 --- /dev/null +++ b/benchmark/train_decoder.py @@ -0,0 +1,259 @@ +"""Issue 2: train the IRRM-CODEC decoder on one representation and score reconstruction. + +The decoder architecture, optimizer, schedule and early stopping are identical for every +representation, so the only thing that varies between runs is the bottleneck vector the +decoder reads. Inputs are standardized with train-split statistics: the projections +arrive on very different scales, and a shared learning rate on unequal scales would make +"identical training settings" true on paper only. The repo's forward/inverse trainers +normalize their embeddings the same way. + +Reported metrics: exact sequence match, amino-acid token accuracy, normalized +Levenshtein distance, fraction of predictions within edit distance 1, inference speed. +""" + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +from rapidfuzz.distance import Levenshtein +from torch.utils.data import DataLoader, TensorDataset + +from irrm_codec.inverse_model import InverseModel +from irrm_codec.losses import inverse_loss +from irrm_codec.tokenization import AA_VOCAB, ID2AA, encode + +GAP_ID = AA_VOCAB["-"] +from irrm_codec.utils import choose_device, save_checkpoint, set_seed, setup_logging + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--bottleneck-dir", default="data/benchmark/trb/bottleneck") + p.add_argument("--representation", required=True) + p.add_argument("--bottleneck-dim", type=int, default=64) + p.add_argument("--output-dir", default="artifacts/benchmark/reconstruction") + p.add_argument("--seed", type=int, default=42) + p.add_argument("--epochs", type=int, default=60) + p.add_argument("--batch-size", type=int, default=256) + p.add_argument("--lr", type=float, default=1e-3) + p.add_argument("--weight-decay", type=float, default=1e-4) + p.add_argument("--patience", type=int, default=8, help="Early-stopping patience in epochs.") + p.add_argument("--max-len", type=int, default=40) + p.add_argument("--train-subset", default="all", help="Training subset manifest: 1k, 10k or all.") + p.add_argument("--threads", type=int, default=8) + p.add_argument("--num-workers", type=int, default=0) + return p.parse_args() + + +def load_split_rows(dataset_dir, name): + return pd.read_csv(Path(dataset_dir) / "manifests" / f"{name}.tsv", sep="\t")["row_index"].to_numpy() + + +def decode_tokens(token_ids): + """Turn predicted token ids back into a gap-free amino-acid string.""" + return "".join(ID2AA[int(t)] for t in token_ids if int(t) > GAP_ID) + + +def build_tensors(matrix, rows, sequences, max_len): + features = torch.from_numpy(np.asarray(matrix[rows], dtype=np.float32)) + targets = torch.tensor( + [encode(sequences[i], max_len=max_len) for i in rows], dtype=torch.long + ) + return features, targets + + +@torch.no_grad() +def evaluate(model, loader, device, sequences, rows, max_len, collect_predictions=False): + """Run the decoder over a split and score it at the sequence level.""" + model.eval() + loss_sum, steps = 0.0, 0 + token_hits, token_total = 0, 0 + predictions = [] + + for features, targets in loader: + features, targets = features.to(device), targets.to(device) + logits = model(features) + loss_sum += inverse_loss(logits, targets).item() + steps += 1 + + predicted = logits.argmax(dim=-1) + # encode() gap-pads to a fixed width, so every position is filled and most of + # them are gaps. Scoring those would let a model inflate token accuracy by + # predicting padding, so accuracy counts real residues only. + residues = targets.gt(GAP_ID) + token_hits += predicted.eq(targets).logical_and(residues).sum().item() + token_total += residues.sum().item() + predictions.extend(decode_tokens(row) for row in predicted.cpu().numpy()) + + truth = [sequences[i] for i in rows] + distances = np.array([Levenshtein.distance(p, t) for p, t in zip(predictions, truth)]) + lengths = np.array([max(len(t), 1) for t in truth]) + + metrics = { + "loss": loss_sum / max(steps, 1), + "token_accuracy": token_hits / max(token_total, 1), + "exact_match": float(np.mean(distances == 0)), + "normalized_levenshtein": float(np.mean(distances / lengths)), + "within_edit_distance_1": float(np.mean(distances <= 1)), + "mean_edit_distance": float(distances.mean()), + } + return (metrics, predictions, truth) if collect_predictions else (metrics, None, None) + + +@torch.no_grad() +def measure_inference_speed(model, features, device, batch_size): + """Throughput on the test split, excluding metric computation.""" + model.eval() + warmup = features[: min(batch_size, len(features))].to(device) + model(warmup) + + started = time.perf_counter() + for start in range(0, len(features), batch_size): + model(features[start : start + batch_size].to(device)) + elapsed = time.perf_counter() - started + return { + "sequences_per_second": len(features) / elapsed, + "ms_per_sequence": elapsed / len(features) * 1000, + "batch_size": batch_size, + "device": str(device), + } + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + set_seed(args.seed) + device = choose_device() + + run_name = f"{args.representation}_d{args.bottleneck_dim}_{args.train_subset}_seed{args.seed}" + output_dir = Path(args.output_dir) / run_name + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "train.log") + + dataset_dir = Path(args.dataset_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + sequences = frame["junction_aa"].tolist() + + source = Path(args.bottleneck_dir) / f"{args.representation}_{args.bottleneck_dim}.npy" + matrix = np.load(source, mmap_mode="r") + log.info("run=%s device=%s features=%s", run_name, device, matrix.shape) + + train_rows = load_split_rows(dataset_dir, f"train_{args.train_subset}") + val_rows = load_split_rows(dataset_dir, "val") + test_rows = load_split_rows(dataset_dir, "test") + + train_x, train_y = build_tensors(matrix, train_rows, sequences, args.max_len) + val_x, val_y = build_tensors(matrix, val_rows, sequences, args.max_len) + test_x, test_y = build_tensors(matrix, test_rows, sequences, args.max_len) + + # Train-split statistics only, so no held-out information reaches the projection. + mean = train_x.mean(dim=0, keepdim=True) + std = train_x.std(dim=0, keepdim=True).clamp_min(1e-6) + train_x, val_x, test_x = ((t - mean) / std for t in (train_x, val_x, test_x)) + np.save(output_dir / "mean.npy", mean.numpy()) + np.save(output_dir / "std.npy", std.numpy()) + + loaders = { + name: DataLoader( + TensorDataset(x, y), + batch_size=args.batch_size, + shuffle=(name == "train"), + num_workers=args.num_workers, + ) + for name, (x, y) in ( + ("train", (train_x, train_y)), + ("val", (val_x, val_y)), + ("test", (test_x, test_y)), + ) + } + + model = InverseModel(embedding_dim=args.bottleneck_dim, max_len=args.max_len).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + log.info("model params=%.2fM train=%d val=%d test=%d", + sum(p.numel() for p in model.parameters()) / 1e6, + len(train_rows), len(val_rows), len(test_rows)) + + best_val = float("inf") + best_epoch = 0 + history = [] + training_started = time.perf_counter() + + for epoch in range(1, args.epochs + 1): + model.train() + epoch_loss, steps = 0.0, 0 + for features, targets in loaders["train"]: + features, targets = features.to(device), targets.to(device) + logits = model(features) + loss = inverse_loss(logits, targets) + optimizer.zero_grad(set_to_none=True) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + epoch_loss += loss.item() + steps += 1 + + train_loss = epoch_loss / max(steps, 1) + val_metrics, _, _ = evaluate(model, loaders["val"], device, sequences, val_rows, args.max_len) + history.append({"epoch": epoch, "train_loss": train_loss, **{f"val_{k}": v for k, v in val_metrics.items()}}) + log.info( + "epoch=%d train_loss=%.4f val_loss=%.4f val_exact=%.4f val_tok=%.4f", + epoch, train_loss, val_metrics["loss"], val_metrics["exact_match"], val_metrics["token_accuracy"], + ) + + if val_metrics["loss"] < best_val - 1e-5: + best_val, best_epoch = val_metrics["loss"], epoch + save_checkpoint(output_dir / "best.pt", model, optimizer, epoch, val_metrics) + elif epoch - best_epoch >= args.patience: + log.info("early stopping at epoch=%d (best epoch=%d)", epoch, best_epoch) + break + + training_seconds = time.perf_counter() - training_started + save_checkpoint(output_dir / "last.pt", model, optimizer, len(history), history[-1]) + + model.load_state_dict(torch.load(output_dir / "best.pt", map_location=device)["model_state"]) + test_metrics, predictions, truth = evaluate( + model, loaders["test"], device, sequences, test_rows, args.max_len, collect_predictions=True + ) + speed = measure_inference_speed(model, test_x, device, args.batch_size) + + pd.DataFrame( + { + "row_index": test_rows, + "true_cdr3": truth, + "predicted_cdr3": predictions, + "edit_distance": [Levenshtein.distance(p, t) for p, t in zip(predictions, truth)], + } + ).to_csv(output_dir / "test_predictions.csv", index=False) + + pd.DataFrame(history).to_csv(output_dir / "history.csv", index=False) + result = { + "run_name": run_name, + "representation": args.representation, + "bottleneck_dim": args.bottleneck_dim, + "train_subset": args.train_subset, + "train_size": int(len(train_rows)), + "seed": args.seed, + "epochs_ran": len(history), + "best_epoch": best_epoch, + "best_val_loss": best_val, + "training_seconds": round(training_seconds, 2), + "test": test_metrics, + "inference": speed, + "config": vars(args), + } + (output_dir / "metrics.json").write_text(json.dumps(result, indent=2), encoding="utf-8") + + log.info("=" * 60) + log.info("test exact_match=%.4f token_accuracy=%.4f", test_metrics["exact_match"], test_metrics["token_accuracy"]) + log.info("test norm_levenshtein=%.4f within_ed1=%.4f", test_metrics["normalized_levenshtein"], test_metrics["within_edit_distance_1"]) + log.info("training_seconds=%.1f inference=%.0f seq/s", training_seconds, speed["sequences_per_second"]) + log.info("wrote %s", output_dir / "metrics.json") + + +if __name__ == "__main__": + main() diff --git a/data/benchmark/trb/dataset_summary.json b/data/benchmark/trb/dataset_summary.json index 1c46115..c45b3af 100644 --- a/data/benchmark/trb/dataset_summary.json +++ b/data/benchmark/trb/dataset_summary.json @@ -13,14 +13,16 @@ "dropped_invalid_chars": 0, "dropped_too_short": 0, "dropped_too_long": 0, + "dropped_non_functional_v_call": 335, + "dropped_non_functional_j_call": 0, "dropped_duplicate_cdr3": 0, - "rows_kept": 99998, + "rows_kept": 99663, "dropped_non_finite_pgen": 2 }, "embedding_dim": 9000, "embedding_alignment": { - "length_corr": 0.5274442408242208, - "shuffled_length_corr": 0.0008568142944854723, + "length_corr": 0.5251705966285264, + "shuffled_length_corr": 0.008426662808806782, "min_corr_threshold": 0.3 }, "alignment_mode": "row_order", @@ -29,9 +31,9 @@ "path": "data\\benchmark\\trb\\pgen.tsv" }, "split_sizes": { - "train": 79998, - "val": 9999, - "test": 10001 + "train": 79730, + "val": 9966, + "test": 9967 }, "split_fractions": { "train": 0.8, @@ -41,7 +43,7 @@ "train_subsets": { "1k": 1000, "10k": 10000, - "all": 79998 + "all": 79730 }, "cdr3_overlap_between_splits": { "train_val": 0, @@ -51,54 +53,54 @@ "targets": { "log10_pgen": { "train": { - "n_finite": 79998, + "n_finite": 79730, "n_non_finite": 0, - "mean": -8.34572029024153, - "std": 1.8845455361342092, + "mean": -8.342815174291603, + "std": 1.8788593865723895, "min": -28.06169119699202, "max": -5.092073042426336 }, "val": { - "n_finite": 9999, + "n_finite": 9966, "n_non_finite": 0, - "mean": -8.351515526786393, - "std": 1.909456406125435, - "min": -23.09528585214532, - "max": -5.365645796309452 + "mean": -8.330849724502892, + "std": 1.8649352353948874, + "min": -23.57673660375092, + "max": -5.252935754631411 }, "test": { - "n_finite": 10001, + "n_finite": 9967, "n_non_finite": 0, - "mean": -8.34374768827681, - "std": 1.8479154152116826, - "min": -21.193822220414155, - "max": -5.3048644505016 + "mean": -8.33931896402931, + "std": 1.8736677602653675, + "min": -22.300802363627707, + "max": -5.272577113539358 } }, "log10_pgen_1mm": { "train": { - "n_finite": 79998, + "n_finite": 79730, "n_non_finite": 0, - "mean": -6.52977416306943, - "std": 1.6300446772117814, + "mean": -6.526844812213512, + "std": 1.6264507836142756, "min": -25.268624790379345, "max": -3.967721318105829 }, "val": { - "n_finite": 9999, + "n_finite": 9966, "n_non_finite": 0, - "mean": -6.532824795313865, - "std": 1.6590462485672821, - "min": -20.17601369470008, - "max": -4.055332526062316 + "mean": -6.516624042597638, + "std": 1.611059243463444, + "min": -19.405392492212744, + "max": -3.999265344121248 }, "test": { - "n_finite": 10001, + "n_finite": 9967, "n_non_finite": 0, - "mean": -6.522161324076908, - "std": 1.5951257276034596, - "min": -18.745888024917427, - "max": -4.127677056652921 + "mean": -6.521180768534297, + "std": 1.6127152970829823, + "min": -19.90410715459764, + "max": -4.018798001189545 } } }, From 555180ddc69dae7ce8c3afd5649ba01f7d7cde1e Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 07:56:21 +0300 Subject: [PATCH 35/70] script for slurm --- benchmark/slurm/reconstruction_array.sbatch | 69 +++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 benchmark/slurm/reconstruction_array.sbatch diff --git a/benchmark/slurm/reconstruction_array.sbatch b/benchmark/slurm/reconstruction_array.sbatch new file mode 100644 index 0000000..b3ba5c6 --- /dev/null +++ b/benchmark/slurm/reconstruction_array.sbatch @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# Issue 2: train the IRRM-CODEC decoder for every representation and seed. +# +# 5 representations x 3 seeds = 15 tasks. The array is throttled to 2 concurrent +# tasks because the cluster allows at most 2 GPUs per user by default. +# +# Submit from the repository root: +# sbatch benchmark/slurm/reconstruction_array.sbatch +# +# Override anything without editing the file: +# sbatch --export=ALL,BOTTLENECK_DIM=32,TRAIN_SUBSET=10k \ +# benchmark/slurm/reconstruction_array.sbatch + +#SBATCH --job-name=irrm-recon +#SBATCH --partition=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=16G +#SBATCH --time=12:00:00 +#SBATCH --array=0-14%2 +#SBATCH --output=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.out +#SBATCH --error=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.err + +set -euo pipefail + +SCRATCH="${SCRATCH:-/mnt/tank/scratch/mpodsytnik/irrm-codec}" +REPO="${REPO:-/nfs/home/mpodsytnik/irrm-codec}" +CONDA_ROOT="${CONDA_ROOT:-/mnt/tank/scratch/mpodsytnik/miniconda3}" +CONDA_ENV="${CONDA_ENV:-irrm-codec}" + +DATASET_DIR="${DATASET_DIR:-$SCRATCH/data/benchmark/trb}" +BOTTLENECK_DIR="${BOTTLENECK_DIR:-$SCRATCH/data/benchmark/trb/bottleneck}" +OUTPUT_DIR="${OUTPUT_DIR:-$SCRATCH/artifacts/benchmark/reconstruction}" + +BOTTLENECK_DIM="${BOTTLENECK_DIM:-64}" +TRAIN_SUBSET="${TRAIN_SUBSET:-all}" +EPOCHS="${EPOCHS:-60}" +BATCH_SIZE="${BATCH_SIZE:-256}" +PATIENCE="${PATIENCE:-8}" + +# Task id maps to (representation, seed): ids 0-2 are the first representation, and so on. +REPRESENTATIONS=(tcremp onehot tcr_bert sceptr esm2_8m) +SEEDS=(42 43 44) +REPRESENTATION="${REPRESENTATIONS[$((SLURM_ARRAY_TASK_ID / ${#SEEDS[@]}))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % ${#SEEDS[@]}))]}" + +mkdir -p "$SCRATCH/logs" "$OUTPUT_DIR" + +# conda init is deliberately not used: it would edit the shared account's ~/.bashrc. +source "$CONDA_ROOT/bin/activate" +conda activate "$CONDA_ENV" + +echo "job=${SLURM_JOB_ID:-local} task=${SLURM_ARRAY_TASK_ID:-0} node=${SLURMD_NODENAME:-?}" +echo "representation=$REPRESENTATION seed=$SEED dim=$BOTTLENECK_DIM subset=$TRAIN_SUBSET" +nvidia-smi --query-gpu=name,memory.total --format=csv,noheader || true + +cd "$REPO" +srun python -m benchmark.train_decoder \ + --dataset-dir "$DATASET_DIR" \ + --bottleneck-dir "$BOTTLENECK_DIR" \ + --output-dir "$OUTPUT_DIR" \ + --representation "$REPRESENTATION" \ + --bottleneck-dim "$BOTTLENECK_DIM" \ + --train-subset "$TRAIN_SUBSET" \ + --seed "$SEED" \ + --epochs "$EPOCHS" \ + --batch-size "$BATCH_SIZE" \ + --patience "$PATIENCE" \ + --threads "${SLURM_CPUS_PER_TASK:-4}" From c1d828cd7d5e69cec4d6cd82b89b699ff6467fcd Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 08:16:53 +0300 Subject: [PATCH 36/70] Add reconstruction results collector and trim the array time limit --- benchmark/collect_reconstruction.py | 148 ++++++++++++++++++++ benchmark/slurm/reconstruction_array.sbatch | 4 +- 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 benchmark/collect_reconstruction.py diff --git a/benchmark/collect_reconstruction.py b/benchmark/collect_reconstruction.py new file mode 100644 index 0000000..0c41543 --- /dev/null +++ b/benchmark/collect_reconstruction.py @@ -0,0 +1,148 @@ +"""Issue 2: aggregate reconstruction runs into the per-run CSV and the summary table. + +Reads every ``metrics.json`` written by ``train_decoder`` and produces: + reconstruction_runs.csv one row per run (representation x seed) + reconstruction_summary.csv mean and std across seeds, per representation + reconstruction_summary.md the same table in Markdown, for REPORT.md + +Explained variance from the PCA fit is joined in, because it is the main explanation +for differences at a fixed bottleneck width: a representation that survives the +projection intact starts from a different place than one that loses most of its variance. +""" + +import argparse +import json +from pathlib import Path + +import pandas as pd + +METRICS = ( + "exact_match", + "token_accuracy", + "normalized_levenshtein", + "within_edit_distance_1", + "mean_edit_distance", +) + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--runs-dir", default="artifacts/benchmark/reconstruction") + p.add_argument("--bottleneck-dir", default="data/benchmark/trb/bottleneck") + p.add_argument("--output-dir", default="results/reconstruction") + p.add_argument("--bottleneck-dim", type=int, default=64) + return p.parse_args() + + +def load_runs(runs_dir, bottleneck_dim): + rows = [] + for path in sorted(Path(runs_dir).glob("*/metrics.json")): + run = json.loads(path.read_text(encoding="utf-8")) + if run["bottleneck_dim"] != bottleneck_dim: + continue + rows.append( + { + "representation": run["representation"], + "seed": run["seed"], + "bottleneck_dim": run["bottleneck_dim"], + "train_subset": run["train_subset"], + "train_size": run["train_size"], + "epochs_ran": run["epochs_ran"], + "best_epoch": run["best_epoch"], + "best_val_loss": run["best_val_loss"], + "training_seconds": run["training_seconds"], + "test_loss": run["test"]["loss"], + **{name: run["test"][name] for name in METRICS}, + "inference_seq_per_second": run["inference"]["sequences_per_second"], + "inference_ms_per_sequence": run["inference"]["ms_per_sequence"], + "device": run["inference"]["device"], + } + ) + if not rows: + raise SystemExit(f"No metrics.json found under {runs_dir} for dim={bottleneck_dim}.") + return pd.DataFrame(rows) + + +def summarize(runs, bottleneck_dir, bottleneck_dim): + aggregated = runs.groupby("representation").agg( + seeds=("seed", "count"), + **{f"{name}_{stat}": (name, stat) for name in METRICS for stat in ("mean", "std")}, + training_seconds_mean=("training_seconds", "mean"), + epochs_mean=("epochs_ran", "mean"), + inference_seq_per_second_mean=("inference_seq_per_second", "mean"), + ) + + summary_path = Path(bottleneck_dir) / "bottleneck_summary.json" + if summary_path.exists(): + bottleneck = json.loads(summary_path.read_text(encoding="utf-8")) + aggregated["source_dim"] = [ + bottleneck.get(name, {}).get("source_dim") for name in aggregated.index + ] + aggregated["explained_variance"] = [ + bottleneck.get(name, {}).get("explained_variance", {}).get(str(bottleneck_dim)) + for name in aggregated.index + ] + + return aggregated.sort_values("exact_match_mean", ascending=False).reset_index() + + +def to_markdown(summary, bottleneck_dim): + header = ( + f"### Reconstruction at a {bottleneck_dim}-dimensional bottleneck\n\n" + "| representation | source dim | expl. var | exact match | token acc | " + "norm. Levenshtein | within ED 1 | train s | seq/s |\n" + "| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |\n" + ) + + def cell(row, name): + std = row[f"{name}_std"] + spread = f" ± {std:.4f}" if pd.notna(std) else "" + return f"{row[f'{name}_mean']:.4f}{spread}" + + lines = [] + for _, row in summary.iterrows(): + expl = row.get("explained_variance") + source_dim = row.get("source_dim") + cells = [ + row["representation"], + f"{source_dim:.0f}" if pd.notna(source_dim) else "-", + f"{expl:.3f}" if pd.notna(expl) else "-", + cell(row, "exact_match"), + cell(row, "token_accuracy"), + cell(row, "normalized_levenshtein"), + cell(row, "within_edit_distance_1"), + f"{row['training_seconds_mean']:.0f}", + f"{row['inference_seq_per_second_mean']:.0f}", + ] + lines.append("| " + " | ".join(cells) + " |") + return header + "\n".join(lines) + "\n" + + +def main(): + args = parse_args() + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + + runs = load_runs(args.runs_dir, args.bottleneck_dim) + runs = runs.sort_values(["representation", "seed"]) + runs.to_csv(output_dir / "reconstruction_runs.csv", index=False) + + summary = summarize(runs, args.bottleneck_dir, args.bottleneck_dim) + summary.to_csv(output_dir / "reconstruction_summary.csv", index=False) + (output_dir / "reconstruction_summary.md").write_text( + to_markdown(summary, args.bottleneck_dim), encoding="utf-8" + ) + + print(f"runs: {len(runs)} representations: {runs.representation.nunique()}") + print( + summary[ + ["representation", "seeds", "exact_match_mean", "exact_match_std", "token_accuracy_mean"] + ].to_string(index=False) + ) + print(f"\nwrote {output_dir}/reconstruction_runs.csv") + print(f"wrote {output_dir}/reconstruction_summary.csv") + print(f"wrote {output_dir}/reconstruction_summary.md") + + +if __name__ == "__main__": + main() diff --git a/benchmark/slurm/reconstruction_array.sbatch b/benchmark/slurm/reconstruction_array.sbatch index b3ba5c6..2ff2f63 100644 --- a/benchmark/slurm/reconstruction_array.sbatch +++ b/benchmark/slurm/reconstruction_array.sbatch @@ -16,7 +16,9 @@ #SBATCH --gres=gpu:1 #SBATCH --cpus-per-task=4 #SBATCH --mem=16G -#SBATCH --time=12:00:00 +# A 60-epoch run takes ~40 min on a GTX 1080 Ti (39 s/epoch at train=79730), so this +# leaves ample headroom while keeping the job small enough to schedule quickly. +#SBATCH --time=02:00:00 #SBATCH --array=0-14%2 #SBATCH --output=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.out #SBATCH --error=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.err From f53870ab97f285810eb000f0ea6e21366d92a1e3 Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 08:32:26 +0300 Subject: [PATCH 37/70] fix comment in script --- benchmark/slurm/reconstruction_array.sbatch | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/benchmark/slurm/reconstruction_array.sbatch b/benchmark/slurm/reconstruction_array.sbatch index 2ff2f63..40ed9d8 100644 --- a/benchmark/slurm/reconstruction_array.sbatch +++ b/benchmark/slurm/reconstruction_array.sbatch @@ -4,7 +4,11 @@ # 5 representations x 3 seeds = 15 tasks. The array is throttled to 2 concurrent # tasks because the cluster allows at most 2 GPUs per user by default. # +# The log directory must exist before submitting: Slurm opens the --output file before +# the script body runs, so a missing directory kills the job immediately. +# # Submit from the repository root: +# mkdir -p /mnt/tank/scratch/mpodsytnik/irrm-codec/logs # sbatch benchmark/slurm/reconstruction_array.sbatch # # Override anything without editing the file: @@ -46,7 +50,7 @@ SEEDS=(42 43 44) REPRESENTATION="${REPRESENTATIONS[$((SLURM_ARRAY_TASK_ID / ${#SEEDS[@]}))]}" SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % ${#SEEDS[@]}))]}" -mkdir -p "$SCRATCH/logs" "$OUTPUT_DIR" +mkdir -p "$OUTPUT_DIR" # conda init is deliberately not used: it would edit the shared account's ~/.bashrc. source "$CONDA_ROOT/bin/activate" From 8eac79d871c2780e72f5441e83b146645d63d21f Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 08:40:47 +0300 Subject: [PATCH 38/70] fix for write to out --- benchmark/slurm/reconstruction_array.sbatch | 3 +++ 1 file changed, 3 insertions(+) diff --git a/benchmark/slurm/reconstruction_array.sbatch b/benchmark/slurm/reconstruction_array.sbatch index 40ed9d8..6eecf76 100644 --- a/benchmark/slurm/reconstruction_array.sbatch +++ b/benchmark/slurm/reconstruction_array.sbatch @@ -61,6 +61,9 @@ echo "representation=$REPRESENTATION seed=$SEED dim=$BOTTLENECK_DIM subset=$TRAI nvidia-smi --query-gpu=name,memory.total --format=csv,noheader || true cd "$REPO" +# Slurm redirects stdout to a file, where Python block-buffers by default and the log +# appears only in bursts. Unbuffered output keeps the .out file usable for monitoring. +export PYTHONUNBUFFERED=1 srun python -m benchmark.train_decoder \ --dataset-dir "$DATASET_DIR" \ --bottleneck-dir "$BOTTLENECK_DIR" \ From db17d9b9941385e72ea5d8d4496d6bbb80bad1cc Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 17:21:05 +0300 Subject: [PATCH 39/70] add report results --- REPORT.md | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 REPORT.md diff --git a/REPORT.md b/REPORT.md new file mode 100644 index 0000000..0ab2718 --- /dev/null +++ b/REPORT.md @@ -0,0 +1,183 @@ +# IRRM-CODEC baseline benchmark + +Comparison of IRRM-CODEC against a small set of baselines on CDR3 sequence +reconstruction and Pgen prediction, using human TRB data from +[Zenodo record 19520535](https://zenodo.org/records/19520535). + +One pretrained checkpoint per model. The pretrained encoders are frozen — only the +task heads are trained. + +## Status + +| issue | scope | state | +| --- | --- | --- | +| 1 | train/validation/test splits | done | +| 2 | sequence reconstruction | done | +| 3 | Pgen prediction | pending | + +## 1. Dataset + +Source files are `trb_background_100k.tsv` and `trb_background_embeddings.parquet`, +both inside `redcea_bg.gz` on the Zenodo record. The embeddings parquet is the only +place TCRemP vectors are published, and it holds exactly 100,000 rows per chain rather +than a large background pool. + +The AIRR table arrived clean: no duplicate CDR3 amino-acid sequences, no non-standard +residues, no missing V/J calls, and nothing longer than the model's 40-residue limit. +Two filters still removed rows: + +| filter | rows | reason | +| --- | ---: | --- | +| non-functional V gene | 335 | `TRBV21-1`, `TRBV23-1`, `TRBV6-7` are pseudogenes; SCEPTR rejects them | +| Pgen = 0 | 2 | `CASSFL`, `CASTTL` give `log10(0) = -inf`, which has no finite gradient | + +Both were dropped for every representation and both targets at once, so all models see +one identical row set. Final dataset: **99,663 unique CDR3 sequences**. + +The embeddings parquet has no `clone_id`, so it is aligned to the AIRR table by row +order. Because a silent misalignment would corrupt every downstream result invisibly, +the pipeline asserts it: mean TCRemP CDR3-distance correlates with sequence length at +**r = 0.525**, against **r = 0.008** under a shuffled control. The run aborts below +r = 0.3. + +Split: one seeded permutation over de-duplicated sequences, so a CDR3 can appear in only +one split. Nested training subsets are prefixes of the same permutation. + +| split | rows | +| --- | ---: | +| train | 79,730 | +| validation | 9,966 | +| test | 9,967 | +| subsets | 1,000 ⊂ 10,000 ⊂ 79,730 | + +Both targets are cached: `log10(Pgen)` and `log10(Pgen_1mm)`, computed with mirpy's OLGA +wrapper (1 h 43 min on 8 CPU cores). Verified: no CDR3 overlap between any pair of +splits, and target means agree across splits to within 0.01 for both targets. + +Reproduce with `python -m benchmark.prepare_splits`. + +## 2. Sequence reconstruction + +Every representation is reduced to the same **64-dimensional bottleneck** by a +`StandardScaler` + PCA fitted on the training split only, then decoded by the same +IRRM-CODEC decoder (`InverseModel`, 14.48 M parameters at this input width) with +identical settings: AdamW, lr 1e-3, weight decay 1e-4, batch 256, up to 60 epochs, +early stopping with patience 8. Three seeds per representation (42, 43, 44), 15 runs +total, each on one GTX 1080 Ti. + +Decoder inputs are standardized with train-split statistics. Without it a shared +learning rate would act differently on each representation — the projections arrive with +standard deviations from 1.0 to 12.2 — making "identical training settings" true only on +paper. The repo's own forward/inverse trainers normalize their embeddings the same way. + +### Results at a 64-dimensional bottleneck + +Mean ± standard deviation over three seeds, on the held-out test split. + +| representation | source dim | expl. var | exact match | token acc | norm. Levenshtein | within ED ≤ 1 | mean ED | train s | seq/s | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| aligned one-hot | 1000 | 0.380 | **0.9144** ± 0.0006 | 0.9878 | 0.0106 | 0.9643 | 0.171 | 1792 | 6807 | +| SCEPTR | 64 | 1.000 | **0.9005** ± 0.0081 | 0.9866 | 0.0112 | 0.9586 | 0.176 | 1322 | 6781 | +| TCRemP | 9000 | 0.950 | 0.8017 ± 0.0038 | 0.9784 | 0.0197 | 0.9406 | 0.295 | 1796 | 6968 | +| TCR-BERT | 768 | 0.910 | 0.7700 ± 0.0056 | 0.9644 | 0.0291 | 0.8879 | 0.451 | 1174 | 6864 | +| ESM-2 8M | 320 | 0.974 | 0.6510 ± 0.0014 | 0.9326 | 0.0560 | 0.7692 | 0.849 | 1435 | 6720 | + +Seed variance is small — at most ±0.008 on exact match — so gaps larger than about 0.02 +are real rather than noise. + +### Explained variance does not predict reconstruction quality + +The relationship is inverted: aligned one-hot retains the least variance (0.380) and +reconstructs best, while ESM-2 retains almost all of it (0.974) and reconstructs worst. + +Explained variance measures how much statistical spread survives the projection, not how +much residue-level information survives. One-hot has no correlations for PCA to exploit, +so its variance is spread evenly and the retained fraction looks low — but the 64 +components it keeps describe the dominant axes of sequence variation, which is exactly +what the decoder needs. + +The consequence is that explained variance cannot be used to normalize or excuse the +comparison. It is reported here because it is informative about each representation's +redundancy, not because it explains the ranking. + +### One-hot is a ceiling, not a peer + +The bottleneck equalizes dimensionality but not provenance. Aligned one-hot is a +**reversible encoding of the target itself**, so reconstructing from its PCA projection is +an autoencoding task: compress a sequence, decompress it. The other four invert a lossy +transformation of the sequence into a biological feature space. These are different +problems. + +One-hot's 0.9144 should therefore be read as an approximate ceiling — what 64 numbers can +carry about a CDR3 when they encode the string directly. Its value is diagnostic: it shows +the decoder's capacity is not the limiting factor, so the spread among the other four +reflects their representations rather than the measuring instrument. + +### Mean pooling handicaps the protein language models + +ESM-2 and TCR-BERT emit one vector per residue, and the decoder needs one vector per +sequence. Both are mean-pooled over real residues, excluding BOS/EOS and padding — the +same rule for both, chosen for comparability. + +Averaging over positions discards positional information, which is precisely what +sequence reconstruction requires. Their low scores partly measure this pooling choice +rather than the representations themselves. A CLS token, or per-position embeddings +concatenated before PCA, would likely score higher. Under the issue's constraint of one +frozen checkpoint producing one vector per receptor, mean pooling is the standard choice, +but the caveat belongs with the numbers. + +### Where IRRM-CODEC wins and loses + +**Loses: TCRemP is not the strongest compact representation.** SCEPTR reaches 0.9005 +against TCRemP's 0.8017 — about 10 points — and does so while losing nothing to the +projection (explained variance 1.000, since it is natively 64-dimensional) where TCRemP +loses 5%. SCEPTR lands within 1.4 points of the one-hot ceiling, meaning its 64 numbers +are nearly as informative about the sequence as a direct compression of the sequence. +This is a genuine negative result for the claim that TCRemP is a good compact receptor +representation. + +**Wins: TCRemP survives aggressive compression, and inversion improves under it.** The +committed multi-chain notebook reports exact match 0.7371 for the inverse model on raw +9000-dimensional TRB embeddings. At 64 dimensions — a 140× reduction — this benchmark +reaches **0.8017**. Compression did not cost accuracy; it appears to have removed noise. +That supports the project's premise that the TCRemP space is invertible and usable as a +design space, and it means the practical form of the model can be far smaller than the +published one. + +**Wins: it beats both pretrained protein language models.** TCRemP is ahead of TCR-BERT +by 3 points and ESM-2 8M by 15, though the mean-pooling caveat above applies to both. + +**Neutral: inference speed does not separate the representations.** All five run at +6,700–7,000 sequences/second, because the cost is dominated by the shared decoder, not by +the input. Encoder cost is what differs and is paid once (measured separately: one-hot +0.013 ms/sequence, SCEPTR 1.30, ESM-2 2.07, TCR-BERT 10.11 on 8 CPU threads). + +Reconstruction quality is not what TCRemP was designed for — it encodes similarity to a +reference panel, for clustering and specificity work. Sequence recoverability is a +property IRRM-CODEC adds on top. The reconstruction benchmark therefore bounds one claim +about the representation; the Pgen benchmark tests the project's speed argument, where +the comparison is against OLGA rather than against other encoders. + +Reproduce with `benchmark/slurm/reconstruction_array.sbatch`, then +`python -m benchmark.collect_reconstruction`. + +## 3. Pgen prediction + +Pending. Both targets are cached and the splits are fixed, so the remaining work is the +model arms themselves. + +Measured reference point for the speed question: exact OLGA Pgen runs at **43 +sequences/second** per core (23.4 ms/sequence), and `Pgen_1mm` at **2.7/second** +(370 ms/sequence). The committed pgen notebook reports about 11,000 sequences/second for +the neural predictor on CPU, so the speed argument is roughly two orders of magnitude — +this benchmark will quantify it against the frozen-embedding baselines. + +## Environment + +Results in section 2 were produced on the ctlab Slurm cluster: GTX 1080 Ti, +torch 2.6.0+cu124, Python 3.11. Section 1 timings are from an 8-core CPU (Ryzen 7 8845HS). +Peak-memory figures for section 3 will be resident set size via `psutil`, not +`torch.cuda.max_memory_allocated`, and the device is recorded with every measurement. + +Encoder checkpoints: `esm2_t6_8M_UR50D` (fair-esm), `wukevin/tcr-bert` (HuggingFace), +SCEPTR default variant (`sceptr` 1.2.0). From 4d31ef6908d463355f67434c8f108dea5b07973e Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 17:43:10 +0300 Subject: [PATCH 40/70] Pretrain the sequence-to-TCRemP encoder on the benchmark split One Pgen arm is initialized from a pretrained sequence-to-TCRemP encoder. The published checkpoints used their own random split, so reusing one would leak benchmark test sequences into pretraining and inflate the very comparison the issue asks about. This trains the encoder on the benchmark training split only. PgenModel is ForwardModel with output_dim=1, so 63 of 65 tensors transfer directly and only the final output layer stays randomly initialized. Co-Authored-By: Claude Opus 5 --- benchmark/train_forward_encoder.py | 202 +++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 benchmark/train_forward_encoder.py diff --git a/benchmark/train_forward_encoder.py b/benchmark/train_forward_encoder.py new file mode 100644 index 0000000..b3acd52 --- /dev/null +++ b/benchmark/train_forward_encoder.py @@ -0,0 +1,202 @@ +"""Issue 3, step 1: pretrain the sequence-to-TCRemP encoder on the benchmark split. + +One of the Pgen arms is initialized from a pretrained sequence-to-TCRemP encoder. The +published checkpoints were trained with their own random split, so reusing one would leak +benchmark test sequences into pretraining and inflate exactly the comparison the issue +asks about. This trains the encoder on the benchmark training split only. + +PgenModel is ForwardModel with output_dim=1, so everything except the final output layer +transfers directly into the Pgen arm. +""" + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +from torch.utils.data import DataLoader, Dataset + +from irrm_codec.forward_model import ForwardModel +from irrm_codec.losses import forward_loss, forward_metrics +from irrm_codec.tokenization import PAD_ID, encode +from irrm_codec.utils import choose_device, save_checkpoint, set_seed, setup_logging + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--output-dir", default="artifacts/benchmark/forward_encoder") + p.add_argument("--train-subset", default="all") + p.add_argument("--seed", type=int, default=42) + p.add_argument("--epochs", type=int, default=40) + p.add_argument("--batch-size", type=int, default=256) + p.add_argument("--lr", type=float, default=1e-3) + p.add_argument("--weight-decay", type=float, default=1e-4) + p.add_argument("--patience", type=int, default=6) + p.add_argument("--max-len", type=int, default=40) + p.add_argument("--threads", type=int, default=8) + return p.parse_args() + + +class SequenceToEmbedding(Dataset): + """Tokenized CDR3 in, normalized TCRemP vector out. + + Shuffled training reads the 9000-wide rows in random order, which is slow against a + memory-mapped file on network storage. The split is materialized once instead: the + full training slice is about 2.9 GB resident, which is cheaper than re-reading it + from NFS every epoch. + """ + + def __init__(self, matrix, rows, sequences, mean, std, max_len): + self.tokens = torch.tensor( + [encode(sequences[i], max_len=max_len) for i in rows], dtype=torch.long + ) + targets = np.empty((len(rows), matrix.shape[1]), dtype=np.float32) + for start in range(0, len(rows), 4096): + block = rows[start : start + 4096] + targets[start : start + len(block)] = np.asarray(matrix[block], dtype=np.float32) + self.targets = torch.from_numpy((targets - mean) / std) + + def __len__(self): + return len(self.tokens) + + def __getitem__(self, index): + tokens = self.tokens[index] + return tokens, tokens.ne(PAD_ID), self.targets[index] + + +def load_rows(dataset_dir, name): + return pd.read_csv(Path(dataset_dir) / "manifests" / f"{name}.tsv", sep="\t")["row_index"].to_numpy() + + +def train_statistics(matrix, rows, batch_size=4096): + """Streaming mean and standard deviation over the training rows only.""" + total = np.zeros(matrix.shape[1], dtype=np.float64) + total_sq = np.zeros(matrix.shape[1], dtype=np.float64) + for start in range(0, len(rows), batch_size): + block = np.asarray(matrix[rows[start : start + batch_size]], dtype=np.float64) + total += block.sum(axis=0) + total_sq += (block ** 2).sum(axis=0) + mean = total / len(rows) + variance = np.maximum(total_sq / len(rows) - mean ** 2, 0.0) + return mean.astype(np.float32), np.sqrt(variance).clip(1e-6).astype(np.float32) + + +def run_epoch(model, loader, device, optimizer=None): + is_train = optimizer is not None + model.train(mode=is_train) + sums = {"loss": 0.0, "mse": 0.0, "cosine": 0.0} + steps = 0 + + for tokens, mask, target in loader: + tokens, mask, target = tokens.to(device), mask.to(device), target.to(device) + with torch.set_grad_enabled(is_train): + prediction = model(tokens, mask) + loss = forward_loss(prediction, target) + if is_train: + optimizer.zero_grad(set_to_none=True) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + + metrics = forward_metrics(prediction.detach(), target) + sums["loss"] += loss.item() + sums["mse"] += metrics["mse"] + sums["cosine"] += metrics["cosine"] + steps += 1 + + return {name: value / max(steps, 1) for name, value in sums.items()} + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + set_seed(args.seed) + device = choose_device() + + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "train.log") + + dataset_dir = Path(args.dataset_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + sequences = frame["junction_aa"].tolist() + matrix = np.load(dataset_dir / "embeddings.npy", mmap_mode="r") + + train_rows = load_rows(dataset_dir, f"train_{args.train_subset}") + val_rows = load_rows(dataset_dir, "val") + log.info("device=%s embeddings=%s train=%d val=%d", device, matrix.shape, len(train_rows), len(val_rows)) + + mean, std = train_statistics(matrix, train_rows) + np.save(output_dir / "mean.npy", mean) + np.save(output_dir / "std.npy", std) + + loaders = { + name: DataLoader( + SequenceToEmbedding(matrix, rows, sequences, mean, std, args.max_len), + batch_size=args.batch_size, + shuffle=(name == "train"), + ) + for name, rows in (("train", train_rows), ("val", val_rows)) + } + + model = ForwardModel(output_dim=matrix.shape[1], max_len=args.max_len).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + log.info("model params=%.2fM output_dim=%d", sum(p.numel() for p in model.parameters()) / 1e6, matrix.shape[1]) + + best_val = float("inf") + best_epoch = 0 + history = [] + started = time.perf_counter() + + for epoch in range(1, args.epochs + 1): + train_metrics = run_epoch(model, loaders["train"], device, optimizer) + val_metrics = run_epoch(model, loaders["val"], device) + history.append( + { + "epoch": epoch, + **{f"train_{k}": v for k, v in train_metrics.items()}, + **{f"val_{k}": v for k, v in val_metrics.items()}, + } + ) + log.info( + "epoch=%d train_loss=%.4f val_loss=%.4f val_cosine=%.4f", + epoch, train_metrics["loss"], val_metrics["loss"], val_metrics["cosine"], + ) + + if val_metrics["loss"] < best_val - 1e-5: + best_val, best_epoch = val_metrics["loss"], epoch + save_checkpoint(output_dir / "best.pt", model, optimizer, epoch, val_metrics) + elif epoch - best_epoch >= args.patience: + log.info("early stopping at epoch=%d (best epoch=%d)", epoch, best_epoch) + break + + elapsed = time.perf_counter() - started + pd.DataFrame(history).to_csv(output_dir / "history.csv", index=False) + (output_dir / "metrics.json").write_text( + json.dumps( + { + "best_val_loss": best_val, + "best_epoch": best_epoch, + "epochs_ran": len(history), + "training_seconds": round(elapsed, 2), + "embedding_dim": int(matrix.shape[1]), + "train_size": int(len(train_rows)), + "final": history[-1], + "config": vars(args), + }, + indent=2, + ), + encoding="utf-8", + ) + + log.info("=" * 60) + log.info("best_val_loss=%.4f at epoch=%d in %.0f s", best_val, best_epoch, elapsed) + log.info("checkpoint for Pgen transfer: %s", output_dir / "best.pt") + + +if __name__ == "__main__": + main() From fd203ffc39d59f012796cf7c37b4995c053e507d Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 4 Aug 2026 23:57:30 +0300 Subject: [PATCH 41/70] Add Pgen benchmark arms, Slurm array and results collector Six arms behind one --arm flag: IRRM from scratch, IRRM initialized from the sequence-to-TCRemP encoder, 1-3-mer TF-IDF + Ridge, and three frozen-embedding arms sharing one regression head so only the representation varies. Two measurement fixes found while testing: - Ridge inference now times vectorization too. Timing only the solve reported 15.7M sequences/second, three orders of magnitude off, because feature extraction is the actual cost of that arm's inference path. - Targets are standardized on train statistics and mapped back before metrics. log10 Pgen sits near -6.5, so a fresh network spent its early epochs finding the offset while Ridge fits an intercept for free; from-scratch IRRM showed bias +5.22 as a result. Reported errors stay in log10 units. Co-Authored-By: Claude Opus 5 --- benchmark/collect_pgen.py | 145 +++++++++++ benchmark/slurm/pgen_array.sbatch | 87 +++++++ benchmark/train_pgen_arm.py | 391 ++++++++++++++++++++++++++++++ 3 files changed, 623 insertions(+) create mode 100644 benchmark/collect_pgen.py create mode 100644 benchmark/slurm/pgen_array.sbatch create mode 100644 benchmark/train_pgen_arm.py diff --git a/benchmark/collect_pgen.py b/benchmark/collect_pgen.py new file mode 100644 index 0000000..cd10108 --- /dev/null +++ b/benchmark/collect_pgen.py @@ -0,0 +1,145 @@ +"""Issue 3: aggregate Pgen runs into the per-run CSV and the summary tables. + +Reads every ``metrics.json`` written by ``train_pgen_arm`` and produces: + pgen_runs.csv one row per run (arm x target x training size x seed) + pgen_summary.csv mean and std across seeds + pgen_summary.md Markdown tables for REPORT.md, one per target + +The Markdown groups by training size so the low-data question is readable directly: +whether the pretrained IRRM arm's advantage over the from-scratch arm grows as the +training set shrinks. +""" + +import argparse +import json +from pathlib import Path + +import pandas as pd + +METRICS = ("rmse", "mae", "r2", "pearson_r", "spearman_rho", "bias") +SUBSET_ORDER = {"1k": 0, "10k": 1, "all": 2} + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--runs-dir", default="artifacts/benchmark/pgen") + p.add_argument("--output-dir", default="results/pgen") + return p.parse_args() + + +def load_runs(runs_dir): + rows = [] + for path in sorted(Path(runs_dir).glob("*/metrics.json")): + run = json.loads(path.read_text(encoding="utf-8")) + memory = run.get("memory") or {} + rows.append( + { + "arm": run["arm"], + "target": run["target"], + "train_subset": run["train_subset"], + "train_size": run["train_size"], + "seed": run["seed"], + "training_seconds": run["training_seconds"], + **{name: run["test"][name] for name in METRICS}, + "inference_seq_per_second": run["inference"]["sequences_per_second"], + "inference_ms_per_sequence": run["inference"]["ms_per_sequence"], + "device": run["inference"]["device"], + "peak_rss_mb": memory.get("peak_rss_mb"), + "peak_gpu_mb": memory.get("peak_gpu_mb"), + "epochs_ran": (run.get("arm_details") or {}).get("epochs_ran"), + } + ) + if not rows: + raise SystemExit(f"No metrics.json found under {runs_dir}.") + frame = pd.DataFrame(rows) + frame["subset_order"] = frame.train_subset.map(SUBSET_ORDER).fillna(99) + return frame.sort_values(["target", "subset_order", "arm", "seed"]) + + +def summarize(runs): + aggregated = ( + runs.groupby(["target", "train_subset", "subset_order", "arm"]) + .agg( + seeds=("seed", "count"), + train_size=("train_size", "first"), + **{f"{name}_{stat}": (name, stat) for name in METRICS for stat in ("mean", "std")}, + training_seconds_mean=("training_seconds", "mean"), + inference_seq_per_second_mean=("inference_seq_per_second", "mean"), + peak_rss_mb_mean=("peak_rss_mb", "mean"), + peak_gpu_mb_mean=("peak_gpu_mb", "mean"), + ) + .reset_index() + ) + return aggregated.sort_values(["target", "subset_order", "rmse_mean"]) + + +def to_markdown(summary): + blocks = [] + for target in summary.target.unique(): + blocks.append(f"### {target}\n") + for subset in summary[summary.target == target].train_subset.unique(): + rows = summary[(summary.target == target) & (summary.train_subset == subset)] + size = int(rows.train_size.iloc[0]) + blocks.append(f"**train = {subset} ({size:,} sequences)**\n") + blocks.append( + "| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB |\n" + "| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |" + ) + for _, row in rows.iterrows(): + std = row["rmse_std"] + rmse = f"{row['rmse_mean']:.4f}" + (f" ± {std:.4f}" if pd.notna(std) else "") + cells = [ + row["arm"], + rmse, + f"{row['mae_mean']:.4f}", + f"{row['r2_mean']:.4f}", + f"{row['pearson_r_mean']:.4f}", + f"{row['spearman_rho_mean']:.4f}", + f"{row['bias_mean']:+.4f}", + f"{row['training_seconds_mean']:.0f}", + f"{row['inference_seq_per_second_mean']:.0f}", + f"{row['peak_rss_mb_mean']:.0f}" if pd.notna(row["peak_rss_mb_mean"]) else "-", + ] + blocks.append("| " + " | ".join(cells) + " |") + blocks.append("") + return "\n".join(blocks) + "\n" + + +def pretraining_delta(summary): + """RMSE improvement from IRRM pretraining, per target and training size.""" + pivot = summary[summary.arm.isin(("irrm_scratch", "irrm_pretrained"))].pivot_table( + index=["target", "train_subset", "subset_order"], columns="arm", values="rmse_mean" + ) + if not {"irrm_scratch", "irrm_pretrained"}.issubset(pivot.columns): + return None + pivot["rmse_delta"] = pivot["irrm_scratch"] - pivot["irrm_pretrained"] + pivot["relative_improvement"] = pivot["rmse_delta"] / pivot["irrm_scratch"] + return pivot.reset_index().sort_values(["target", "subset_order"]) + + +def main(): + args = parse_args() + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + + runs = load_runs(args.runs_dir) + runs.drop(columns=["subset_order"]).to_csv(output_dir / "pgen_runs.csv", index=False) + + summary = summarize(runs) + summary.drop(columns=["subset_order"]).to_csv(output_dir / "pgen_summary.csv", index=False) + (output_dir / "pgen_summary.md").write_text(to_markdown(summary), encoding="utf-8") + + print(f"runs: {len(runs)} arms: {runs.arm.nunique()} targets: {runs.target.nunique()}") + delta = pretraining_delta(summary) + if delta is not None: + delta.drop(columns=["subset_order"]).to_csv(output_dir / "pretraining_delta.csv", index=False) + print("\nDoes IRRM pretraining help? (positive rmse_delta means pretraining wins)") + print( + delta[["target", "train_subset", "irrm_scratch", "irrm_pretrained", "rmse_delta", "relative_improvement"]] + .to_string(index=False) + ) + print(f"\nwrote {output_dir}/pgen_runs.csv, pgen_summary.csv, pgen_summary.md") + + +if __name__ == "__main__": + main() diff --git a/benchmark/slurm/pgen_array.sbatch b/benchmark/slurm/pgen_array.sbatch new file mode 100644 index 0000000..409e091 --- /dev/null +++ b/benchmark/slurm/pgen_array.sbatch @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# Issue 3: every Pgen arm across both targets, three training sizes and three seeds. +# +# 5 neural arms x 2 targets x 3 subsets x 3 seeds = 90 runs, plus tfidf_ridge which is +# deterministic and needs one run per target and subset = 6. Total 96 tasks, throttled to +# 2 concurrent because the cluster allows at most 2 GPUs per user. +# +# The log directory must exist before submitting: Slurm opens the --output file before the +# script body runs, so a missing directory kills the job immediately. +# +# mkdir -p /mnt/tank/scratch/mpodsytnik/irrm-codec/logs +# sbatch benchmark/slurm/pgen_array.sbatch +# +# tfidf_ridge does not need a GPU, but it finishes in seconds, so keeping one array is +# simpler than splitting it onto the CPU partition. + +#SBATCH --job-name=irrm-pgen +#SBATCH --partition=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=24G +#SBATCH --time=02:00:00 +#SBATCH --array=0-95%2 +#SBATCH --output=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.out +#SBATCH --error=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.err + +set -euo pipefail + +SCRATCH="${SCRATCH:-/mnt/tank/scratch/mpodsytnik/irrm-codec}" +REPO="${REPO:-/nfs/home/mpodsytnik/irrm-codec}" +CONDA_ROOT="${CONDA_ROOT:-/mnt/tank/scratch/mpodsytnik/miniconda3}" +CONDA_ENV="${CONDA_ENV:-irrm-codec}" + +DATASET_DIR="${DATASET_DIR:-$SCRATCH/data/benchmark/trb}" +REPRESENTATIONS_DIR="${REPRESENTATIONS_DIR:-$SCRATCH/data/benchmark/trb/representations}" +PRETRAINED_CHECKPOINT="${PRETRAINED_CHECKPOINT:-$SCRATCH/artifacts/benchmark/forward_encoder/best.pt}" +OUTPUT_DIR="${OUTPUT_DIR:-$SCRATCH/artifacts/benchmark/pgen}" + +EPOCHS="${EPOCHS:-60}" +BATCH_SIZE="${BATCH_SIZE:-256}" +PATIENCE="${PATIENCE:-8}" + +# Build the task list in a fixed order so a task id always maps to the same run. +CONFIGS=() +for target in log10_pgen log10_pgen_1mm; do + for subset in 1k 10k all; do + for arm in irrm_scratch irrm_pretrained sceptr_mlp tcr_bert_mlp esm2_8m_mlp; do + for seed in 42 43 44; do + CONFIGS+=("$arm $target $subset $seed") + done + done + CONFIGS+=("tfidf_ridge $target $subset 42") + done +done + +if [ "${SLURM_ARRAY_TASK_ID:-0}" -ge "${#CONFIGS[@]}" ]; then + echo "task ${SLURM_ARRAY_TASK_ID} is past the end of the ${#CONFIGS[@]}-run list" >&2 + exit 1 +fi +read -r ARM TARGET SUBSET SEED <<< "${CONFIGS[${SLURM_ARRAY_TASK_ID:-0}]}" + +mkdir -p "$OUTPUT_DIR" + +# conda init is deliberately not used: it would edit the shared account's ~/.bashrc. +source "$CONDA_ROOT/bin/activate" +conda activate "$CONDA_ENV" + +echo "job=${SLURM_JOB_ID:-local} task=${SLURM_ARRAY_TASK_ID:-0} node=${SLURMD_NODENAME:-?}" +echo "arm=$ARM target=$TARGET subset=$SUBSET seed=$SEED (${#CONFIGS[@]} runs total)" +nvidia-smi --query-gpu=name,memory.total --format=csv,noheader || true + +cd "$REPO" +# Slurm redirects stdout to a file, where Python block-buffers by default. +export PYTHONUNBUFFERED=1 +srun python -m benchmark.train_pgen_arm \ + --arm "$ARM" \ + --target "$TARGET" \ + --train-subset "$SUBSET" \ + --seed "$SEED" \ + --dataset-dir "$DATASET_DIR" \ + --representations-dir "$REPRESENTATIONS_DIR" \ + --pretrained-checkpoint "$PRETRAINED_CHECKPOINT" \ + --output-dir "$OUTPUT_DIR" \ + --epochs "$EPOCHS" \ + --batch-size "$BATCH_SIZE" \ + --patience "$PATIENCE" \ + --threads "${SLURM_CPUS_PER_TASK:-4}" diff --git a/benchmark/train_pgen_arm.py b/benchmark/train_pgen_arm.py new file mode 100644 index 0000000..12ce2aa --- /dev/null +++ b/benchmark/train_pgen_arm.py @@ -0,0 +1,391 @@ +"""Issue 3: train one Pgen-prediction arm and score it on the benchmark test split. + +Arms: + irrm_scratch PgenModel from a random initialization + irrm_pretrained PgenModel initialized from the sequence-to-TCRemP encoder + tfidf_ridge 1-3-mer character TF-IDF + Ridge regression + sceptr_mlp frozen SCEPTR embeddings + the shared regression head + tcr_bert_mlp frozen TCR-BERT embeddings + the same head + esm2_8m_mlp frozen ESM-2 8M embeddings + the same head + +The three frozen-embedding arms share one head and one training configuration, so the +only thing that varies between them is the representation. The two IRRM arms differ only +in initialization, which is the comparison the issue asks about. + +Targets stay in raw log10 units, matching the repo's pgen trainer, so RMSE, MAE and bias +are directly interpretable as log10 error. +""" + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +import torch.nn as nn +from scipy import stats +from torch.utils.data import DataLoader, TensorDataset + +from irrm_codec.losses import pgen_loss +from irrm_codec.pgen_model import PgenModel +from irrm_codec.tokenization import PAD_ID, encode +from irrm_codec.utils import choose_device, save_checkpoint, set_seed, setup_logging + +SEQUENCE_ARMS = ("irrm_scratch", "irrm_pretrained") +FROZEN_ARMS = {"sceptr_mlp": "sceptr", "tcr_bert_mlp": "tcr_bert", "esm2_8m_mlp": "esm2_8m"} +ARMS = (*SEQUENCE_ARMS, "tfidf_ridge", *FROZEN_ARMS) + +# Ridge has no training loop, so the penalty is selected on validation instead. This is +# the baseline's equivalent of early stopping; fixing it arbitrarily would handicap it. +RIDGE_ALPHAS = (0.01, 0.1, 1.0, 10.0, 100.0) + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--arm", required=True, choices=ARMS) + p.add_argument("--target", default="log10_pgen_1mm", choices=("log10_pgen", "log10_pgen_1mm")) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--representations-dir", default="data/benchmark/trb/representations") + p.add_argument("--pretrained-checkpoint", default="artifacts/benchmark/forward_encoder/best.pt") + p.add_argument("--output-dir", default="artifacts/benchmark/pgen") + p.add_argument("--train-subset", default="all") + p.add_argument("--seed", type=int, default=42) + p.add_argument("--epochs", type=int, default=60) + p.add_argument("--batch-size", type=int, default=256) + p.add_argument("--lr", type=float, default=1e-3) + p.add_argument("--weight-decay", type=float, default=1e-4) + p.add_argument("--patience", type=int, default=8) + p.add_argument("--max-len", type=int, default=40) + p.add_argument("--threads", type=int, default=8) + return p.parse_args() + + +class RegressionHead(nn.Module): + """One head shared by every frozen representation, so only the input differs.""" + + def __init__(self, input_dim, hidden_dims=(512, 256), dropout=0.2): + super().__init__() + layers = [] + previous = input_dim + for width in hidden_dims: + layers += [nn.Linear(previous, width), nn.GELU(), nn.Dropout(dropout)] + previous = width + layers.append(nn.Linear(previous, 1)) + self.net = nn.Sequential(*layers) + + def forward(self, features): + return self.net(features).squeeze(-1) + + +def load_rows(dataset_dir, name): + return pd.read_csv(Path(dataset_dir) / "manifests" / f"{name}.tsv", sep="\t")["row_index"].to_numpy() + + +def peak_memory_mb(): + """True peak resident set size, plus GPU peak when a device was used.""" + result = {} + try: + import resource + + # ru_maxrss is in kilobytes on Linux. + result["peak_rss_mb"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 + except (ImportError, AttributeError): + try: + import psutil + + result["peak_rss_mb"] = psutil.Process().memory_info().rss / 1024**2 + except ImportError: + result["peak_rss_mb"] = None + if torch.cuda.is_available(): + result["peak_gpu_mb"] = torch.cuda.max_memory_allocated() / 1024**2 + return result + + +def regression_metrics(predictions, truth): + residual = predictions - truth + total_variance = np.var(truth) + return { + "rmse": float(np.sqrt(np.mean(residual**2))), + "mae": float(np.mean(np.abs(residual))), + "bias": float(np.mean(residual)), + "r2": float(1.0 - np.mean(residual**2) / total_variance) if total_variance > 0 else float("nan"), + "pearson_r": float(stats.pearsonr(predictions, truth)[0]), + "spearman_rho": float(stats.spearmanr(predictions, truth)[0]), + } + + +def build_features(args, frame, rows_by_split, log): + """Return per-split model inputs for the requested arm.""" + if args.arm in SEQUENCE_ARMS: + tokens = { + name: torch.tensor( + [encode(frame.junction_aa.iloc[i], max_len=args.max_len) for i in rows], + dtype=torch.long, + ) + for name, rows in rows_by_split.items() + } + return tokens, None + + representation = FROZEN_ARMS[args.arm] + matrix = np.load(Path(args.representations_dir) / f"{representation}.npy", mmap_mode="r") + features = { + name: torch.from_numpy(np.asarray(matrix[rows], dtype=np.float32)) + for name, rows in rows_by_split.items() + } + # Train-split statistics only: a shared learning rate across representations with + # different scales would not be the identical setting the issue requires. + mean = features["train"].mean(dim=0, keepdim=True) + std = features["train"].std(dim=0, keepdim=True).clamp_min(1e-6) + for name in features: + features[name] = (features[name] - mean) / std + log.info("%s features dim=%d", representation, features["train"].shape[1]) + return features, (mean, std) + + +def build_model(args, input_dim, log): + if args.arm in SEQUENCE_ARMS: + model = PgenModel(max_len=args.max_len) + if args.arm == "irrm_pretrained": + state = torch.load(args.pretrained_checkpoint, map_location="cpu")["model_state"] + own = model.state_dict() + # Everything but the output layer matches: PgenModel is ForwardModel with + # output_dim=1, so only mlp. differs in shape. + transferable = {k: v for k, v in state.items() if k in own and own[k].shape == v.shape} + model.load_state_dict(transferable, strict=False) + log.info( + "transferred %d/%d tensors from %s", + len(transferable), len(own), args.pretrained_checkpoint, + ) + return model + return RegressionHead(input_dim) + + +def run_epoch(model, loader, device, is_sequence, optimizer=None): + is_train = optimizer is not None + model.train(mode=is_train) + loss_sum, steps = 0.0, 0 + for batch in loader: + inputs, target = batch[0].to(device), batch[-1].to(device) + with torch.set_grad_enabled(is_train): + prediction = model(inputs, inputs.ne(PAD_ID)) if is_sequence else model(inputs) + loss = pgen_loss(prediction, target) + if is_train: + optimizer.zero_grad(set_to_none=True) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + loss_sum += loss.item() + steps += 1 + return loss_sum / max(steps, 1) + + +@torch.no_grad() +def predict_all(model, inputs, device, is_sequence, batch_size): + model.eval() + chunks = [] + for start in range(0, len(inputs), batch_size): + block = inputs[start : start + batch_size].to(device) + prediction = model(block, block.ne(PAD_ID)) if is_sequence else model(block) + chunks.append(prediction.cpu().numpy()) + return np.concatenate(chunks) + + +def fit_ridge(args, frame, rows_by_split, targets, log): + """1-3-mer character TF-IDF into Ridge, with the penalty chosen on validation.""" + from sklearn.feature_extraction.text import TfidfVectorizer + from sklearn.linear_model import Ridge + + started = time.perf_counter() + sequences = { + name: frame.junction_aa.iloc[rows].tolist() for name, rows in rows_by_split.items() + } + vectorizer = TfidfVectorizer(analyzer="char", ngram_range=(1, 3)) + train_features = vectorizer.fit_transform(sequences["train"]) + val_features = vectorizer.transform(sequences["val"]) + + best = (None, float("inf"), None) + for alpha in RIDGE_ALPHAS: + model = Ridge(alpha=alpha).fit(train_features, targets["train"]) + rmse = float(np.sqrt(np.mean((model.predict(val_features) - targets["val"]) ** 2))) + log.info("ridge alpha=%.3g val_rmse=%.4f", alpha, rmse) + if rmse < best[1]: + best = (model, rmse, alpha) + model, val_rmse, alpha = best + training_seconds = time.perf_counter() - started + log.info("selected alpha=%.3g val_rmse=%.4f features=%d", alpha, val_rmse, train_features.shape[1]) + + # Vectorization is part of this arm's inference path, so it belongs inside the timed + # section; excluding it would report the Ridge solve alone and overstate throughput + # by orders of magnitude. + inference_started = time.perf_counter() + test_features = vectorizer.transform(sequences["test"]) + predictions = model.predict(test_features) + elapsed = time.perf_counter() - inference_started + + return ( + predictions, + training_seconds, + { + "sequences_per_second": len(predictions) / elapsed, + "ms_per_sequence": elapsed / len(predictions) * 1000, + "batch_size": len(predictions), + "device": "cpu", + }, + {"alpha": alpha, "val_rmse": val_rmse, "n_features": int(train_features.shape[1])}, + [], + ) + + +def fit_neural(args, features, targets, log): + device = choose_device() + is_sequence = args.arm in SEQUENCE_ARMS + if torch.cuda.is_available(): + torch.cuda.reset_peak_memory_stats() + + loaders = { + name: DataLoader( + TensorDataset(features[name], torch.from_numpy(targets[name].astype(np.float32))), + batch_size=args.batch_size, + shuffle=(name == "train"), + ) + for name in ("train", "val") + } + + model = build_model(args, features["train"].shape[-1], log).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + log.info("device=%s params=%.2fM", device, sum(p.numel() for p in model.parameters()) / 1e6) + + best_val, best_epoch = float("inf"), 0 + best_state = None + history = [] + started = time.perf_counter() + + for epoch in range(1, args.epochs + 1): + train_loss = run_epoch(model, loaders["train"], device, is_sequence, optimizer) + val_loss = run_epoch(model, loaders["val"], device, is_sequence) + history.append({"epoch": epoch, "train_loss": train_loss, "val_loss": val_loss}) + if epoch % 5 == 0 or epoch == 1: + log.info("epoch=%d train_loss=%.4f val_loss=%.4f", epoch, train_loss, val_loss) + + if val_loss < best_val - 1e-6: + best_val, best_epoch = val_loss, epoch + best_state = {k: v.detach().cpu().clone() for k, v in model.state_dict().items()} + elif epoch - best_epoch >= args.patience: + log.info("early stopping at epoch=%d (best epoch=%d)", epoch, best_epoch) + break + + training_seconds = time.perf_counter() - started + if best_state is not None: + model.load_state_dict(best_state) + + inference_started = time.perf_counter() + predictions = predict_all(model, features["test"], device, is_sequence, args.batch_size) + elapsed = time.perf_counter() - inference_started + + return ( + predictions, + training_seconds, + { + "sequences_per_second": len(predictions) / elapsed, + "ms_per_sequence": elapsed / len(predictions) * 1000, + "batch_size": args.batch_size, + "device": str(device), + }, + {"best_val_loss": best_val, "best_epoch": best_epoch, "epochs_ran": len(history)}, + history, + model, + optimizer, + ) + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + set_seed(args.seed) + + run_name = f"{args.arm}_{args.target}_{args.train_subset}_seed{args.seed}" + output_dir = Path(args.output_dir) / run_name + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "train.log") + + dataset_dir = Path(args.dataset_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + rows_by_split = { + "train": load_rows(dataset_dir, f"train_{args.train_subset}"), + "val": load_rows(dataset_dir, "val"), + "test": load_rows(dataset_dir, "test"), + } + targets = { + name: frame[args.target].to_numpy()[rows] for name, rows in rows_by_split.items() + } + # log10 Pgen sits near -6.5, so a freshly initialized network spends its first epochs + # just finding the offset while Ridge fits an intercept for free. Standardizing the + # target on train statistics removes that asymmetry; predictions are mapped back + # before any metric is computed, so the reported errors stay in log10 units. + target_mean = float(targets["train"].mean()) + target_std = max(float(targets["train"].std()), 1e-6) + scaled_targets = {name: (values - target_mean) / target_std for name, values in targets.items()} + log.info( + "run=%s train=%d val=%d test=%d target_mean=%.3f", + run_name, *(len(r) for r in rows_by_split.values()), targets["train"].mean(), + ) + + history, model, optimizer = [], None, None + if args.arm == "tfidf_ridge": + scaled_predictions, training_seconds, speed, extra, history = fit_ridge( + args, frame, rows_by_split, scaled_targets, log + ) + else: + features, _ = build_features(args, frame, rows_by_split, log) + scaled_predictions, training_seconds, speed, extra, history, model, optimizer = fit_neural( + args, features, scaled_targets, log + ) + save_checkpoint(output_dir / "best.pt", model, optimizer, extra["best_epoch"], extra) + + predictions = scaled_predictions * target_std + target_mean + metrics = regression_metrics(predictions, targets["test"]) + pd.DataFrame( + { + "row_index": rows_by_split["test"], + "cdr3": frame.junction_aa.iloc[rows_by_split["test"]].to_numpy(), + "true": targets["test"], + "predicted": predictions, + } + ).to_csv(output_dir / "test_predictions.csv", index=False) + if history: + pd.DataFrame(history).to_csv(output_dir / "history.csv", index=False) + + result = { + "run_name": run_name, + "arm": args.arm, + "target": args.target, + "train_subset": args.train_subset, + "train_size": int(len(rows_by_split["train"])), + "seed": args.seed, + "training_seconds": round(training_seconds, 2), + "test": metrics, + "inference": speed, + "memory": peak_memory_mb(), + "target_scaling": {"mean": target_mean, "std": target_std}, + "arm_details": extra, + "config": vars(args), + } + (output_dir / "metrics.json").write_text(json.dumps(result, indent=2), encoding="utf-8") + + log.info("=" * 60) + log.info( + "test rmse=%.4f mae=%.4f r2=%.4f pearson=%.4f spearman=%.4f bias=%.4f", + metrics["rmse"], metrics["mae"], metrics["r2"], + metrics["pearson_r"], metrics["spearman_rho"], metrics["bias"], + ) + log.info( + "training=%.0f s inference=%.0f seq/s peak_rss=%.0f MB", + training_seconds, speed["sequences_per_second"], result["memory"].get("peak_rss_mb") or 0, + ) + log.info("wrote %s", output_dir / "metrics.json") + + +if __name__ == "__main__": + main() From 3a57bce2f7043c15b35a074bbdd13c35a2657369 Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 6 Aug 2026 22:55:06 +0300 Subject: [PATCH 42/70] Add anchored padding as an alternative to end-padding Keeps the first/last token at fixed buffer positions and puts padding between them, instead of always at the end - lets conv layers key on a stable position for the conserved sequence ends. Off by default. --- irrm_codec/wordpiece_tokenization.py | 55 +- .../compare_forward_tokenizers_report.ipynb | 633 +++++++++++++++--- .../convergence_curves_by_epoch_report.ipynb | 257 ++++++- 3 files changed, 826 insertions(+), 119 deletions(-) diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py index e8fef18..e9df86f 100644 --- a/irrm_codec/wordpiece_tokenization.py +++ b/irrm_codec/wordpiece_tokenization.py @@ -33,7 +33,7 @@ def load_wordpiece_tokenizer(path) -> Tokenizer: def encode_wordpiece(seq, tokenizer, max_len): - """Encode a CDR3 sequence into exactly max_len ids: truncated or PAD-padded.""" + """Encode a CDR3 sequence into exactly max_len ids: truncated or PAD-padded at the end.""" seq = "" if seq is None else str(seq).strip().upper() if not seq: raise ValueError("Sequence must not be empty.") @@ -41,6 +41,42 @@ def encode_wordpiece(seq, tokenizer, max_len): return ids + [PAD_ID] * (max_len - len(ids)) +def encode_wordpiece_anchored(seq, tokenizer, max_len, left_anchor=1, right_anchor=1): + """Encode a CDR3 sequence, with padding split into the middle instead of the end. + + Keeps the first left_anchor and last right_anchor tokens at fixed offsets from the + start/end of the buffer, and inserts all padding between them - e.g. for + left_anchor=1, right_anchor=1: [tok0, PAD, PAD, ..., PAD, tok_{-1}]. The idea: the + convolutional ForwardModel is position-sensitive, and the N-/C-terminal ends of a CDR3 + are its most conserved regions (see the WordPiece longest-token analysis earlier in + this project) - with end-padding those ends land on a different absolute position in + every example (depending on how long the encoded sequence happens to be), while + anchoring keeps them at a fixed position always, mirroring what gap_pad_cdr3() already + does for the char tokenizer (there with actual gap characters; here with real PAD_ID, + still excluded from mean_pool/max_pool by the model's mask). + + Falls back to plain end-padding if there's no room for both anchors plus padding + (short sequences, or left_anchor+right_anchor >= sequence length). + """ + seq = "" if seq is None else str(seq).strip().upper() + if not seq: + raise ValueError("Sequence must not be empty.") + ids = tokenizer.encode(seq).ids + if len(ids) > max_len: + raise ValueError(f"Sequence '{seq}' encodes to {len(ids)} WordPiece tokens, exceeds max_len={max_len}.") + + pad_total = max_len - len(ids) + if pad_total == 0 or len(ids) <= left_anchor + right_anchor: + return ids + [PAD_ID] * pad_total + + left = ids[:left_anchor] + right = ids[len(ids) - right_anchor:] + middle = ids[left_anchor: len(ids) - right_anchor] + pad_left = pad_total // 2 + pad_right = pad_total - pad_left + return left + [PAD_ID] * pad_left + middle + [PAD_ID] * pad_right + right + + def decode_wordpiece(token_ids, tokenizer, stop_at_eos=True): """Decode ids back to an amino-acid string, stopping at the first EOS by default.""" ids = list(token_ids) @@ -110,10 +146,21 @@ def filter_vocab_by_max_token_length(tokenizer: Tokenizer, max_token_length: int class WordpieceEncodeFn: - """Binds a tokenizer to encode_wordpiece so it matches datasets.py's encode_fn(seq, max_len).""" + """Binds a tokenizer to an encode_* function matching datasets.py's encode_fn(seq, max_len). + + pad_layout="end" (default) uses encode_wordpiece - unchanged from before this option + existed. pad_layout="anchored" uses encode_wordpiece_anchored instead. + """ - def __init__(self, tokenizer): + def __init__(self, tokenizer, pad_layout="end", left_anchor=1, right_anchor=1): + if pad_layout not in ("end", "anchored"): + raise ValueError(f"pad_layout must be 'end' or 'anchored', got {pad_layout!r}.") self.tokenizer = tokenizer + self.pad_layout = pad_layout + self.left_anchor = left_anchor + self.right_anchor = right_anchor def __call__(self, seq, max_len): - return encode_wordpiece(seq, self.tokenizer, max_len) \ No newline at end of file + if self.pad_layout == "end": + return encode_wordpiece(seq, self.tokenizer, max_len) + return encode_wordpiece_anchored(seq, self.tokenizer, max_len, self.left_anchor, self.right_anchor) \ No newline at end of file diff --git a/notebooks/compare_forward_tokenizers_report.ipynb b/notebooks/compare_forward_tokenizers_report.ipynb index 2159d0e..596e9cc 100644 --- a/notebooks/compare_forward_tokenizers_report.ipynb +++ b/notebooks/compare_forward_tokenizers_report.ipynb @@ -5,26 +5,26 @@ "id": "d4b91ee9", "metadata": {}, "source": [ - "# Compare Forward Tokenizers \u2014 char vs WordPiece\n", + "# Compare Forward Tokenizers — char vs WordPiece\n", "\n", "Reads the output of `scripts/compare_forward_tokenizers.py` (`raw_results.csv` +\n", "`summary.json`) and, optionally, `scripts/calc_tokenization_stats.py`'s output for the\n", "same AIRR file, and renders the comparison as tables and plots.\n", "\n", "Interpretation notes live in markdown cells next to each plot, not on the plots\n", - "themselves \u2014 the plots only show data (axes, legend identifying which series is which)." + "themselves — the plots only show data (axes, legend identifying which series is which)." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "25047bb7", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:29.527950Z", - "iopub.status.busy": "2026-07-30T17:10:29.527800Z", - "iopub.status.idle": "2026-07-30T17:10:29.533251Z", - "shell.execute_reply": "2026-07-30T17:10:29.532239Z" + "iopub.execute_input": "2026-08-02T09:59:01.633666Z", + "iopub.status.busy": "2026-08-02T09:59:01.633666Z", + "iopub.status.idle": "2026-08-02T09:59:01.653541Z", + "shell.execute_reply": "2026-08-02T09:59:01.653541Z" }, "tags": [ "parameters" @@ -42,17 +42,167 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "b314dd93", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:29.535656Z", - "iopub.status.busy": "2026-07-30T17:10:29.534957Z", - "iopub.status.idle": "2026-07-30T17:10:34.312793Z", - "shell.execute_reply": "2026-07-30T17:10:34.311678Z" + "iopub.execute_input": "2026-08-02T09:59:01.653541Z", + "iopub.status.busy": "2026-08-02T09:59:01.653541Z", + "iopub.status.idle": "2026-08-02T09:59:03.331902Z", + "shell.execute_reply": "2026-08-02T09:59:03.331297Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 18 individual runs across 6 tokenizer configs from ..\\artifacts\\compare_forward_tokenizers_background100k_40epochs_upto30k\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizemax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_path
0char254010.2023770.8644000.191109331122.7319380.54961410850856NaN
1char2540420.2001860.8663640.191719371121.6011780.56569110850856NaN
2char25407770.2025250.8641060.199392361122.4595360.54959510850856NaN
3wordpiece10004010.2298820.8445520.224929361142.9400600.55186710913256artifacts/tokenizers_1M_integ/wordpiece_vocab_...
4wordpiece100040420.2330810.8430240.225724371143.0590100.55277210913256artifacts/tokenizers_1M_integ/wordpiece_vocab_...
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size max_len seed test_loss test_cosine \\\n", + "0 char 25 40 1 0.202377 0.864400 \n", + "1 char 25 40 42 0.200186 0.866364 \n", + "2 char 25 40 777 0.202525 0.864106 \n", + "3 wordpiece 1000 40 1 0.229882 0.844552 \n", + "4 wordpiece 1000 40 42 0.233081 0.843024 \n", + "\n", + " best_val_loss epochs_to_best_val train_time_sec inference_time_sec \\\n", + "0 0.191109 33 1122.731938 0.549614 \n", + "1 0.191719 37 1121.601178 0.565691 \n", + "2 0.199392 36 1122.459536 0.549595 \n", + "3 0.224929 36 1142.940060 0.551867 \n", + "4 0.225724 37 1143.059010 0.552772 \n", + "\n", + " num_parameters tokenizer_path \n", + "0 10850856 NaN \n", + "1 10850856 NaN \n", + "2 10850856 NaN \n", + "3 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", + "4 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import json\n", "from pathlib import Path\n", @@ -79,22 +229,147 @@ "id": "a1f9d58c", "metadata": {}, "source": [ - "## Summary table (mean \u00b1 std across seeds)" + "## Summary table (mean ± std across seeds)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "41f68c7f", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:34.314620Z", - "iopub.status.busy": "2026-07-30T17:10:34.314442Z", - "iopub.status.idle": "2026-07-30T17:10:34.327971Z", - "shell.execute_reply": "2026-07-30T17:10:34.327073Z" + "iopub.execute_input": "2026-08-02T09:59:03.334061Z", + "iopub.status.busy": "2026-08-02T09:59:03.334061Z", + "iopub.status.idle": "2026-08-02T09:59:03.344312Z", + "shell.execute_reply": "2026-08-02T09:59:03.344312Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizetest_losstest_cosinebest_val_lossepochs_to_best_valnum_parametersn_seeds
0char250.2017 ± 0.00130.8650 ± 0.00120.1941 ± 0.004635.3 ± 2.1108508563
1wordpiece10000.2318 ± 0.00170.8439 ± 0.00080.2263 ± 0.001736.0 ± 1.0109132563
2wordpiece50000.2695 ± 0.00290.8166 ± 0.00210.2679 ± 0.004939.7 ± 0.6111692563
3wordpiece100000.3090 ± 0.00320.7883 ± 0.00190.3077 ± 0.002840.0 ± 0.0114892563
4wordpiece200000.3552 ± 0.00080.7559 ± 0.00100.3534 ± 0.003239.3 ± 1.2121292563
5wordpiece300000.3774 ± 0.00450.7398 ± 0.00400.3744 ± 0.005237.7 ± 2.1127692563
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size test_loss test_cosine best_val_loss \\\n", + "0 char 25 0.2017 ± 0.0013 0.8650 ± 0.0012 0.1941 ± 0.0046 \n", + "1 wordpiece 1000 0.2318 ± 0.0017 0.8439 ± 0.0008 0.2263 ± 0.0017 \n", + "2 wordpiece 5000 0.2695 ± 0.0029 0.8166 ± 0.0021 0.2679 ± 0.0049 \n", + "3 wordpiece 10000 0.3090 ± 0.0032 0.7883 ± 0.0019 0.3077 ± 0.0028 \n", + "4 wordpiece 20000 0.3552 ± 0.0008 0.7559 ± 0.0010 0.3534 ± 0.0032 \n", + "5 wordpiece 30000 0.3774 ± 0.0045 0.7398 ± 0.0040 0.3744 ± 0.0052 \n", + "\n", + " epochs_to_best_val num_parameters n_seeds \n", + "0 35.3 ± 2.1 10850856 3 \n", + "1 36.0 ± 1.0 10913256 3 \n", + "2 39.7 ± 0.6 11169256 3 \n", + "3 40.0 ± 0.0 11489256 3 \n", + "4 39.3 ± 1.2 12129256 3 \n", + "5 37.7 ± 2.1 12769256 3 " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "def fmt(mean_std, precision=4):\n", " mean, std = mean_std\n", @@ -126,17 +401,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "e9fac0c5", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:34.329706Z", - "iopub.status.busy": "2026-07-30T17:10:34.329556Z", - "iopub.status.idle": "2026-07-30T17:10:34.500172Z", - "shell.execute_reply": "2026-07-30T17:10:34.498906Z" + "iopub.execute_input": "2026-08-02T09:59:03.344312Z", + "iopub.status.busy": "2026-08-02T09:59:03.344312Z", + "iopub.status.idle": "2026-08-02T09:59:03.559127Z", + "shell.execute_reply": "2026-08-02T09:59:03.559127Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "loss_means = [r[\"test_loss\"][0] for r in wp]\n", "loss_stds = [r[\"test_loss\"][1] for r in wp]\n", @@ -159,7 +445,7 @@ "id": "a27ed78f", "metadata": {}, "source": [ - "*Notes: lower `test_loss` is better. `char` has no `vocab_size` position of its own \u2014 it's\n", + "*Notes: lower `test_loss` is better. `char` has no `vocab_size` position of its own — it's\n", "drawn as a horizontal reference (line + shaded std band), not a point on the WordPiece\n", "ablation grid.*" ] @@ -174,17 +460,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "f24dbe8c", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:34.502628Z", - "iopub.status.busy": "2026-07-30T17:10:34.501710Z", - "iopub.status.idle": "2026-07-30T17:10:34.621402Z", - "shell.execute_reply": "2026-07-30T17:10:34.620208Z" + "iopub.execute_input": "2026-08-02T09:59:03.559127Z", + "iopub.status.busy": "2026-08-02T09:59:03.559127Z", + "iopub.status.idle": "2026-08-02T09:59:03.713955Z", + "shell.execute_reply": "2026-08-02T09:59:03.713955Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkwAAAG4CAYAAAC3j7hRAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYjJJREFUeJzt3QV4U9f/BvC3Rktxd3d3d4fhDJfhMsE22GDsN/+PsTEmjCnuNtzdYcPd3V0KhRba+3++55KQtE0T2jT6fp7nQu7Nyc3NTdq8Pefcc3w0TdNARERERBb5Wr6LiIiIiBiYiIiIiGzAGiYiIiIiKxiYiIiIiKxgYCIiIiKygoGJiIiIyAoGJiIiIiIrGJiIiIiIrGBgIiIiIrKCgYmInGLdunXw8fHBpk2b+A440Pz589V537Nnj8Oek+81eQIGJqIEtmzZMvUFtW3bNo94HiIib+Tv7AMgIu9Ut25dcCpL78D3mjwBa5iIiIiIrGBgIkpAv/76K5o2bapuV6tWTTWZyTJ+/Hhjmfv372Pw4MHImTMnEiVKhMyZM+O9997Do0ePjGWePn2Kjz76CHny5EHixImRK1cu9OzZE5cvX7b5eWwhx/LBBx8gb968CAoKUv+PGDECjx8/NpY5f/48OnbsiHTp0iEwMBAFChTA119/jRcvXth8vJb6tZj2rxk9ejSyZcumHl+jRg0cOXIkxuO1du6iOnTokHqOn376Kdp9586dg6+vL0aOHGnz64jP/m09n7a8N3J+DO+7LHK8xYoVw5gxY2KsyZNtX375pTpnwcHBqF27Ng4cOIDXFdf3OmXKlGbHa7osWrQoXu8xUYLQiChBLV26VL6ttK1bt0a778GDB1rBggXVsmHDBi0kJETbvXu3VrRoUa1ixYra8+fPVbl+/fppGTJk0LZs2aKFhoZqly9f1iZNmqR9+OGHNj2PLe7du6flz59fy507t7ZixQp1bGfPntVGjhypTZkyRZWR502XLp1WqlQpbe/evarMtGnTtODgYK1NmzbGfdlyvGvXrlXHu3HjRuO2efPmqW2dOnXSxowZo925c0c7ceKEVqxYMS1fvnzaixcvXvvcxaRs2bKqXFQjRozQ/Pz8tKtXr9r8OuKzf1vPpy3vTVRy7saPH68FBQVpP/74Y7Rz/Oabb2o//PCD8RzXqlVLS548uXbmzBntdcT1vY7qyZMnWpkyZbTAwEDt8OHD8X6PieyNgYkogcUWZIYPH66+QI8fP262/eDBg+oxs2bNUuvyhdGhQ4c4P48thgwZovn6+hq/rGLyzjvvaP7+/urL2pR8cZs+ty3HG1tg6tOnj1nZxYsXq+3r169/7XMXkz/++EOV+ffff43bIiIitKxZs2pNmjQxbrPldcRn/7aeT1veG0t69eqlXkfUc9y1a1ezchKckiRJor311luvtf+4vtem5Nw0a9ZM8/HxMXvf4vMeE9kbm+SInGjp0qWq2aRgwYJm24sXL460adNi8+bNar1EiRKqmeLbb7/FqVOnEuRYVqxYoZ63aNGiFsusX78eJUuWRO7cuc22t27d2ni/PY63cePGZuuGY5Imrdc9dzHp0KGDaoaaOHGicdvq1atx5coV1ZxkENfXYev+bT2ftrw3Qp6vYsWKSJ48uVmz7JkzZ6KVbdasmdl6mjRpVHPuhg0b8Drs8dkcNGgQlixZgm+++Qbt27e3y3tMZG8MTEROdOPGDRw8eBD+/v5q8fPzU31c5Ivuzp07uHv3rir322+/oVu3bvjhhx9UHxfpx9GnT59Y+9K8rlu3biFLliyxlpHjyZgxY7Tthm1yzPY43kyZMpmtSwAQDx48eO1zFxPZX5s2bTBr1izVB0dMmDABGTJkQJMmTYzl4vo6bN2/refTlvdG+rFJGGvZsiWOHj2K58+fq35KEkai9ocSciwxbTM8p63i+15LX6+xY8eid+/eGDZsmNl98XmPieyNgYnIieSv5CpVqqgvNFkiIiIQGRmpvuhkmTt3riqXOnVq9cV08+ZN9WU4dOhQLFiwADVr1lTl7UE6HV+9ejXWMnIccgxRGbbJ67HH8coXor3OnSUSLqTjsHQ0ly9fqc1466231Bez6euN6+uwdf+2nE9b3pupU6eiUqVKqgO2dJY3PI90Ko+JpeeVmqbXEZ9ztHjxYtWRvX79+mof9n6PieyJgYkogSVJkkT9HxYWFu0+ubJt9+7dFr/UopK/rgsXLqyuGpKaA2mikmYea89jC6n5kCu8YroazaBOnTrYv38/Ll68aLb9n3/+Md5v6/HG1+ueu6ik+UlqRKTmZ9q0aQgPD0ePHj1iLBuX12HL/m09n7a8N0KusjMlIWbNmjUxlpUAZ+revXtq0NOo76GtXvccyXsnVwcWKVIE8+bNMwuS9nqPiezK7r2iiMjMtWvXVMde6bj79OlTs/vu37+vFS5cWCtUqJC6+kmuhpLOt9LZt3v37tqSJUtUObmCacaMGdr58+e1Z8+eaUeOHNFKly5tduVYbM9ji7t376r9yZVYK1eu1B4+fKidO3fO7EqsS5cuaWnTplVXM+3fv1+VkeNKmjSp1qpVK+O+bDne2Dp9y5VQpm7fvq22f//996997mIzatQo1dFYOmNXqVIl2v22vI747N/W82nLe/PVV1+pjuFyld3jx4+1ffv2aVWrVtWaNm2qzl1MV8nJ1XOy75MnT2p169bVkiVLpp06dcrq63rdcxT1vZb3Tq6sy5w5szoHltjjPSayFwYmIgf47bfftFy5cqkrfuSL4++//zbeJ19+cjVQgQIFtESJEqnLzGvUqKFNnjxZCwsLU2X27Nmjrl7KmTOnukw8R44c6nLuK1eu2Pw8tpAvzwEDBqj9y7HkzZtXXQovl3MbyGXn7dq109KkSaMFBASoMl988YUWHh5uLGPL8cY3MNl67mJz48YN9Rpk3xMnTox2v63nPa77t/V82vLeSHk5FxLOEidOrFWoUEHbtGmT9tFHH8UYmOQKvv/9738quMhrq1mzphra4HXF5b0+ffq0Wre0LFy40G7vMZG9+Mg/9q2zIiIiIvIs7MNEREREZAUDExEREZEVDExEHkzmGbM0X5dhKVu2rLMPk1wMPzdE0bEPExEREZEVrGEiIiIisoKBiYiIiMiK6EOrkiLD71+7dg3JkiWzaZoGIiIicj8yulJISIiaB1FGrLeEgckCCUsyHxMRERF5PpkwOmvWrBbvZ2CyQGqWDCfQMFM6EREReRaZJFsqSAzf+5YwMFlgaIaTsMTARERE5Nmsdb9hp28iIiIiKxiYiIiIiKxgYCIiIiKygoGJiIiIyAoGJiIiIiIrGJiIiIiIrGBgIiIiIrKCgYmIiIjICgYmIiIiIisYmIiIiIisYGAiIiIisoKBiYiIiMgKTr5rxYsXL9RCREREnsfW73gGJitu3ryJ0NBQe7wnRERE5GJCQkJsKsfAZIWfnx8SJUpkj/eEiIiIXPB73hYMTFZERkaqJSofHx/4+786fc+fP7e4j4QqKwICAuJUVqogNU1z6bJyHuR8iIiIiBjfB1cqKz90vr6+LlNWykl5S6Sc4ReFK5SVz0JsVeOuUNYVfu75O8K1fu75O8L9f0cYfmdaw8BkxZQpUxAUFBRte44cOdC0aVPj+oQJEyy+OZkzZ0arVq3M9vns2bMYy6ZPnx5t27Y1rs+cOdNidWHq1KnRsWNH4/q8efNw7969GMsmS5YMXbt2Na4vWLAAt27dirGsvN5evXoZ15csWYJr165Z/GXRr18/4/rKlStx8eJFWPLee+8Zb69duxZnz561WLZv377GgLVx40acOHHCYtmePXsiceLE6va2bdtw+PBhi2XfeustJE+eXN3etWsX9u/fb7Fshw4dkCZNGnV7z5492L17t8Wybdq0QYYMGdTtgwcPYseOHRbLtmjRAlmzZlW3jx49ii1btlgs26RJE+TMmVPdPnXqFNavX2+xbMOGDZE3b151+9y5c1i1apXFsnXq1EGhQoXU7UuXLmHZsmUWy1avXh3FixdXt+WzsGjRIotlK1eujNKlS6vbt2/fVp9LS8qVK4cKFSqo2/LZnTVrlsWypUqVQpUqVdRt+ZmYOnWqxbLFihVDjRo11G35WZOfT0sKFiyIunXrqtvyM/znn39aLJsnTx40atTIuB5bWf6O0PF3xCv8HeG6vyNswavkiIiIiKzw0WJrE/Fijx49QooUKXD8+HGkTJky2v2sbn+FTXI6Nsm5ZnU7m+TYbC/YJBf995QrNMVHusDviPv37yNfvnx4+PChsfUhJgxMVgLTyZMnYwxMRERE5P4ePHiAAgUKWA1M7MNkhSTf8PBwe78/RERE5AJiq+EyxcBkhXTijS1xEhERkfsKDg62qRwDk7UT5O9vdrkvEREReQ5bv+N5lRwRERGRqwemiRMnokSJEsiYMSPq1asX65g4hrEVhgwZgsKFCyNTpkxqfIZJkyZFK3f58mX06NFDjV8jZX/66adYBx8jIiIicsnAJANQvf322xg6dCi2b9+uBoWrXbs2rl+/bvExMkji4sWL1UB0+/btU+u9e/fG/PnzjWVkYD0JUo8fP1YDKcpy9epV9RxEREREr8upwwrIyMEy4ucff/xh7KmeJUsW9OnTB19++WWMj5Eao27duuHzzz83bpMaKglaP/74o1rv3r07du7ciSNHjsS5/5FhWAFrlxkSERGR+7L1+97XmeMeyPQVMj2DgQwiJcFHprawpFmzZli+fDlu3Lih1mVKCZleQ6aPENLstnDhQjVlCDtrExERkT04LTAZ5iYzzL1lOpeapXnLhNQiyVxZ0n9J5jyTfk/jxo0zBi+Zl0ZSYqpUqVSIknJlypTBL7/8EmsfprCwMJUyTRciIiIil+j0HXWWYKkViq2V8N1331V9l6RmSSYXlckvpR/UihUrzAagGjFihJpkde/evfjkk0/w8ccfY/To0Rb3O3LkSFUlZ1iyZctmt9dIRERE7s1pfZju3LmDdOnSqeYzmbndQELO+fPnsXXr1miPkZmK06ZNqzqLt2vXzmxGeekovmnTJlVTlCRJEnWF3F9//WUsM2DAAHX/oUOHYjweeZwsBlLDJKGJfZiIiIg8l8v3YZLgkzt37mjBSGqO5Aq3mEi2k0Wa4kzJuqG5LTAwEKVLl1b/m5L12Cbik/vlRJkuRERERE5vkhs4cCDGjx+vLveX+dqkWUw6c/ft29esZkiupBNp0qRBxYoVVbkrV66o8CS1RvPmzUPjxo2Nj/nggw8wY8YM7N69W63L2E5TpkxB69atnfAqiYiIyN05dc6P/v37q6a5N954A0+ePFFDBixatAj58uUzlgkNDTXrgD137lwMGjQIhQoVUiFLOncPHjxYDWZpIM11t27dUp2+5Wo8qWrr1asXPv30U4e/RiIiInJ/Th2HyUAO4dmzZ0icOHG0+54+faqa0pIlSxbtPulzFLXpLSrZb9QmPFtwHCYiIiLP98jGPkwuMausj49PjGFJWNourIUlEZewRERERORSwwoQERERuToGJiIiIiIrGJiIiIiIrGBgIiIiIrKCgYmIiIjICgYmIiIiIisYmIiIiIisYGAiIiIisoKBiYiIiMgKBiYiIiIiKxiYiIiIiKxgYCIiIiKygoGJiIiIyAoGJiIiIiIrGJiIiIiIrGBgIiIiIrKCgYmIiIjICgYmIiIiIisYmIiIiIisYGAiIiIisoKBiYiIiMgKBiYiIiIiKxiYiIiIiKxgYCIiIiKygoGJiIiIyAoGJiIiIiIrGJiIiIiIrGBgIiIiIrLC31oBsrPICODiDuDxTSBpBiBHZcDXj6eZiIjIhTEwOdKxJcCqj4BH115tS54ZaDgKKNzMoYdCREREtmOTnKPsmwrM7WIeloSsy3a5n4iIiFwSA5OjmuFWfRx7mdUf6+WIiIjI5TAwOYL0WQoPib1MWIhejoiIiFwOA5MjSAdve5YjIiIih2JgcgS5Gs6e5YiIiMihGJgcQYYOSJQs9jKJkurliIiIyOUwMDnkLPsBDb+JvUyyTEBEuEMOh4iIiNxsHKawsDCsWbMGN2/eRLFixVChQgWrj7l79y42b96M+/fvI3v27KhVqxb8/WN+KWfPnsXKlStRsmRJVK1aFU5T+i0gKGX0cZiSpNM7fN89DczrBrSbDvgFOO84iYiIKBofTdM0OMmtW7dQs2ZNdbtEiRJYvXo1WrVqhfHjx1t8zNKlS9GhQwcVrHLmzImtW7fCx8cHmzZtQqZMmaKFMSl3+vRp9O7dGz/99JPNx/bo0SOkSJECDx8+RPLkyZGgI31f2gVMbwW8eAYUfRNo9TdH/yYiInIAW7/vnVrDNGzYMAQEBGDXrl1InDgxDhw4gDJlyqB58+Zo2rRpjI8ZMWIE2rRpg0mTJqn10NBQ5MmTB3/88Qe++OILs7Lvv/8+Kleu7HrNc7mqmW/LWUWvWZrVATjyD5AoCdD0F8DHx1lHSURERK7QhykyMhLz589Ht27dVFgS0mwmAWfOnDkWHydNbylTpjSuBwUFITg4OFqT3MKFC7FhwwaMHj0abiFfPeDNvwEfX33U7zWfAM6r/CMiIiJXqGG6fPkyQkJCUKhQIbPtsr5nzx6Lj/vtt9/Qq1cv9O/fHzly5FChqHDhwhgwYIDZvt9++22sWLFChSlbSPOdLKZVdA5XpCUQ/gRY/C6w81cgMDlQ8yPHHwcRERG5Rg2ThCVhWlskUqVKFWtYCQwMVDVShw4dwrFjx3D+/Hm1D19f/aVERESgY8eOGDx4MEqXLm3z8YwcOVK1YRqWbNmywSlKdQYafqvf3vQNsPM35xwHEREROT8wGZrhDMHJQMKSpVohCUPSv6latWrqKrmJEyeqfk9SIzV8+HBVZsaMGTh8+LDa/6+//qqWO3fu4ODBg+q2pT7u8njp8GVYpJbKaSq+DdQaod9ePRzYN815x0JERETOa5KT4QASJUqkaohMnTt3Dvny5YvxMdeuXVNBpmHDhmY1TnKl3c6dO9W6XDnXuXNnnDp1ylhGmtpkCIITJ06owCRX1UUl+5HFZVQfCjx7qDfNLR2gdwQv2srZR0VEROSVnBaY5Oq4Ro0aYebMmeqSfwkxV65cUcMD/PXXX8ZyGzduxI0bN9RQAjJsgHTy3rt3L+rXr6/ulwC0f/9+5M6dW61Xr15dLaa2bdumQtXrDCvgdBLq6n+tj9G0bwqwoLc+Gnh+/XUTERGR4zh1WIFRo0apq+KaNGmixkuaPn26Wu/UqZOxjDSxybADEpjkSrhvvvlGDUdw8eJFFZLWrl2r+jKZhiyPIaGpyY9A+GN9uIG5XYDO/wA5nTgAJxERkRdy6tQoBQoUwJEjR1CjRg3Vb+jjjz9Wo36bDhFQu3Zt1YnbQDpzS/ObNL3dvn1b9WmS0byLFy9u8Xnat2+v+j25JRm3qeWfQP5G+sCWM9sBV/c6+6iIiIi8ilNH+nZlCTbSd1w9fwbMaA1c2AokTgV0WwFkKOzsoyIiIvKK73tOvusuAoKADrOALGWBp/eBaS2Au2edfVRERERegYHJnQQmAzrNA9IX0eeim9oCeHjV2UdFRETk8RiY3E1waqDLQiB1HuDhJWBqc+DxbWcfFRERkUdjYHJHyTIAby0GkmcF7p4GprcEnj5w9lERERF5LAYmd5Uymx6akqQDbhwGZrbV56EjIiIiu2Ngcmdp8wJdFgFBKYDL/wKzO+pX0xEREZFdMTC5u4xFgU7/AAFJgHObgH96AhEvnH1UREREHoWByRNkK6cPOeAXCJxYBix+F4iMdPZREREReQwGJk+RuwbQdgrg4wccmg2sHCoT7Tn7qIiIiDwCA5MnKdAIaCVz6vkAu8cD679w9hERERF5BAYmT1OstT5hr9j2I7D1B2cfERERkdtjYPJEZbsD9b7Sb6//Evjvb2cfERERkVtjYPJUVQYA1Yfqt1cMAQ7McvYRERERuS0GJk9WawRQoZ9+e/E7wPGlzj4iIiIit8TA5Ml8fIAGI4GSnQAtEpjfAziz3tlHRURE5HYYmDydry/Q9BegcHMgIhyY3Qm4tMvZR0VERORWGJi8gZ8/0Go8kLcu8OIpMKMNcO2As4+KiIjIbTAweQv/REDbaUD2ykDYI2B6K+D2SWcfFRERkVtgYPImiYKBjnOATCWB0LvA1BbA/QvOPioiIiKXx8DkbYKSA50XAOkKAiHXgKnNgUfXnX1URERELo2ByRslSQN0WQSkyqnXME1rATy56+yjIiIiclkMTN4qeSbgrcVAskzA7RN6n6Znj5x9VERERC6JgcmbSQ2ThKbgNMD1A8Cs9kB4qLOPioiIyOUwMHm7dAX0Pk2ByYGL24G5XYAX4c4+KiIiIpfCwERA5pJAx7mAf2LgzDpgQS8g4gXPDBER0UsMTKTLUQloPwPwSwQcWwwsHQhERvLsEBERMTCRmbx1gDcnAD6+wIHpwOrhgKbxJBERkddjDROZK9wMaP6bfvvfP4CN3/AMERGR12NgouhKdgDeGK3f3vIdsP0XniUiIvJqDEwUs/K9gdr/02+v/R+wZxLPFBEReS0GJrKs2gdAlUH67WWDgcPzebaIiMgrMTCRZT4+QN3PgbI9AWjAgj7AyZU8Y0RE5HUYmMh6aJL+TMXbAVoEMLcrcG4zzxoREXkVBiay4VPiq185V6AxEBEGzOoAXN7NM0dERF6DgYls4+cPtJ4I5K4JPH8CzHgTuHGEZ4+IiLwCAxPZLiAIaD8TyFoeePYQmNYSuHOGZ5CIiDweAxO9nkRJgE7zgIzFgCe3gKnNgQeXeRaJiMijMTDR60ucEui8EEiTD3h0RQ9Nj2/xTBIRkcdyemCaOXMmKlSogJw5c6Jp06Y4ciT2fjFPnjzBJ598gtKlSyNXrlyoUaMGZs2aZVbm2LFj6N27N4oUKYISJUrg3XffxY0bNxL4lXiZpOmAtxYBKbID987qzXNP7zv7qIiIiDwvMM2fPx/dunVT4Wb58uVImzYtatasiVu3LNdWvPPOO5gxYwZ++OEHbNiwAe3bt0fnzp2xaNEidX9ERATatWuHihUrYt68eZgwYYIKYXXq1MHTp08d+Oq8QIqsemhKmgG4eQSY3hoIC3H2UREREdmdj6Y5bzr6kiVLoly5cvj777/V+osXL5A5c2ZVI/TZZ5/F+BipiZKQ9fnnnxu3SS1S7dq18eOPP6p1eUk+Mn7QS2fOnEG+fPmwceNGFchs8ejRI6RIkQIPHz5E8uTJ4/lKPdzNY8DkN/QaplzVgY7z9A7iRERELs7W73tfZx7gwYMHUa9ePeM2f39/VRO0ZcsWi49r2LAhVq1ahXv37qn1//77D2fPnlXbDUzDkggLC1P/J0qUKAFeCSFDYaDzP0CipMD5LcC8bkDEc54YIiLyGE4LTFevXlX/Z8iQwWy7rF+7ds3i48aNG6f6LqVPnx4pU6ZE9erV1bYGDRrEWF5qm4YNG4b8+fOr2ixLJFRJiDNd6DVkKQN0mA34BwGnVgIL+wGRETyFRETkEZwWmAwtgVKrZErWpR+SJYMHD1a1SitXrsS+ffvw008/qX5Na9eujbH8hx9+qGqs5syZg4CAAIv7HTlypKqSMyzZsmWL82vzWrmqAW2nAb7+wJH5wPL35Y129lERERG5b2BKly6d+v/OnTtm22/fvq1qj2Jy//59/Prrr/j6669VU17u3LnRr18/NG7cWAWeqORquj///FM14Ul/qdgMHz5ctV8alsuXObZQnOSvD7T6G/DxBfZOBtb+j6GJiIjcnnn1joMDk3Tg3rZtG5o3b27cvnXrVrRo0SLGx0jNk9RMJUmSxGx70qRJozXjffrpp/jll19UWKpUqZLV4wkMDFQL2UHRVkD4Y2BJf2DHWD08FWlluXyyjPpCRETkopw6rMB7772H8ePHY+/evSoMjRkzBleuXEGfPn2MZT744APjlW0y7ECZMmXw3XffGYce2LVrlxqeoFGjRsbHfPHFF6qpTsJS5cqVnfDKCKXfAhq8rPXb/jPwVw3Ly55JPGFEROTSnFbDJN5//33cvHlTddyOjIxUtU4SfgoWLGgsI81jps12MraSBK0cOXKoPkl+fn7o27cvPvroI3W/XD0nQw4EBQWhVSvzWg0JZB07dnTgK/Ryld4Bwh4Bm14GJ7mKTmqeDJKkAyoPAIq3ddohEhERufw4TAYy/lJISIi66i3qkABytdrz58+RJk0as+0SsOQx0kHblLwcCWExkbKJEye26Zg4DpOdyMdrVnvg1KoY7nz5XredChRuZq9nJCIispmt3/dOrWEyvTIuVapUMd5n6eB9fX2jhSUhgStjRvaHcRlaJHDjkKU79dC0ahhQsDHg6+fggyMiInKTueTIw13cATyyPK6WCk2PrurliIiIPC0wySS4ixcvNk5HIk6dOmUcX4lIeRxz82icyxEREblLYJJgVKRIEdXZWjpuG3z11VdqgEgiI5mY157liIiI3CUwDRo0CG3btsX169fNtg8cOBCjR4+217GRJ8hRGUie+VUH75gEBANZLU9bQ0RE5JaBaefOnfj444+jXdEmwwEcPnzYXsdGnkA6cjcc9XLFQmh6HgrM6QyEmQw5QERE5O6BSS7pDw8PV7dNQ9OFCxdivHKNvFy28kC9L4Fg86EhkCQ9UKKjPmHvmbXA5DeAEPZlIiIiDwlMMo+boenNEJhkcMkBAwagYcOG9j1Ccn8ykrfMKRdqPm8gntwCDs4EirXVw9T1g8CEusDtU846UiIiIvsNXHnx4kU1XYmMpn3y5EnUqFEDe/bsUSN1y9xwmTNLnxX3xoEr7Sjkhr5YIvPIhT8BZrQG7p0DglICHWYDOazPAUhEROSI7/s4j/Qto2xPnz5dBSVpoitdujS6du0a65O5EwYmJ3hyB5jZDri6B/ALBFr9BRSJeSJmIiIitwhMno6ByUnCQ4F/egInV+idxBt8o89JR0RE5I5To4SGhuLEiRNqstuo6tatG9fdkrdLFAy0mw6s/BDYPR5YPRx4eBmo/38yH46zj46IiLxUnALTmjVr0LFjR9y9ezfG+1lpRfEeiuCN0UCKbMC6z4Bdv+nTp7T8CwgI4sklIiL3GbiyV69eqnZJwlHUhSje5OrLqoOAVuMB3wDg2GJgWgsgNHqNJhERUUKLUx+mJEmS4NatW+p/T8U+TC7k/BZgtgxs+RBIkw/oPB9IldPZR0VERF70fR+nGiYZ0VsGqSRyiFzVgR6rgORZgbungfH1gGv7efKJiMhh4hSY3n77bTWEwMaNG3H58mVcuXLFbCGyuwyFgV5rgQxF9QEvJzUGTq/liSYiItdtkos6h1xUntCPiU1yLurZI2BuF+DcJsDHD2j6E1D6LWcfFRERuakEHVbg+PHj8Tk2orgLSg50nAcsHQAcnAUs6Q88vALUHK53FCciIkoA/nHtw0TkNP6JgBa/AymyAlu+BzaP0kNT058BvwC+MURE5LzAJINUGsKS4bYlDFSU4KQ2qfYnQPIswPIPgAMzgJDrQJspei0UERGRM/owGfotSXH2YSKXcmo1MK8b8DwUyFhMb7JLnsnZR0VERN7Yh0muhovpNpHT5W8AdFsOzGwL3DgMTKgHdJoPpGfTMRER2YfdJt+VcZnSp0+P4OBgeAJeJeeG7p0HZrQG7p4BglIA7WcCOas6+6iIiMhbB67cu3cv+vfvb1zv3LkzcuXKhYwZM2LHjh1xO2Ki+EqdC+i5FshWAXj2EJjWEjjyD88rERHFW5wC05AhQ9CuXTt1+8iRI1i6dCl27dqFoUOHYvjw4fE/KqK4Ck4NvLUYKNQUiAgH5vcAtv8ine94TomIyLFNcsmSJVNzySVOnBhjxozBoUOHMHnyZDx+/BhZsmRR1Vrujk1ybi4yAlj9MfDvH/p6+b5Aw5GAr5+zj4yIiLylSS5p0qTGueSWLVuG2rVrq9vyZHIfkdNJMGr4LVD///T1//4E5r4FPH/q7CMjIiI3FKfA1Lp1azRu3BjNmjXDgQMH0LRpU7V99erVaNSokb2PkShuZCiMyu8BrScBfomAE8uAKc2AJ3d5RomIKOEDkzTDDRw4EHnz5sX69euRKlUqtV0GtPzss8/iskuihFO0FdBlkX7l3JX/9GEH7p3jGSciIscPK+Bp2IfJA90+CUxvDTy8BASnBTrNBbKUcfZRERGRp/ZhMjhz5oy6Qm7JkiXqNpFLS1cA6LUWyFgcCL0DTG4CnFzl7KMiIiI3EKfAJCnszTffRL58+dCiRQu0bNlS3ZZtnnCFHHmwZBmB7iuAPHX0qVRmdwD2THT2URERkScGpkGDBuHs2bPYunUrnj17pha5LbVMgwcPtv9REtlTYDKg4xygVGdAiwSWDQbWf8mxmoiIyL59mFKnTo3t27ejUKFCZtuPHz+OqlWr4u5d978KiX2YvIB89DePAjaN1NeLtwOa/Qr4J3L2kRERkSf0YXr69CnSpk0bbXuaNGkQGhoal10SOWfYgZrD9JDk4wccmqPPRSfTqhAREcU3MFWqVAmffPIJwsPDjdvCwsIwYsQIdR+RWyndBeg4F0iUFDi/GZjYCHh41dlHRURE7t4kd/DgQTRo0ADy0BIlSqhtMoClr6+vGrzSsM2dsUnOC107AMxsCzy+CSTLDHSeD2Qo4uyjIiIiF/i+j/M4TCEhIZgyZQqOHj0KHx8fFC5cGF27dlXzzL2O58+fY9OmTbh58yaKFStmU9iSFyV9qO7fv4/s2bOjSpUqKqzFd7+mGJi81P2LwIw2wJ2TQGByoN10IHcNZx8VERG5a2CyB+kcXqdOHTVpr4SaDRs2oEuXLvj1118tPmbVqlVo164dihYtipw5c6rgJCFNHpsuXbo47zcqBiYvFnoPmN0JuLQD8A0AWvwGFG/r7KMiIiJ36/QtO581a1a07bJN7rPV8OHDVU2QNPEtXLgQ69atw2+//YaVK1dafMywYcPUHHYSlGbMmIEjR47g1q1bGDduXLz2S2QUnBroshAo0hKIfA4s6A1sHcNhB4iIvFicAtMHH3yAJ0+eRNsuNToffvihTfuIjIzEnDlz0KNHDyRJkkRtK1euHCpWrBhjGDOQCrEMGTIY1+Wxps2Acd0vkZmAIODNiUCl9/T19V8Ayz8AIl7wRBEReaE4BaYFCxaoUb2jkm1yny0uX76saqOk75OpIkWKqFojS6RZTaZjGTp0qLoto4znypVLTQYcn/3KVX7yONOFvJz0i2vwf0DDb6X1GtgzAZjTGQiP/scCERF5tjgFJqnFiWlwStlmOtRAbAyBJFWqVNEGxYwtrEh5GQNqy5Yt2LFjh+p0Ln2ZAgMD47XfkSNHqjZMw5ItWzabXgd5gYpvA22nAP5BwKmVwJSmwOPbzj4qIiJy9cBUr149DBkyRDXBmV419/7776Nu3bo27SNx4sTGx5mSdcN9UUVERKBJkyYoVaoU/v33X8ycOVP1U9q8ebPqtxTX/Qp5vHT4MixSU0VkVLg58NZiIHEq4OpeYEI94O5ZniAiIi/hH5cHff/996hWrRpy5Mihwov0K9q/f7/qSyThxRYyHEBAQAAuXLhgtv38+fPImzdvjI+5du0aLl68iKZNmxq3BQcHqyvipBN4XPcrpIbKUEtFFPOHtiLQcy0w/U3g/nk9NHWYA2QrxxNGROTh4lTDJEHp8OHD+Pzzz1XTlax/8cUXOHTokGoes0WiRInU4JezZ89WgUtcv34dGzduNAtE27ZtM/aLypgxowo18jymZF2O4XX2SxQnafMBvdYBmUoCoXeBKU2AE8t5MomIPFyCjsPUsGFDNW6SJceOHUPlypVRu3ZtdRWbDISZMmVKNeCk1BKJXr16YdeuXcYO299++60KZ3379kXu3Lmxdu1aNc7S1q1bUbp0aZv3aw3HYaJYhT0G5ncHTq8BfHyBRt8B5XvzpBERuRmXGLhSRgC3tvtLly5h8uTJxhG5u3fvbtY0JmHn3LlzKiQZ7Ny5U03BIp3MpWapU6dOyJQp02vt1xoGJrJKhhhY/j6wb4q+XmUgUOdz/eo6IiJyC24TmFwVAxPZRD7fW0cDG77W14u21kcG92d/OCIiePtI30T0ko8PUH0o0OIPwNcfODJf7xT+9AFPERGRB2FgIrKHkh2ATvOARMmAC1uBiQ2BBxyagojIUzAwEdlLntpAj5VAskzA7eP6sAPXza/oJCIi98TARGRPGYvpww6kKwSEXAcmvQGc3cBzTETkjYEpttG8Te8zzO9G5FVSZAV6rAJyVgPCQ4AZbYADM519VEREFA9xukrO0tVvMsecjHMkU5i4O14lR/H2IgxY9I7eEVzU+gSoPkTvKE5ERG71ff9aU6OcOXMmxtuGsCST4WbJkiUux0vkeWRogVZ/6zVO238CNn4NPLwMNB4D+MVpViIiInKS1/qtnS9fvhhvGwQFBWHs2LH2OTIiTyCDWNb7Qg9NKz/UB7mUvk2tJwGBSZ19dERElBCBSSawFbly5TLeNpCmuAwZMsDfn385E0Uj06YkzwzM76lPpzK5sT4MQdL0PFlERJ7ah+nx48dImtT8r+MLFy4gffr0CA4OhidgHyZKEJd3A7Pa6RP3pswBdP5Hn9CXiIg8b6TvkydPon///sb1zp07q1qnjBkzqn5MRGRBtnJAz7VAqlzAg4v6WE2XdvF0ERG5uDgFpiFDhqBdu3bq9pEjR7B06VLs2rULQ4cOxfDhw+19jESeJU0ePTRlKQM8vQ9MaQYcW+zsoyIiInsHpj179qBMmTLq9po1a9CyZUtUqFABgwcPxoEDB+KySyLvkjQd0HUZkL8REBEGzO0K7Prd2UdFRET2DEzSf0n6LIlly5ahdu3a6ra0/0Xt20REFiQKBtrPAMr2BKABq4YBq0fIGB08ZURELiZOl7S1bt0ajRs3RtGiRVWNUtOmTdX21atXo1GjRvY+RiLP5esHNP4BSJkNWPc5sPNX4OEVoOWfQECQs4+OiIjiU8M0ZswYNe1J3rx5sX79eqRKlUptP3HiBD777LO47JLIe8nI31UH64Nc+gYAxxYB01oAofecfWRERBSfYQW8AYcVIKc4txmY0xkIewSkzQ90mg+kysE3g4jInaZGMfXkyROsW7cO586dU529xalTp9QI4DLXHBHFQe4a+sS9MmHvnVP6sAMtfgeC0wCREcCNQ/oYTrKesbjepJcso74QEZFr1TBJMKpfvz6ePXuGmzdvGifi7dKli+rb1L59e7g71jCRUz28CsxsC9w8ojfTRT63XLbGMKAWh/MgInK5gSsHDRqEtm3b4vr162bbpV/T6NGj47JLIjKVIgvQfQWQq0bsYclQloiIXK+GSTp5y1xyKVOmVM1vhl3IlClp0qRBWFgY3B1rmMglhD8Fvs8FPH9qoYCPPkfdoMN68xwREblODVNkZCTCw8PVbdP+SjI2kzwpEdnJ1T2xhCWhAY+uAhc5JRERUUKKU2CqV6+esenNEJju3LmDAQMGoGHDhvY9QiJv9vimfcsREVGcxOkquR9++AE1a9ZUc8hJc1ytWrXUdCnp0qXD9OnT43YkRBRd0gy2nRW/RDx7RESuOA5TSEiICkcSlKSJrnTp0ujatWus7X/uhH2YyCXIUAI/FQUeyQUWsfyo+gUC5XoBVQcBSdM78giJiLzi+z5Ogalu3bpqDKbXvc+dMDCRyzi2BJj71ssV0x9XaQ7XgDR5gLtn9U3+iYFyPYEqEpzSOeNoiYjcSoIGJtMr40xJTVNAQAAiIiLg7hiYyGWE3AAOzQW2/wyE3nm1PUl6oHJ/oFgb4NZRYONIvZO4CAjWg1PlgQxORESOHun7zJkzMd42hKUdO3YgSxaOCUNkV3smAZu/jb79yS1g7f+A8Cf6wJV56gBn1gEbvwGu7QN2jAV2TwDK9wYqDwCSpOUbQ0QUR69Vw2RtypOgoCCMHTsWvXr1grtjDRO5VA2TLJZEnRpFfqRPrwE2jQSu7de3BSQxCU5pEv6YiYi8uUlOxlkSuXLlUgNXmpKmuAwZMsDfP87T07kUBiZye/KjfWo1sOkb4PpBfVuipED5PnpTXnBqZx8hEZFn92GSEb2TJk0KT8bARB5DfsRPrtRrnGTyXpEoGVChL1DpXQYnIvJqjxIyMHkDBibyzOC04mVwOvwqOFXspwenxKmcfYRERA7HwOSgE0jkdiIjgZPLgU3fAjeP6NsCkwMV3wYqvgMkTunsIyQichgGJgedQCK3Dk4nlurB6dYxfVtgCqDSO3p4CuK8kETk+R6xSc4xJ5DII4LT8SV6cLp9XN8mYaniu3pzHYMTEXkwBiYHnUAijwpOxxYBm0cBt0/o24JSApXe0zuIB/HngIg8DwOTg04gkUfOXyfBadMo4M7JV8GpsgSnfkBgMmcfIRGR3TAwOegEEnl0cDq6UG+qu3ta3yZX0skYTjKWE4MTEXnR970vnOyff/5BjRo1ULBgQbRp0wYnT778i9aCIkWKIGfOnNGWTz75xFjm6dOn+Prrr1G5cmUUKlQIDRo0wIIFCxzwaog8iK8fUKw18O6/QKu/gTR5gaf3gfVfAj8VB7b9CIQ9dvZREhE5hFPHYVq8eDFat26NH3/8EZUqVcKYMWOwbt06HD16FGnTxjzv1aVLl9S8dQZ79uxRQWvZsmVo3Lix2iZTs6xZswZ//vmnClOrVq3CkCFD1PM1adLEpmNjDRNRFBEvgCP/6H2c7p3VtwWn0adbkWlXEiXhKSMit+MWTXJlypRBiRIlMHHiRLX+/PlzZMqUCYMGDTKrMYpNv379sHz5cjVti5+fn3Hqlq5du+Lzzz83litevDjq1KmjwpktGJiIYglOh+cBW74D7p3TtwWnBaoMBMr1ZHAiIrfi8k1yISEh2Ldvn2ouM52PTkLNpk2bbNpHaGgoZs2ahZ49exrDkqhdu7aqqZKTIA4cOIBz586hbt26CfBKiLyMnz9QsgPw7m6gxe9AqlxA6B1g7f+An0sAO8YC4aHOPkoiIrtyWmC6cuWK+j9jRpNZ1l+uX7161aZ9zJs3T81r16NHD7Pt0hSXLVs2pEuXTu1Pmvt+/fVXY5NdTMLCwlTAMl2IyFpw6gi8txtoPg5ImQN4chtY84kenHaOA54/5SkkIo/gtMBk6Ifk7+9vtl1qmSIiImzax4QJE1QNVfbs2c22Dx8+HDt37sT8+fOxYcMGjBw5Eu+99x42btxocV9SRqrkDIsELiKygV8AUKoz0H8v0GwskDI78OQWsPpjPTjt+p3BiYjcntP6MN28eVPV/khH7GbNmhm3d+vWDadPn8b27dtjfbyUyZ8/v7r6rWXLlsbtDx48QJo0aTBlyhR07tzZuF06l8t90lRnqYZJFgOpYZLQxGEFiF7Ti3Dg4Cxgy2jg4SV9W9KMQNXBQJluQEAQTykRuQyX78OUIUMGVTO0Y8cOs+0SlMqVK2dT7ZLso2nTpmbbpeO41F6lTGk+gaicDBluwJLAwEB1okwXIooD/0RAma56jVOTn4AU2YDHN4BVHwG/lAT+/Qt4/oynlojcilPHYXrnnXcwfvx4HDlyBFLR9dtvv6mr3Xr37m0sM2zYMLOO4eLFixeYOnUqunfvHq1JT/otyZV3P/zwA+7fv6+27d+/X433VL9+fQe9MiJSwalsd6D/PqDxGCB5FiDkOrByKPBLKeC/v4EXr2p1iYhcmXnacLChQ4eqDt5ly5ZVNTxBQUGYOXOmGpzS4M6dO9E6ga9YsQI3btxQV8dZ6gwuww3IEAVSU/TkyRPVMVz6NhGRE4KTDDcg/Zz2TwO2jgEeXQVWDNEHv6z2PlCqC+AfyLeGiFyWU8dhMpCmMulfJE1svr7mlV53795VfYsyZ85s3CZlZVgCax2zw8PDVS1T+vTp4ePj81rHxHGYiBKI1Crtmwps/UGvcRLJswLVPwBKdtYDFhGRg7jFwJWujIGJKIFJP6Z9U/QaJ+njJFJk14NTiY4MTkTkEAxMDjqBRGSH4LR3MrBNgtNNfZsMTVBtiD7OkwxbQESUQBiYHHQCichOZJDLPZP0fk0yjpOQwTCrDwVKtGdwIqIEwcDkoBNIRHYm06rsmQhs/0kfOVykyqkHp+ISnJx6rQoReRgGJgedQCJKyOA0Adj2kz5XnZB562p8CBRry+BERHbBwOSgE0hECSz8CbB7PLD9ZyD0rr4tdR49OBVtzeBERPHCwBRPDExELibssR6cdvzyKjilyQtUlxqn1oCvn7OPkIjcEAOTg04gETkhOP33lx6cnuqj+SNNPqDGR0DRVgxORPRaGJjiiYGJyMWFhQD//gns/PVVcEqbXw9ORVoyOBGRTRiY4omBichNPHsE/PcnsONX4NkDfVvaAkDNj4DCEpycOmUmEbk4BiYHnUAichHPHr6qcZLbIl0hPTgVas7gREQxYmCKJwYmIjclYWnXH8DOcUDYy+CUvrDeVFeoGYMTEZlhYIonBiYiN/f0AbDrd2DXb0DYI31bhqJ6cCrYhMGJiBQGpnhiYCLyENIhfOdvengKD9G3ZSimN9VJcPLxcfYREpETMTA56AQSkZsIvafXNklznSE4ZZTgNBwo8AaDE5GXemTj972PpmmaQ4/MTTAwEXlwcJKO4dJBPPyxvi1j8ZfBqRGDE5GXecTA5JgTSERuHJx2jNWD0/Mn+rZMJfXglL8BgxORl3jEwOSYE0hEbu7JXX3U8P/+fhWcMpfWg1O+egxORB7uEQOTY04gEXmIJ3f0CX5lvrrnofq2LGX04JS3LoMTkZd/33MIXCIikSQtUP8rYOAhoHJ/wD8xcHUvMKM1ML4ucGYdwC6fRF6Lnb4tYA0TkZd7fOtljdME4MVTfVvW8kDNYUCe2qxxIvIQrGEiIoqPpOmBBv8HDDwIVHwH8A8CrvwHTG8FTGwInN3IGiciL8ImOSKi2CTLADQcqQenCm8DfoHA5V3AtBbApEbAuc0MTkRegIGJiMgWyTICjb7Vg1P5vnpwurQTmNoMmNwYOL+F55HIgzEwERG9juSZgDe+AwYeAMr3AfwSARe3A1OaApMaAxe28XwSeSAGJiKiuEieGXjje2DAAaBcr5fBaZte2zS5CXBxB88rkQdhYCIiio8UWYDGPwAD9gNlewC+AcCFrXr/pinNgIs7eX6JPAADExGRPaTICjT5ERiwDyjTXQ9O5zcDkxoCU5sDl/7leSZyYwxMRET2lDI70PQnPTiV7gr4+gPnNgET6wPTWgKX/+P5JnJDDExERAkVnJr9AvTfC5R+Sw9OZzcAE+oB01oBV/bwvBO5EQYmIqKElCon0Gws8N4eoFRnwMcPOLseGF8HmN4auLKX55/IDTAwERE5QupcQPNxQP89QMlOenA6sxYYXxuY0Ra4uo/vA5ELY2AiInKk1LmBFr8B7+0GSnQEfHyB06uBv2sBM9sB1/bz/SByQQxMRETOkCYP0PJ3vamueHs9OJ1aBfxVE5jVAbh2gO8LkQthYCIicnZwavUn8O5/QPF2enA6uQL4qwYwqyNw/RDfHyIXwMBEROQK0uYDWv0FvPMvUKwNAB/g5HLgz2rA7E7AjSPOPkIir8bARETkStLlB94cD7z7L1D0TT04nVgG/FEFmNMFuHnU2UdI5JUYmIiIXFG6AkDricA7O4EirfTgdHwJ8HtlYO5bwM1jzj5CIq/io2ma5swDiIiIwI4dO3Dz5k0UK1YMBQoUiLX8nDlz8Pz582jb8+bNi4oVK5ptu3v3Lnbu3Ing4GBUrVoViRIlsvm4Hj16hBQpUuDhw4dInjz5a7wiIqIEIAFp8yjg2KKXG3yAIi2AGh8B6QvxlBPFka3f904NTPfv30eDBg1w48YNFClSBNu2bUPfvn0xevRoi4/p1asXnj17Zlx//PgxFi9ejC+//BL/+9//jNt//vlnjBgxAhUqVFCB6dq1a6pc1qxZbTo2BiYicknSJKeC02KT4NTyZXAq6OSDI3I/bhGY3nnnHWzYsAG7d+9GsmTJVE2T1AStXr0a9erVs2kff//9N/r164cLFy4gW7ZsatuiRYvw5ptvYtWqVcb9nDx5Ev7+/siTJ49N+2VgIiKXJp3AN38LHF/6coOP3udJgpP0gyIizwhM8rSpU6fGxx9/jKFDhxq3S7NawYIFMXnyZJv2I+XTpEmD5cuXG7dJrZKEp/nz58f5+BiYiMgtyLADUuMkHcOFDEtQtDVQ40P9yjsissv3vdM6fV++fBkPHjxA0aJFzbZLP6bDhw/btI+jR4/i33//RZ8+fYzbnj59ij179qB+/fo4c+YM/vnnH9WP6cWLF7HuKywsTJ0004WIyOVlKg60nwH03QIUaAxokcDhucC48sCCPsCdM84+QiKP4LTAJElOpEqVymy71DoZ7rNm/PjxyJQpExo3bmzW0TsyMhIrV65U/aNmzJiBjh07okSJErh48aLFfY0cOVIlTMNiaN4jInILmUoAHWYCfTYD+RvpwenQHGBcOWBhP+DuWWcfIZFbc1pgSpw4sbHTtqmQkBDjfbEJDw/H9OnT0b17d9U3ySAoKEj9f/bsWVUDtWDBAtV/Sfb5wQcfWNzf8OHDVVAzLFIDRkTkdjKXBDrOBnpvBPI31IPTwVnArxKc3gbunXP2ERK5JacFJqnBCQgIiFbrI+u5c+e2+ni54k1qk3r27Gm2PW3atEiZMqWqXTKEJxlOoFGjRti7d6/F/QUGBqq2S9OFiMhtZSkNdJwD9N4A5KsPaBHAwZnA2LLAoneBe+edfYREbsVpgUkCSp06dTB37lzjttu3b6ur5kyb2Hbt2oVly152ZjQxYcIE9fiYwlXTpk1x7Jj5oG6yniNHDru/DiIil5alDNBpHtBrPZC3rh6cDkwHfi0LLH4PuH/B2UdI5BacOqzAoUOHUKVKFTRp0gSVKlXCxIkTVa3T9u3bjYNMyrhLEpqOHHk1j5I0l+XMmROzZs1C27Zto+1XaqnkSjmpZZL9S8dw6cu0du1aVKtWzaZj41VyROSRLv8HbPoWOLteX/f1B0p2BKoNAVLxj0ryPo9c/So5Ubx4cRw4cAC5cuXCwYMH0a1bN2zevNlsRG4JUlJjZOrEiRPo0qULWrRoEeN+pSZJ9iujf//3339q/fjx4zaHJSIij5WtPNBlAdBjDZC7FhD5Atg3FRhbGlg6EHhwKfpjIiOA81uBw/P1/2WdyMs4fWoUV8UaJiLyCpd2AZtGAuc26eu+AUCpzkC1D4CU2YBjS4BVHwGPrr16TPLMQMNRQOFmTjtsIq8ZuNLVMTARkVe5uEMPTue3vApO2SoAF7dZfkyzsUDptxx2iERe2yRHREQuIkdloOtSoNtyIGc1IPJ57GFJrP6YzXPkNRiYiIjolZxVgW7LgAbfWD8rYSF6zRSRF2BgIiKi6JJmsO2snFmnByciD/dqiGwiIqLXDUzbfwJ2jAUyl9Jrp3JVA7JVBAKT8lySR2FgIiKimPs0Jc0IPL4RyzdIYiBJWuDhZeDqHn2RAOXjp480LgFKFgYo8gAMTEREFJ2vH5C9EnBsoeWzI3PVtZ0M3L8IXNwOXNgGXNiqj+V0Zbe+bPtRHxzTUAPFAEVuisMKWMBhBYjI64XcAA7NBXb8Ajy5/ep0JEkPVO4PFG8LJMsY/TRJgFLh6WWAkhooUypAmdZAVWATHjkNx2Fy0AkkIvJ4MrK3XA33+Kbet0ma66QGylavG6CyVwQSJbH7yyCKCQNTPDEwERElEFsClEwabFoDxQBFCYSByUEnkIiI4kEmm3hgEqBkrrpHV8zLMEBRAmJgctAJJCIiZwYoGcagPGugKM4YmOKJgYmIyIUClAQnQxPeo6vmZWTeu2hNeMHOOmJyMwxMDjqBRETk4AB1/4J5HygGKIoHBqZ4YmAiIvKgAJW17KsaqKzShMcaKNIxMDngBEZGRiI8PDy+T0UuLFGiRPD15ZSLRO4VoM6b94EKuWZehgGKTDAwJfAJlKB0/vx5FZrIc0lYypUrlwpOROShAcovEZDFpAZKOpEHJHbWEZODMTAl4AnUNA2XLl3C8+fPkTlzZtZAeCgJw9euXUNAQACyZ88OHx8fZx8SEdkrQBk7kW9jgPJyj2zss8ypUeJwAiUonTlzRoUlKUOeS95/CU158+ZVwYmIPDBA3Ttn3gcq5LrlGqhc1YCs5VgD5YWBiZPvxkFERIT6n800ns/wHst7zsBE5IGk5jhNHn0p09VygLq0Q1+2fKcHKAlNxk7kDFDegIEpHthE4/n4HhN5GYsB6mUTnjTlPb4BXNyuL5tHMUB5CQYmMvr++++RM2dOtGnThmeFiChagOpmY4AKjKEGKojn080xMJHR6tWrUbZsWQYmIqLXDVDnt7xqxlMBapu+bJY+UAxQnoCBiYiIyB4Bqmx3PUDdPfuqBkr+f3wzeoCSoQsMNVDSoZw1UC6PgcnLXL58GdOmTVP/FytWDD179kRgYKBZmXXr1qlFOjq3bdsW5cqVM943ZcoUbNy4Ud1OkyYNKlasGK1GytC0lzRpUqxcuRJZsmTBRx995KBXSETk5ACVNq++xBag1PpW/TEMUG6BgcmLbNmyBY0bN0bdunVRq1YtHD16VIWdJUuWGMtMnToVu3fvRosWLXD8+HFUrlwZu3btQpkyZdT9+fPnV+NQiZs3b6ogtGbNGvz9999mTXuyb7kUv127dup/IiKvFGOAOmMSoLZZCVAyjEFZwN/8D1tyPI7DFIdxGZ49e6ZG+ZYRoIOCXnXki22aFBkx2t/f36aycmWW6SXslsq+zrAGEnLy5cuH2rVr46+//jJulzGGZDwpIUHq9u3b2L9/v3Ewzjp16qBo0aL4+eefY9zvuXPnVCCSgTyzZs1q3M/FixdV4DJ9ze7I0ntNRGQXlgKUKf+gl53Iq73sRM4AZU8ch8kJRo4cafE+CSsdO3Y0ro8ePVoNgBmTHDlyoFu3bsZ1CSuhoaHRyn322Wc2H9vp06dx9uxZzJw502y7ISwZSM2T6dxpBQoUwJUrV8xGv160aJGqdbpz545al/InT540BiZD0HL3sERE5JgaqHz6UrbHqwBl2on8yS3zGigGKKfgN5qXuH//vvo/ffr0sZaLWosiYcgwUKfo0KED9u7diy5duqgQKDVhEsJCQkLMHpcyZUq7Hj8RkdcFqHI99QB157R5DVRMAUo14b2sgcpShk14CYCByY6GDx9u8b6oM94PGTLE5sESBw4cGO9jM9T+yJQu0iE7rqFr7ty52LdvH0qVKqW2SS2TpZoyIiKKJ/k+SJdfX2ILUFIjJYtggEoQDEx29Dp9ihKqrCVypVrNmjXxf//3f6ojd3BwsLGDdoMGDWzahyHIGWqrhOyPiIicGaBORQlQt6MEqMRRaqBKswYqDhiYvIgMCdCkSRMULFhQDRVw6tQpNGzY0ObAJM1s7733Hlq2bIn69eurDt/SmTzqsAREROTIAFVAX8r1iiVAbdaXGAOUNOHF/w9zT8er5Ox4lZw7kP5IO3bsUFfHFS9eHIUKFTLeJ8MDyNhKhiEExL///osnT56oq+sM9uzZozqRZ8qUCdWqVcPs2bPV/9mzZ7e4H3flzu81EZExQJl2Ig+9Y35iTANUrmpA5tKuEaBCbuiLJcky6ouDrpJjYIrDCeSXqPfge01EHhegbp80r4GKKUBlr/BqHChnBaiNI4HN31q+v8YwoJblvsO24rACREREFL0JL31BfSnf23KAOrdJX5wZoMp2Bwo0Al48BSY21Lf1WKUfj7BD7dLrYB8mIiIibxVjgDrxahoXFaDumgeogGAgm2mAKpUwAcrQ5Bb+5NW2jMWBREngDAxMREREZBKgCulLrAFqo744MkA5GQMTERER2RagIiOBOyeB8y8Hzry4PeYAlb2ieYDyezXdl7tyemBavnw5fvnlFzWRa7FixfDFF18gd+7cFsvLlVdy1VZU7du3x+effx5t+x9//IGffvoJXbt2jXVgSSIiIrLC1/dVgKrQRw9QUWugnt4Dzm7QFxGQJEofqNcMUJGvZpvAxR1AntqAr593BaYVK1agRYsWag62SpUq4ccff1SXpx85cgSpUqWK8TGzZs1S85cZHDhwQE3XUbp06WhlDx48aJzfTQIZERER2TlAZSisL3EKUNWBzCUtB6hjS4CVH75an9EaSJ4ZaDgKKNzMoW+lU4cVKF++vBoHSAZUFOHh4ciYMSOGDh1qc23Qu+++qyaDvXTpEvz8XiVOqYUqW7asmuR2xIgRapRrqWmyFYcVIMFhBYiI4kEFqOMmAWq7HqBMqQBl2oT3MkBJWJr7loyFEGWnL6cPazvVLqHJ5YcVePz4sRoAcfDgwWZTgNStWxcbN260KTDJl5lM/CqhyTQsCdkmgy02btxYBSaX4qDBuIiIiJxfA1VEXyr0tRygzq7XF0OAkk7kV/fEEJbwcpsPsGoYULCxw5rnnBaYrly5oqbVkNGiTUkNkzTJ2eKff/5RibBnz55m22fMmIH//vsPe/futfl4wsLC1GKaOBPMnkkOGYzLlSxZsgQlSpRAjhw5bH7MggULVC2kYeJgIiLy0AB13qQT+dP7wLmXzXcWacCjq3qfJhmd3BGHDidO0RHTxLIyL9mLFy9s2sf48eNRr149NW2FwZkzZzBw4EAVmhInfjm4lQ2kr5NUyRmWbNmyIUEH4+qzWR+Ay0BuyzZZ5H4P884772Dr1q2v9ZgePXpg165dCXZMRETkIgGqYj+g/Qxg6Dmg33ageAfbHv/Ycf2TnVbDJHONiTt3zIdkl3XDfbE5e/YsNm/ejLlz55ptX7VqFUJDQ1VHcIMLFy6oPk5y39GjR6M13wlpAnz//ffNapgSLDQZmtyemdRihT0GspZ3Ss9/V/Xmm28mbHAlIiLXC1AZiwKlOgGHZlkvnzSDI47KuYFJmt6kqUVqEJo1e9Vpa+fOnarWyJqJEycibdq0aN68udn2zp07q35Qplq2bKmadiQUxRSWDDVbsjiMg3v+S2g8dOiQ8Vw/f/5cNWkWKVJEDecgTp06pSaabdCggbETvrwf9+7dU2Xy5s1rts9NmzYhderUxvdRavRq1aql7rt69arqoyaBRyb5jUqCbvXq1dVxHD58WIXkChUqmJWR/mdZsmSJ1m9NjklCcdGiRWNs4pOmVZk0OCQkRO1TPievuw8iInKiHJX178RH1y30Y/LR75dyjqI50VdffaWlS5dOO3XqlFqfMGGC5ufnpx08eNBY5pNPPtGaNm1q9rgXL15oWbJk0YYOHWrT85QoUUIbOHDgax3bw4cP5R1S/0f19OlT7dixY+r/ODm6WNM+S6FpnyWPssi2FPr9drZnzx7N19dXu3//vlrftm2ben0tW7Y0lunVq5fWsWNHdVvek9y5c2t58+bV6tevryVJkkR77733zPZZp04drXLlylrOnDm1xo0ba1988YXaPmvWLC0oKEirWrWqVqFCBa1ixYpaqlSptGnTphkfK+9zgwYNtGzZsmkNGzZU9zdv3ly9twYpUqTQ5s2bZ1zfvn27lilTJq1cuXLq+eQxUT8D8royZ86s5c+fX2vUqJE6toULF77WPuz6XhMRUTy/K1Mk6HdlbN/3ppw6DtOwYcNUU5n8lS/9hqTv0uTJk81qJK5fv45z586ZPU6a1qQGo1evXnAJMjLD81DbB+BSNUux9fz/CMhd07bmORlRVUZitaJUqVLqcsktW7aoWiapHZJhF2RdOt/7+PiobR9++KGxz1GBAgVUZ21/f3/Vgb5ixYpo1KgR3njjDeN+pYO+1BBlz55drUsnfHms9AkbNGiQ2vbJJ5/E2BdJ3nt5vBzXxYsXVafwqVOnonv37jFeVSk1haNGjUK3bt3UtsuXL6vHyNWQDRs2VM2oUuPYqVMnNYSEvCZ5nNQ22boPIiJyEYWb6UMHyHdmiNQ0vaRaY751+DhMTg1M8kX8119/qbGS7t69q5p2AgLMB6/6+uuv8fTpU7Nt0sxy+vTpaE1Elsg4TcHBwUgwEpa+yWynnUnP/2vAtzb23fn4mk0TEfr6+qJq1apqyAZDYJJgI6FVmurSpUunOszLeFXyXqxbtw4bNmxQ75FhhHUJFLNnzzYLTBJQDGFJrF27VjWJyb4NJIR988030Y6pb9++xjEvpFmsXbt2qqkupsAkg5xKGEuSJAnmzZunnylNUx3+5TXJscmo8VJGnkvCkkiaNCnq1Klj8z6IiMiFFG6mVyAYvhM7zffOkb4N5EvT0mBR0tcpKumTErVfSmxy5swZr+PzFBKGpk2bpvoNSR+ev//+W/UjkrAggSlz5szIly8f9u3bp8pHnaImT5482L9/v9m2qMNCSK2R7Mf06kd5b6Wvk7X3RYKLpSvppA+WhGnpd2VKjtdwlaThuSUQxXUfRETkYnxNwpH0WXLSxVEuEZjcnjSLSU2PLWTMCOngbY2kaFs6s8lzv0ZgklHUpUlTApIEFtkmtUKyLreFIYxKZ2/TDtGyHjWoGmpyDKTz9v379822yVQ2MY1rFbWcrFsKwhK6pMlWhouw1HE/ZcqU6hgtsWUfRERELjUOk0eR0CDNYrYsUpUo7a+God2j7wxInkUvZ8v+bOi/ZNqPSfqKffnll8ZwJP/L8AxSy2TYJle2SVCSgSNNp5pZuXKlataLjcwJKMFn27Ztxm1Lly5VtVoxNZWajsu1ePFiVKlSJcb9ypWTctWeYRodA9l2+/ZtdVua3uTKN9PjFob7bdkHERFRTFjD5GhSlShDB6j5cXyidP5+GX6kM1sCVDka+jEtW7YM/fv3V9tkWAFpPpNxrQyBSWqNpNN027ZtVVDKnz+/GsYhffr0ePvtt2N9Dinbu3dvNYaS9F2SGp2xY8ciKCgoWtnt27ejS5cuasLl+fPnq/5FH3zwQYz7leZA6Ujer18/1Swo4U+a2ORxf/zxh6ohkz5tn3/+uer0PWDAALUuQVDmK/zf//5n0z6IiMjFphF7YdKP+cYhwD+xU6YRYw2TM3v+R32jpebJTpMJWiIdqqVztelYVTJgp4yqLX15DFq0aKFqiaQ5Tfo7yWPkf9PgI2MuyRVmUY0bN0511per5+TKtPXr16v9R+2zNGHCBNWBf/fu3Sq8yP+mTXJRB66UACZ9nOQY5Oo+GTdLOnpLPywDCUbSuVsuFJBxoKRTumx7nX0QEZEL2DMJ+KsGMNHkghy5LdtkkfsdyEfGFnDoM7qJ2GYvttsM9jLStwv0/HcGufpOarpc/co0u73XRETkkhPVx/Z9b4pNcq5SzRiYFLhx2CnVjERERC4nmWt9FzIwOYNUI27+1nybaZVjjWFAreHwZNLEF3VIAiIiIlfFwOQMZbsDBRpZvt+FEnVCkUv7iYiI3AUDkzO4WDUjERERxY5XyRERERFZwcAUD7zA0PPxPSYiIsHAFAeGaTVkhGjybIb3mFOpEBF5N/ZhistJ8/dHcHCwmk5DJnOVEbTJ88ignfIey3st7zkREXkvfgvEgUwdIpfEy4CGFy9etP+7Qi5DwnD27NmjTTJMRETehYEpjmT+NZlKhM1ynv8+swaRiIgYmOJBvkg5XQYREZHnY+cbIiIiIisYmIiIiIisYJOclfF3ZBZjIiIi8kyG73lr4+4xMFkQEhKi/s+WLZu93xsiIiJywe/9FClSWLzfR+NQxhbH4Ll27RqSJUsW7ZJySaMSpC5fvozkyZPb+z3zaDx3PH/8/Lkn/uzy/Hnq509ikISlzJkzx3pVNGuYLJCTljVr1lhPsrxpDExxw3MXPzx/PH/Ows8ez58nfv5iq1kyYKdvIiIiIisYmIiIiIisYGCKg8DAQHz22Wfqf+K5cyR+9nj+nIWfPZ4/b//8sdM3ERERkRWsYSIiIiKygoGJiIiIyAoGJiIiIiIrOA7Ta3ry5AlOnDiB1KlTI1euXPA2L168wK5du6JtL1iwINKmTWu2LTw8HEeOHEGSJElQoECBGPdnrzKu7tChQwgLC0O5cuVivD8iIgJHjx5Vg6QWKVIkxsHTHFnGlYSGhmL//v1q0Lrs2bOb3Xf37l0cP3482mMqVKiAgIAAs23379/H2bNnkSlTJmTJkiXG57JXGVfx/PlznDx5EsHBwciRIwf8/PxiLHfu3Dn1uuTnWH7OnF3GVchxXrhwQX32ov5+k5+jnTt3RnuM/I5Kly5dtN9h8jOXOHFi9bpjYq8yruT69eu4efOm+uylSpUqxjK3bt3CxYsXVZn06dM7vUysZKRvss3UqVO1pEmTavnz51f/161bV3v48KFXnb7bt2/LZDtayZIltSpVqhiXdevWmZVbvXq1ljZtWi1Xrlxa6tSptVKlSmlXrlxJkDKu7M8//9SKFSumpUyZUsuSJUuMZfbt26flyJFD3Z8xY0YtT5482uHDh51WxlXcuHFDGzhwoJYpUyYtKChIGzFiRLQy8+bN0/z8/Mw+i7LcvXvXrNy3336r9lGoUCH1f8eOHbXw8PAEKeMKnj17pg0bNkxLkyaNVqRIES1z5sxa3rx5tS1btpiVe/DggVarVi0tWbJk6vea/D9jxgynlXEVR44c0Ro1amT8nZMkSRLtzTff1EJCQoxl7t+/r34XlihRwuyzJ7+zTMnvxnTp0qnfYfJ+SPlLly4lSBlXsXPnTq1ChQpatmzZ1HHKz0r37t2j/awMGjRICwwM1AoXLqz+l/WoHFnGGgYmG504cULz9/fXJk6cqNbv3bun5cuXT+vdu7fmjYFp//79FsvIl1WKFCm0Tz/91PjLW36R1KtXz+5lXN3QoUO1gwcPaiNHjowxMMkvkNy5c2tdu3ZV65GRkVqbNm20ggULahEREQ4v42q/dH/88Uf1s1agQAGLgUk+I7GRLxpfX19jqD9//rwK4f/3f/9n9zKu9HMqn7lHjx6pdXl/3377bfVFGxoaaizXrVs39QUiYUb8/vvvWkBAgHbmzBmnlHEVCxcu1FasWGFcv3btmpYzZ051DqMGpt27d1vcj5RJlSqV9vHHH6v1sLAwrVq1aio42ruMK5k9e7Z26NAh4/rJkydV6Bw7dqxx2+TJk7Xg4GDtwIEDxj/mEidOrE2ZMsUpZWzBwGQj+aBmzZrVbNtPP/2k3gT5Ive2wLRkyRJt7969xl9+pv766y/1F4XpX2OLFi1SjzP8RWSvMu7CUmBas2aNej2mXxryQy3btm7d6vAyriq2wJQ8eXLt6NGjqqbs6dOn0cpILVDVqlXNtslfl1K7Zu8yrszwXsvPrZDgJD9ff/zxh7GMBKsMGTJon332mcPLuDp5r6W2OGpgWrBggbZnzx61HpX8gZ0oUSKzlohly5apx0ngtmcZV5c/f35V62lQvXp1rX379mZlWrdurdWoUcMpZWzh2p0XXIj0oShTpozZtvLly6v+FadOnYK36dWrF7p27ara6jt37qwmRjQ9V9KOnzRpUrNzJQ4cOGDXMu5OXqPMYZQnTx7jthIlSiBRokTqPkeXcUfy2WvevLlapG/hN998Y9PPrvRDkgk37VnGle3evVv1YcqZM6dal75fz549M3tN0p9N1g2fB0eWcXV79uxB3rx5o23v27cvunXrpvrEdOzYEQ8fPjTeJ68tX758ZnOfGX6Hmf5c2qOMqwkLC8O2bduwZs0aDBgwQK3LuTKw9PNk+nocWcYWDEw2unfvHtKkSWO2zbAu93kL+XKdNWuW6sh3+PBh1Rl78+bNGDx48GudK3uVcXcxvUYh22I7DwlVxt1I5819+/bh9OnTKrjMnTsXn376KaZNm2Ysw88jVMfl4cOH491331Wh0nBeREw/Y6afGUeVcWW//vqruthl2LBhxm1yUcGMGTNUR2L5XXjs2DFs375dhYPYPntRz7+9yrhih/lhw4ZhyJAhmDBhAnr27Kk6zxsuHpI/MmL6PMgfQNKh3pFlbMXAZCP54ZC/kEw9ffrUGCK8hfyF0759e+N6/vz58cEHH2DOnDnSvGvzubJXGXcX02s0vM7YzkNClXE3ctVhqVKljOtNmjRRy+zZs43bvP3zKFcq1a9fX52r77//3rjdcBVhTK/J9DU7qoyrkhD+/vvvY/z48cZaHSFX+EmNkoHUPg0dOhTz5s1DZGSkxc+MYT22z1VcyriajBkzqhomuUJY/qgZO3Ysvv76a3Wf1HRKDWNMnwfZLvc7soytGJhe4y/Zq1evmm0zrEe91NnbZMiQQQ23YKiKtuVc2auMu5PXeOfOHXW5sIHhXJqeB0eV8ZTPo+nnxtLnSOakMlxabK8yrubGjRuoXbs2cufOjYULF5p9ucrrETG9JtPPjKPKuKL58+ejS5cu+OOPP1QXBFs+e/JFbKj14e9CnXStkCbzlStXqnUZ0kRqm2L7PDiyjK0YmGxUr1497NixQ33hGCxevBiFChVy+bFY7Em+YKOSNuqsWbMiZcqUxnMlY13IXxam50ruN4xDZK8y7q5OnTpqrJxVq1YZty1ZskT95SNfdI4u4+6fR3l90kRctGhR4zb5HK1evdosKMrnSF6z4a9Le5VxJdJsLscmXwqLFi2KNmmp9GWSWhH5DJjWRv3333/qtTq6jKv5559/0KlTJ/z222/o0aOHzb8LpWbF0Pwjr02+mKWGxfQzIzX1MlaYPcu4kicxnJszZ86YNYvJa1q2bJmxZUL+X7p0qdnnwZFlbPJaXcS9mFzGKeNJVK5cWV1y+uWXX6rxX+SqLW8yatQorVOnTtrMmTPVVRp9+/ZVwy3IuikZw0QuV587d666lFSukPnll18SpIwrkyu35Aq0fv36qTFU5LYspldzyaXKMiaSjPM1adIkden3+++/b7YfR5ZxpZ85w/nKnj279tZbb6nbppcry9g4H330kbZ48WJ1xZxcZi1j5xw/ftxseAq5wrVp06bq6k4Z20nGYfnvv//sXsZVyNVUMv6SjNmzdu1a43mURYZpMJg/f776+ZWhEeRqr/Lly2ulS5fWnj9/7pQyrmLVqlVqyIOePXuanbtdu3YZy/zwww/qyisZS2r58uXqZ0ten/xsmZLPi1whNmfOHG3cuHHqcvYxY8YkSBlXUbVqVe2rr75S50W+L+UKU/lZMb0a9+zZs2p8Ovm5lp+nLl26qHXZ7owytvCRf14vYnkv6cQ2atQodbWEdLjr3bu3y/51lJCkan/BggWqtk3+apQrH0z/ohdSLT1mzBj1176MMtyhQwe0a9cuQcq4MukML1cnRSV9vgw1k9Lp8Pfff8fy5ctV9XGzZs3Qp08fsxG4HVnGVdy+fRstW7aMtr148eLqr34hV978+eef2Lhxo/qrUe6TTrdRR2W+cuUKvv32W3W1VubMmVWZqLWU9irjCs6fP6+akmLy3XffoXLlysZ1qTWT/jny+01ey0cffWSsLXZGGVcwbtw4dXFLVHKsUlNhWssjzXbyu1CuPpWfJfkMmpK+Mz/++KP6jMoI3dIHVH6PJUQZV/Ho0SP1MyqtMvJ7Rlpi3n77bWPTrIHMmjF69Gg1+rs0G0sH8agjmDuyjDUMTERERERWuN6flUREREQuhoGJiIiIyAoGJiIiIiIrGJiIiIiIrGBgIiIiIrKCgYmIiIjICgYmIiIiIisYmIjIq8nAojt37kyQfe/fvx9bt25NkH0TkWP5O/j5iIhciowU/vjxY1SqVMnu+54yZYqaQ6tatWp23zcRORYDExFRAildurSaQoWI3B8DExE5nMzndODAAbRq1cps+9mzZ3Hw4EHj9sjISPz7779qZvt8+fKhWLFiMe7v2LFjOHXqlJrb0HReQ5nzTfYnUqRIoe7Lli1bjPuQWiZpQpN5sKpXr45kyZLZ/HouXbqEw4cPqzkmJSQFBgaq7XK8uXLlMs6LKHOPRZUkSRI0bdrUuH7kyBFVK5U1a1aUKlUKfn5+Nh8HESUcBiYicrjnz5/jzTffVCHDNOB8+umnCAkJUYFJJt9t2LAhbt26pcrs2rULtWvXVhMX+/v7G0OOTEK6fft2VKhQAVevXkWJEiUwffp0df/p06exaNEidVsmfN22bRtGjBiBjz/+2Ox4JFjJ42RSTtnHvXv3sG7dumiTSsdEJuP95ptvULVqVTx58gQPHjxQE7JKwDNtkpPAZDgWAzkeCVcSmOSxMrG0BEkJXXLsMuH00qVLWUtF5Ao0IiInKFOmjDZs2DDj+uPHj7UkSZJoc+bMUeu9evXSSpYsqYWEhKj18+fPaylTptTGjRtnfEzv3r21vHnzatevXzduW7RokcXnPHDggBYYGKidPHnSuK1nz56a/Cpcs2aNWo+IiNBatWqlVa9e3eprePHihRYUFKStWLHCuO306dPaoUOH1O2BAwdqjRs3jvGxGzdu1AICArQZM2ao9XfeeUerX7++FhYWZjyOtm3bau3atbN6HESU8HiVHBE5RefOnTFz5kz5o02tS+2LND81a9ZMrUtN0oABA5A0aVK1njNnTvWY2bNnq/UXL15gxowZGDJkCDJmzGjcb/Pmzc2eR2qstmzZgnnz5qmapJQpU2Lv3r1mZUqWLIl69eqp276+vmqf8pibN2/G+hqkrNQQSTOaNB8KaRa01HRocOHCBbRp0wbvv/8+OnbsiIiICEybNg1FihTBkiVL1LFKLVWWLFmwceNGm88pESUcNskRkVNIU5oEE2mWkiYrCT/STBcUFKSaxCToSBOZqTx58qhAIe7evYvQ0FDkz5/f4nNICOvevbvqR5QjRw4Vbp49e6aa+UxJGDNl6Hd08eJFZMiQweL+fXx8VPPfoEGD8N1336m+T9Ks1rZtW4uPkaY3CXXly5dXTXmG1yKv99ChQ7h27ZpZeWmGJCLnY2AiIqeQWqE6deqooFSwYEGsXbsWq1evNnbQDggIUMHJlKynTZtW3ZZO2VLDI2HDEqmhkn5RgwcPNnteQ62WgfRvimnd8FyxadKkiVqkr9LKlSvRr18/VYP04YcfRisrz9utWzeEh4er2jU5fiG1aHK7R48eqsaJiFwPm+SIyGk6deqkmp+kOUpqcmrWrKm2S9NcxYoVsWDBAmNZafKSdelcLaRDtNyeOnWq2T6ls7ghnEhNUoECBYz3SW1WTM1s0qH8xo0bxnV5HrlKTWqlYiO1VYZQJ01x/fv3R8uWLdX+YvLVV1+pzuRytZyEQgN5LVLLJmNCRQ1z0gmdiJyPNUxE5DRyNdzbb7+Nzz77TP1vqHERo0ePRo0aNVRNk4Qn6dMj4USucjP45ZdfUKtWLTRu3Fj1fZJwIbU8Mnq3NJfJNqldunz5sqqJ+vnnn9Vl/FHJtrp166pjkLI//PADJk2aZPWSfmlek6vz5Co36bckzWlz585VwScqufrt888/V7VI+/btU4vhueXx48aNU69FQqM06Ukt1IYNG1Rw+/333+N5pokovnyk53e890JEFEejRo1S4x9JmJCmOVPSSVuCi9T+yGX6ffr0idanSELKhAkT1BhO0p9JQk+qVKnUfXIpv4QN6RskYyRJjZZ0Gpd+QY0aNVJl/vrrL1VTJEMILFu2TPUlat26NRo0aGDT8T98+BCTJ09WzyHP26JFC2MtmNR+ybFL85x0DP/666+jPT5dunQYO3asun3nzh31eo8ePaqaA6XJ0nCcRORcDExEREREVrBJjojIAqmAl+ENLJEmtNiuoiMiz8HAREQUS2CKOjq3KWnGY2Ai8g5skiMiIiKygsMKEBEREVnBwERERERkBQMTERERkRUMTERERERWMDARERERWcHARERERGQFAxMRERGRFQxMRERERFYwMBEREREhdv8PCMLJXsFwGkQAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "cos_means = [r[\"test_cosine\"][0] for r in wp]\n", "cos_stds = [r[\"test_cosine\"][1] for r in wp]\n", @@ -220,17 +517,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "a718abe6", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:34.623103Z", - "iopub.status.busy": "2026-07-30T17:10:34.622904Z", - "iopub.status.idle": "2026-07-30T17:10:34.858709Z", - "shell.execute_reply": "2026-07-30T17:10:34.857746Z" + "iopub.execute_input": "2026-08-02T09:59:03.713955Z", + "iopub.status.busy": "2026-08-02T09:59:03.713955Z", + "iopub.status.idle": "2026-08-02T09:59:03.888337Z", + "shell.execute_reply": "2026-08-02T09:59:03.888337Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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bt262aOPPmolSpSwF154wS644AJbsGCBtWjRwpXZvXt3xHO++OIL69Kli1188cUR2/v06WOTJ08O8BUCAAAAQNG1Oyo2S28Yedd/zLINOw+k+bgGlFdNKm0zbu1U4BKoxXl52Od+4oknuuB5zJgx7r5OpVatWjZgwAAbPXp0TPtISUmx0qVL27hx4+yqq65Ks8zll1/uAvJffvklood7y5YtRxVwJycnu172nTt3WmJiYrb3AwAAAABF1fe/b7XLXp6Tabl3hrbJFwnVshIH5tmQ8m3btrkAuFOnTqFtGtat+999913ML/TJJ5+0hIQE69q1a5plduzYYe+//74NHTo01WPTpk2zMmXKWPXq1a1v3762cuXKo3hFAAAAAICs2rRrf46Wy0/yLODesGGD+3nsscdGbK9SpUrosfQoUFZwrqsKDz/8sL377rtuHnha3nrrLdcLPmjQoIjtDRo0sHfeeccdS0POdXWiY8eO7md6Dhw44IL88BsAAAAAIPuqJMTnaLn8JM+TpkXTsHIF0xnRPG+V27x5s/3tb3+zXr162dy5c9OdJ6453tGBvZ53/vnnuyEAjRs3tokTJ7oh5vqZHg1zV5Dv3zT8HQAAAACQfafWqWCZTc3W4ypX0ORZwF2tWjX3U0FzON2vWrVqTPuoXLmyS7qm7OIKrKMtWrTI3dIaTh6tfPnyVrNmTfv111/TLTNixAjXA+7fVq9eHdN5AgAAAADS9sOf2y0lk8xielzlCpo8C7grVqxoJ5xwgn355Zehbeq1njVrllvqKysOHTqUZq+4gvB69eqlO787eq73mjVrrEaNGumWUXI29YiH3wAAAAAA2beJOdzB0LDuV1991aZMmeKSqN1xxx0u8FUGcd+QIUNC62Pv2bPHLrnkEpdxfO/evbZu3TobOXKkLV261GU2D7d//357++23Xeby6GBcc7F79+5t8+bNc/tcvny5XXrppS75mjKaAwAAAAByR5VCPIc7T9fhVjCtxGPDhg2zjRs3WvPmzV1CtPQSoJUtW9YlP7v11lvdUHHdP+WUU1wveYcOHSLKKjO59n3llVem2VOtYyvg134qVKjgEqZpHriStgEAAAAAckerehWtelK8bdi539IaWa7u02pJ8a5cQZOn63AXdKzDDQAAAABHb9qS9TZswkL3e3iA6o9VHtu/pXVvVj1f/KkLxDrc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2/fff28lSpSwtm3bWoMGDSIenzFjhi1evDhiW+XKle2KK67IgVcFAAAAACjq8rSHW4FzixYtbNSoUfbDDz/YJZdcYv3798/wOY888oh16tTJpk2bZnPmzLHevXtbt27dbP/+/e5xz/Ps/PPPtz59+tjXX3/tgnkF8jpGuMmTJ9vLL79sGzZsCN22bt0a6OsFAAAAABQdedrDffvtt1tCQoLriS5durQtWbLEBeAXX3yxXXjhhWk+p3379vb3v//dihcv7u7/+eefVq9ePfvkk0/c8xRwX3PNNdazZ8/Qc9577z3r27evC+gbNWoU2q5A/IknnsiFVwoAAAAAKGryrIf7yJEj9v7779ugQYNcsC3NmjWzDh062KRJk9J9XseOHUPBtpQrV86KFSsW2qbfw4Nt8Yep//bbbxHb161bZy+88IK99dZb9vvvv+fo6wMAAAAAFG151sO9evVq27Nnj51wwgkR20888USbN29ehs9duXKlGxKenJxsH3/8sevRvuCCC9Itr8Bec7lPOeWUiO3bt29387jXrl1rgwcPtvvuu89GjBiR7n4OHDjgbj4dHwAAAACAfBVw79q1y/0sX758xHbd9x9Lj4JezbnesmWLbd682fWWHz582EqVKpWq7I8//uiGoI8cOdKqV68e2j5s2DAbO3asxcXFufsTJ060yy67zDp37mxt2rRJ87ijR4+2+++/P1uvFwAAAABQtOTZkPIyZcqk2Uu8c+dOK1u2bIbPVa+45l6//vrrrjdcwfLzzz+fqtzy5ctdQrVLL73U9V6H01xxP9gWlalatarNnDkz3eOq91vn59/USw8AAAAAQL7q4a5Tp46bux09d1r3GzZsGPN+atSo4YLnhQsXRmz/5Zdf7KyzzrLzzjvPXnrppYjgOj0adp7RMHGdrz/fHAAAAACAfNnDreBWwbASlqWkpITmZs+ePdst9eWbPn2668mWQ4cO2X//+9+I/WhI+U8//RQxF1xlNDS8R48e9sorr7hEauE0BF3rdEevy71mzRo744wzAnm9AAAAAICiJc7TOlp5RL3Z7dq1c8tztWrVyt59913Xuz116tRQ1vEhQ4a49ba1ZNjBgwfd/Got7dWkSRPbsWOHy2iu3vJPP/3UEhMTbd++fW4fCs6HDx8eEWyfc8457lia763jNWjQwJo2bWqrVq2yt99+22VMHzdu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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots(figsize=(10, 4.5))\n", "configs = sorted(raw[[\"tokenizer\", \"vocab_size\"]].drop_duplicates().itertuples(index=False),\n", @@ -270,17 +578,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "70921265", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:34.860502Z", - "iopub.status.busy": "2026-07-30T17:10:34.860340Z", - "iopub.status.idle": "2026-07-30T17:10:34.985922Z", - "shell.execute_reply": "2026-07-30T17:10:34.984808Z" + "iopub.execute_input": "2026-08-02T09:59:03.888337Z", + "iopub.status.busy": "2026-08-02T09:59:03.888337Z", + "iopub.status.idle": "2026-08-02T09:59:04.069254Z", + "shell.execute_reply": "2026-08-02T09:59:04.069254Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "val_means = [r[\"best_val_loss\"][0] for r in wp]\n", "\n", @@ -318,17 +637,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "11901b9c", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:34.988071Z", - "iopub.status.busy": "2026-07-30T17:10:34.987841Z", - "iopub.status.idle": "2026-07-30T17:10:35.131573Z", - "shell.execute_reply": "2026-07-30T17:10:35.130491Z" + "iopub.execute_input": "2026-08-02T09:59:04.069254Z", + "iopub.status.busy": "2026-08-02T09:59:04.069254Z", + "iopub.status.idle": "2026-08-02T09:59:04.222734Z", + "shell.execute_reply": "2026-08-02T09:59:04.222734Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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UaNGmdW9v/76a4/HGzZsmFy4cMG5HT16NNV5AgAAAJDOXaH69Okj9erVk8OHD8u9994rOXLkMPt1HYv27dun6lg6E5QeQ6eQXbRokelSldLYjIIFC5puUZ7ooPCE09YCAAAACLDAQtWqVctsrh599NE0BRUaTCxevNgEFwlX8758+bLkzZvXuW/37t1y6NAhuf3229OadQAAAACBEljs2LFDPvroIzlw4IB89tlnzq5Qbdq0SbHVQensTtqFShe/0+5PP/zwg/OxypUrm25WOpVt3bp1pXv37nLbbbeZMRb/+c9/zFoZnTt3TmvWAQAAAARCYLF8+XITQOi4CF28zrU1QbtHDR06NMVj6LSyOtWsLnz33//+1+2xQYMGmcAie/bssnr1ajML1IwZM8xYi1dffdWsk+FYnA8AAABAJg0sXnzxRbMQns7OpAOqHXTgdqtWrbwKLDSoWLFiRYrpChcubFboBgAAABBks0L98ssvpsVCuQYWJUuWZAYmAAAAIAtKU2ChrQ26tkTCwELXmtAuTAAAAACyljQFFjpwun///nLmzBlzXwdZf/vtt2bxurSsYwEAAAAgCwYWY8aMMQOrixYtaqaE1WliddrYatWqyciRI32fSwAAAADBN3hbp5NdsGCBmXJ28+bNJrioWbOm1KhRw/c5BAAAABC861gonSpWNwAAAABZW5q6QimdKlanli1btqzZWrduLStXrvRt7gAAAAAEb2ChC9a1bNnSLFg3YMAAs+XPn98smKeraAMAAADIWtLUFWr06NHy4YcfSteuXd32t2jRwiyO16tXL1/lDwAAAECwtlhcvHhRHnjggUT7dV90dLQv8gUAAAAg2AOLWrVqydKlSxPt1321a9f2Rb4AAAAABGNXqLlz5zpvN27cWHr06CHLly+XOnXqiGVZZtrZjz/+WF544YX0yisAAACAzB5Y9OvXz+1+njx55PPPPzeb677JkyfLqFGjfJtLAAAAAMERWJw9ezZ9cwIAAAAg661j4Y2IiIj0PDwAAACArBBYXL58OT0PDwAAACArBBYAAAAAsgYCCwAAAAC2EVgAAAAAsI3AAgAAAIBtBBYAAAAAAjuwmD9/fnoeHgAAAEBmWyAvoWvXrsncuXNl9+7dYlmWVK5cWR5++GHJmTOnM02HDh18lU8AAAAAwdZisWfPHrn11lulf//+smrV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hw6VzZs3m0Dhs88+k8uXLydKo2M3ihcvLm+99ZZzHzNPAQAAAEEQWBQqVEiWLVsm27dvl127dpkF8nS62erVq6fqOK+88orkypVLjh07Js8884zHdPny5TMtFQAAAACCcIE8DSRSG0y40qDCGzrrVN26dSUyMlIaN24sgwcPNi0lAAAAADLxGAulYyN0rIXOAqVb69atZeXKlb7N3f+3VvTr108mTJggTz31lFmUT4OLGzdueHxOTEyMREdHu20AAAAAAqzFYsqUKWa9ik6dOjnXrdCB182bN5dJkyZJr169fJbBMWPGSFjY39nUlovy5cvLvHnzpFu3bkk+Z+zYsTJq1Cif5QEAAABAOgQWo0ePlg8//FC6du3qtr9FixZmQLYvAwvXoEKVLl3abK4zUiU0bNgwGThwoPO+tlhERUX5LE8AAAAAfNAV6uLFi/LAAw8k2q/70rvbkXaBOn36tOki5YmupaGPu24AAAAAAiywqFWrlixdujTRft1Xu3Zt8ZXr16/LiBEjTCDjGDvRv39/s79jx44+ex0AAAAAfugKpYOndYG85cuXS506dcw6FroexccffywvvPCCGWDt8PDDD3s8zoIFC+Sll16S2NhYc//xxx+XPHnySJ8+fcyWPXt2iYiIkHLlypn92lKh4ys0gKlQoUJasg4AAAAgUAKLyZMnm4r+559/bjYH3aePuUousGjSpIlbEOJQpEgR87+ujzFkyBATrBw5ckQKFChAtyYAAAAgWAKLs2fP+uTF8+fPb7aUaIChA7YBAAAABNk6FgAAAABgO7DYsWOHPP/889K+fXvnvjlz5siVK1fSekgAAAAAWSmw0EHb9erVk/3797uNsdi9e7e8/fbbvswfAAAAgGANLF588UV5//333YIK1aVLF5k2bZqv8gYAAAAgmAOLX375Rdq0aeMcWO1QsmRJOXr0qO9yBwAAACB4Awtdyfr3339PFFhs2rRJihcv7rvcAQAAAAjewKJz585mBewzZ86Y+3FxcfLtt99Kz549TXcoAAAAAFlLmgKLMWPGmFWxixYtKvHx8WZ17HvvvVeqVasmI0eO9H0uAQAAAATfAnm5c+eWBQsWmClnN2/ebIKLmjVrSo0aNXyfQwAAAADBGVg4VK1a1WwAAAAAsjZW3gYAAABgG4EFAAAAANsILAAAAADYRmABAAAAwDYCCwAA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5v6pU6esPHnymEDBQSuBTzzxhFuZaxpHYHHlyhXr5ptvtkaOHOl8fPz48ZZeB0ousND8vf322877R44csUJCQqyNGzc69+lraMBy4cIFr95TSuWSlNGjR5vKvystF63Unjlzxtw/ceKEeY9vvfVWiufeN998Y4KhS5cuOfd9+eWXVlxcXKLAIqFBgwZZhQsXtg4dOmRdv37dVNy1LB1Onz5tKutz5syxvJGa80DLIDo62uOxvClbb84nb8vfU37+97//mfwDgC8weBtAlqfdjI4ePSqvvfaas5uJdhe6//77ze1169aZx4cNG+Ysqx49ekiRIkVMNxNXOhA7d+7c5rY+rt12fv31V6/LeO3atabry6BBg5z7+vTp4zymJ9odpkCBAs77UVFRcuedd8r//vc/5z69rWMStCuSN+8ppXJx0JmLli5dKvPmzTMDx3fu3GnGfLh6/PHHTVctdfPNN5vX0hmsUpIrVy7T5ci1DNu0aSOhocn/+Zo1a5a8/fbbZuYj7Sr13XffyeHDh837033z5883+7QrlP7vjdScB/p+PXUJS03ZenM+eVv+SeVHzxktX+3eBQB2McYCQJanFTOtbCfVv11phTR//vxSsGBB5z7tr162bFnzmCvXNErHW1y7ds3rMtbK5k033eRWCcyRI4cZa5Ec7X+fcOrQrl27yvDhw+Wtt94yFU0d2K2VT2/fU0rl4piV6cMPPzTjAzRwuHr1qtl/5swZ59gHVaZMGbfn3XLLLfLxxx+nWB733HOP9O/f3/yv+WjatKk89dRTZtCxJzqORWdU0sBCgyt16NAhU45fffWVW9oSJUpIxYoVxRupOQ8SjplJyJuy9eZ88rb8PeVHzxkN0lIKXAHAGwQWALI8rSxeunTJXLnViltCWmHTK7q6TkRY2N8/m+fOnXNehfcVrUhGR0dLfHy821V5HdybHK0cHzx40G1fx44dTcVTB/ieOHFC8uTJIy1atPD6PaVULjoQWKe41UHTjkHQOjBaB6lrV1tXCfOv970tu7Fjx5oZr3Rgtg5S1wHp27Ztk9tuuy1RWh303rZtW3OFvnfv3s79WonXgdvTp083QVhapOY8SGlgekpl643UlL+n/Og5U758ebcB4QCQVnSFApDlNWnSxFQUXbsNOa76Kr0arI8vWLDA+diePXtk165d0qhRI5+Wn76WVgqXLFni1gXnjz/+SPZ5eiVf0yWsvLZs2dK8L906derkXOPCm/eUUrloJV67KrleGdduRknRNTsc9P1p16GGDRumWB76GnFxcSbfOiOStkJoa05Ssz9p4NCuXTtTUZ44caLbY3fddZdpsXjvvffc9uuxteuZg86+lLBVw8GX50FKZeuN1JS/J3rO6PTHAOALtFgAyPK0z/8bb7whTz/9tOzYscNMQ6rTiepVaN2v3UhefPFFcxVcK5JasR03bpy5Mn733Xf7tPy0a452/enevbsMGTLEVD61Mq1X2ZO7Cv7Pf/7TXNnXLjY6nahDt27dzLG0+4xe9Xfw5j2lVC46ta3mSwOW1q1bm+lxdexCUrTyret16PSw2iVr3759XlWCteKr+dbn6vvS8RBaDto1KiEdr6ALDY4fP95tnRDHdLMTJkwwLTj6fnWaWJ2+VtONGTPG5F/NnDnTBBYPPvhgouP78jxIqWy9kZryT4pOuatjM9JzET4AWQstFgAgYirzjkG8uq6AVhT/85//OMvm5ZdfNleXdQyEXtUeOXKkc7yCg14td716rPRqcJUqVZz3df2GhGtLJFwgT19XK6y7d+82g7K1oqsVyOQGA+vrahAxadIkt/2tWrWShx56yAQe+tquvHlPyZWLDvzVrjfaQvD999+bir+un9G5c2fT7cq1XD7//HMTVGhLg3bb0gDANQDypH379jJnzhyz3oOuwaGvpXl1lJfrAnk6YF3T6wB4bSFxbFpxV9o1St+DdjfTfCqtiDuCCqXvR9+zJ2k9D9JyzqV0PqWm/JPKz7Rp00yA5mmNDQBIrRCdGirVzwIApBvts+86aFcrsFr50wqya5CSkHbp0RmL3n33XWeXJ3hPg5e+ffuacQtZofz69esnAwYM8LjoIgCkFoEFAASYqVOnmulI9eq0tlhoVyi9sqwDl4ONdkfSFoakaOVeWyAAAJkDgQUABCAd3Pztt9+a2Xp0kLP2ow9GOi5Ax0QkRdd1mDFjRobnCQCQNgQWAAAAAGxj8DYAAAAA2wgsAAAAANhGYAEAAADANgILAAAAALYRWAAAAACwjcACAAAAgG0EFgAAAABsI7AAAAAAYBuBBQAAAACx6/8APU4dimTIqEkAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "inferred_total_epochs = int(raw[\"epochs_to_best_val\"].max())\n", "\n", @@ -357,23 +687,127 @@ "source": [ "*Notes: the dashed line marks the last epoch of the run (`--epochs` used). A bar\n", "reaching that line means best `val_loss` landed on the final epoch for at least some\n", - "seeds \u2014 i.e. training may not have plateaued yet for that config. See the per-seed\n", + "seeds — i.e. training may not have plateaued yet for that config. See the per-seed\n", "breakdown below for exactly how many of the 3 seeds hit that ceiling per config.*" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "305a88cc", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:35.133631Z", - "iopub.status.busy": "2026-07-30T17:10:35.133381Z", - "iopub.status.idle": "2026-07-30T17:10:35.153688Z", - "shell.execute_reply": "2026-07-30T17:10:35.152834Z" + "iopub.execute_input": "2026-08-02T09:59:04.222734Z", + "iopub.status.busy": "2026-08-02T09:59:04.222734Z", + "iopub.status.idle": "2026-08-02T09:59:04.242945Z", + "shell.execute_reply": "2026-08-02T09:59:04.242945Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizeseeds_hitting_ceilingn_seedsfraction_hitting_ceiling
3wordpiece10000331.000000
2wordpiece5000230.666667
4wordpiece20000230.666667
5wordpiece30000130.333333
1wordpiece1000030.000000
0char25030.000000
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size seeds_hitting_ceiling n_seeds \\\n", + "3 wordpiece 10000 3 3 \n", + "2 wordpiece 5000 2 3 \n", + "4 wordpiece 20000 2 3 \n", + "5 wordpiece 30000 1 3 \n", + "1 wordpiece 1000 0 3 \n", + "0 char 25 0 3 \n", + "\n", + " fraction_hitting_ceiling \n", + "3 1.000000 \n", + "2 0.666667 \n", + "4 0.666667 \n", + "5 0.333333 \n", + "1 0.000000 \n", + "0 0.000000 " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "def summarize_convergence(group):\n", " hit_ceiling = int((group[\"epochs_to_best_val\"] == inferred_total_epochs).sum())\n", @@ -398,17 +832,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "95004f13", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:35.155306Z", - "iopub.status.busy": "2026-07-30T17:10:35.155133Z", - "iopub.status.idle": "2026-07-30T17:10:35.324377Z", - "shell.execute_reply": "2026-07-30T17:10:35.323274Z" + "iopub.execute_input": "2026-08-02T09:59:04.242945Z", + "iopub.status.busy": "2026-08-02T09:59:04.242945Z", + "iopub.status.idle": "2026-08-02T09:59:04.438527Z", + "shell.execute_reply": "2026-08-02T09:59:04.438527Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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BSvebsMbGnRrCsQzzzwjw4cPN19cDhw4kOA6GkTWqVPHtLx+8803cuXKFY/0geRsPyXPO6F9J7QfX+nrUis8xD4+ba2253t7fElZBgg0BLAATCBy1113mdJIGsReuHBBPvvsszhbktKatrC988475tarfmj36tVLrl27Jm+88YZHfudvv/0mkyZNMgGuBjhdunSRli1ber2flNiGt55//nm58847TTD2/fffm9vOes3Xr19vykHNmjXLLKe5nnq7XvMg9Zx92UZCNI932rRp5pa0BnEaeM2ZM8eUBrO/1CREA9YtW7aYHE3N19TXUEpsPyXO25t9J7QfX73wwgvmVn+PHj1k8+bNEhkZaYLXl19+Wdq1a2ce3h5fcn8/QEZGAAvA0FY0vXVer1490/FIOy5pDUp/e/bZZ82tVw2QtGOMBivaAqu3+92X0YBWA/CCBQuaPMERI0bcFlAltp/kbsNbOXPmlLVr15o8Ut2H5qdqJyStbarXv3Pnzma5vHnzyoQJE2TZsmXmdrJ7nVJvt5GQd999V1avXm3yfjUlQ4Mr/d3rtNit0XHRfWvKwLFjx+JsffV1+ylx3t7sO6H9+EpzXTds2GBer9qBUlMGhg4dKk8//bTMnz/flWLizfEl9/cDZGRBWorA3wcBALFprp+2QP3888/SvHlzLhAAwIUWWAAAADgKASwAAAAchQAWQJqyBwiI76G9rQF/4jUKpH/kwAIAAMBRaIEFAACAoxDAAgAAwFH+N1YifKK1KU+cOGHGOk/p4TMBAACcxrIsM7x0sWLFJFOm1GsnJYBNBg1edUQUAAAA/B8d4KREiRKSWghgk0FbXu1fko7iAgAAEMgiIyNN454dI6UWAthksNMGNHglgAUAAPif1E6tpBMXAAAARPv2HDp0SK5evXrb1bh165bs379fLl++nCbzCGABAACQoHnz5kmpUqWkdevWUqRIERk9erRr3u7du6VcuXLStGlTKVq0qMyYMSPeebNmzfJpPfd53qAFFgAAIMCdPn1adu7cKQcOHJANGzbIq6++KteuXTPzhg8fLg899JDpvL5ixQoZPHiwXLlyJc55+tyWlPXc53mDkbiSmagcFhYmERER5MACAABH+/vvv+Xs2bOybNkymTNnjmzatMmUxQoNDTWpBcWLFzfL1a1bV95++21p06bNbfNq164t27dvlwsX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LAAAAByFABYAAACOQgALAAAARyGABQAAgKMQwAIAAMBRCGABAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjhLs7wM4efKkzJgxQ06fPi01atSQ3r17S5YsWeJd3rIsWbZsmfz6668SHBwsjRs3lhYtWngsM2vWLFmzZo3HtGLFisnLL7+crH0DAAAgwFtg9+7dawLHn3/+WXLlyiVvv/22tG3bVm7duhXn8jExMVK7dm0ZN26cZM6cWa5cuSJdu3aVJ554wmM53d66deukSpUqrkfZsmWTtW8AAACkD0GWNmn6SZcuXeTChQsmiAwKCpLjx49L+fLlZdKkSdKvX7/bltdD3bVrlwk8bT/99JO0adNGtm/fLjVr1jTTBg4cKOfOnZO5c+em2L7jEhkZKWFhYRIRESG5c+f26RoAAABkFJFpFBv5rQX2xo0bsnjxYnPbXgNIVaJECWnevLksWLAgznV0OffgVVWrVs38f+rUKY/p+/fvl2HDhpmW1dWrVyd73wAAAEgf/BbAHj16VKKjo2+7tV+uXDnZt2+f19uZOnWqZM+eXerWreuapkFp4cKFJU+ePHLixAlp3769DBo0KNn71nX0m4X7AwAAAAHSievatWvmf80/dafNzVevXvVqG5o+8MYbb8jHH38s+fPnd03XzlolS5Z0PX/wwQdN66rmy2q6ga/7Hj16tLz55pteniEAAAAyVAtszpw5zf8XL170mK55qd7kTGiVgc6dO8trr71mcl7duQevqlmzZmba2rVrk7XvESNGmJwO+3Hs2LFEjxMAAAAZJIAtVaqUCSR3797tMV2fV61aNcF1tcJAhw4d5IUXXpB//etfXu3v+vXrcvPmzWTtOyQkxAS47g8AAAAESACbKVMm6d69u3zxxReuW/paSUDru/bo0cO13FdffSWjRo1yPdf5mtP6/PPPx3k7X4PUFStWeEybPn26qfXarl27JO0bAAAA6Y9fy2idOXPG5KaqWrVqyZIlS0x5qylTpriWGTBggGzYsMGUz7p8+bIUL15cQkNDTQDqrk+fPtKgQQNTx7VTp06mjJZWKNAOW+vXrzcttS+99FKS9p0YymgBAACkfWzk1wDW7tm/dOlS12hY99xzj8d8rdOqJbJ69eolUVFRMnny5Di307JlS4/b/zt37pRt27ZJ3rx5pV69elK0aNEk7zsx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Xzv63hrfYCj6fqAdYG26rFZ50aomes7x0Tx7bYXVDk3p4X1WR67T31Ns+t5hv3/o35emRNx5553m2uj7S1x0FC3337WWD9M7NbE/o91pC6wOKKTXUisZpIf32IQQwAIAAMBRyIEFAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAABzF/wXyAAAAkCZ+/fVXMzqgDs89e/bsJNeQ1jrlDz/8cJzzBg0aJPfff7+kBerAAgBSlA7CoAXimzdvzpUF0pFevXqZIbtr164tEyZMMIMn6IAPSaGDG61atcpjmg5n/MEHH5hBSnSQhbRAAAsASFEvvfSSGSHop59+4soC6cipU6fM6GRLliyRe++9N94Adt68eTJ//nwTrOqIeIMHD453lETVsWNHM3rkxo0bJa2QQgAgQ9q2bZsZcrFevXpmCEoddlV/tofutIe+1eES69ev75qmQ3rqrbXWrVt7bEeHYNTt6Jt048aNzXCLOkTnunXrzHINGzaUHDlyJOnYdEhd/VmHU23SpIkZTtmmQzrqcMVKhwWtXr26GTI2vu3obUH9uXPnzkla19fz0mF9dQjYYsWKmdYce2hgnabz9DbjN998Y6bpdu2hMONbL6HzUToUq7bu6DXS+bGHmAWQuISG1rW98MILsnDhQvN/vnz5ZObMmXL33XfL1q1b4/y707/NpUuXysSJEyUtEcACyJCmTZtmbmtpgKrBkgaJOs64TtMASI0fP16Cg4M9AlhteVi0aJErgNXtaGuFjhOuY6brmOI6jvvYsWPlzTffNNMOHTokt27dks2bN0uePHm8OrZly5aZscxLlixpWkE0aNb92GOV6za1BURFRETImjVrTCvI22+/fdt2LMsyAaKOI68Bn7fr+nJeOs583759TYCrx6rL6DXWD7wyZcqY4FkfmkJgH4Mel7byJLReQufz0UcfySuvvCKNGjWS6OhoOXPmjMyaNcsE5gBSzq5du+TDDz80f5/63qS6du0qVapUMYHsY489dts6X3zxhWTLlk169uwpacoCgAxo8ODBVnBwsLV582bXtC5dulhdu3Z1Pe/Tp4/18MMPe6w3cuRIq379+rdtZ+vWreb5zZs3rWrVqlkhISHWrl27zLTr169bZcuWtd5//32vj03ffr/77jvzPCYmxurbt6911113xbvOnj17rGzZslnbtm3z2E5QUJC1evXqBPcX37q+nNewYcOsxo0bW1evXnUd+6OPPmp17NjRtczw4cOtVq1aeRyDN+vFdz558+a1Zs+e7Xp++PBh67fffkvwnAHEb/HixeY96OzZsx7Tx44da4WGhpq/yw4dOpjHvffeaxUsWNB67rnnbtuO/h2XL1/eevzxx620RgssgAxLUwbsFk3VrFkzmTRpUpK3o7fP9Ha3ypw5s9lu4cKFpVq1amaa3gbXVt29e/d6vc0KFSq4bo9rS+SwYcNM5wdtJS5fvryZfuXKFXPbTvPWtCW0UKFCpjVUc9Js+rOmH8Tmzbq+nNfnn38u3bp1kx9++MG0lOpDb0tqb2b9Wc8lLt6uF9f56G3LP/74w7QE6XFqOkTslAgAyad3bDSN6Omnn75tXqlSpW6b9ssvv5j3rK+//lrSGgEsgAxL87fchYSEmFvgSaVv6LG3E9e0pGzbvm1u09vl6siRIyaA1Zyy3r17m9t4uqwGcZoTqrfP3RUtWvS2bXu7blLPS3NjNd1B84Q1RcDdP/7xD5OOoMvHlpT14jqf6dOnmw9UTSVo2rSpdO/e3ZxffMEyAN/o+5C+T2haVez3grhMmTJFatasab78pjUCWAABK1OmTBITE+MxzZcA1xeakxvXc7tH8HPPPSdDhgyR1157zaPVVlsr3cUVxHm7blJpIJw1a1YTPD7xxBOpsl5c56P5yHv27DF5eZq3q+enHcH+/e9/+3QeAOKmd4WGDh0qzzzzjAlO7S+W+qVY786438HRjrHffvut/Oc//xF/YCQuAAGrePHisn///ttuiaUF7fmv9RjdO48VLFjQdJ5Seuu/cuXKHj30Dx486NW2k7NuYgF/mzZtTBqGpiXE7ols03I77l8EvF0vLjdu3HC1HGvrkBZK11qWWkECQNLoAAbt27eXV1991Tzv0aOHeb527VrzXAc1+PHHH026kaYMaDqPdqjUjl36/uROO3XpF84+ffqIP9ACCyBgaYugth7o7WltWdDqA5rvWa5cuVTft35Q6AeH7ltLTo0ZM0bGjRvnKlOjLSFaTzU8PFwuXbpkqgMkVIfRXXLWTYweo+YSa2ksvX7agq1FzXX7eqtfad7xqFGjzC1/zb3VZb1ZL74AVkt5ac1K/R1pKoJWK9DrBSBp7IA0tooVK7p+1rx3veOhFQk05UfnaSWX2PRv+eeff/aq8kpqIIAFkCHVqVPntjddvY2uOZe2GjVqmHqjM2bMMDVGdXhEfWjnp4S2o/leGhi6a9CggWlp9JYGZcOHD5cFCxaY9IE5c+ZIp06dXPO1puKnn34qmzZtMrVPtYVWW0bsDlbxHVty1vXmvPQa6gebls7R66QfXo888ojcd999rmU0MNeWHg1Q9fpqy6nm1CW2XlzHlD17dtNareutX7/eBP7fffedtGjRwutrDeB/9M6M+92Z+GjLqr4/JkRzX/2JkbgAII1pfqqmLmiLLwAg6WiBBYAUpq2psXM9bXGVvAIAJA0BLACkMB1dSktDxUVvwcd36x8A4B1SCAAAAOAolNECAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAAByFABYAAACOQgALAAAARyGABQAAgDjJ/wO3b+HkqvSIYgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots(figsize=(7, 5))\n", "for row in summary:\n", @@ -445,14 +890,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "46065c2c", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:35.326171Z", - "iopub.status.busy": "2026-07-30T17:10:35.326006Z", - "iopub.status.idle": "2026-07-30T17:10:35.337145Z", - "shell.execute_reply": "2026-07-30T17:10:35.336246Z" + "iopub.execute_input": "2026-08-02T09:59:04.438527Z", + "iopub.status.busy": "2026-08-02T09:59:04.438527Z", + "iopub.status.idle": "2026-08-02T09:59:04.446964Z", + "shell.execute_reply": "2026-08-02T09:59:04.446964Z" } }, "outputs": [], @@ -470,17 +915,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "dfe53dfa", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:35.338767Z", - "iopub.status.busy": "2026-07-30T17:10:35.338616Z", - "iopub.status.idle": "2026-07-30T17:10:35.481143Z", - "shell.execute_reply": "2026-07-30T17:10:35.480036Z" + "iopub.execute_input": "2026-08-02T09:59:04.446964Z", + "iopub.status.busy": "2026-08-02T09:59:04.446964Z", + "iopub.status.idle": "2026-08-02T09:59:04.586200Z", + "shell.execute_reply": "2026-08-02T09:59:04.586200Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAARMpJREFUeJzt3QmcTfX/+PH3MPYx9n0bo83OV2WLyL5LSpGWr8IX8Y18Q6JNqKiob31DqUh9LVEUQskSEkJRJIzs24xtxjLn/3h/vv97f/fO3Jk5d86dMXPv6/l4XOae87nnfs7nnHvveZ/PFmZZliUAAAAA4EAOJy8GAAAAAAILAAAAAAFBjQUAAAAAxwgsAAAAADhGYAEAAADAMQILAAAAAI4RWAAAAABwjMACAAAAgGMEFgAAAAAcI7AAgkSDBg2kZcuWIfv+2cUtt9wiXbt2lWA2ffp0ufHGGyVnzpxSvHhxs6xOnTrStm3bDHk/Pe/69Okj15Ov8z9UPhPpLf9GjRrJoEGDJKuaOXOmhIWFyd69ewO63RUrVpjt6v8Zuc0PP/xQSpQoIWfPng3Y+wBpIbAAMklGXlhllmDYB2SsrVu3St++fWXkyJGSkJAgJ0+ezND3++KLL+T777+XZ599VjIa539gy//FF1+U//znP/Lrr78G5PjA24MPPijFihUz5QxklvBMeycAGWrDhg0h/f7IGlauXCmWZckDDzwg4eH/9xOzbdu2DHm/l19+WTp16iRRUVGS1YTCZ8JJ+bdo0UJuuOEGefXVV+WDDz7IkPyFMq0x7N+/v4waNUpGjx4tRYoUud5ZQgigxgIAEDDHjx83/+fLly/DS1WDlY0bN0rv3r0z/L2QMeXfq1cv+eyzz+TMmTMUcQbQAF9rDj/66CPKF5mCwALIBIULF5aff/5Zli1bZtrB6sPzDp+r3f3OnTtNe+UCBQqYO01Kl7teo3egSpYsKd27d5fffvstzfbcru1qWl2XP39+KVeunKka17vKgdyH1N5/x44d0rRpU7Nf1atXl2+++cZ9YdKsWTOTL93WJ5984vO9v/zyS7nzzjulYMGC5oK1cePGsnz5cvHXt99+K3fddZdp91+oUCFp2LChzJkzJ1lZ2H2/xYsXm+1p2eijVatWsm7dOlt50bJs0qSJ2feKFSvKCy+8IImJie71d999t5QqVUouX76c7LU9evSQokWLmguG1NjJ3zvvvCO1atWSvHnzmjuanTt3NnlLz3mk54TefXb9nfSRtBndtWvX5Pnnnzf7r+V8xx13mKZUen7rney06HHS7eo55IudfYuIiPDZzl/3V/fb7vnvS0p9LOycX6l9J/iSWnq7++jvd0Zq5W/3s6ZpLl26ZLu/QVplN2bMGMmRI4csWbLE63XDhw8335+e7/PXX39Jv379zPmn50i1atXklVdeSfVz9dRTT3nVxLksXbrUlMV3333ntXz9+vUmj5rXChUqyGuvvZbitjU/jz/+uCnv3Llzm/NLaxuS5sefbep3iH7napM1IFNYADJF7dq1rTZt2vhcd/PNN1t33HGH1bZtW2vLli3W0aNHrf/+97/J0iUkJFjbtm2zWrRoYUVFRVlxcXHudfXr1zfLk263SZMm1t13321eFxsba02aNEl/2a05c+YEdB9Sen/dL33/X375xTp16pTVr18/K1++fNb69eut9u3bWzt27LBOnz5tDRgwwMqRI4f1+++/e21j6tSpVlhYmPXss89aMTEx1okTJ6wXX3zRypkzp7V48WLbed+7d6+VN29ea8iQIdaRI0esCxcuWJs2bbJ69uxp/fHHH36/3+uvv27SDR061Gxby3blypVW9+7dU82Hlknjxo3NsdZjcubMGWv69OlWnjx5rMGDB7vTffPNN+Y4zZ492+v1mvdcuXJZgwYNSvV97ORv+PDhZr8mT55snTx50tq9e7fVqlUrK3/+/NbWrVvTdR4NGzbMLLdz7gwcONDs94wZM0w5bN++3erQoYN5rypVqlhpad26tXXjjTf6XGd33woUKGDykVSXLl3Mfqe1D6md/76W2T2/7H4n2Envzz76c6xTKn+7nzUVHx9v9j2t89lu2V27ds1q2bKlVaRIEevPP/80yz7//HOTf03rsn//fqtUqVLmmK5evdp8l+7atcsaMWKE9fXXX5s0H3zwgXndnj17vM5vfb+k9DWa9ttvv3Uv0+Og5dC5c2dTJsePH7eee+45q2vXriatfsZdDh48aJUpU8a6/fbbrY0bN1rnzp0z26pYsaI5TunZpkufPn3Md+6VK1fSLGPAKQILIIsEFvpjlfRHNyX6o6g/IvPmzUvzwj537tzmR9hTzZo1rebNmwd0H1J6f71w/Ouvv9zLzp49ay6M9Ydff0xd9Idd044cOdK9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qVKl5PHHH5dbbrklQ9LAngEDBsjx48e9lnXu3Fkeeughr2Vff/21LFiwQK5evSpt2rSR+++/P9m2ApUGyWnXxJUrV8rs2bMlX7588u9//9tnMc2dO1e++uoryZkzp3Tp0kU6dep0XdOEuitXrshnn30m69atM8PQN2rUSB544AFTZp727Nkj7733nhw5ckSqVasmgwYNSjYXU2amgchff/0lH374oezevVtKlixprjcaNGiQ7PhqWerNTp1zQb83b7/99uuWJlRRYwEEma1bt8qNN94oP/zwgxkFbdu2bcnSJCQkSJMmTWT+/PnStGlTU+NUr14989pAp4F9emFYokQJc4HvetStW9crzZtvvin33HOPVKpUSWrWrGkuRJ588skMSQPf6tSpIy+//LIJAvWY+TJy5Ejp16+fVK9eXaKjo82xnDhx4nVLAzGjQerNFj1+evPjmWeeMQFYYmKiu3h27txpvsP0Ql+/07744gsTgFy8ePG6pMH/WkW0bdvW/N60atVKcuTIYcpLL+w9aUCt32sNGzaUXLlySePGjZN9PjMzTcjSUaEAO/78809r69atVkJCgtfyQoUKWXPnzjXLd+zYYR04cCDZa7dt22atWbPGWrt2rbVv3z7r2rVrydL88MMP1smTJ63z589bP/74o3k/+O/UqVPW2bNnzd/16tWzhgwZkizNv//9b6tAgQLW6dOn3ctat25ttWnTJuBpYF+lSpWsadOmpbg+Li7OlPeUKVPcyxYsWGDlyJHD2rt3b0DTIGX6HaZefPFFc8ySOnjwoJUzZ07rv//9r9dnJW/evO7PSmamwf/ExMR4FcWWLVt0VEzz2+TSuXNn66677nI/1+/SggULWq+//vp1SYP//aZduXLFqyj69+9v1a1b1/38q6++Msfyt99+cy/r27evdfPNN1+XNKGMwAJp2rNnj3XrrbdakZGRVq1atayyZctaX3/9tVdg0atXL6t8+fJWnTp1rPz581sPPPCA1zb69OljNW7c2GrUqJFVpkwZq2rVqtbOnTu90uh29HWlS5e2brvtNuutt97i6DiUUmDRsWNH86Pmafr06VZ4eLgVHx8f0DSwTy9SW7RoYT5PI0aMsDZt2uS1fvHixeYH7fDhw+5lGtDrZ+7tt98OaBqkLaXAQj8DuXPnti5duuRepjdNtMznz5+f6Wng2/Hjx005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8WIJJZ06dZIqVapc72xkSyNGjJA6derIk08+KSVKlLje2QGQxRFYAIAftAnRpk2b5MyZM3LbbbdJqVKlvNafO3fO3EFOSEiQ+vXrJ1uvTVfq1asnefLkkW3btklERIQ0aNBAcubM6b5DrDUWefPmNc2gXNq2bStlypRJ1lxq48aNUrZsWaldu7a5K68X0DfeeKPPvH/yySdSvHhxadiwoXn+/fffm/e5/fbbvdKtXr3aLNf829mntMplxYoVcvLkSQkLCzP7ULduXSlYsKDPPB4+fFh+/vlniYyMlEaNGpnX2LVlyxY5dOiQ2f+qVau6l7du3VoqVapk/t6zZ4/89NNPyV6rNUSaL3X58mXZsGGDxMbGSrVq1dIVlNg9D3T/NN8VK1Z0v7+/55w6duyYz/PJbvmnlB8tl1q1asmMGTNMkAEAqbIAALZs2bLFioqKsqKjo6327dubvz/++GP3+hUrVliFCxe26tWrZ915551Wvnz5rHfeecdrG8WKFbPatGljttGxY0erTJkyVpMmTayrV6+a9UOGDLEqVqxo1vfo0cP9CA8Ptz7//HP3dhYsWGDlzZvXatCggXl93bp1rbJly1pTp05NMf9dunSx+vfv734+YcIEq0qVKl5pEhISrCJFilgzZsywvU9plcvo0aPNPtx3333WrbfeapUsWdJas2ZNsnJp1aqVVa5cOatdu3ZW8eLFrRYtWljx8fFpHhdN07x5c6tChQpmH2vUqGHdfffdVmJiollfqVIla9q0aebvZcuWeZVr9+7drZw5c1pDhw4167du3WrSa3nq8dF89OvXz/KH3fOgdevW5r26du1qffjhhz63lVbZpnU++VP+KeVnxIgRVuPGjf0qAwChicACAGzQi1e9cH3kkUfcF22XLl2yli5d6v5b1z/11FPu18ycOdPKkyePtW/fPq8LuNtvv926cOGCeX7s2DGrQIECJlBw0YvAPn36eL2/pnEFFhcvXrRKly5tjR071r3+9ddft/ReUWqBheZvypQp7ucHDx60wsLCrA0bNriX6XtowBIbG2trn9IqF1/GjRtnLv49abnoRe2JEyfM8yNHjph9nDx5spWWxYsXm2Do/Pnz7mULFy60rl27liywSGrYsGFWiRIlrP3791uXL182F+5ali7Hjx83F+tz5syx7PDnPNAyiIuLS3FbdsrWzvlkt/xTys/s2bNN/gEgLXTeBgAbtJlRTEyMTJgwwd3MRJsLtWnTxvy9bt06s37kyJHu1zz00ENSsmRJ08zEk3bEzp8/v/lb12uznd9++832cVi7dq1p+jJs2DD3sgEDBri3mRJtDlOkSBH38woVKkjTpk1l9uzZ7mX6t/ZJ0KZIdvYprXJx0ZGLli1bJp999pnpOL5z507T58PTo48+appqqdKlS5v30hGs0pIvXz7T5MizDLt06SI5cqT+Ezdr1iyZMmWKGflIm0p9++23cuDAAbN/umzu3LlmmTaF0v/t8Oc80P1NqUmYP2Vr53yyW/6+8qPnjJavNu8CgNTQxwIAbNALM73Y9tW+XekFaeHChaVo0aLuZdpePTo62qzz5JlGaX+L+Ph428dBLzaLFSvmdRGYO3du09ciNdr+PunQob169ZLRo0fL5MmTzYWmduzWi0+7+5RWubhGZfrggw9M/wANHC5dumSWnzhxwt33QUVFRXm9rnLlyvLxxx+nWR533XWXDB482Pyv+WjRooX07dvXdDpOifZj0RGVNLDQ4Ert37/flOMXX3zhlbZcuXJy0003iR3+nAdJ+8wkZads7ZxPdss/pfzoOaNBWlqBKwAQWACADXqxeP78eXPnVi/cktILNr2jq/NEhIf/31fr6dOn3XfhA0UvJOPi4iQxMdHrrrx27k2NXhz/+eefXsvuvfdec+GpHXyPHDkiBQoUkHbt2tnep7TKRTsC6xC32mna1QlaO0ZrJ3Vtjuspaf71ud2yGz9+vBnxSjtmayd17ZC+detWqV69erK02um9a9eu5g59//793cv1Il47bk+fPt0EYenhz3mQVsf0tMrWDn/KP6X86Dlzww03eHUIBwBfaAoFADbceeed5kLRs9mQ666v0rvBun7RokXudbt375ZffvlF7rjjjoCWsb6XXhQuXbrUqwnOqVOnUn2d3snXdEkvXtu3b2/2Sx/33Xefe44LO/uUVrnoRbw2VfK8M67NjHzROTtcdP+06VDjxo3TLA99j2vXrpl864hIWguhtTm+Rn/SwKFbt27mQvnNN9/0WtesWTNTY/Hee+95Lddta9MzFx19KWmthksgz4O0ytYOf8o/JXrO6PDHAJAWaiwAwAZt8//qq6/KP/7xD9mxY4cZhlSHE9W70Lpcm5GMGjXK3AXXC0m9sJ00aZK5M968efOAlrE2zdGmP71795ann37aXHzqxbTeZU/tLvjf//53c2dfm9jocKIuDz74oNmWNp/Ru/4udvYprXLRoW01XxqwdOzY0QyPq30XfNGLb52vQ4eH1SZZe/futXURrBe+mm99re6X9ofQctCmUUlpfwWdaPD111/3mifENdzsG2+8YWpwdH91mFgdvlbTvfzyyyb/6sMPPzSBRefOnZNtP5DnQVpla4c/5e+LDrmrfTMychI+AMGDGgsAsEkv5l2deHVeAb1QfOWVV9zrx4wZY+4uax8Ivas9duxYd38FF71b7nn3WOnd4Bo1arif6/wNSeeWSDpBnr6vXrDu2rXLdMrWC129gEytM7C+rwYRU6dO9VreoUMHufvuu03goe/tyc4+pVYu2vFXm95oDcF3331nLvx1/owePXqYZlee5bJgwQITVGhNgzbb0gDAMwBKyT333CNz5swx8z3oHBz6XppXV3l5TpCnHdY1vXaA1xoS10Mv3JU2jdJ90OZmmk+lF+KuoELp/ug+pyS950F6zrm0zid/yt9XfqZNm2YCtJTm2AAAT2E6NJTXEgBAlqdt9j077eoFrF786QWyZ5CSlDbp0RGL/vOf/7ibPME+DV4GDhxo+i2EQvkNGjRIhgwZkuKkiwDgicACALKhd9991wxHqnentcZCm0LpnWXtuBxstDmS1jD4ohf3WgMBALj+CCwAIJvSzs0rV640o/VoJ2dtRx+MtF+A9onwRed1mDlzZqbnCQCQHIEFAAAAAMfovA0AAADAMQILAAAAAI4RWAAAAABwjMACAAAAgGMEFgAAAAAcI7AAAAAA4BiBBQAAAADHCCwAAAAAOEZgAQAAAECc+n9+LCV9gbfFnAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "time_stats = (\n", " clean.groupby([\"tokenizer\", \"vocab_size\"])[\"train_time_sec\"]\n", @@ -509,17 +965,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "b82b3da1", "metadata": { "execution": { - "iopub.execute_input": "2026-07-30T17:10:35.482895Z", - "iopub.status.busy": "2026-07-30T17:10:35.482730Z", - "iopub.status.idle": "2026-07-30T17:10:35.490843Z", - "shell.execute_reply": "2026-07-30T17:10:35.489975Z" + "iopub.execute_input": "2026-08-02T09:59:04.586200Z", + "iopub.status.busy": "2026-08-02T09:59:04.586200Z", + "iopub.status.idle": "2026-08-02T09:59:04.764447Z", + "shell.execute_reply": "2026-08-02T09:59:04.764447Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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wcdTUVGBHTt2yP/79++PwMBAudzLy0vOda8NZDds2IDMzMwG648ZM0a3Tl5eHrZv3y7X6devH3x9fQ3eDyIia8VAloishggk3333XezatQtvvvmmbvnff/+NqVOnIj09Xd5/9tlnZTsRwKalpaG0tBSrVq1Cr169dOssWLAAM2fORM+ePeHm5oasrCz89NNP6Ny5M1QqlS6QFakDu3fvlgHy2rVrZZBZ17XXXovU1FQEBQXh33//xYsvvoj//e9/5z0WEfyOHTsWERERCA4Olveffvpp3HPPPbrUgpycHPj7+2PLli04dOiQbl1xnOJ3bdq0SQayH3/8MWbNmoWBAwdCURTs2bMHCxcuxA033GCSficislgKEZEV+eCDD5QOHTooarVat+z2229XJkyYIH/+999/FRsbG2Xz5s3yvmg3efJkZdCgQYpGo9Fr88MPP+i2kZiYqBw8eLDR36lSqZThw4crs2fP1i0T2xcfoVOnTtVt9+eff1bs7e2VhISE8x7HjBkzlBtuuEHvd/z+++/y53379slt5+TkNFivtLRU6d27tzJ+/Hh5bNu3b1c8PDyUQ4cO6dqI7Yhl2dnZ590PIiJrxhxZIrIqN954I7Kzs+XpdkGclhcjqWJEVhBX+48cOVKmGWhHccVopUghOH36tFz21VdfYfDgwZg8ebJuuyJ9QIzO1iVSE1auXCm3L0ZkxTbqe/LJJ2FjYyN/FukAHTt2lO3PR6QxiJFVkRIgODo6YuLEiedcR4y2Tps2TR6zOE5xbF9++SViYmLkxWci7eK7776TI9DV1dVyJJmIqC1jagERWRVxqv3SSy/FsmXLZI7ob7/9JgM8EUQKycnJMpisq1OnTnqPpaSkyBSCpojgUvyOM2fOoG/fvjLPNiEhodG2UVFRevdFQCx+z/k888wzmDFjBsLCwmRO6/jx4/HAAw+cM7f15Zdfxh9//CHzarUpDiINoaioSOYI13XVVVfJlAkioraMgSwRWR0x+nrffffho48+kgHtNddcA1dXV12gqx3lrHtRl/Yxwdvbu0Gbut577z35v8h9tbev/ZgU+asiR7a+goICvbxZcV/7e85F5MX+/vvvMggVua6vv/46vv32W8THxzfa/tdff5X5t+L/Ll266JaLIFsE6mKEloiovWFqARFZHTHaKCoVfP311zK41KYVCCKl4J9//pEBpZY45S4uitKOworRVnGBmLgQrG5FBG1wKyoEiOBQG8TW1NTIFIPGaC8K046O7t27F8OHDz/vMWgvTBNB8BVXXIFXX30VR48ebbR2rAhuxTGKNhMmTNB7TIzkijQLkVpQf8IGTqhARG2djUiUNfdOEBE112233Yaff/4Z7u7uMiC1s7OTy0WAO3ToUFl5QFQAEGkE77zzDhYtWiTX0QamIh9VBIgPPfSQHM1dsWIFXnrpJVx88cWywoFIVRCjsOLUvwiYjxw5gsjISJk3K4iqASIXt0OHDpg+fbocYX3//fdlFYI///zzvPsv1hEjxaJygSgN9umnn8LPzw/r1q2Tv0OkNGirFojUg5KSErl/dYnUCrGOGJHetm0bHn74YYSEhMgKB6tXr5ZBtYeHB19cRNRmMZAlIqskaqaKElujR4+WAWtd5eXl+Oyzz3SBnChDJYLOukQwK07lb9y4UbYRExCIWrJaIqAUo63ioimxrkhHEMHi/Pnz5ePHjx/H3LlzZUqAuHjs1KlT6N69u8xz1dajPR+R3yuCXhF0DxgwQI66iqBW5Ng+9dRTMvgW+ya22VgqxJw5cxAXFydHk0VQ/9dff8n9FTVvRdDOIJaI2joGskRERERklXixFxHRBRoxFjmzTVU6qDv6S0RExmEgS0R0AYjZtTZv3tzoYyJVgYEsEVHLMbWAiIiIiKwSy28RERERkVViIEtEREREVomBLBERERFZJQayRERERGSVGMgSERERkVViIEtEREREVomBLBERERFZJQayRERERGSVGMgSEREREazR/wHTJrePCkKv6gAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "domain_stats_path = Path(DOMAIN_TOKENIZATION_STATS_PATH)\n", "\n", @@ -588,9 +1055,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.11.15" } }, "nbformat": 4, "nbformat_minor": 5 -} \ No newline at end of file +} diff --git a/notebooks/convergence_curves_by_epoch_report.ipynb b/notebooks/convergence_curves_by_epoch_report.ipynb index bd12516..0d0d8f1 100644 --- a/notebooks/convergence_curves_by_epoch_report.ipynb +++ b/notebooks/convergence_curves_by_epoch_report.ipynb @@ -5,7 +5,7 @@ "id": "4b450bf4", "metadata": {}, "source": [ - "# Convergence curves \u2014 char vs every WordPiece vocab_size in the grid\n", + "# Convergence curves — char vs every WordPiece vocab_size in the grid\n", "\n", "Reads the per-epoch history files `scripts/compare_forward_tokenizers.py` writes under\n", "`/history/*.json`, and plots train/val loss vs epoch as one small subplot\n", @@ -16,14 +16,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "11f2b459", "metadata": { "execution": { - "iopub.execute_input": "2026-08-01T11:40:12.339841Z", - "iopub.status.busy": "2026-08-01T11:40:12.339644Z", - "iopub.status.idle": "2026-08-01T11:40:12.344805Z", - "shell.execute_reply": "2026-08-01T11:40:12.343818Z" + "iopub.execute_input": "2026-08-02T09:59:31.035596Z", + "iopub.status.busy": "2026-08-02T09:59:31.035596Z", + "iopub.status.idle": "2026-08-02T09:59:31.045291Z", + "shell.execute_reply": "2026-08-02T09:59:31.045291Z" }, "tags": [ "parameters" @@ -37,17 +37,180 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "379bff96", "metadata": { "execution": { - "iopub.execute_input": "2026-08-01T11:40:12.347155Z", - "iopub.status.busy": "2026-08-01T11:40:12.346439Z", - "iopub.status.idle": "2026-08-01T11:40:13.379434Z", - "shell.execute_reply": "2026-08-01T11:40:13.378214Z" + "iopub.execute_input": "2026-08-02T09:59:31.045291Z", + "iopub.status.busy": "2026-08-02T09:59:31.045291Z", + "iopub.status.idle": "2026-08-02T09:59:32.720511Z", + "shell.execute_reply": "2026-08-02T09:59:32.720511Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "18 runs across 6 configs\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizemax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_pathmax_token_len
0char254010.2023770.8644000.191109331122.7319380.54961410850856NaNNone
1char2540420.2001860.8663640.191719371121.6011780.56569110850856NaNNone
2char25407770.2025250.8641060.199392361122.4595360.54959510850856NaNNone
3wordpiece10004010.2298820.8445520.224929361142.9400600.55186710913256artifacts/tokenizers_1M_integ/wordpiece_vocab_...None
4wordpiece100040420.2330810.8430240.225724371143.0590100.55277210913256artifacts/tokenizers_1M_integ/wordpiece_vocab_...None
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size max_len seed test_loss test_cosine \\\n", + "0 char 25 40 1 0.202377 0.864400 \n", + "1 char 25 40 42 0.200186 0.866364 \n", + "2 char 25 40 777 0.202525 0.864106 \n", + "3 wordpiece 1000 40 1 0.229882 0.844552 \n", + "4 wordpiece 1000 40 42 0.233081 0.843024 \n", + "\n", + " best_val_loss epochs_to_best_val train_time_sec inference_time_sec \\\n", + "0 0.191109 33 1122.731938 0.549614 \n", + "1 0.191719 37 1121.601178 0.565691 \n", + "2 0.199392 36 1122.459536 0.549595 \n", + "3 0.224929 36 1142.940060 0.551867 \n", + "4 0.225724 37 1143.059010 0.552772 \n", + "\n", + " num_parameters tokenizer_path \\\n", + "0 10850856 NaN \n", + "1 10850856 NaN \n", + "2 10850856 NaN \n", + "3 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", + "4 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", + "\n", + " max_token_len \n", + "0 None \n", + "1 None \n", + "2 None \n", + "3 None \n", + "4 None " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import json\n", "from pathlib import Path\n", @@ -75,17 +238,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "7b0dc511", "metadata": { "execution": { - "iopub.execute_input": "2026-08-01T11:40:13.381776Z", - "iopub.status.busy": "2026-08-01T11:40:13.381555Z", - "iopub.status.idle": "2026-08-01T11:40:13.396990Z", - "shell.execute_reply": "2026-08-01T11:40:13.395714Z" + "iopub.execute_input": "2026-08-02T09:59:32.720511Z", + "iopub.status.busy": "2026-08-02T09:59:32.720511Z", + "iopub.status.idle": "2026-08-02T09:59:32.779079Z", + "shell.execute_reply": "2026-08-02T09:59:32.779079Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 1440 (config, seed, epoch, split) rows from history/\n" + ] + } + ], "source": [ "def history_filename(row):\n", " \"\"\"Mirrors compare_forward_tokenizers.py's run_one() naming exactly, so this stays in\n", @@ -134,17 +305,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "a04f58e1", "metadata": { "execution": { - "iopub.execute_input": "2026-08-01T11:40:13.399303Z", - "iopub.status.busy": "2026-08-01T11:40:13.399078Z", - "iopub.status.idle": "2026-08-01T11:40:13.809454Z", - "shell.execute_reply": "2026-08-01T11:40:13.808202Z" + "iopub.execute_input": "2026-08-02T09:59:32.779079Z", + "iopub.status.busy": "2026-08-02T09:59:32.779079Z", + "iopub.status.idle": "2026-08-02T09:59:33.447848Z", + "shell.execute_reply": "2026-08-02T09:59:33.447848Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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Y3H55Zfjww8/xNSpU3HVVVft93UPPPAA+vbti1dffVVtkyZNws6dO9vkLyT9l4x6HQLBEHaWO9rkMxARtSZmarRwtob01KhwMKhBRNSSgsEglixZolZWDRs2DP369dvn85ctW4YtW7bU25eQkICjjjqqbTI13D4EQiHooWvV309E1NnJuV1IcGLPCazExMQGXxPef8ghh+DRRx9Vt0855RTk5eXhwQcfxMknn9zg62655RZcd9119TI1miuwkRkJauzOBCEiouYh52/J1Fi1ahWio6OxdOlSlZl37LHHqp5MDXn//fdx22234YcffsC0adPUvm3btqnswLZg0OvQPdGGHWVO5JQ4MDCd5UKIqHNr86CGTEC9/fbbkRS/008/HUZj0z7Wr7/+ql4rA8ieFxcH8r7N2Sw8v9KFcgY1iIhaTFVVlQpGyKqoIUOGYNGiRarx6/3339/oa1566SV88cUXatVtmEw8tXZQI9wo3O7yq1VVJmaJExE1KykzlZKSghUrVqjJqTC5f/DBBzf4GpnQ6t+/P3r37l1vf3Z2NhYvXtzo77JYLGprCeGgRkk1G8ASETX34qj33nsPd9xxhzr/C8namDBhAt55551GgxqSpTFr1qxIQEP06dOnzZuFS1BjB/svEVEX0KblpzZv3qwCDtKkz2Qy4Z///KeaUGpKZLuiogJ//etf8frrr2PevHnN9r4t0Vejwsla6URELUVWSMkK3HXr1uG7777DN998oy4yZNXUvsjqq3fffTeyPfTQQ63+R4oENdw+BNnQj4ioRUgvjJdffhmlpaXqvowTEtQ477zzIs95/PHHMXv27Mj9iy66CJ9++ikqKyvV/erqalV6SkqStIXM2kbhJdUeFQQnIqLm670kmXWyOKquoUOHYs2aNY2WKZRx5PDDD1fXIG+99Zbq09RYWcMw6bskv6vu1pyykrQAuCyuJSLq7No0qHHzzTdj0KBB+Oqrr/Cvf/0Lc+fOxfz581WGxf7Ihcb555+PXr16Nev7NqfEqN210omIqPmFQiF1ESFjgtQvD5cLGTduHN588839Bsc/++wzFRgPT1q1VVDD6Q3A7W2bVHUios7u7rvvVpkXssn4cNJJJ+Hee+9V40WYTFxJo9ew66+/Xj1XaqVLIENW36anp+ORRx5pk39DZrwtsliqxs1rCyKi5hIOLOxZkjApKanR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x1sCem126Rtl7ecmsURE1DskG89htcBh3XZ5XVlcJYFzf0jOL6KJYIdkUeR54iXeewGDGkREHQVQ3Hn6Fh6qZ3pIOaq+TrHuqUyQQcDtdqvARWckcyM5cHHppZf20ScjIur/wEdnkktcbV4CS05CMjs6iyEiogHDbDbBDGnsKrcs8Dikybin0zFDxgsJfEu5ESk/InXTiYhocDF1WF63bayIJC2uctt773yCZypERFuzefYEERHRADohsUh1Rq60JSKiLowZVosJOR672iaD5VeJiGjLscJmka33F+lyGTAREREREREREREREaUFBjWIiIiIiIiIiIiIiCgtMKhBRERERERERERERERpgUENIiIiIiIiIiIiIiJKCwxqEBERERERERERERFRWmBQg4iIiIiIiIiIiIiI0oK1vz9AqtI0TV02Nzf390chIkoZxjHROEYOZhwniIi2xHGC4wQR0dZwnOA4QUTUE+MEgxqdaGlpUZdlZWVb3YFERIP1GJmdnY3BjOMEEdHWj5EcJ3g+QUTEcYLnE0REvXE+YdK43LZDsVgMFRUVyMzMhMlk2iJiJMGODRs2ICsra7v+YQYT7i/uL/6NDZz/J2XIkIFl6NChMJsHdwVDjhM9h+ME91dv499Y3+0vjhNtOE70HP4/zP3V2/g31nf7i+NEG44TPYf/D3N/9Tb+jaXeOMFMjU7ITistLd3qTpZ/FAY1uo77q3u4v7qP+6xv9tdgX3lr4DjR8/j/MPdXb+PfWN/sL44TOo4TPY//D3N/9Tb+jfXN/uI4oeM40fP4/zD3V2/j31jqjBODe5ktERERERERERERERGlDQY1iIiIiIiIiIiIiIgoLTCosR0cDgf+9Kc/qUvi/upp/PviPutt/BvrfdzH3F/8+0ot/H+S+yvV8G+S+4t/X6mF/09yf6Ua/k1yf/HvK7Xw/8nU219sFE5ERERERERERERERGmBmRpERERERERERERERJQWGNQgIiIiIiIiIiIiIqK0wKAGERERERERERERERGlBWt/f4B0EggEcNddd+Gzzz5DZmYmzjzzTBx22GH9/bFSRnV1NR566CG8//77OOWUU/CLX/yiw+fcdtttWLJkCUpKSvCb3/wGM2bMwGD03Xff4bHHHsOKFSswbNgwnH322Zg1a1a750SjUTzwwAN46623YLVaccIJJ+C0007D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7LNaZmamNmXKFK2oqEibMWNGpxPSg019fb124IEHqs3j8WgjRoxQ1y+88MJ2z7vhhhtUcGjmzJlqX8okfSAQ0Aab2267TZOY4vTp0xP7TbZDDjmk3fM+/PBDrbCwUBs3bpxWVlamjRo1Slu8eLE22Ph8Pm3u3LkqCDZnzhy1P/Lz87U777xzi7/DvfbaSx0gZd+63W7t/vvv77fPneqDi7jyyisT/0/K/7unnHKKFgqF+uUzDgQcJzrHcaJ7OE50D8eJHcdxom9wnOgcx4nu4TjRPRwndhzHib7BcaJzHCe6h+NE93CcSL9xwiT/2bFcj8FF+hksWrQImZmZquyU1AAjvbnLxx9/vMWukPpou+22W7v7qqurVZ21kpISjB07dlDuPunPsnLlyi3ul3JmBxxwwBbpglJCSerU7bzzzrBYLBispDbfkiVLkJOToxqFOxyODp8nz5GafVOmTFHPpbbahrNmzdpid0gJrxUrVqC0tBSjRo3i7tpBHCc6xnGiezhObB+OE9uP40Tf4TjRMY4T3cNxYvtwnNh+HCf6DseJjnGc6B6OE9uH40T6jBMMahARERERERERERERUVow9/cHICIiIiIiIiIiIiIi6goGNYiIiIiIiIiIiIiIKC0wqEFERERERERERERERGmBQQ0iIiIiIiIiIiIiIkoLDGoQEREREREREREREVFaYFCDiIiIiIiIiIiIiIjSAoMaRERERERERERERESUFhjUIBrAnnjiCRxxxBH9/TGIiChFcZwgIiKOE0RExPMJSjcMahANYA0NDVi9enV/fwwiIkpRHCeIiIjjBBER8XyC0g2DGkRERERERERERERElBYY1CDqBatWrcIvfvEL7LzzzjjooINw9913IxaLbVHu4/nnn8dRRx2lnnfxxRfD6/W2e5/58+fjhBNOwLRp03DooYfixRdf7PBn/fKXv8TMmTNx+OGH4/XXX9/iOS+//DKOOeYY7LbbbrjwwgvR1NTEf3cion7EcYKIiDhOEBERzyeItpNGRD1q1apVWn5+vvb73/9e++qrr7TXX39dmzx5sva73/0u8Zy7775bs1gs2rRp07R33nlHe+utt7SJEydqP/nJTxLP+fHHHzWHw6FdfPHF2rx587Q77rhDs9vt2gsvvJB4zvLly7WcnBzttNNO0z788EPtzTff1I444ghtzZo1iZ9jtVq1/fffX/vggw/UJp/lZz/7Gf/ViYj6CccJIiLiOEFERDyfINp+DGoQ9bCzzz5bO+OMM9rd99lnn6kgRiAQSAQbJKa4ePHixHPmz5+v7luyZIm6ffrpp2sHHHBAu/e56KKLtClTpiRuy8+ZNWvWFp8hEokkfo4EQurq6hKPPfLII1pRUVGP/b5ERNQ9HCeIiIjjBBERbS+eTxBpmnV7MzyIqGOffPIJWltbMWXKFAkaqi0cDiMajaqm3ZMmTVLPKywsxOTJkxOv23XXXZGRkYFvv/1WPWfhwoX46U9/2u69Dz74YNxzzz0IhUKw2+347LPPcPbZZ2/xGSwWS+J6WVkZ8vLyEreHDh2K6upq/vMREfUTjhNERMRxgoiIeD5BtP0Y1CDqYX6/H2eccQbmzp27xWOjRo1KXHc6nVs87nK51OuN95Hbmz8uvTkCgYAKagSDQbjd7q1+HquV/5sTEaUSjhNERMRxgoiIeD5BtP0420nUwyZMmIAVK1Zg4sSJW31eZWUlGhoakJubq25XVVWhpqYGY8eOVbfl8vvvv2/3mkWLFqGoqAhZWVnqtvyMBQsW8N+QiCiNcJwgIiKOE0RExPMJou1n3oHXElEHLr74Yrzyyiu4//77VekpsWbNGlx55ZXtnheJRHDFFVeozAu5fumll6qyU3vttZd6/Pzzz8czzzyjSkwJKV11xx13qPsNF110EZ599lk8//zz6raUuHrggQewceNG/tsQEaUojhNERMRxgoiIeD5BtP0Y1CDqYUcddRQeeeQRXH/99cjOzkZxcbHqhTFt2rR2zxsxYgR8Ph8KCgpUz4vPP/8cjz/+OMxm/X/L448/XgVCDjnkENUHQwIeBx10ULvgyLHHHot7771XBTry8/NVn45vvvlGXRIRUWriOEFERBwniIiI5xNE288k3dJ34PVEtBWSMSG9MyRwkUyafcu2dOlS1R9DSk9JQ28joJFMHq+oqFCBiszMzA5/jmRoyM+S0lTJfTgaGxtViavkXh4SSFm/fv02y2MREVHv4zhBREQcJ4iIiOcTRN3DnhpEvai0tHSbz5Ggh2RtbO3x0aNHb/U9LBZLh++Rk5OjtmTSWJwBDSKi1MBxgoiIOE4QERHPJ4i6h+WniIiIiIiIiIiIiIgoLbD8FFE/6KgsFBEREccJIiLi+QQREXHeiWjrGNQgIiIiIiIiIiIiIqK0wPJTRERERERERERERESUFhjUICIiIiIiIiIiIiKitMCgBhERERERERERERERpQUGNYiIiIiIiIiIiIiIKC0wqEFERERERERERERERGmBQQ0iIiIiIiIiIiIiIkoLDGoQEREREREREREREVFaYFCDiIiIiIiIiIiIiIjSAoMaRERERERERERERESUFhjUICIiIiIiIiIiIiKitMCgBhERERERERERERERpQUGNYiIiIiIiIiIiIiIKC0wqEFERERERERERERERGmBQQ2iHbBgwQI8+OCD3IdERMRxgoiIiIiIiKgPMKhB1EdBDZ/Ph2uvvRatra3c50REgwTHCSIiIiIiIqKeZe3h9yOiFBUKhfDGG29g+fLlGD58OI455hi4XK52z5k/fz4++OADZGZm4oQTTkBxcXGfPk5ERP3r/fffV4GYgoICNU7k5eW1e5zjBBEREREREfU3ZmoQ9RG3260yNTIyMvp8n//444+YOnUqHn74YVRXV+P222/HxIkTUVFRkXjOPffcgwMPPBBr1qzBa6+9hsmTJ6vX9dXjRESDXX+OE7FYDHvuuSduvfVWNU48++yzGDVqFBYuXJh4DscJIiIiIiIiSgUmTdO0/v4QRD3hs88+w7p16/DTn/40sdpU7vv9738Pk8mEjRs34rHHHsNVV12VeI1M1nz66adwOp04+OCDMXLkyMRjd9xxh1qlumrVKixatAgnnniievyll17C2rVrMXPmTKxYsUKVn/ryyy/R3NysXnPRRRfh7bffRmVlJfbdd1/1PKP81F//+ldceuml7SasZNWrvF6yJg4//HAMGzas3e/19ddfY968eWqy66STTlJZDl19rWH9+vXqUjI0RCQSUUEOeb8bbrgBTU1NKCkpwX/+8x+ccsop6jnymDzvxRdf7PXHiYj6AseJzscJ+TooY9306dMT9x155JEoLCxUAXGOE0RERERERJQqmKlBA4YEDS655JLE7b/85S+47rrr8N1336nb//vf/1SwwSCrUffbbz8sXboUH330kZrkf/311xOPS4Di6KOPxj/+8Q+0tLSo+4499lhcccUVKkAiwRLJeDBIUEN+3j777IM333xTva9cf+ihhxKfTx5P7qnx29/+Fscff7wKnEhwRSaTJIBhuPDCC3HYYYdh8eLF6nH5vFJGqiuvTSbBDCOgIaxWK7KyshCNRtXtjz/+WK3SlfczSHBI9pfc39uPExH1BY4TnY8TEvxPDmgYY4UE/QXHCSIiIiIiIkoV7KlBA8bee++NxsZG/PDDDxg/frzKYDjzzDPxzjvvYMaMGXj33Xdx0EEHqedKFoUEJSSIISWRjCDI+eefr7I9DJJpcd9996nrUjJJVvlKECE3N1dNxicHGQxz585VAQex//7749e//nUieySZBFIeeeQRFfwwekv87W9/w+WXX64ek0wTCYjI7yMlQIRkhsjE07Zeuy2vvPKKWpErmRNiw4YNKCoqgt1uTzyntLQUfr8fdXV1vf64rAQmIuptHCe2PU5I2anvv/9ejREShP/Tn/6k7uc4QURERERERKmCQQ0aMGQ16Zw5c1TwoqamBlOmTFGZAZJpcfHFF6tJnKuvvlo999tvv1Ulm4yAhpDG1VdeeSU2bdqEIUOGqPsOPfTQxOOyulUyLySgIcxmsypP9fzzz7f7HMcdd1ziumR2nHbaaSoYIeWXksmqV3mvf/7zn4n7JNjyzTffqOuffPKJqm9uBDTEuHHjuvTarZH9IMEeCYpIXwuDBEuSGZXpjPt7+3Eiot7GcaJr44QcnyVLQ0oXLl++PDF+cZwgIiIiIiKiVMCgBg0okolhBDWkR4ZkUpxxxhkqQCB23XXXxIRNVybTJfCRrLMJna09pzNS+kkmjZLJxJH03JAskK21u9nWayXg0hEpi3XqqaeqDBAJ4hjKyspQVVWlsk6MbIry8nL1++fl5fX640REfYXjxNbHiZNPPlltQpqWSwbjkiVLOE4QERERERFR6pBG4UQDxVdffaVlZGRoM2fO1D755BN135w5c7R9991XO+644xLPKy8v12w2m/bBBx8k7rvlllu0srKyxO1hw4Zpb7zxRuL2K6+8ouXl5WkNDQ3qdiwW0/bZZx9t9913V7c3bNggUQjtrrvuSrzmmWee0XJycjS/36/V1NSoxysrK9Vj7777rlZQUKDuTzZ//vzE4263W1u9enXisRUrVmihUGibr+3ICy+8oGVnZ2uvv/76Fo81NjZqLpdLe/rppxP3nXjiidqxxx7bJ48TEfUVjhMdjxNr167V6uvr29131VVXadOmTVPXOU4QERERERFRqmCmBg0ou+yyC2w2myqXsfvuuydW5V5//fW45557Es8bOnSouk9KRZ1++umqybc0En/66ac7fe+jjjoKe+yxh3pfuT5//nxUV1cjJyen3fPuv/9+LFy4EA6HA48//rjqdSElT5IbhAspfSVZJNKYVT6HfG7JKJGSV5JRIo+fddZZ2G233dSqWclykLJZn3/++TZfuzl5zU9+8hPV40PKaBmNYqX8lLx3dna26ily7rnnqvJUUjtd+ofIJnr7cSKivsJxouNxQnpSHX300Zg5c6Yqwbh48WLV2+mZZ55Rj3OcICIiIiIiolRhkshGf38Iop706KOPIhKJ4Oc//7m6LQGOJ598UjXwlubUyRYsWIBPP/1UBR2kXFVy/4o77rhD9cwYO3Zsu7JPL730EtauXasmxjIzM9V7yHtv3LhRleeQskoycS89LqTRuDxP+Hw+/PWvf1UlojIyMhLvKYGKL774Qn1mef60adPafUYjCCETSieeeGK3XmuQZuOb9/5IDmoYJFAjk1jye8nPMpqQ99XjRER9geNExyTA/8orr6hxTIL/hx9+OPLz89s9h+MEERERERER9TcGNYh6iBHUaGho2CJ7g4iIiOMEERERERER0Y7ruEskERERERERERERERFRimFQg6iHZGVl4U9/+pMqZUVERMRxgoiIiIiIiKjnsfwUERERERERERERERGlBWZqEBERERERERERERFRWmBQg4iIiIiIiIiIiIiI0gKDGkRERERERERERERElBas/f0BUlUsFkNFRQUyMzNhMpn6++MQEaUETdPQ0tKCoUOHwmwe3HFxjhNERFviOEFERERERL2NQY1OSECjrKys1/8BiIjS0YYNG1BaWorBjOMEEVHnOE4QEREREVFvYVCjE5KhYZyQZWVl9do/ABFROmlublYBX+MYOZhxnCAi2hLHCSIiIiIi6m0ManTCKDklAQ0GNYiIOj5GDmYcJ4iItn2MJCIiIiIi6mmDuyA6ERERERERERERERGlDQY1iIiIiIiIiIiIiIgoLTCoQUREREREREREREREaYFBDSIiIiIiIiIiIiIiSgsMahARERERERERERERUVqwIg3U1dXh2WefRVVVFaZOnYrjjz8eZnPn8Zg//elPCAaDW9w/a9YsnHDCCb36WWMxDdUtQdgsJuRnOHr1ZxERUZs1a9aocWLChAnIzc3d6q755JNPEI1Gt7i/pKREvZ6IiIiIiIiIiFKTNR0mqfbcc0+MHz8eu+22Gy655BI8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YKYGERF1ZES8p0Zlox+apnEnERERERERERFtA4MafRLUCCASjfXmjyIiojTO1KhsDiAQ5jhBRERERERERLQtDGr0otJcfbLKF4qiqpklqIiIqL2hOS5YzSZEohrW13u5e4iIiIiIiIiItoFBjV7ksltQmOlQ11fWtPbmjyIiojRkMZtQmudS11dWc5wgIiIiIiIiItoWBjV62Yh4Cao1NVyBS0REWxoZ76uxppbjBBERERERERHRtjCo0cuGx+ulb2zw9/aPIiKiNDSyQA9qbKj39fdHISIiIiIiIiJKeQxq9FGz8IpGBjWIiKjzcaK8kb2XiIiIiIiIiIi2hUGNvgpqNHGyioiItjSygMFvIiIiIiIiIqKuYlCjj4Iam5r80DStt38cERGlmeHxnhqVTQGEItH+/jhERERERERERCmNQY0+CmpUtwThDUV6+8cREVGaKctzwQTAH44yq4+IiIiIiIiIaBsY1OhlhZkOOKxmxDRgbQ2bwBIRUXsOqwUl2U51fWV1K3cPEREREREREdFWMKjRy0wmE8ri2RqrajlZRUREWxqRr5egWl3t5e4hIiIiIiIiItoKBjX6wIh4UGNtHTM1iIio82bhGxs4ThARERERERERbQ2DGn3AyNSobPT3xY8jIqI0zdTY2MigBhERERERERHR1jCo0YfNwisY1CAioq1k9FU0Brh/iIiIiIiIiIi2gkGNPgxqVDZxsoqIiDrP1JDgdzSmcRcREREREREREXWCQY0+MDy/LajBySoiIupsnGgORFDbEuQOIiIiIiIiIiLqBIMafaAsV5+sag1GUN3CbA0iImovw2FFQYZdXV9R3cLdQ0RERERERETUCQY1+oDLbkFhhkNdX1nd2hc/koiI0szwPL0E1aoab39/FCIiIiIiIiKilMWgRh+XFlnDySoiIurAyAJ9nFhfz6AGEREREREREVFnrEgDS5cuxQMPPICqqipMnToVv/nNb5CRkbHV10SjUTzzzDN4//334Xa7cc4552DnnXdGfzYL/2ZdAzY0+PrtMxARDWQrVqxQ48TEiRNRUFDQpdeEQiEsWrRIjROTJk2CyWRCfxkRz9Qob/D322cgIiIiIiIiIkp1KZ+psWDBAuyyyy6or6/H3nvvjeeff15dBoOdN1KVxxULPjUAAHoRSURBVA499FD86U9/wvTp09V2wQUX4Ntv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xrqmpiatXLlSVVVV/T6ns7NTq1ev1tq1a9Xd3a2xzH5++7dn+8J+1/qzfft2vfnmm2ptbT2ir2+kCoVCevXVV93vUV/q6ur0xhtvqLy8/Ii/ttGIdeLgWCcGh3VicFgnDg3rBAAAAIB4QqgxCE888YRKS0t1+eWX65RTTtGiRYsOejJ6LLH9cMstt2jGjBk655xzdM899/T5vJ/97GeaMGGCrrnmGs2ePVtXXHGFOjo6NNZs2bJFl1xyiaZMmaLrrrvO7bcLLrjAnVyOtXTpUk2dOlUf+tCHtHjxYh1zzDHatGmTxqLHHnvM7aeLL77Y7buSkhLdcccdB5z8O++88zR//nxdddVV7jmPPPKIxrof//jHOvPMM93v2v6+//3vu+PaJz/5SU2bNk3XXnuturq6huV1jgasE/1jnRgc1onBY504dKwTAAAAAOIJocYA2RXMV155pb7+9a+7K8X37t3rTsZ/9rOfHdq/oThhlRllZWV655133InnvixZskS33XabHn/8ca1bt04bNmzQCy+84N5IjzVbt27Vxz/+cRdiWOXPjh073HbTTTf1upr50ksvdSfxd+3apX379mn69Onu93Asqq+vd1VA9ruzceNG3X///fryl7/sKl0i7P7u3bvd/rLn3HnnnfrUpz41ZoOgSDBm+8oCxP099dRT+sEPfqBnnnnGVb+sWbNGf/3rX3XXXXcNy2uNd6wTB8c6MTisE4PHOnFoWCcAAAAAxJ1uDMgdd9zRnZOT0x0IBKKPPfroo91JSUndNTU17MUYc+fO7f7qV796wD655ppruk899dRej916663dU6ZMYf91d3d/97vf7S4rK4vui7/85S/dCQkJ3fv27Ys+9sorr1j/qe6VK1eO+X1WVVXl9sXf/vY3ty/8fn93RkZG99133x3dN6FQqLu0tLT7G9/4xpjcX/X19d3Tpk3rfv7557tvvPHG7pNOOqnXn19yySXd5557bq/HPvvZz7p/wxg81omBY504NKwTg8M68e5YJwAAAADEIyo1BsiuBj/22GOVkpISfcxaUFmblrfffnuoMqdRtw9POumkXo/ZPrSrd+3qyrHOZhrMnDmz1/6ytkDWrit2f0X+bCyqrq7WK6+8oieffNJVupx11lmu3ZSxyoy2trZev2MJCQlasGDBmN1f119/vav2Ofvsswf1b3L9+vUKBAJH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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "def config_label(tokenizer, vocab_size, max_token_len):\n", " if tokenizer == \"char\":\n", @@ -213,17 +395,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "7a5eab55", "metadata": { "execution": { - "iopub.execute_input": "2026-08-01T11:40:13.811551Z", - "iopub.status.busy": "2026-08-01T11:40:13.811340Z", - "iopub.status.idle": "2026-08-01T11:40:14.114172Z", - "shell.execute_reply": "2026-08-01T11:40:14.112983Z" + "iopub.execute_input": "2026-08-02T09:59:33.447848Z", + "iopub.status.busy": "2026-08-02T09:59:33.447848Z", + "iopub.status.idle": "2026-08-02T09:59:33.665460Z", + "shell.execute_reply": "2026-08-02T09:59:33.665460Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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kyY1+HlPhMPNEhERkauSsPT73mwtfOTZwocthMiFu3G0NAlL0mUpLlQboSxO5qGxrWVQA2d+Mi6tE9IiILlQryWQ4/1lxzH1fUh3R7nwV6HBx1PVO0QE+NRq/XM1FotVtdJI0BCJUdXBtKU5mWtipwYLnQQAmSFbJr+Li4urdZ/MQzF27FiYTCb8/LM25nhNycnJtWoijve8J8JgQURERC2NXNbJ/C1wO/GgBEStMli4IgYLIiIiImrrCk8iWJxaCT4REREREZEBgwURERERETUagwURERERETUagwURERERETFYEBERERGR87HFgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGs2z8U/ROlmtVrUuLCx09qEQERERETmFfi2sXxsfD4NFPYqKitQ6ISGhKX82REREREQt8to4JCTkuI9xszYkfrRBFosF6enpCAoKgpub20knOwkkaWlpCA4OPm3H2BbwXPJcuhq+JnkuXRFflzyProavydZzLiUqSKiIi4uDu/vxqyjYYlEPOXHx8fGN+kHID5/BomnwXDYdnkueR1fD1yTPpavha5Ln0hUFO/G68kQtFToWbxMRERERUaMxWBARERERUaMxWJwGPj4+ePzxx9WaeC5dBV+XPI+uhq9JnktXw9ckz6Ur8mlB15Us3iYiIiIiokZjiwURERERETUagwURERERETUagwURERERETUa57E4DQ4ePIjs7Gz07NkTgYGBp+NLtHp//vlnranju3TpoiZnoRPbu3cvMjIyMHLkyHons9m9ezdKSkrQp08feHt787TWwWw2Y8OGDQgICEBSUpLDfRUVFVi3bl2tfyOPCwsL4/k0kN/lAwcOoKysDImJifD19a3z/GRmZuLQoUPo2LEjoqOjeQ7rIK87+d2VMeU7dOhQawLXv/76CwUFBQ77oqKi0KNHD57PGuT9b8+ePYiIiFDnsr7zvX37dvUewHNYv2PHjuHo0aPqdzc8PLzWffv27av1b0aPHs3XZD3k77f8HZf3y3bt2tW6X86n/J737t0bfn5+cCky8zY1jaKiIuvkyZOtAQEB1h49eqj1Rx99xNN7Cjw8PKxJSUnWUaNG2ZevvvqK5/IE5s+fbx0zZow1LCxM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ZGdnqwv6r7/+GkOGDLF3UXr66afVBb6fnx8sFosKIV988QWmTp1qDwOXXXYZfvvtN/U8EgwkeCxcuBBRUVH2r3XXXXfh/fffV6GjvLwcnp6e+OmnnxAcHKweU1BQgDFjxsDHx0dtr1mzBl9++aX96xARUdNiVygiImoScpEvF/Z79uxRa7mQv+mmm3DNNdc4PC4jIwPTp0/HH3/8gZUrV+If//iHelxZWZm6/5133sHy5ctV4JAC7J07d8JkMuHhhx+2P8esWbPwwQcfYPXq1Vi2bBlWrVqFF154ARUVFfbHHDt2DPfff78KKLLcfvvtePTRR/nTJiI6TRgsiIioSXz00Ufo16+futCfO3cuvvrqKwQGBmLXrl2q5UInLQh33HGHfVsu/jMzM7FixQq1La0XV111FTp06KC2g4KCcOedd6rWBt3s2bNVYJGvpxsxYoS9RUPI7Ysvvti+PX78eOzevZs/bSKi04RdoYiIqEkcPHgQlZWVmDdvnsP+yy+/XO3XSc2E3j1JSPiQECC1GULWl1xyicNzJCYmorCwEHl5eQgLC0NqaiqmTZt23OMJDw932JavaWzRICKipsVgQURETUJqG84880zVJel48vPzHbalXkL2RUZGqm1Z5+bmOjxGtr28vOz1E6GhocjJyeFPjojIhbArFBERNYmzzz4bn3/+OYqKihz2y8hPRhIipOZBJ3UUUsStF3iPHj0a3333ndqnk65V0tVJH/Vp0qRJqmuUsSWkpKQEpaWl/GkSETkJWyyIiKhJPPbYY1iyZIkKCDNnzlTDzEoBd0pKir1+QgQEBKj6CKmbkPDw3HPPqdsJCQnq/kceeUQFiSlTpuCiiy5Shdnz5893CCNShL1o0SIVNq699lo1KtScOXNUSDEOb0tERM2HLRZERNQkpKZh7dq1uO+++9RITtu3b8eECROwdOlSh8fFx8erUaOkXkIe9/LLL+PFF1+03x8dHa1GhBo5cqQaOUrqLzZu3IihQ4faHyPdpdavX68CisxjIUPLSm2H1G+I7t2749xzz3X4ujJkrdR7EBHR6eFmlc6tREREzeCNN95Qi4wURURErQtbLIiIiIiIqNEYLIiIqNnU1UWJiIhaB3aFIiIiIiKiRmOLBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERobH+H+v/R72O46JgAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots(figsize=(8, 5))\n", "val_data = history_df[history_df[\"split\"] == \"val\"]\n", @@ -274,9 +467,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.11.15" } }, "nbformat": 4, "nbformat_minor": 5 -} \ No newline at end of file +} From 1558cc757f64192e9405b13c710f64e4fcf773cc Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 6 Aug 2026 22:55:34 +0300 Subject: [PATCH 43/70] Expose dropout as a CLI flag Was hardcoded to 0.2 in ForwardModel before this. --- irrm_codec/train_forward.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/irrm_codec/train_forward.py b/irrm_codec/train_forward.py index 63e5876..298f6ce 100644 --- a/irrm_codec/train_forward.py +++ b/irrm_codec/train_forward.py @@ -39,6 +39,7 @@ def parse_args(): parser.add_argument("--epochs", type=int, default=20) parser.add_argument("--lr", type=float, default=1e-3) parser.add_argument("--weight-decay", type=float, default=1e-4) + parser.add_argument("--dropout", type=float, default=0.2, help="Dropout used in ForwardModel's conv blocks and MLP head.") parser.add_argument("--train-fraction", type=float, default=0.8) parser.add_argument("--val-fraction", type=float, default=0.1) parser.add_argument("--seed", type=int, default=42) @@ -153,6 +154,7 @@ def main(): vocab_size=vocab_size, output_dim=merge_stats["embedding_dim"], max_len=args.max_len, + dropout=args.dropout, ).to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) num_parameters = sum(param.numel() for param in model.parameters()) From e48434d0ca9a24645ec876b9e34caad785d1e79d Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 6 Aug 2026 22:55:50 +0300 Subject: [PATCH 44/70] Wire up --pad-layout in the comparison script end and anchored are tracked as separate configs everywhere (CSV, history filenames, resume, summary) so they never get averaged together by accident. --- scripts/compare_forward_tokenizers.py | 71 +++++++++++++++++++-------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/scripts/compare_forward_tokenizers.py b/scripts/compare_forward_tokenizers.py index 275897f..d719de2 100644 --- a/scripts/compare_forward_tokenizers.py +++ b/scripts/compare_forward_tokenizers.py @@ -50,7 +50,7 @@ ) RESULT_FIELDS = [ - "tokenizer", "vocab_size", "max_token_len", "max_len", "seed", + "tokenizer", "vocab_size", "max_token_len", "pad_layout", "max_len", "seed", "test_loss", "test_cosine", "best_val_loss", "epochs_to_best_val", "train_time_sec", "inference_time_sec", "num_parameters", "tokenizer_path", ] @@ -68,6 +68,7 @@ def parse_args(): parser.add_argument("--epochs", type=int, default=20) parser.add_argument("--lr", type=float, default=1e-3) parser.add_argument("--weight-decay", type=float, default=1e-4) + parser.add_argument("--dropout", type=float, default=0.2, help="Dropout used in ForwardModel's conv blocks and MLP head.") parser.add_argument("--train-fraction", type=float, default=0.8) parser.add_argument("--val-fraction", type=float, default=0.1) parser.add_argument("--num-workers", type=int, default=0) @@ -82,6 +83,17 @@ def parse_args(): "(the original vocab is used as-is). Does not touch tokenizer.json files or char " "configs - filtering happens per-run, in this script only, not in tokenizer training.", ) + parser.add_argument( + "--pad-layout", + choices=["end", "anchored"], + default="end", + help="'end' (default): pad after the real tokens, as before. 'anchored': keep the " + "first --left-anchor and last --right-anchor tokens at fixed buffer positions and " + "put all padding between them, so the (conserved) sequence ends land on the same " + "position across every example. WordPiece configs only - char is unaffected.", + ) + parser.add_argument("--left-anchor", type=int, default=1, help="Only used with --pad-layout anchored.") + parser.add_argument("--right-anchor", type=int, default=1, help="Only used with --pad-layout anchored.") parser.add_argument("--seeds", type=int, nargs="+", default=[1, 42, 777]) parser.add_argument( "--configs", @@ -129,23 +141,29 @@ def run_one(spec, seed, args, logger): device = choose_device() tokenizer_args = _tokenizer_args_from_spec(spec) - if args.max_token_len is not None and tokenizer_args.tokenizer_type == "wordpiece": + needs_custom_handling = tokenizer_args.tokenizer_type == "wordpiece" and ( + args.max_token_len is not None or args.pad_layout != "end" + ) + if needs_custom_handling: tokenizer = load_wordpiece_tokenizer(tokenizer_args.tokenizer_path) original_vocab_size = wordpiece_vocab_size(tokenizer) - tokenizer = filter_vocab_by_max_token_length(tokenizer, args.max_token_len) + if args.max_token_len is not None: + tokenizer = filter_vocab_by_max_token_length(tokenizer, args.max_token_len) vocab_size = wordpiece_vocab_size(tokenizer) - encode_fn = WordpieceEncodeFn(tokenizer) + encode_fn = WordpieceEncodeFn( + tokenizer, pad_layout=args.pad_layout, left_anchor=args.left_anchor, right_anchor=args.right_anchor + ) tokenizer_info = { "tokenizer_type": "wordpiece", "tokenizer_path": tokenizer_args.tokenizer_path, "vocab_size": vocab_size, } logger.info( - "tokenizer_type=wordpiece vocab_size=%d (filtered from %d by max_token_len=%d) tokenizer_path=%s", - vocab_size, original_vocab_size, args.max_token_len, tokenizer_args.tokenizer_path, + "tokenizer_type=wordpiece vocab_size=%d (from %d, max_token_len=%s) pad_layout=%s tokenizer_path=%s", + vocab_size, original_vocab_size, args.max_token_len, args.pad_layout, tokenizer_args.tokenizer_path, ) else: - # char, or wordpiece with no --max-token-len: unfiltered, shared with train_forward.py/train_inverse.py + # char, or wordpiece with every new option left at default: unchanged, shared with train_forward.py/train_inverse.py encode_fn, vocab_size, tokenizer_info = resolve_tokenizer(tokenizer_args, logger) data_args = argparse.Namespace( @@ -168,6 +186,7 @@ def run_one(spec, seed, args, logger): vocab_size=vocab_size, output_dim=prepared["merge_stats"]["embedding_dim"], max_len=args.max_len, + dropout=args.dropout, ).to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) @@ -188,12 +207,14 @@ def run_one(spec, seed, args, logger): inference_time_sec = _benchmark_inference(model, prepared["test_loader"], device, args.inference_repeats) row_max_token_len = args.max_token_len if tokenizer_info["tokenizer_type"] == "wordpiece" else None + row_pad_layout = args.pad_layout if tokenizer_info["tokenizer_type"] == "wordpiece" else "end" tokenizer_label = "char" if tokenizer_info["tokenizer_type"] == "char" else f"wordpiece_{vocab_size}" filter_suffix = f"_n{row_max_token_len}" if row_max_token_len is not None else "" + layout_suffix = f"_{row_pad_layout}" if row_pad_layout != "end" else "" history_dir = Path(args.output_root) / "history" history_dir.mkdir(parents=True, exist_ok=True) - history_path = history_dir / f"{tokenizer_label}{filter_suffix}_seed{seed}.json" + history_path = history_dir / f"{tokenizer_label}{filter_suffix}{layout_suffix}_seed{seed}.json" save_json(history_path, history) logger.info("wrote per-epoch history path=%s", history_path) @@ -201,6 +222,7 @@ def run_one(spec, seed, args, logger): "tokenizer": tokenizer_info["tokenizer_type"], "vocab_size": tokenizer_info["vocab_size"], "max_token_len": row_max_token_len, + "pad_layout": row_pad_layout, "max_len": args.max_len, "seed": seed, "test_loss": test_metrics["loss"], @@ -224,20 +246,21 @@ def _mean_std(values): def summarize(rows): - """One aggregated row per (tokenizer, vocab_size, max_token_len), mean +/- std across seeds.""" + """One aggregated row per (tokenizer, vocab_size, max_token_len, pad_layout), mean +/- std across seeds.""" groups = {} for row in rows: - key = (row["tokenizer"], row["vocab_size"], row["max_token_len"]) + key = (row["tokenizer"], row["vocab_size"], row["max_token_len"], row.get("pad_layout", "end")) groups.setdefault(key, []).append(row) summary = [] - for (tokenizer, vocab_size, max_token_len), group_rows in sorted( - groups.items(), key=lambda kv: (kv[0][0], kv[0][1] or 0, kv[0][2] or 0) + for (tokenizer, vocab_size, max_token_len, pad_layout), group_rows in sorted( + groups.items(), key=lambda kv: (kv[0][0], kv[0][1] or 0, kv[0][2] or 0, kv[0][3]) ): summary.append({ "tokenizer": tokenizer, "vocab_size": vocab_size, "max_token_len": max_token_len, + "pad_layout": pad_layout, "max_len": group_rows[0]["max_len"], "n_seeds": len(group_rows), "test_loss": _mean_std([r["test_loss"] for r in group_rows]), @@ -258,15 +281,15 @@ def _fmt(mean_std, precision=4): def write_markdown_table(summary, path): lines = [ - "| tokenizer | vocab_size | max_token_len | max_len | test_loss | test_cosine | best_val_loss | " + "| tokenizer | vocab_size | max_token_len | pad_layout | max_len | test_loss | test_cosine | best_val_loss | " "epochs_to_best_val | train_time_sec | inference_time_sec | num_parameters | notes |", - "|---|---|---|---|---|---|---|---|---|---|---|---|", + "|---|---|---|---|---|---|---|---|---|---|---|---|---|", ] for row in summary: notes = f"n={row['n_seeds']} seeds" max_token_len = row["max_token_len"] if row["max_token_len"] is not None else "-" lines.append( - f"| {row['tokenizer']} | {row['vocab_size']} | {max_token_len} | {row['max_len']} | " + f"| {row['tokenizer']} | {row['vocab_size']} | {max_token_len} | {row['pad_layout']} | {row['max_len']} | " f"{_fmt(row['test_loss'])} | {_fmt(row['test_cosine'])} | {_fmt(row['best_val_loss'])} | " f"{_fmt(row['epochs_to_best_val'], precision=1)} | {_fmt(row['train_time_sec'], precision=1)} | " f"{_fmt(row['inference_time_sec'], precision=3)} | {row['num_parameters']} | {notes} |" @@ -275,20 +298,26 @@ def write_markdown_table(summary, path): def _load_completed_runs(csv_path): - """(tokenizer_path or None, max_token_len, seed) triples already present in raw_results.csv.""" + """(tokenizer_path or None, max_token_len, pad_layout, seed) tuples already present in raw_results.csv.""" if not csv_path.exists(): return set(), [] with open(csv_path, newline="", encoding="utf-8") as f: existing_rows = list(csv.DictReader(f)) - # .get(..., "") covers resuming from a CSV written before --max-token-len existed + # .get(..., default) covers resuming from a CSV written before --max-token-len/--pad-layout existed completed = { - (row["tokenizer_path"] or None, int(row["max_token_len"]) if row.get("max_token_len") else None, int(row["seed"])) + ( + row["tokenizer_path"] or None, + int(row["max_token_len"]) if row.get("max_token_len") else None, + row.get("pad_layout") or "end", + int(row["seed"]), + ) for row in existing_rows } # csv.DictReader gives strings back; downstream code (summarize()) expects numeric fields for row in existing_rows: row["vocab_size"] = int(row["vocab_size"]) row["max_token_len"] = int(row["max_token_len"]) if row.get("max_token_len") else None + row["pad_layout"] = row.get("pad_layout") or "end" row["max_len"] = int(row["max_len"]) row["seed"] = int(row["seed"]) row["test_loss"] = float(row["test_loss"]) @@ -303,11 +332,11 @@ def _load_completed_runs(csv_path): def _spec_key(spec, args): - """(tokenizer_path or None, max_token_len) identity matched against a CSV row.""" + """(tokenizer_path or None, max_token_len, pad_layout) identity matched against a CSV row.""" if spec == "char": - return None, None + return None, None, "end" path = spec.split(":", 1)[1] - return path, args.max_token_len + return path, args.max_token_len, args.pad_layout def main(): From 7837d288a2d5bc0a8e874ac1c3e10a1357e625e8 Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 6 Aug 2026 23:04:50 +0300 Subject: [PATCH 45/70] Add anchored-padding experiment scripts, with and without extra dropout Same per-vocab max_len + max_token_len=9 grid as run3b, now with --pad-layout anchored, and a second variant that also raises dropout to 0.4 - to see whether anchoring the sequence ends helps on its own, and whether stacking more regularization on top helps further. --- scripts/run4_all_sequential.sh | 3 ++ ...individual_maxlen_maxtokenlen9_anchored.sh | 48 ++++++++++++++++++ ...al_maxlen_maxtokenlen9_anchored_dropout.sh | 49 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 scripts/run4_all_sequential.sh create mode 100644 scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh create mode 100644 scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh diff --git a/scripts/run4_all_sequential.sh b/scripts/run4_all_sequential.sh new file mode 100644 index 0000000..97f9bae --- /dev/null +++ b/scripts/run4_all_sequential.sh @@ -0,0 +1,3 @@ +#!/bin/bash +bash scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh +bash scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh diff --git a/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh b/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh new file mode 100644 index 0000000..77a6412 --- /dev/null +++ b/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh @@ -0,0 +1,48 @@ +#!/bin/bash +set -e + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 8 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 7 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs diff --git a/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh b/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh new file mode 100644 index 0000000..5ce67c1 --- /dev/null +++ b/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -e + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --dropout 0.4 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored --dropout 0.4 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 8 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored --dropout 0.4 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 7 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored --dropout 0.4 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs From 666ad4d68bae88dc0e323e57d946849128a13cac Mon Sep 17 00:00:00 2001 From: maria Date: Thu, 6 Aug 2026 23:12:48 +0300 Subject: [PATCH 46/70] Set PYTHONPATH inside the scripts --- scripts/run4_all_sequential.sh | 3 ++- scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh | 3 ++- .../run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/run4_all_sequential.sh b/scripts/run4_all_sequential.sh index 97f9bae..21e4665 100644 --- a/scripts/run4_all_sequential.sh +++ b/scripts/run4_all_sequential.sh @@ -1,3 +1,4 @@ #!/bin/bash +export PYTHONPATH="$PWD" bash scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh -bash scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh +bash scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh \ No newline at end of file diff --git a/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh b/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh index 77a6412..eaa304f 100644 --- a/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh +++ b/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh @@ -1,5 +1,6 @@ #!/bin/bash set -e +export PYTHONPATH="$PWD" python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ @@ -45,4 +46,4 @@ python scripts/compare_forward_tokenizers.py \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ - --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs \ No newline at end of file diff --git a/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh b/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh index 5ce67c1..feb6190 100644 --- a/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh +++ b/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh @@ -1,5 +1,6 @@ #!/bin/bash set -e +export PYTHONPATH="$PWD" python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ @@ -46,4 +47,4 @@ python scripts/compare_forward_tokenizers.py \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ - --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs \ No newline at end of file From 166b4857921a771ea516a47fc5d76fe200dc5424 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 7 Aug 2026 00:26:20 +0300 Subject: [PATCH 47/70] Fix encode_wordpiece silently truncating on overflow --- irrm_codec/wordpiece_tokenization.py | 11 +++++++++-- .../run4a_individual_maxlen_maxtokenlen9_anchored.sh | 12 ++++++------ ...ndividual_maxlen_maxtokenlen9_anchored_dropout.sh | 12 ++++++------ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py index e9df86f..de8af24 100644 --- a/irrm_codec/wordpiece_tokenization.py +++ b/irrm_codec/wordpiece_tokenization.py @@ -33,11 +33,18 @@ def load_wordpiece_tokenizer(path) -> Tokenizer: def encode_wordpiece(seq, tokenizer, max_len): - """Encode a CDR3 sequence into exactly max_len ids: truncated or PAD-padded at the end.""" + """Encode a CDR3 sequence into exactly max_len ids: PAD-padded at the end. + + Raises on overflow (matches encode_wordpiece_anchored and the char tokenizer's + gap_pad_cdr3) rather than silently truncating - a silently truncated sequence would + lose real information every epoch without any warning. + """ seq = "" if seq is None else str(seq).strip().upper() if not seq: raise ValueError("Sequence must not be empty.") - ids = tokenizer.encode(seq).ids[:max_len] + ids = tokenizer.encode(seq).ids + if len(ids) > max_len: + raise ValueError(f"Sequence '{seq}' encodes to {len(ids)} WordPiece tokens, exceeds max_len={max_len}.") return ids + [PAD_ID] * (max_len - len(ids)) diff --git a/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh b/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh index eaa304f..47afc5b 100644 --- a/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh +++ b/scripts/run4a_individual_maxlen_maxtokenlen9_anchored.sh @@ -13,7 +13,7 @@ python scripts/compare_forward_tokenizers.py \ python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ --embeddings-path data/raw/trb_background_embeddings.parquet \ - --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --locus beta --max-len 11 --batch-size 512 --epochs 40 \ --max-token-len 9 --pad-layout anchored \ --seeds 1 \ --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ @@ -22,7 +22,7 @@ python scripts/compare_forward_tokenizers.py \ python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ --embeddings-path data/raw/trb_background_embeddings.parquet \ - --locus beta --max-len 8 --batch-size 512 --epochs 40 \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ --max-token-len 9 --pad-layout anchored \ --seeds 1 \ --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ @@ -33,17 +33,17 @@ python scripts/compare_forward_tokenizers.py \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ --embeddings-path data/raw/trb_background_embeddings.parquet \ - --locus beta --max-len 7 --batch-size 512 --epochs 40 \ + --locus beta --max-len 9 --batch-size 512 --epochs 40 \ --max-token-len 9 --pad-layout anchored \ --seeds 1 \ - --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ - wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ - wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs \ No newline at end of file diff --git a/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh b/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh index feb6190..a81311c 100644 --- a/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh +++ b/scripts/run4b_individual_maxlen_maxtokenlen9_anchored_dropout.sh @@ -14,7 +14,7 @@ python scripts/compare_forward_tokenizers.py \ python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ --embeddings-path data/raw/trb_background_embeddings.parquet \ - --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --locus beta --max-len 11 --batch-size 512 --epochs 40 \ --max-token-len 9 --pad-layout anchored --dropout 0.4 \ --seeds 1 \ --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ @@ -23,7 +23,7 @@ python scripts/compare_forward_tokenizers.py \ python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ --embeddings-path data/raw/trb_background_embeddings.parquet \ - --locus beta --max-len 8 --batch-size 512 --epochs 40 \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ --max-token-len 9 --pad-layout anchored --dropout 0.4 \ --seeds 1 \ --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ @@ -34,17 +34,17 @@ python scripts/compare_forward_tokenizers.py \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs python scripts/compare_forward_tokenizers.py \ --airr-path data/raw/trb_background_100k.tsv \ --embeddings-path data/raw/trb_background_embeddings.parquet \ - --locus beta --max-len 7 --batch-size 512 --epochs 40 \ + --locus beta --max-len 9 --batch-size 512 --epochs 40 \ --max-token-len 9 --pad-layout anchored --dropout 0.4 \ --seeds 1 \ - --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ - wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ - wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_dropout0.4_40epochs \ No newline at end of file From 67f05c1292096a39b6ece8f24cc69866b39906a1 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 7 Aug 2026 13:48:26 +0300 Subject: [PATCH 48/70] Fix the epoch-curves notebook silently dropping anchored-padding runs --- .../convergence_curves_by_epoch_report.ipynb | 475 ------------------ 1 file changed, 475 deletions(-) delete mode 100644 notebooks/convergence_curves_by_epoch_report.ipynb diff --git a/notebooks/convergence_curves_by_epoch_report.ipynb b/notebooks/convergence_curves_by_epoch_report.ipynb deleted file mode 100644 index 0d0d8f1..0000000 --- a/notebooks/convergence_curves_by_epoch_report.ipynb +++ /dev/null @@ -1,475 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4b450bf4", - "metadata": {}, - "source": [ - "# Convergence curves — char vs every WordPiece vocab_size in the grid\n", - "\n", - "Reads the per-epoch history files `scripts/compare_forward_tokenizers.py` writes under\n", - "`/history/*.json`, and plots train/val loss vs epoch as one small subplot\n", - "per config (char + every vocab_size, and every `--max-token-len` variant present).\n", - "\n", - "Interpretation goes in markdown cells, not on the plots themselves." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "11f2b459", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-02T09:59:31.035596Z", - "iopub.status.busy": "2026-08-02T09:59:31.035596Z", - "iopub.status.idle": "2026-08-02T09:59:31.045291Z", - "shell.execute_reply": "2026-08-02T09:59:31.045291Z" - }, - "tags": [ - "parameters" - ] - }, - "outputs": [], - "source": [ - "# parameters\n", - "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_background100k_40epochs_upto30k\"" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "379bff96", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-02T09:59:31.045291Z", - "iopub.status.busy": "2026-08-02T09:59:31.045291Z", - "iopub.status.idle": "2026-08-02T09:59:32.720511Z", - "shell.execute_reply": "2026-08-02T09:59:32.720511Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "18 runs across 6 configs\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizemax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_pathmax_token_len
0char254010.2023770.8644000.191109331122.7319380.54961410850856NaNNone
1char2540420.2001860.8663640.191719371121.6011780.56569110850856NaNNone
2char25407770.2025250.8641060.199392361122.4595360.54959510850856NaNNone
3wordpiece10004010.2298820.8445520.224929361142.9400600.55186710913256artifacts/tokenizers_1M_integ/wordpiece_vocab_...None
4wordpiece100040420.2330810.8430240.225724371143.0590100.55277210913256artifacts/tokenizers_1M_integ/wordpiece_vocab_...None
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size max_len seed test_loss test_cosine \\\n", - "0 char 25 40 1 0.202377 0.864400 \n", - "1 char 25 40 42 0.200186 0.866364 \n", - "2 char 25 40 777 0.202525 0.864106 \n", - "3 wordpiece 1000 40 1 0.229882 0.844552 \n", - "4 wordpiece 1000 40 42 0.233081 0.843024 \n", - "\n", - " best_val_loss epochs_to_best_val train_time_sec inference_time_sec \\\n", - "0 0.191109 33 1122.731938 0.549614 \n", - "1 0.191719 37 1121.601178 0.565691 \n", - "2 0.199392 36 1122.459536 0.549595 \n", - "3 0.224929 36 1142.940060 0.551867 \n", - "4 0.225724 37 1143.059010 0.552772 \n", - "\n", - " num_parameters tokenizer_path \\\n", - "0 10850856 NaN \n", - "1 10850856 NaN \n", - "2 10850856 NaN \n", - "3 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", - "4 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", - "\n", - " max_token_len \n", - "0 None \n", - "1 None \n", - "2 None \n", - "3 None \n", - "4 None " - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import json\n", - "from pathlib import Path\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import pandas as pd\n", - "\n", - "results_dir = Path(RESULTS_DIR)\n", - "raw = pd.read_csv(results_dir / \"raw_results.csv\")\n", - "if \"max_token_len\" not in raw.columns:\n", - " raw[\"max_token_len\"] = None # older raw_results.csv, from before --max-token-len existed\n", - "\n", - "print(f\"{len(raw)} runs across {raw[['tokenizer','vocab_size','max_token_len']].drop_duplicates().shape[0]} configs\")\n", - "raw.head()" - ] - }, - { - "cell_type": "markdown", - "id": "1431d8f3", - "metadata": {}, - "source": [ - "## Load per-epoch history for every run" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "7b0dc511", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-02T09:59:32.720511Z", - "iopub.status.busy": "2026-08-02T09:59:32.720511Z", - "iopub.status.idle": "2026-08-02T09:59:32.779079Z", - "shell.execute_reply": "2026-08-02T09:59:32.779079Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loaded 1440 (config, seed, epoch, split) rows from history/\n" - ] - } - ], - "source": [ - "def history_filename(row):\n", - " \"\"\"Mirrors compare_forward_tokenizers.py's run_one() naming exactly, so this stays in\n", - " sync with whatever that script actually wrote - no separate parsing of filenames.\"\"\"\n", - " label = \"char\" if row[\"tokenizer\"] == \"char\" else f\"wordpiece_{int(row['vocab_size'])}\"\n", - " max_token_len = row[\"max_token_len\"]\n", - " suffix = f\"_n{int(max_token_len)}\" if pd.notna(max_token_len) else \"\"\n", - " return f\"{label}{suffix}_seed{int(row['seed'])}.json\"\n", - "\n", - "\n", - "records = []\n", - "missing = []\n", - "for _, row in raw.iterrows():\n", - " history_path = results_dir / \"history\" / history_filename(row)\n", - " if not history_path.exists():\n", - " missing.append(history_path.name)\n", - " continue\n", - " with open(history_path) as f:\n", - " history = json.load(f)\n", - " for entry in history:\n", - " for split in (\"train\", \"val\"):\n", - " records.append({\n", - " \"tokenizer\": row[\"tokenizer\"],\n", - " \"vocab_size\": row[\"vocab_size\"],\n", - " \"max_token_len\": row[\"max_token_len\"],\n", - " \"seed\": row[\"seed\"],\n", - " \"epoch\": entry[\"epoch\"],\n", - " \"split\": split,\n", - " \"loss\": entry[split][\"loss\"],\n", - " \"cosine\": entry[split][\"cosine\"],\n", - " })\n", - "\n", - "history_df = pd.DataFrame.from_records(records)\n", - "if missing:\n", - " print(f\"Missing {len(missing)} history file(s), e.g. {missing[:5]} - those runs are skipped below.\")\n", - "print(f\"Loaded {len(history_df)} (config, seed, epoch, split) rows from history/\")" - ] - }, - { - "cell_type": "markdown", - "id": "e468bfa2", - "metadata": {}, - "source": [ - "## Loss vs epoch, one subplot per config" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "a04f58e1", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-02T09:59:32.779079Z", - "iopub.status.busy": "2026-08-02T09:59:32.779079Z", - "iopub.status.idle": "2026-08-02T09:59:33.447848Z", - "shell.execute_reply": "2026-08-02T09:59:33.447848Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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Y3H55Zfjww8/xNSpU3HVVVft93UPPPAA+vbti1dffVVtkyZNws6dO9vkLyT9l4x6HQLBEHaWO9rkMxARtSZmarRwtob01KhwMKhBRNSSgsEglixZolZWDRs2DP369dvn85ctW4YtW7bU25eQkICjjjqqbTI13D4EQiHooWvV309E1NnJuV1IcGLPCazExMQGXxPef8ghh+DRRx9Vt0855RTk5eXhwQcfxMknn9zg62655RZcd9119TI1miuwkRkJauzOBCEiouYh52/J1Fi1ahWio6OxdOlSlZl37LHHqp5MDXn//fdx22234YcffsC0adPUvm3btqnswLZg0OvQPdGGHWVO5JQ4MDCd5UKIqHNr86CGTEC9/fbbkRS/008/HUZj0z7Wr7/+ql4rA8ieFxcH8r7N2Sw8v9KFcgY1iIhaTFVVlQpGyKqoIUOGYNGiRarx6/3339/oa1566SV88cUXatVtmEw8tXZQI9wo3O7yq1VVJmaJExE1KykzlZKSghUrVqjJqTC5f/DBBzf4GpnQ6t+/P3r37l1vf3Z2NhYvXtzo77JYLGprCeGgRkk1G8ASETX34qj33nsPd9xxhzr/C8namDBhAt55551GgxqSpTFr1qxIQEP06dOnzZuFS1BjB/svEVEX0KblpzZv3qwCDtKkz2Qy4Z///KeaUGpKZLuiogJ//etf8frrr2PevHnN9r4t0Vejwsla6URELUVWSMkK3HXr1uG7777DN998oy4yZNXUvsjqq3fffTeyPfTQQ63+R4oENdw+BNnQj4ioRUgvjJdffhmlpaXqvowTEtQ477zzIs95/PHHMXv27Mj9iy66CJ9++ikqKyvV/erqalV6SkqStIXM2kbhJdUeFQQnIqLm670kmXWyOKquoUOHYs2aNY2WKZRx5PDDD1fXIG+99Zbq09RYWcMw6bskv6vu1pyykrQAuCyuJSLq7No0qHHzzTdj0KBB+Oqrr/Cvf/0Lc+fOxfz581WGxf7Ihcb555+PXr16Nev7NqfEqN210omIqPmFQiF1ESFjgtQvD5cLGTduHN588839Bsc/++wzFRgPT1q1VVDD6Q3A7W2bVHUios7u7rvvVpkXssn4cNJJJ+Hee+9V40WYTFxJo9ew66+/Xj1XaqVLIENW36anp+ORRx5pk39DZrwtsliqxs1rCyKi5hIOLOxZkjApKanR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x1sCem126Rtl7ecmsURE1DskG89htcBh3XZ5XVlcJYFzf0jOL6KJYIdkUeR54iXeewGDGkREHQVQ3Hn6Fh6qZ3pIOaq+TrHuqUyQQcDtdqvARWckcyM5cHHppZf20ScjIur/wEdnkktcbV4CS05CMjs6iyEiogHDbDbBDGnsKrcs8Dikybin0zFDxgsJfEu5ESk/InXTiYhocDF1WF63bayIJC2uctt773yCZypERFuzefYEERHRADohsUh1Rq60JSKiLowZVosJOR672iaD5VeJiGjLscJmka33F+lyGTAREREREREREREREaUFBjWIiIiIiIiIiIiIiCgtMKhBRERERERERERERERpgUENIiIiIiIiIiIiIiJKCwxqEBERERERERERERFRWmBQg4iIiIiIiIiIiIiI0oK1vz9AqtI0TV02Nzf390chIkoZxjHROEYOZhwniIi2xHGC4wQR0dZwnOA4QUTUE+MEgxqdaGlpUZdlZWVb3YFERIP1GJmdnY3BjOMEEdHWj5EcJ3g+QUTEcYLnE0REvXE+YdK43LZDsVgMFRUVyMzMhMlk2iJiJMGODRs2ICsra7v+YQYT7i/uL/6NDZz/J2XIkIFl6NChMJsHdwVDjhM9h+ME91dv499Y3+0vjhNtOE70HP4/zP3V2/g31nf7i+NEG44TPYf/D3N/9Tb+jaXeOMFMjU7ITistLd3qTpZ/FAY1uo77q3u4v7qP+6xv9tdgX3lr4DjR8/j/MPdXb+PfWN/sL44TOo4TPY//D3N/9Tb+jfXN/uI4oeM40fP4/zD3V2/j31jqjBODe5ktERERERERERERERGlDQY1iIiIiIiIiIiIiIgoLTCosR0cDgf+9Kc/qUvi/upp/PviPutt/BvrfdzH3F/8+0ot/H+S+yvV8G+S+4t/X6mF/09yf6Ua/k1yf/HvK7Xw/8nU219sFE5ERERERERERERERGmBmRpERERERERERERERJQWGNQgIiIiIiIiIiIiIqK0wKAGERERERERERERERGlBWt/f4B0EggEcNddd+Gzzz5DZmYmzjzzTBx22GH9/bFSRnV1NR566CG8//77OOWUU/CLX/yiw+fcdtttWLJkCUpKSvCb3/wGM2bMwGD03Xff4bHHHsOKFSswbNgwnH322Zg1a1a750SjUTzwwAN46623YLVaccIJJ+C0007D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7LNaZmamNmXKFK2oqEibMWNGpxPSg019fb124IEHqs3j8WgjRoxQ1y+88MJ2z7vhhhtUcGjmzJlqX8okfSAQ0Aab2267TZOY4vTp0xP7TbZDDjmk3fM+/PBDrbCwUBs3bpxWVlamjRo1Slu8eLE22Ph8Pm3u3LkqCDZnzhy1P/Lz87U777xzi7/DvfbaSx0gZd+63W7t/vvv77fPneqDi7jyyisT/0/K/7unnHKKFgqF+uUzDgQcJzrHcaJ7OE50D8eJHcdxom9wnOgcx4nu4TjRPRwndhzHib7BcaJzHCe6h+NE93CcSL9xwiT/2bFcj8FF+hksWrQImZmZquyU1AAjvbnLxx9/vMWukPpou+22W7v7qqurVZ21kpISjB07dlDuPunPsnLlyi3ul3JmBxxwwBbpglJCSerU7bzzzrBYLBispDbfkiVLkJOToxqFOxyODp8nz5GafVOmTFHPpbbahrNmzdpid0gJrxUrVqC0tBSjRo3i7tpBHCc6xnGiezhObB+OE9uP40Tf4TjRMY4T3cNxYvtwnNh+HCf6DseJjnGc6B6OE9uH40T6jBMMahARERERERERERERUVow9/cHICIiIiIiIiIiIiIi6goGNYiIiIiIiIiIiIiIKC0wqEFERERERERERERERGmBQQ0iIiIiIiIiIiIiIkoLDGoQEREREREREREREVFaYFCDiIiIiIiIiIiIiIjSAoMaRERERERERERERESUFhjUIBrAnnjiCRxxxBH9/TGIiChFcZwgIiKOE0RExPMJSjcMahANYA0NDVi9enV/fwwiIkpRHCeIiIjjBBER8XyC0g2DGkRERERERERERERElBYY1CDqBatWrcIvfvEL7LzzzjjooINw9913IxaLbVHu4/nnn8dRRx2lnnfxxRfD6/W2e5/58+fjhBNOwLRp03DooYfixRdf7PBn/fKXv8TMmTNx+OGH4/XXX9/iOS+//DKOOeYY7LbbbrjwwgvR1NTEf3cion7EcYKIiDhOEBERzyeItpNGRD1q1apVWn5+vvb73/9e++qrr7TXX39dmzx5sva73/0u8Zy7775bs1gs2rRp07R33nlHe+utt7SJEydqP/nJTxLP+fHHHzWHw6FdfPHF2rx587Q77rhDs9vt2gsvvJB4zvLly7WcnBzttNNO0z788EPtzTff1I444ghtzZo1iZ9jtVq1/fffX/vggw/UJp/lZz/7Gf/ViYj6CccJIiLiOEFERDyfINp+DGoQ9bCzzz5bO+OMM9rd99lnn6kgRiAQSAQbJKa4ePHixHPmz5+v7luyZIm6ffrpp2sHHHBAu/e56KKLtClTpiRuy8+ZNWvWFp8hEokkfo4EQurq6hKPPfLII1pRUVGP/b5ERNQ9HCeIiIjjBBERbS+eTxBpmnV7MzyIqGOffPIJWltbMWXKFAkaqi0cDiMajaqm3ZMmTVLPKywsxOTJkxOv23XXXZGRkYFvv/1WPWfhwoX46U9/2u69Dz74YNxzzz0IhUKw2+347LPPcPbZZ2/xGSwWS+J6WVkZ8vLyEreHDh2K6upq/vMREfUTjhNERMRxgoiIeD5BtP0Y1CDqYX6/H2eccQbmzp27xWOjRo1KXHc6nVs87nK51OuN95Hbmz8uvTkCgYAKagSDQbjd7q1+HquV/5sTEaUSjhNERMRxgoiIeD5BtP0420nUwyZMmIAVK1Zg4sSJW31eZWUlGhoakJubq25XVVWhpqYGY8eOVbfl8vvvv2/3mkWLFqGoqAhZWVnqtvyMBQsW8N+QiCiNcJwgIiKOE0RExPMJou1n3oHXElEHLr74Yrzyyiu4//77VekpsWbNGlx55ZXtnheJRHDFFVeozAu5fumll6qyU3vttZd6/Pzzz8czzzyjSkwJKV11xx13qPsNF110EZ599lk8//zz6raUuHrggQewceNG/tsQEaUojhNERMRxgoiIeD5BtP0Y1CDqYUcddRQeeeQRXH/99cjOzkZxcbHqhTFt2rR2zxsxYgR8Ph8KCgpUz4vPP/8cjz/+OMxm/X/L448/XgVCDjnkENUHQwIeBx10ULvgyLHHHot7771XBTry8/NVn45vvvlGXRIRUWriOEFERBwniIiI5xNE288k3dJ34PVEtBWSMSG9MyRwkUyafcu2dOlS1R9DSk9JQ28joJFMHq+oqFCBiszMzA5/jmRoyM+S0lTJfTgaGxtViavkXh4SSFm/fv02y2MREVHv4zhBREQcJ4iIiOcTRN3DnhpEvai0tHSbz5Ggh2RtbO3x0aNHb/U9LBZLh++Rk5OjtmTSWJwBDSKi1MBxgoiIOE4QERHPJ4i6h+WniIiIiIiIiIiIiIgoLbD8FFE/6KgsFBEREccJIiLi+QQREXHeiWjrGNQgIiIiIiIiIiIiIqK0wPJTRERERERERERERESUFhjUICIiIiIiIiIiIiKitMCgBhERERERERERERERpQUGNYiIiIiIiIiIiIiIKC0wqEFERERERERERERERGmBQQ0iIiIiIiIiIiIiIkoLDGoQEREREREREREREVFaYFCDiIiIiIiIiIiIiIjSAoMaRERERERERERERESUFhjUICIiIiIiIiIiIiKitMCgBhERERERERERERERpQUGNYiIiIiIiIiIiIiIKC0wqEFERERERERERERERGmBQQ2iHbBgwQI8+OCD3IdERMRxgoiIiIiIiKgPMKhB1EdBDZ/Ph2uvvRatra3c50REgwTHCSIiIiIiIqKeZe3h9yOiFBUKhfDGG29g+fLlGD58OI455hi4XK52z5k/fz4++OADZGZm4oQTTkBxcXGfPk5ERP3r/fffV4GYgoICNU7k5eW1e5zjBBEREREREfU3ZmoQ9RG3260yNTIyMvp8n//444+YOnUqHn74YVRXV+P222/HxIkTUVFRkXjOPffcgwMPPBBr1qzBa6+9hsmTJ6vX9dXjRESDXX+OE7FYDHvuuSduvfVWNU48++yzGDVqFBYuXJh4DscJIiIiIiIiSgUmTdO0/v4QRD3hs88+w7p16/DTn/40sdpU7vv9738Pk8mEjRs34rHHHsNVV12VeI1M1nz66adwOp04+OCDMXLkyMRjd9xxh1qlumrVKixatAgnnniievyll17C2rVrMXPmTKxYsUKVn/ryyy/R3NysXnPRRRfh7bffRmVlJfbdd1/1PKP81F//+ldceuml7SasZNWrvF6yJg4//HAMGzas3e/19ddfY968eWqy66STTlJZDl19rWH9+vXqUjI0RCQSUUEOeb8bbrgBTU1NKCkpwX/+8x+ccsop6jnymDzvxRdf7PXHiYj6AseJzscJ+TooY9306dMT9x155JEoLCxUAXGOE0RERERERJQqmKlBA4YEDS655JLE7b/85S+47rrr8N1336nb//vf/1SwwSCrUffbbz8sXboUH330kZrkf/311xOPS4Di6KOPxj/+8Q+0tLSo+4499lhcccUVKkAiwRLJeDBIUEN+3j777IM333xTva9cf+ihhxKfTx5P7qnx29/+Fscff7wKnEhwRSaTJIBhuPDCC3HYYYdh8eLF6nH5vFJGqiuvTSbBDCOgIaxWK7KyshCNRtXtjz/+WK3SlfczSHBI9pfc39uPExH1BY4TnY8TEvxPDmgYY4UE/QXHCSIiIiIiIkoV7KlBA8bee++NxsZG/PDDDxg/frzKYDjzzDPxzjvvYMaMGXj33Xdx0EEHqedKFoUEJSSIISWRjCDI+eefr7I9DJJpcd9996nrUjJJVvlKECE3N1dNxicHGQxz585VAQex//7749e//nUieySZBFIeeeQRFfwwekv87W9/w+WXX64ek0wTCYjI7yMlQIRkhsjE07Zeuy2vvPKKWpErmRNiw4YNKCoqgt1uTzyntLQUfr8fdXV1vf64rAQmIuptHCe2PU5I2anvv/9ejREShP/Tn/6k7uc4QURERERERKmCQQ0aMGQ16Zw5c1TwoqamBlOmTFGZAZJpcfHFF6tJnKuvvlo999tvv1Ulm4yAhpDG1VdeeSU2bdqEIUOGqPsOPfTQxOOyulUyLySgIcxmsypP9fzzz7f7HMcdd1ziumR2nHbaaSoYIeWXksmqV3mvf/7zn4n7JNjyzTffqOuffPKJqm9uBDTEuHHjuvTarZH9IMEeCYpIXwuDBEuSGZXpjPt7+3Eiot7GcaJr44QcnyVLQ0oXLl++PDF+cZwgIiIiIiKiVMCgBg0okolhBDWkR4ZkUpxxxhkqQCB23XXXxIRNVybTJfCRrLMJna09pzNS+kkmjZLJxJH03JAskK21u9nWayXg0hEpi3XqqaeqDBAJ4hjKyspQVVWlsk6MbIry8nL1++fl5fX640REfYXjxNbHiZNPPlltQpqWSwbjkiVLOE4QERERERFR6pBG4UQDxVdffaVlZGRoM2fO1D755BN135w5c7R9991XO+644xLPKy8v12w2m/bBBx8k7rvlllu0srKyxO1hw4Zpb7zxRuL2K6+8ouXl5WkNDQ3qdiwW0/bZZx9t9913V7c3bNggUQjtrrvuSrzmmWee0XJycjS/36/V1NSoxysrK9Vj7777rlZQUKDuTzZ//vzE4263W1u9enXisRUrVmihUGibr+3ICy+8oGVnZ2uvv/76Fo81NjZqLpdLe/rppxP3nXjiidqxxx7bJ48TEfUVjhMdjxNr167V6uvr29131VVXadOmTVPXOU4QERERERFRqmCmBg0ou+yyC2w2myqXsfvuuydW5V5//fW45557Es8bOnSouk9KRZ1++umqybc0En/66ac7fe+jjjoKe+yxh3pfuT5//nxUV1cjJyen3fPuv/9+LFy4EA6HA48//rjqdSElT5IbhAspfSVZJNKYVT6HfG7JKJGSV5JRIo+fddZZ2G233dSqWclykLJZn3/++TZfuzl5zU9+8hPV40PKaBmNYqX8lLx3dna26ily7rnnqvJUUjtd+ofIJnr7cSKivsJxouNxQnpSHX300Zg5c6Yqwbh48WLV2+mZZ55Rj3OcICIiIiIiolRhkshGf38Iop706KOPIhKJ4Oc//7m6LQGOJ598UjXwlubUyRYsWIBPP/1UBR2kXFVy/4o77rhD9cwYO3Zsu7JPL730EtauXasmxjIzM9V7yHtv3LhRleeQskoycS89LqTRuDxP+Hw+/PWvf1UlojIyMhLvKYGKL774Qn1mef60adPafUYjCCETSieeeGK3XmuQZuOb9/5IDmoYJFAjk1jye8nPMpqQ99XjRER9geNExyTA/8orr6hxTIL/hx9+OPLz89s9h+MEERERERER9TcGNYh6iBHUaGho2CJ7g4iIiOMEERERERER0Y7ruEskERERERERERERERFRimFQg6iHZGVl4U9/+pMqZUVERMRxgoiIiIiIiKjnsfwUERERERERERERERGlBWZqEBERERERERERERFRWmBQg4iIiIiIiIiIiIiI0gKDGkRERERERERERERElBas/f0BUlUsFkNFRQUyMzNhMpn6++MQEaUETdPQ0tKCoUOHwmwe3HFxjhNERFviOEFERERERL2NQY1OSECjrKys1/8BiIjS0YYNG1BaWorBjOMEEVHnOE4QEREREVFvYVCjE5KhYZyQZWVl9do/ABFROmlublYBX+MYOZhxnCAi2hLHCSIiIiIi6m0ManTCKDklAQ0GNYiIOj5GDmYcJ4iItn2MJCIiIiIi6mmDuyA6ERERERERERERERGlDQY1iIiIiIiIiIiIiIgoLTCoQUREREREREREREREaYFBDSIiIiIiIiIiIiIiSgsMahARERERERERERERUVqwIg3U1dXh2WefRVVVFaZOnYrjjz8eZnPn8Zg//elPCAaDW9w/a9YsnHDCCb36WWMxDdUtQdgsJuRnOHr1ZxERUZs1a9aocWLChAnIzc3d6q755JNPEI1Gt7i/pKREvZ6IiIiIiIiIiFKTNR0mqfbcc0+MHz8eu+22Gy655BI8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YKYGERF1ZES8p0Zlox+apnEnERERERERERFtA4MafRLUCCASjfXmjyIiojTO1KhsDiAQ5jhBRERERERERLQtDGr0otJcfbLKF4qiqpklqIiIqL2hOS5YzSZEohrW13u5e4iIiIiIiIiItoFBjV7ksltQmOlQ11fWtPbmjyIiojRkMZtQmudS11dWc5wgIiIiIiIiItoWBjV62Yh4Cao1NVyBS0REWxoZ76uxppbjBBERERERERHRtjCo0cuGx+ulb2zw9/aPIiKiNDSyQA9qbKj39fdHISIiIiIiIiJKeQxq9FGz8IpGBjWIiKjzcaK8kb2XiIiIiIiIiIi2hUGNvgpqNHGyioiItjSygMFvIiIiIiIiIqKuYlCjj4Iam5r80DStt38cERGlmeHxnhqVTQGEItH+/jhERERERERERCmNQY0+CmpUtwThDUV6+8cREVGaKctzwQTAH44yq4+IiIiIiIiIaBsY1OhlhZkOOKxmxDRgbQ2bwBIRUXsOqwUl2U51fWV1K3cPEREREREREdFWMKjRy0wmE8ri2RqrajlZRUREWxqRr5egWl3t5e4hIiIiIiIiItoKBjX6wIh4UGNtHTM1iIio82bhGxs4ThARERERERERbQ2DGn3AyNSobPT3xY8jIqI0zdTY2MigBhERERERERHR1jCo0YfNwisY1CAioq1k9FU0Brh/iIiIiIiIiIi2gkGNPgxqVDZxsoqIiDrP1JDgdzSmcRcREREREREREXWCQY0+MDy/LajBySoiIupsnGgORFDbEuQOIiIiIiIiIiLqBIMafaAsV5+sag1GUN3CbA0iImovw2FFQYZdXV9R3cLdQ0RERERERETUCQY1+oDLbkFhhkNdX1nd2hc/koiI0szwPL0E1aoab39/FCIiIiIiIiKilMWgRh+XFlnDySoiIurAyAJ9nFhfz6AGEREREREREVFnrEgDS5cuxQMPPICqqipMnToVv/nNb5CRkbHV10SjUTzzzDN4//334Xa7cc4552DnnXdGfzYL/2ZdAzY0+PrtMxARDWQrVqxQ48TEiRNRUFDQpdeEQiEsWrRIjROTJk2CyWRCfxkRz9Qob/D322cgIiIiIiIiIkp1KZ+psWDBAuyyyy6or6/H3nvvjeeff15dBoOdN1KVxxULPjUAAHoRSURBVA499FD86U9/wvTp09V2wQUX4Ntv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xrqmpiatXLlSVVVV/T6ns7NTq1ev1tq1a9Xd3a2xzH5++7dn+8J+1/qzfft2vfnmm2ptbT2ir2+kCoVCevXVV93vUV/q6ur0xhtvqLy8/Ii/ttGIdeLgWCcGh3VicFgnDg3rBAAAAIB4QqgxCE888YRKS0t1+eWX65RTTtGiRYsOejJ6LLH9cMstt2jGjBk655xzdM899/T5vJ/97GeaMGGCrrnmGs2ePVtXXHGFOjo6NNZs2bJFl1xyiaZMmaLrrrvO7bcLLrjAnVyOtXTpUk2dOlUf+tCHtHjxYh1zzDHatGmTxqLHHnvM7aeLL77Y7buSkhLdcccdB5z8O++88zR//nxdddVV7jmPPPKIxrof//jHOvPMM93v2v6+//3vu+PaJz/5SU2bNk3XXnuturq6huV1jgasE/1jnRgc1onBY504dKwTAAAAAOIJocYA2RXMV155pb7+9a+7K8X37t3rTsZ/9rOfHdq/oThhlRllZWV655133InnvixZskS33XabHn/8ca1bt04bNmzQCy+84N5IjzVbt27Vxz/+cRdiWOXPjh073HbTTTf1upr50ksvdSfxd+3apX379mn69Onu93Asqq+vd1VA9ruzceNG3X///fryl7/sKl0i7P7u3bvd/rLn3HnnnfrUpz41ZoOgSDBm+8oCxP099dRT+sEPfqBnnnnGVb+sWbNGf/3rX3XXXXcNy2uNd6wTB8c6MTisE4PHOnFoWCcAAAAAxJ1uDMgdd9zRnZOT0x0IBKKPPfroo91JSUndNTU17MUYc+fO7f7qV796wD655ppruk899dRej916663dU6ZMYf91d3d/97vf7S4rK4vui7/85S/dCQkJ3fv27Ys+9sorr1j/qe6VK1eO+X1WVVXl9sXf/vY3ty/8fn93RkZG99133x3dN6FQqLu0tLT7G9/4xpjcX/X19d3Tpk3rfv7557tvvPHG7pNOOqnXn19yySXd5557bq/HPvvZz7p/wxg81omBY504NKwTg8M68e5YJwAAAADEIyo1BsiuBj/22GOVkpISfcxaUFmblrfffnuoMqdRtw9POumkXo/ZPrSrd+3qyrHOZhrMnDmz1/6ytkDWrit2f0X+bCyqrq7WK6+8oieffNJVupx11lmu3ZSxyoy2trZev2MJCQlasGDBmN1f119/vav2Ofvsswf1b3L9+vUKBAJH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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "def config_label(tokenizer, vocab_size, max_token_len):\n", - " if tokenizer == \"char\":\n", - " return \"char\"\n", - " label = f\"wordpiece {int(vocab_size)}\"\n", - " if pd.notna(max_token_len):\n", - " label += f\" (max_token_len={int(max_token_len)})\"\n", - " return label\n", - "\n", - "\n", - "configs = (\n", - " history_df[[\"tokenizer\", \"vocab_size\", \"max_token_len\"]]\n", - " .drop_duplicates()\n", - " .sort_values([\"tokenizer\", \"vocab_size\", \"max_token_len\"], na_position=\"first\")\n", - " .to_records(index=False)\n", - ")\n", - "\n", - "n = len(configs)\n", - "ncols = min(4, n)\n", - "nrows = int(np.ceil(n / ncols))\n", - "fig, axes = plt.subplots(nrows, ncols, figsize=(4 * ncols, 3 * nrows), squeeze=False)\n", - "\n", - "for ax, (tokenizer, vocab_size, max_token_len) in zip(axes.flat, configs):\n", - " subset = history_df[\n", - " (history_df[\"tokenizer\"] == tokenizer)\n", - " & (history_df[\"vocab_size\"] == vocab_size)\n", - " & (history_df[\"max_token_len\"].isna() if pd.isna(max_token_len) else history_df[\"max_token_len\"] == max_token_len)\n", - " ]\n", - " for split, color in [(\"train\", \"tab:blue\"), (\"val\", \"tab:orange\")]:\n", - " split_data = subset[subset[\"split\"] == split]\n", - " per_epoch = split_data.groupby(\"epoch\")[\"loss\"].agg([\"mean\", \"std\"])\n", - " ax.plot(per_epoch.index, per_epoch[\"mean\"], color=color, label=split)\n", - " if per_epoch[\"std\"].notna().any():\n", - " ax.fill_between(per_epoch.index, per_epoch[\"mean\"] - per_epoch[\"std\"].fillna(0),\n", - " per_epoch[\"mean\"] + per_epoch[\"std\"].fillna(0), color=color, alpha=0.15)\n", - " ax.set_title(config_label(tokenizer, vocab_size, max_token_len), fontsize=9)\n", - " ax.set_xlabel(\"epoch\")\n", - " ax.set_ylabel(\"loss\")\n", - "\n", - "for ax in axes.flat[n:]:\n", - " ax.axis(\"off\")\n", - "\n", - "axes.flat[0].legend(fontsize=8)\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "3109807f", - "metadata": {}, - "source": [ - "*Notes: line = mean across seeds, shaded band = std across seeds (band is flat/invisible\n", - "with only 1 seed). Train and val loss diverging within a config is the usual overfitting\n", - "signal; a val curve still trending down at the last epoch means that config likely hasn't\n", - "converged yet.*" - ] - }, - { - "cell_type": "markdown", - "id": "d1c44955", - "metadata": {}, - "source": [ - "## Loss vs epoch, all configs overlaid (val split only)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "7a5eab55", - "metadata": { - "execution": { - "iopub.execute_input": "2026-08-02T09:59:33.447848Z", - "iopub.status.busy": "2026-08-02T09:59:33.447848Z", - "iopub.status.idle": "2026-08-02T09:59:33.665460Z", - "shell.execute_reply": "2026-08-02T09:59:33.665460Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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kyY1+HlPhMPNEhERkauSsPT73mwtfOTZwocthMiFu3G0NAlL0mUpLlQboSxO5qGxrWVQA2d+Mi6tE9IiILlQryWQ4/1lxzH1fUh3R7nwV6HBx1PVO0QE+NRq/XM1FotVtdJI0BCJUdXBtKU5mWtipwYLnQQAmSFbJr+Li4urdZ/MQzF27FiYTCb8/LM25nhNycnJtWoijve8J8JgQURERC2NXNbJ/C1wO/GgBEStMli4IgYLIiIiImrrCk8iWJxaCT4REREREZEBgwURERERETUagwURERERETUagwURERERETFYEBERERGR87HFgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGo3BgoiIiIiIGs2z8U/ROlmtVrUuLCx09qEQERERETmFfi2sXxsfD4NFPYqKitQ6ISGhKX82REREREQt8to4JCTkuI9xszYkfrRBFosF6enpCAoKgpub20knOwkkaWlpCA4OPm3H2BbwXPJcuhq+JnkuXRFflzyProavydZzLiUqSKiIi4uDu/vxqyjYYlEPOXHx8fGN+kHID5/BomnwXDYdnkueR1fD1yTPpavha5Ln0hUFO/G68kQtFToWbxMRERERUaMxWBARERERUaMxWJwGPj4+ePzxx9WaeC5dBV+XPI+uhq9JnktXw9ckz6Ur8mlB15Us3iYiIiIiokZjiwURERERETUagwURERERETUagwURERERETUa57E4DQ4ePIjs7Gz07NkTgYGBp+NLtHp//vlnranju3TpoiZnoRPbu3cvMjIyMHLkyHons9m9ezdKSkrQp08feHt787TWwWw2Y8OGDQgICEBSUpLDfRUVFVi3bl2tfyOPCwsL4/k0kN/lAwcOoKysDImJifD19a3z/GRmZuLQoUPo2LEjoqOjeQ7rIK87+d2VMeU7dOhQawLXv/76CwUFBQ77oqKi0KNHD57PGuT9b8+ePYiIiFDnsr7zvX37dvUewHNYv2PHjuHo0aPqdzc8PLzWffv27av1b0aPHs3XZD3k77f8HZf3y3bt2tW6X86n/J737t0bfn5+cCky8zY1jaKiIuvkyZOtAQEB1h49eqj1Rx99xNN7Cjw8PKxJSUnWUaNG2ZevvvqK5/IE5s+fbx0zZow1LCxM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ZGdnqwv6r7/+GkOGDLF3UXr66afVBb6fnx8sFosKIV988QWmTp1qDwOXXXYZfvvtN/U8EgwkeCxcuBBRUVH2r3XXXXfh/fffV6GjvLwcnp6e+OmnnxAcHKweU1BQgDFjxsDHx0dtr1mzBl9++aX96xARUdNiVygiImoScpEvF/Z79uxRa7mQv+mmm3DNNdc4PC4jIwPTp0/HH3/8gZUrV+If//iHelxZWZm6/5133sHy5ctV4JAC7J07d8JkMuHhhx+2P8esWbPwwQcfYPXq1Vi2bBlWrVqFF154ARUVFfbHHDt2DPfff78KKLLcfvvtePTRR/nTJiI6TRgsiIioSXz00Ufo16+futCfO3cuvvrqKwQGBmLXrl2q5UInLQh33HGHfVsu/jMzM7FixQq1La0XV111FTp06KC2g4KCcOedd6rWBt3s2bNVYJGvpxsxYoS9RUPI7Ysvvti+PX78eOzevZs/bSKi04RdoYiIqEkcPHgQlZWVmDdvnsP+yy+/XO3XSc2E3j1JSPiQECC1GULWl1xyicNzJCYmorCwEHl5eQgLC0NqaiqmTZt23OMJDw932JavaWzRICKipsVgQURETUJqG84880zVJel48vPzHbalXkL2RUZGqm1Z5+bmOjxGtr28vOz1E6GhocjJyeFPjojIhbArFBERNYmzzz4bn3/+OYqKihz2y8hPRhIipOZBJ3UUUsStF3iPHj0a3333ndqnk65V0tVJH/Vp0qRJqmuUsSWkpKQEpaWl/GkSETkJWyyIiKhJPPbYY1iyZIkKCDNnzlTDzEoBd0pKir1+QgQEBKj6CKmbkPDw3HPPqdsJCQnq/kceeUQFiSlTpuCiiy5Shdnz5893CCNShL1o0SIVNq699lo1KtScOXNUSDEOb0tERM2HLRZERNQkpKZh7dq1uO+++9RITtu3b8eECROwdOlSh8fFx8erUaOkXkIe9/LLL+PFF1+03x8dHa1GhBo5cqQaOUrqLzZu3IihQ4faHyPdpdavX68CisxjIUPLSm2H1G+I7t2749xzz3X4ujJkrdR7EBHR6eFmlc6tREREzeCNN95Qi4wURURErQtbLIiIiIiIqNEYLIiIqNnU1UWJiIhaB3aFIiIiIiKiRmOLBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERNRqDBRERERERobH+H+v/R72O46JgAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(8, 5))\n", - "val_data = history_df[history_df[\"split\"] == \"val\"]\n", - "\n", - "for tokenizer, vocab_size, max_token_len in configs:\n", - " subset = val_data[\n", - " (val_data[\"tokenizer\"] == tokenizer)\n", - " & (val_data[\"vocab_size\"] == vocab_size)\n", - " & (val_data[\"max_token_len\"].isna() if pd.isna(max_token_len) else val_data[\"max_token_len\"] == max_token_len)\n", - " ]\n", - " per_epoch = subset.groupby(\"epoch\")[\"loss\"].mean()\n", - " style = \"--\" if tokenizer == \"char\" else \"-\"\n", - " ax.plot(per_epoch.index, per_epoch.values, style,\n", - " label=config_label(tokenizer, vocab_size, max_token_len), linewidth=1.5 if tokenizer == \"char\" else 1)\n", - "\n", - "ax.set_xlabel(\"epoch\")\n", - "ax.set_ylabel(\"val_loss\")\n", - "ax.set_title(\"val_loss vs epoch, all configs\")\n", - "ax.legend(fontsize=7, ncol=2, loc=\"upper right\")\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "644f5c19", - "metadata": {}, - "source": [ - "*Notes: same data as the small-multiples grid above, just overlaid for a direct\n", - "side-by-side comparison of convergence speed and final level. `char` is dashed to stand\n", - "out from the WordPiece vocab_size curves.*" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.15" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From adef5a20b560662bc93e298f86bede348be6821b Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 7 Aug 2026 13:50:12 +0300 Subject: [PATCH 49/70] Fix the epoch-curves notebook silently dropping anchored-padding runs --- .../convergence_curves_by_epoch_report.ipynb | 479 ++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 notebooks/convergence_curves_by_epoch_report.ipynb diff --git a/notebooks/convergence_curves_by_epoch_report.ipynb b/notebooks/convergence_curves_by_epoch_report.ipynb new file mode 100644 index 0000000..d70187b --- /dev/null +++ b/notebooks/convergence_curves_by_epoch_report.ipynb @@ -0,0 +1,479 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4b450bf4", + "metadata": {}, + "source": [ + "# Convergence curves — char vs every WordPiece vocab_size in the grid\n", + "\n", + "Reads the per-epoch history files `scripts/compare_forward_tokenizers.py` writes under\n", + "`/history/*.json`, and plots train/val loss vs epoch as one small subplot\n", + "per config (char + every vocab_size, and every `--max-token-len` variant present).\n", + "\n", + "Interpretation goes in markdown cells, not on the plots themselves." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "11f2b459", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-07T10:45:11.022647Z", + "iopub.status.busy": "2026-08-07T10:45:11.022478Z", + "iopub.status.idle": "2026-08-07T10:45:11.026871Z", + "shell.execute_reply": "2026-08-07T10:45:11.025929Z" + }, + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "# parameters\n", + "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "379bff96", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-07T10:45:11.028653Z", + "iopub.status.busy": "2026-08-07T10:45:11.028088Z", + "iopub.status.idle": "2026-08-07T10:45:11.689406Z", + "shell.execute_reply": "2026-08-07T10:45:11.688584Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "15 runs across 15 configs\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tokenizervocab_sizemax_token_lenpad_layoutmax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_path
0char25NaNend4010.1976780.8678360.192469331148.3492790.55189410850856NaN
1wordpiece10009.0anchored1110.2223790.8500600.21952925815.8021140.47294910913256artifacts/tokenizers_2026-08-01_fine_grid/word...
2wordpiece20009.0anchored1010.2357470.8407430.22957027800.5669070.49776610977256artifacts/tokenizers_2026-08-01_fine_grid/word...
3wordpiece29989.0anchored1010.2424570.8358470.24023038792.8189000.46958711041128artifacts/tokenizers_2026-08-01_fine_grid/word...
4wordpiece39869.0anchored1010.2504180.8304160.24791538793.6826300.47194111104360artifacts/tokenizers_2026-08-01_fine_grid/word...
\n", + "
" + ], + "text/plain": [ + " tokenizer vocab_size max_token_len pad_layout max_len seed test_loss \\\n", + "0 char 25 NaN end 40 1 0.197678 \n", + "1 wordpiece 1000 9.0 anchored 11 1 0.222379 \n", + "2 wordpiece 2000 9.0 anchored 10 1 0.235747 \n", + "3 wordpiece 2998 9.0 anchored 10 1 0.242457 \n", + "4 wordpiece 3986 9.0 anchored 10 1 0.250418 \n", + "\n", + " test_cosine best_val_loss epochs_to_best_val train_time_sec \\\n", + "0 0.867836 0.192469 33 1148.349279 \n", + "1 0.850060 0.219529 25 815.802114 \n", + "2 0.840743 0.229570 27 800.566907 \n", + "3 0.835847 0.240230 38 792.818900 \n", + "4 0.830416 0.247915 38 793.682630 \n", + "\n", + " inference_time_sec num_parameters \\\n", + "0 0.551894 10850856 \n", + "1 0.472949 10913256 \n", + "2 0.497766 10977256 \n", + "3 0.469587 11041128 \n", + "4 0.471941 11104360 \n", + "\n", + " tokenizer_path \n", + "0 NaN \n", + "1 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", + "2 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", + "3 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", + "4 artifacts/tokenizers_2026-08-01_fine_grid/word... " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import json\n", + "from pathlib import Path\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "results_dir = Path(RESULTS_DIR)\n", + "raw = pd.read_csv(results_dir / \"raw_results.csv\")\n", + "if \"max_token_len\" not in raw.columns:\n", + " raw[\"max_token_len\"] = None # older raw_results.csv, from before --max-token-len existed\n", + "if \"pad_layout\" not in raw.columns:\n", + " raw[\"pad_layout\"] = \"end\" # older raw_results.csv, from before --pad-layout existed\n", + "\n", + "print(f\"{len(raw)} runs across {raw[['tokenizer','vocab_size','max_token_len']].drop_duplicates().shape[0]} configs\")\n", + "raw.head()" + ] + }, + { + "cell_type": "markdown", + "id": "1431d8f3", + "metadata": {}, + "source": [ + "## Load per-epoch history for every run" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "7b0dc511", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-07T10:45:11.691106Z", + "iopub.status.busy": "2026-08-07T10:45:11.690952Z", + "iopub.status.idle": "2026-08-07T10:45:11.699331Z", + "shell.execute_reply": "2026-08-07T10:45:11.698549Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 1200 (config, seed, epoch, split) rows from history/\n" + ] + } + ], + "source": [ + "def history_filename(row):\n", + " \"\"\"Mirrors compare_forward_tokenizers.py's run_one() naming exactly, so this stays in\n", + " sync with whatever that script actually wrote - no separate parsing of filenames.\"\"\"\n", + " label = \"char\" if row[\"tokenizer\"] == \"char\" else f\"wordpiece_{int(row['vocab_size'])}\"\n", + " max_token_len = row[\"max_token_len\"]\n", + " filter_suffix = f\"_n{int(max_token_len)}\" if pd.notna(max_token_len) else \"\"\n", + " pad_layout = row.get(\"pad_layout\", \"end\")\n", + " layout_suffix = f\"_{pad_layout}\" if pad_layout != \"end\" else \"\"\n", + " return f\"{label}{filter_suffix}{layout_suffix}_seed{int(row['seed'])}.json\"\n", + "\n", + "\n", + "records = []\n", + "missing = []\n", + "for _, row in raw.iterrows():\n", + " history_path = results_dir / \"history\" / history_filename(row)\n", + " if not history_path.exists():\n", + " missing.append(history_path.name)\n", + " continue\n", + " with open(history_path) as f:\n", + " history = json.load(f)\n", + " for entry in history:\n", + " for split in (\"train\", \"val\"):\n", + " records.append({\n", + " \"tokenizer\": row[\"tokenizer\"],\n", + " \"vocab_size\": row[\"vocab_size\"],\n", + " \"max_token_len\": row[\"max_token_len\"],\n", + " \"pad_layout\": row.get(\"pad_layout\", \"end\"),\n", + " \"seed\": row[\"seed\"],\n", + " \"epoch\": entry[\"epoch\"],\n", + " \"split\": split,\n", + " \"loss\": entry[split][\"loss\"],\n", + " \"cosine\": entry[split][\"cosine\"],\n", + " })\n", + "\n", + "history_df = pd.DataFrame.from_records(records)\n", + "if missing:\n", + " print(f\"Missing {len(missing)} history file(s), e.g. {missing[:5]} - those runs are skipped below.\")\n", + "print(f\"Loaded {len(history_df)} (config, seed, epoch, split) rows from history/\")" + ] + }, + { + "cell_type": "markdown", + "id": "e468bfa2", + "metadata": {}, + "source": [ + "## Loss vs epoch, one subplot per config" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a04f58e1", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-07T10:45:11.700786Z", + "iopub.status.busy": "2026-08-07T10:45:11.700646Z", + "iopub.status.idle": "2026-08-07T10:45:12.009374Z", + "shell.execute_reply": "2026-08-07T10:45:12.008530Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABjUAAASlCAYAAADgeltjAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Qd4FGXXBuAnvfcQCCH03nvvXVQQFAtiwYYF62eBz/4rYm+fKKIUFRXBriBI7733HhJCCOm9Z//rvLO77Ca7IUCS3WSf+7qG7ZvJbJh3Z857znHS6XQ6EBERERERERERERER2TlnW68AERERERERERERERFReTCoQURERERERERERERE1QKDGkREREREREREREREVC0wqEFERERERERERERERNUCgxpERERERERERERERFQtMKhBRERERERERERERETVAoMaRERERERERERERERULTCoQURERERERERERERE1QKDGkR25LXXXsMtt9xi69Ugompu6tSpmDhxoq1Xo9oaPXo0Fi5ciJpi7dq1CA0NtcnPljFNxjZ79NBDD+Hjjz+GPbnhhhvw9ttv23QdVq5ciTp16th0HajycZy4NhwnKg7HiSvDcYKqCseJa8NxouJwnLgyNzjQ8QSDGkRERA5s69at8PX1tfVq2NX2OHz4MG699VZbrwpVwcH69OnTkZWVZfU5ffv2hZOTk82CQvZADkhkG/Ts2dPWq0I2wnGi9PbgOOEYOE6UD8cJ4jhhjuOE4+A4YdtxgkENIiIiByZfLDIzM23yswsLC9WXG8Py7LPPlnrOwYMH0a9fP3h6eqJBgwaYOXNmhT5e0ueff44777wTzs72+RVp48aNCAwMtPVqVAtpaWkqGyM8PBw+Pj646aabEBcXZ3y8cePGaNGiBRYtWlTm+3z11VdITEyEo7pw4YLaBuS4bDlOSNBxxowZaNmypQrAd+7cGb/++qvZczhOmOM4UX4cJyoGxwmy93Hit99+Q4cOHeDl5YVmzZrhhx9+uKLH//jjD3Ts2BHe3t6IiIjA008/jfz8fKvrxOOJmoPjhH2PE/Z5xE5EREQ1nqurK3Q6nVqGDBlS6vGcnByMGjVKHUScP38es2fPxgsvvKAOLCri8ZKKi4vx559/YuTIkZX8m1NVkIDG/v37sXnzZpw9exYeHh4qsGFqxIgRpQ58ich+LF68WJ2wkv22HBDL/+vbbrsNO3fuVI9znKBrwXGCqOaPE5I1IRnYMqNeJqlI6dH7778f69atK9fjUVFRGD9+PCZPnqwe/+eff9R3x3feecfi+vB4ombhOGHfGNQgsoF58+ahffv28PPzw4ABA3DkyBHjY9nZ2Xj44YdVelZYWBhefvll42Nff/21cUazlMKQwffixYvGx6VuuZzAe/DBB1G3bl3ccccdVf67EZG55557Dvfcc4/x9rBhw9T/bzmRLz755BOzE/oHDhxQtwMCAtCoUSO8+uqrKqNB5Obmqv//n376qZpNJCdp5Yv2jz/+qGYVBQUFYezYsWb7BUM/hXfffVe9X0hIiPqibii5YyldfMuWLejfv79aB5nN/t577xnXV8hJYtl3ScaAzIqSQEB5X3sllixZgpSUFLXuwcHB6gS0ZFHMmjWrQh4vSfbFMhtHtm3J7ff666+r30dm/N977704c+YMrr/+ejVjq2nTpli1apXxNSdPnjTuq+X5UsJo165dxsfff/999Rr5WSI6Olp9Lr/88kuZ20MO1CTrRF5neH9D74+//voLnTp1Up9lmzZtsGDBAqvvs2HDBjVGGF4rM83k70zWyd/fH4MGDVIzn03rsj7++OOqNrB85g0bNiw1g628qupnyf+Z33//HS+++KL6u5fPULb79u3bsWPHDuPzZDaf/B+4EjJGG7Z/vXr18MwzzyAvL6/cv4M8V7aB/J+V/ydy4J2UlGR8PDY21uprMzIy8Mgjj6hZgvI3M27cOJw7d87sZ0+ZMkX9bcr+QH5nCejJ9wHD94r77rvP+LcnJPDTu3dv9Xl0794d27Ztu8KtTdeK44T1cUL2t2+++abKqpL9m/z/k/93Mg4JjhPmOE6UH8cJjhPVCceJqx8nJAAh33Pku5B8L5fvSPI9S7IpyvP40aNH1aW8r3zvl/M41113Hfbt22dxfXg8weOJ8uDxRAXREVGVmjt3ri4kJES3ZMkSXXp6um7dunW6119/XT326quv6pycnHRz5szRZWZm6jZv3qzz9PTUbdq0qdT7xMXF6e644w7d+PHjjffJ6+W/9cyZM9Xricj2li1bpqtbt666npubq/P399c1aNBAt2/fPnXfDTfcoHvrrbfU9dTUVF1YWJju+eef16WkpOh27dqla9iwoe7//u//1OM5OTnq/3iPHj10J06cUPft2LFD5+Hhofvll1/UPuX777/XOTs76+688071+Jo1a9Rrbr75Zl18fLx6XefOnXWPPPKIenzLli06Hx8f4/oeP35c3ZZ9VUZGhm7//v26pk2bqtviyJEjar/08ccf65KTk3VHjx7VPfTQQ+V6bVmGDBmi+89//mN230svvaR+V1OzZ8/WhYeHV8jjJS1fvtxsW5huv8cee0z9vocOHdIFBQWpz3TFihVqX/v222/rIiIiLL6nfCYffPCBLjIyUn3+BqNHj9aNGzdOl5eXp9bxiSee0JXHhg0bdAEBAWb3yd+Jm5ubbsGCBern/fHHH+oz+vfff42/g4w7Qv4+5Pdfv3698fWPP/64Wgf53eRze//999X6ZmVlqcevv/56XWBgoG7VqlXqPvk8vby81N/o5cjfnYxNFfWzXnzxRfV5WFvuuece9byCggK1Tf766y/jz46OjlbP+fLLL433bd++Xd0nn4Mlffr00X311VcWHysuLlZ//926ddO98847xvsv9zs8+uijurZt2+p27typS0tL0/3000+6efPmleu1EyZMUNvv5MmT6v/zrbfequvUqZOuqKjI+Hr5G/7nn390+fn5apGfJf/f5fmy3HTTTep9hPwM+dt94YUX1M+Q7VGvXj1d7dq1zX5X2QYl/y9RxeE4Ub5xQpw5c0aNcfL9WXCcKI3jBMcJjhM1D8eJqx8nnn32Wd2AAQPMniPfn5o1a1aux+X7kXzvnzVrli47O1t38OBBdXz2448/Wvz5PJ7g8URJPJ6ovOMJBjWIqpicfHjvvfcsPiYnfvr162d2X//+/XWfffaZxeefPXtWnbiSEyuG13ft2rUS1pqIrpZ8+ZWgg5zEXblypa5v377qBLmczJUTr35+fupEouGEs3xpLiwsNBv869evbxbUkPcxmDJligpwmpJAScmghpzMND0w8vb2VvuOkkENCSyYBksN6zB48GB1/emnn1YnTi253GuvNKghJ/qHDx9udt+iRYuM63utj5f3IEROjpue9B4zZowxkCMSEhLUNr5w4YLV369Ro0ZqWxvIAZIcEHXs2FHXvXt3qyfVy3OySgIFsk6m7r//fnVAZhrUePPNN3VNmjRRJ+IN5KS3/H7btm0ze32LFi10S5cuVdfl85bP3ZRsp61bt15RUKOyf1ZJEjjq1auXOrhNTExU/09k4oDpGGwIasi6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kpKizuvWrVvqCiQistfvSD8/P9gzxgkiotK/IxknuD1BRMQ4we0JIqLK2J5w0PFw22Ll5+cjMjISPj4+cHBwKJIxkmTHxYsX4evre1VvjD3h+uL64mes+vyflJAhgSU0NBSOjvbdwZBxouIwTnB9VTZ+xqpufTFOXME4UXH4f5jrq7LxM1Z164tx4grGiYrD/8NcX5WNnzHrixOs1CiBrLQ6deqUupLlTWFSw3xcX+XD9VV+XGdVs77s/chbPcaJisf/w1xflY2fsapZX4wTGsaJisf/w1xflY2fsapZX4wTGsaJisf/w1xflY2fMeuJE/Z9mC0REREREREREREREdkMJjWIiIiIiIiIiIiIiMgmMKlxFdzc3PDiiy+qc+L6qmj8fHGdVTZ+xiof1zHXFz9f1oX/J7m+rA0/k1xf/HxZF/6f5PqyNvxMcn3x82Vd+H/S+tYXB4UTEREREREREREREZFNYKUGERERERERERERERHZBCY1iIiIiIiIiIiIiIjIJjCpQURERERERERERERENoFJjXI4deoUhg0bBl9fX4SFheG5555Dbm5u5b07NiQvLw/Lli3DDTfcAFdXV8ycObPYx23cuBHdunWDt7c3mjZtii+//BL2KCMjA5988gm6dOkCPz8/tGrVCu+++65aj8aio6MxceJE+Pv7IygoCPfddx9SU1Nhj44dO4bJkyer/3uyLq677jps3rzZ5DE6nQ6vv/466tevDx8fHwwcOBAHDhyAvVu1ahVcXFzQo0ePIvetW7cOnTt3hpeXF1q0aIEffvjBIstYXTBOlIxxonwYJ8qPceLqMU5UHcaJkjFOlA/jRPkxTlw9xomqwzhRMsaJ8mGcKD/GCRuLEzoyS3p6uq5Bgwa6W265RRceHq7bsmWLLjg4WPfss89yDep0utWrV+tGjhypW7Vqla5ly5bFrpdTp07pPD09dTNnztRFR0frFi5cqHN1ddUtWLDA7tbhN998o3vkkUd0u3fv1iUlJenWrl2r8/f3182aNcvwmPz8fF2PHj10ffv21Z0+fVp34MABXbNmzXQTJkzQ2aM777xTt2jRIvXZiYyM1D322GM6Dw8P3fnz5w2Peeedd3R+fn66devWqcfcfffduqCgIF18fLzOXkVEROjq1q2rGzhwoK5z584m9x08eFD9H3zttdd0MTExuh9++EHn7Oys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dWuVXJBqiQkTJqh5Gps3b8acOXNMHicVF1OnTsWjjz6qHicVGvPmzTPc3759e6xZswbr16/HkCFD8Pnnn+OLL77AbbfdZniMJEC2bt2KiIgIjB49Go8//jhGjhyJRo0aqfu9vLxM5nYINzc3Nd+DiIgsg3GCiIgYJ4iIiNsTRFfPQaalX8PziegqfPbZZ+p07Ngxrj8iImKcICIibk8QEVGF4X4nqu5YqUFERERERERERERERDaBSQ0iCyiuLRQRERHjBBERcXuCiIi434modGw/RURERERERERERERENoGVGkREREREREREREREZBOY1CAiIiIiIiIiIiIiIpvApAYREREREREREREREdkEJjWIiIiIiIiIiIiIiMgmMKlBREREREREREREREQ2gUkNIiIiIiIiIiIiIiKyCUxqEBERERERERERERGRTWBSg4iIiIiIiIiIiIiIbAKTGkREREREREREREREZBOY1CAiIiIiIiIiIiIiIpvApAYREREREREREREREdkEJjWIiIiIiIiIiIiIiMgmMKlBREREREREREREREQ2gUkNIiIiIiIiIiIiIiKyCUxq2KA5c+bg9ddft/Ri2Ky33noLy5cvR3Wxb98+jB492iKv/eKLL+L777+HNXr55ZexZs0aWJPnnnsO8+fPt+gy7N69G2PHjrXoMlDlY5y4NowTFYdxonwYJ6iqME5cG8aJisM4UT6ME1RVGCeuDeNExWGcKJ/n7Gi/E5MaNujMmTM4evSoWY89cuQIhg0bVunLZCvOnz+Pjz76CAMHDkR1kZiYiC1btljktQ8fPoxz587BGg0aNAhPPvkk8vPzS3zMww8/jAEDBlRZUujgwYO4cOECLCkhIQFbt241XJdAI+vgwQcftOhyUcVinLh6jBMVi3GifBgnqKowTlw9xomKxThRPowTVFUYJ64e40TFYpwon4N2tN+JSY1qrk6dOpgxY4ZFA6HsWB4xYgTuu+8+7Nmzp8iX/aOPPorhw4fjnnvuKZKsOXv2LB577DF1/6RJk7Bs2bIir/HXX39h8uTJGDVqFH744YdSl2f27NkYM2YMfHx8YI3ky+fGG2+09GLYDMk+33rrrerzJcmq3Nxcw319+/ZFTk4O/vzzzxKfv3fvXnTt2hXPPPMM7NVTTz2l1kHh/5tkPywdJ/SioqIwZMgQ9Z1vbpyQaiz5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RERERC6BSQ0iIiIiIiIiIiIiInIJTGoQEREREREREREREZFLYFKDiIiIiIiIiIiIiIhcApMaRERERERERERERETkEpjUIGrEvvnmG1x22WWO3gwiInJSjBNERMQ4QUREPJ8gV8OkBlEjlpWVhSNHjjh6M4iIyEkxThAREeMEERHxfIJcDZMaRERERERERERERETkEpjUILKBw4cP484770Tv3r0xcuRIzJgxA5WVlTXKffz000+44oor1OumTp2KgoICk6+zceNGXHfddejRowcuueQS/Pbbb2Y/66677kKfPn0wevRozJ8/v8Zr/vjjD1x11VXo378/pkyZgpycHH7fiYgciHGCiIgYJ4iIiOcTRGdJR0QN6vDhw7qoqCjd008/rduwYYNu/vz5ui5duuj+85//GF4zY8YMnZeXl65Hjx66xYsX6xYtWqTr1KmT7sYbbzS8Zu/evTo/Pz/d1KlTdevXr9e9/fbbOl9fX90vv/xieM2BAwd04eHhurFjx+qWL1+uW7hwoe6yyy7THT161PA53t7euuHDh+uWLVumLrItEyZM4HediMhBGCeIiIhxgoiIeD5BdPaY1CBqYBMnTtTdeuutJo+tXr1aJTGKi4sNyQbJKe7evdvwmo0bN6rH9uzZo+7fcsstuhEjRph8nQcffFDXrVs3w335nAEDBtTYhvLycsPnSCIkIyPD8NysWbN0MTExDfb/JSKi+mGcICIixgkiIjpbPJ8g0um8z3aFBxGZt3LlSuTn56Nbt26SNFSXsrIyVFRUqKbdnTt3Vq9r0qQJunTpYnhfv379EBwcjG3btqnXbN26FePGjTP52hdffDHef/99lJaWwtfXF6tXr8bEiRNrbIOXl5fhdkJCAiIjIw334+LikJqaym8fEZGDME4QERHjBBER8XyC6OwxqUHUwIqKinDrrbdi0qRJNZ5r3bq14ba/v3+N5wMCAtT7ta8j96s/L705iouLVVKjpKQEgYGBtW6Ptzd/zYmInAnjBBERMU4QERHPJ4jOHkc7iRpYx44dcfDgQXTq1KnW1yUnJyMrKwsRERHqfkpKCtLS0tCuXTt1X6537txp8p4dO3YgJiYGoaGh6r58xpYtW/g9JCJyIYwTRETEOEFERDyfIDp7nufwXiIyY+rUqfjzzz/x6aefqtJT4ujRo5g2bZrJ68rLy/H444+rlRdy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siQy60J+t+WPtvr8H+R3VdsH8rPRvXt3k8+Qr2/pvUePHlVLf+XnQH7fjX/Gtc/29fVVP+/9+/dXM0d2796NlStXqlkl8nna779G/hDbtWsXOnXqZPK7TPbBOGE5TtQVB+p63vh4IINYltT1vIZxgnHCGowT1NAYJyzHibrOB+qKE56enoa/q82VXigoKFB/i8ms3ClTphgSJTLRyBzGCcYJazBO0LliXLAcF+o6rtf1fF3jSHW9v664VB3jBuOGNRg3zg5XapwjSRoYl7Z4/PHHVcZJli6LL774Qg1gaiRJIX84y8zyn3/+GV27dlXL34xnlF500UXquZKSEpUFloHZd955R/1xLf0gjPtpyKC8HHDPP/989Qe9XPr06aMGRc311JBBz6uvvhr3338/Tp48id9//13NdpftEXJAloFwGeSXwVV5Xsue1fXeunz88ccq4SKD7SI0NLTGa2QgWXtcmjxLcNCW8Xl5eanSUfPnz7fq61cnSSIJUMalp7T9J7P8JdG0ceNGtf/kpEa+jzJA//LLL2PChAlmv6YksO666y71fdVIgJSyR7KEXUgC5K233jIJnPUhPwdSHkkCpATPN998UyULcnJyzJ6YyeoEGcQeMWKEemz16tUqMSLbc+rUKZUAM+41IQPlEsDl/yvPy/bKz6BOp6v3tp7rZ0nCTL4fli7aMlH5vUhMTFQzIjSSrJJEgCTkNG3btq115U5t5OddZunJz+DWrVut/j9IckGSB99//73axokTJ6o/SjWzZs2y+F55nfxOSeJTtlsSQm+//bbJZ8vSPNmncvIu5GdLfn4lgSqJC9kP8rupkQSrbIMcP+QEXwZ3yb4YJyzHibriQF3Pa7755hs1w0r+GJQ4Vl1dz2sYJxgn6oNxghoK44TlOFHX+YC1ccISiQvyt7ac48iAlJxPyPfDUiKccYJxoj4YJ+hsMS5YP850ruoaR6quvuNUjBuMG/XBuFFPOjonBw4c0Hl7e+vy8vJ0R48e1cXFxelGjx6t++WXX9TzXbp00X3//ffq9rp163Q+Pj66gwcPGt4/adIk3YgRI9TtoqIiGdnUvfnmm4bn3333XV3nzp11paWlhte0atVKd8stt6j7y5YtU+/5888/De956aWXdN26dVO3165dqwsKCjI89/nnn+vat2+vKywsNDx2//336+644w51+5NPPtE1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wIEDUVlZiSuvvBKLFi3C0KFDUVRUZPE9xcXFGDFihBrUuuCCC9Tlsccew5YtW2BvzcL94eEBFJdVIqOg1O6fT0TU2D333HPYvXu3WqmxdetW/Pzzz3j00UexZs0ai+9ZunSpSnq/99576r0bN27Ea6+9hoyMDNibj5cnmoWx/xIRkS3NmzcPl1xyCXr16oXx48fjyJEjdb4nKysLTz75JAYNGqTOLb7//nuHfJM8PDzYV4OIyMZOnDiBl156CQ888AA++eQTlJRYN9lo/vz5+L//+z88++yz6nzE0VVCWNKWiNyF0yc1nnjiCYwaNQofffSRmkkrAePYsWP44osvLL7nlVdewd69e7FixQpMnjwZt9xyC5YtW4b27dvD3vy8vRAb4q9un2QTWCKiBjdr1ixMmjQJMTEx6r6s2pBBq6+++srie1588UVceumlGDdunOGxwYMHo3Pnzo5tFp5pOWFPRERnR84frrnmGlx88cX44IMP1OSoYcOGqaSFJZmZmWpilaz2fvXVV9VFEiOrV692yLchIbIqTvB8goiowUkp2p49e6qJsLLqWyY+STK7rKys1uog1157raoMEhYWpi5jxozBrl27HNtXI5N9NYjIPXjDicmKi3///dckgREeHo6LLroICxcuVBl0c2bOnKlmYEVHRxse8/T0REhICByheUQATucWq3rpPRPCHbINRESN0cmTJ5GWloY+ffqYPC73t23bZvY9MutKBqXeffddNWglSXApQ9W6detaP0veZzxjKzc3t0FPQtYfzeRycSIiG3j++edVEltm0or+/fujadOm+Pjjj9UEKnNkxq30Xfrrr78QEKBPKEiSQwaxHDoDl4NVREQN7vHHH1fnD7/88otaHXfbbbepc4PZs2fjjjvuMPued955B0uWLFGrviURIqRsekFBgUP7L3GSFBG5C09nX/5XUVGB+Ph4k8clYBw9etTse2SAKikpSc3SlVIiN954Ix566CHVCLY2MlAlA1TGl4aegXsymxlzIqKGpM2yjYyMNHk8KirK4gxcaSQug1ISF7p166ZKVfXt21eVKqytp4bM0tVmYclFO3lpCAmG5eJcqUFE1JDy8/PV8V5W52l8fX0xcuRItZLbEik1JWUKtYSGxtvb26EzcBOzeD5BRNSQJIEtZc5llYUkNESzZs0wfPhw/PnnnxbfJ4lxmUxr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LrvsMtWA3DSxsXPnTmRkZPDnSkRkpxgniIiIcYKIiHg8QXT6uFODqIHdfffd2L17NwYNGoSzzz5b9dfYsmULJk6ciClTppiVknrnnXfw22+/qaTH8uXL8emnn8Lf31/df8cdd+D3339H7969MWrUKPU1pD/HK6+8Yvwa99xzj7pdHiPfSxIlUtZk6dKl/LkSEdkpxgkiImKcICIiHk8QnT6ddAs/g+cTUS0OHDiAjRs3wsvLCwMGDEBMTIzZrgw5bd68GWvXrsXx48dVz40OHTqYfQ359Vy9ejXi4uLQokULlbgwbRxusH37dmzbtk2VNJEEiOExklzZtWsXLr30UuNjk5KSVJPaU5XHIiKixsU4QUREjBNERMTjCaL6Y1KDyAYMSY19+/Zx/ImIiHGCiIh4PEFERJx3IrISe2oQEREREREREREREZFDYE8NIhsYM2aM6qlBRETEOEFERDyeICIizjsRWY/lp4iIiIiIiIiIiIiIyCGw/BQRERERERERERERETkEJjWIiIiIiIiIiIiIiMghMKlBREREREREREREREQOgUkNIiIiIiIiIiIiIiJyCExqEBERERERERERERGRQ2BSg4iIiIiIiIiIiIiIHAKTGkRERERERERERERE5BCY1CAiIiIiIiIiIiIiIofApAYRERERERERERERETkEJjWIiIiIiIiIiIiIiMghMKlBREREREREREREREQOgUkNIiIiIiIiIiIiIiJyCExqEBERERERERERERGRQ2BSwwEcPnwYe/futfXLaLaOHj2qxri5yM7Oxpo1a2zyvXfv3o34+HjYoy1btiAnJwf2ZOfOnUhISLDpa8jKysLatWtt+hrozDFONC7GiYbDOFE/jBPUUBgnGhfjRMNhnKgfxgkiInJWTGo4gI8//hgvvPCCVY/Nzc3F6tWrG/01NReVlZWYPHkyUlJS0Fxs27YNU6ZMscn3njVrFj7//HPYoyVLluCJJ56o8zFbt27FqlWrmiwp9Oijj2L+/Pmwpc2bN2PatGnG65LgkDGQJBA5DsaJxsM40bAYJ+qHcYIaCuNE42GcaFiME/XDOEFERM7KzdYvgBrWsWPH8OKLL6oJ3Kam1+vx999/G69HR0ejffv2tT7+33//hZ+fH3r37m08IPjnn39qPG706NFW3W+a2NmzZw8iIiLQrl27Ol/zggUL1GsY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NWqUiitNhXGCiIiIiKhubrBzzzzzDHbv3q1W0bZv3x579+7Fq6++imHDhhkfs2fPHqxfv97seX///TcOHTpk1aqqhhTqq21jP5pR0KTfl4jIWfXt21ftxJCEhnz2T58+HbfffrtZWZH+/fvXWDG7a9cuXHTRRZg2bZpN4kRChnkpFCIiahzS62LEiBEqiT1kyBB89NFH6rjCNPn93nvvqeMJiQ2mpWyXLFmCL774okl/NDyeICIiIiJy8KSG7LKQ3RkHDhxQW7+7du2KsLAws8fcf//9xiaABjExMfjrr7/Qp0+fJn29sWHarpB4TlYRETWZLl26qF17tbnllltq3HbOOeeoU1OLCdXixNFMJr+JiJqCJLY3bdqkkhmyQ++CCy7AXXfdpXZxGMgxg6+vr9nzduzYgalTp6pkuU3iBI8niIiIiIgcM6lhIFu+a9v2LYmO6qRGrjV1chtaTKh2MMSdGkREZEl0iDZZxZ0aRERNp3v37pg9e3at98sOv+qknKGcmhqTGkREREREDt5Tw9HEVq2sSsktQVFpha1fDhER2RnDZFVybjFKyhkniIjI8iKpE7nFKC5jnCAiIiIiqo5JjQYW5OOBAC9tA0xCJuulExGRuVBfD/h6uEKvB45lFXF4iIjITLCPO/yrjicSeTxBRERERFQDkxqNIDZMW10Vz2bhRERUjU6nYwkqIiKqM04YdvWxTx8RERERUU1MajQC9tUgIqK640RVXw2uwCUiIh5PEBERERHVC5MajdhX42gGy08REVFdyW/GCSIishAnQng8QURERERUGyY1GkEbHoQQEVEdoqviREJmAceJiIhq3dF3lDv6iIiIiIhqYFKjEbCnBhERWbMCl+WniIio7h19TH4TEREREVXHpEYjrqw6nl2E0vLKxvgWRETUDHb0SVJDr9fb+uUQEZGdHk8kZRWhvILHE0REREREppjUaAThfp7w8XBFpR44lsV66UREZC4q2BuuLjoUl1UiNa+Ew0NERGYi/b3g6eaC8ko9jmcXc3SIiIiIiEwwqdEIdDod+2oQEVGt3F1d0CrIS11mCSoiIqrOxeXk8UQ8S1AREREREZlhUqORxFbVweVBCBERWWKYrDqawR19RERUR18NNgsnIiIiIjLDpEYjiQnjZBUREdWuTYg2WZXAFbhERFRHX42j6WwWTkRERERkikmNRhJTNVl1lJNVRERUx2QVy08REVFdcYI7NYiIiIiIzDGp0UhiDQchLCtCRER1lZ9iWREiIqqr/BQXSRERERERmWFSo5HEhGkHIYlZhaio1DfWtyEiIgdPaiQw+U1ERBbEGOJEZiH0eh5PEBEREREZMKnRSFoGeMHDzQVlFXoczy5qrG9DREQOqk3Vjr6MglLkl5Tb+uUQEZGdiQr2hquLDsVllUjNK7H1yyEiIiIishtMajTWwLroEB3srS6zBBUREVUX4OWOYB93dZm7NYiIqDp3VxdEBWnHE/FsFk5EREREZMSkRiOKraqDG886uEREZEGbqjjBZuFERGQJm4UTEREREdXEpEYjYnM/IiKyrl56AQeKiIgsHE9ocYLNwomIiIiITmJSo0kOQgob89sQEZGDNwtnnCAiIktiQrQdfYwTREREREQnManRiJjUICIia5qFs/wUERHxeIKIiIiIyDpMajRBT42jmQWorNQ35rciIiIH3qnBpAYREdVVzlZ69On1PJ4gIiIiIhJMajSiqGBvuLroUFxWidS8Er7jiIjI4o6+pKwilFdUcnSIiMhi8juvuBzZhWUcHSIiIiIiJjUal7urC6KCvNVlNvcjIqLqIv294OHmgvJKPZJzijlARERkxtvDFZEBntrxRCb79BERERERCe7UaGTsq0FERLVxcdEhOtiQ/OZkFRER1dUsvIDDQ0RERETEpEbT9dWQOrhERES11UuX/ktEREQ144RWgorJbyIiIiIiDXdqNNVBCLeLExGRBWwWTkREVh1PcEcfEREREZHCpEZTrcDlTg0iIqorqcHJKiIi4vEEEREREdEpManRyGINK6vSC6HX6xv72xERkYPhClwiIrIqTnDnNxERERGRwqRGI4sO8YFOB+SVlCOzoLSxvx0RETnoZFViJpPfRERUe6PwtLwSFJSUc4iIiIiIyOkxqdHIvNxd0TLAS13m6ioiIqqudbCW1JDkd1ZhGQeIiIjMBPq4I8jHXV1O4G4NIiIiIiLHSGosX74cU6ZMweDBg3HjjTciMTHxlM/Jzc3Fs88+i9GjR2PSpElYuHAhbKWNsblfgc1eAxFRc5eamopdu3ahsLDQ6udIWcC4uDgcP34ctkx+tzAkvxkniIjIgpiq/ktsFk5ERERE5ABJjWXLluHcc8/FgAED8MILLyAlJQXDhg1DTk5Orc/Jzs7GkCFD1HMffvhhdfr666+xbt062EJsVbPw+HTrJ9qIiMg6paWlmDFjBtq0aYMLLrgAERER+N///nfK5y1evBixsbEYNWqUOp1//vnIzMy0afKbK3CJiBpHRkYG5syZg6effhoLFixAZWWlVc/bsGEDXn75ZcyePRvJyck2+/HEVB1PMPlNREREROQASY2nnnoKl156KZ544gmMGzcO33//PfLy8vDRRx/V+hw5WJGdGn/88YdKiMhk1Q8//IB+/frBFngQQkTUeJ5//nn89ddfOHjwII4cOYJPPvkEN998MzZv3lzrc9auXYupU6eqpHdSUpJ67p133qku20KbqhW4CRlMfhMRNTSJDT179sR3332HgoIC3H///SoJXldiQ3byyQ5xOZaQZIaczjnnHOzfv98mPyA2CyciIiIicpCkRn5+vlodJeWjDLy8vFRyY8WKFbU+b/78+bjqqqvg66utaDLw8PCALfAghIio8cydOxczZ85EdHS0ui6J8K5du6rkRm1mzZqlEt633Xab8TaZrJJJL5uWFWGtdCKiBicJbNmZJ8cPr732GlauXImlS5eqJEdtZFeHYaf3O++8g5deegn//PMPAgMDbfIT4iIpIiIiIiIHSWrIillZJdWyZUuz21u1alVrX4309HSkpaWhffv2uOOOO1QZqunTp+PXX3+t83uVlJSo3R2mpwZPanAFLhFRgzKsnpUShaYGDRqELVu21FquSiamJk+ejKKiIuzevRtZWVk2/cmw/BQRUeMoLy/HokWLcOWVV8LV1VXd1q5dO5XY/umnn2p93rvvvosrrrgCnTt3Nt4WFBSEFi1a2ORHxeMJIiIiIiIHSWqUlZWpc09PT7Pb5brhPkvJCfHAAw+o+upvvPEGhg8fjosuugifffZZrd9LVl/JyivDybDityFXVmUWlCKnyPLrJiKi06uRLkJDQ81uDwsLM95nKfktiY0DBw6oBPjFF1+MqKgoleSQnky2SH6z/BQRUeNISEhAcXExOnToYHa7XJc4YImUut23bx9GjhyJ3377Dc8884zq1SQLp2y9SOp4dhFKy63rB0JERERE1FzZdVLDMElVfWJKrlefwDIICQmBTqfDeeedh4ceeghDhw7Fvffei6uvvhrvv/9+rd/r0UcfVc3HDafadoKcDj9PN4T5aYkZ1ksnImo47u7uZgltA9mBYbiv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Y+PPF8estfFnrPVxjDle/PkyL/yd5HiZG/5Mcrz482Ve+DvJ8SIiIsvCRuFERERERERERERERGQRuFODiIiIiIiIiIiIiIgsApMaRERERERERERERERkEZjUICIiIiIiIiIiIiIii8CkRguVlpZi+/btOHToUOv8j1i4kpISbNy4EYmJiQZfk5ubi23btuHkyZOwdfn5+YiPj0d6errB11RWVmLnzp3Yu3cvdDodbJn8++V3T8ZCftYMOXbsGP755x8UFRW16fszV9XV1diwYYP6OWpMdnY2/v77b6Smprb5e7NGjBNNY5xoGcaJlmGcODeME22LcaJpjBMtwzjRMowT54ZxgoiIzI6Omm3hwoU6Pz8/XUxMjM7X11c3ZMgQXVpaGkdQp1PjMH36dF1oaKjO1dVV98QTTzQ6Lm+++ab6eNeuXXVubm66SZMm6crKymxuDA8dOqS75ppr1M9R3759dZ6enrpLL71Ul5WV1eB1Gzdu1LVv314XERGhCw4O1sXFxekOHDigs0Xz58/XdejQQf3sdO7cWeft7a2bNWtWg9fk5eXpxo4dq8ZTXiO3X375pc7WvfLKKzp7e3td//79z/jYiy++qHNxcdF169ZN3d5xxx26yspKk7xPa8A4YRjjRMswTrQc48S5Y5xoO4wThjFOtAzjRMsxTpw7xgkiIjI3TGo0U0pKis7d3V33xhtvqMdFRUW6fv36qYlp0um2bt2qJphlUr579+6NJjVWr16ts7Oz0y1btkw9TkxMVBP1Mqlqa5YuXar7+eefddXV1epxZmammlSePHly7WuKi4t1YWFhugceeEA9lolmSXzIz50tmjNnji41NbX28XfffSfbVnTbt2+vfe7uu+/WdenSRZedna0ez5s3T+fo6GiziSB9Yiw6Olp30003nZHU+P3339X4rF27Vj0+ePCgSrSdniyi5mGcaBrjRMswTrQc48S5YZxoO4wTTWOcaBnGiZZjnDg3jBNERGSOmNRoprfeekutDK+/q0BWejg4OKgJaapjKKlx2223qd0t9T366KO6qKgoDp9Op3vhhRfUjgw9SXpIEkgugPXWr1+vJvLj4+NtfszS09PVWMjEvCgtLVWJx7lz59aOjSSNJDH09NNP2+R45eTkqN0tK1eu1D344INnJDUmTpyodrbUd99996nfYWo5xonmY5w4N4wTLcM4cXaME22LcaL5GCfODeNEyzBOnB3jBBERmSv21Ggm6XvQs2dPODs71z43aNAgVFVVYdeuXa1VHczqxrB///4NnpMxlP4bOTk5sHXS0yAmJqbBeIWFhSE0NLTBeOk/ZosyMjKwfv16/Pbbb7j11ltx4YUXYty4cepjBw4cQHFxcYOfMTs7OwwYMMBmx+vuu+/Gddddh9GjR7fodzIhIQFlZWVt9C6tB+OEccaQccIwxomzY5xoGcaJtsU4YZwxZJwwjHHi7BgnWoZxgoiIzJWjqd+ApZBGugEBAQ2e0z+Wj9H5j6Gfn5/NDuP8+fOxZMkSLF++vMnxcnJygpeXl83+zMmF7EsvvYS0tDQUFBRg7ty5tYlG/Zg09jMmk/S25v3338fRo0exYMGCFv9OSiPA3NxctGvXrg3eqfVgnGj9MWScYJw4G8aJ5mOcaHuME60/howTjBNnwzjRfIwTRERkzrhTo5lkMrm0tLTBcyUlJeq2/u4N4hi2lCQz7rrrLsyePRtjxoxp8mdOyHO2+jM3fvx4tVPj0KFD+PDDDzFp0iT89ddfteMlGvs9tbXxSk5OxowZM3D//fdj69atasxSU1NRWFio7ufl5anX8bxmXBxPjmFrYZxoPsaJ5mGcMA3GCY5ha2GcaD7GieZhnCAiInPHpEYzRUVFqcBen/5xZGSk8f9nbGgM5QIvJCQEtmjp0qWYOHEiXnvtNUydOvWM8Tp16pRaNa+Xnp6OiooK/swBuOqqq9C5c2c1hvrxEo39jNna76gkcvr164cvvvgCTz75pDo2bdqkxkLuyw6Opn4nZTeQLa90PFeME603howTjBPngnHCMMYJ02CcaL0xZJxgnDgXjBOGMU4QEZG5Y1KjmaRu/969e3HkyJHa5xYuXKgm46XXBjVvDKW8Uv1a/TKG0hdBv8relshYXHPNNXjllVfw73//u9Hxys/Px+rVqxuMl+w6GDVqFGxJeXm5SubUV1RUpJI++pID4eHhiIuLw6JFixokgWQyX993w1ZIbxbZkVH/kORZly5d1P2+ffuq18m4yMq+ysrKBj9jY8eONeG7t1yME8YZQ8aJOowTzcc40TKME6bBOGGcMWScqMM40XyMEy3DOEFEROaOPTWa6dJLL8UFF1yAa6+9Fs8++6xqbv3mm2/igw8+gL09c0My4bxlyxY1VtKs+eTJk2ry1NvbG7169VLPP/DAA/joo4/U5Op9992nJuuldNCaNWtgazZs2ICrr74aV155pWrMLGOlb2w9fPhwdb979+6qGfadd96JV199VY3rY489plba29oq+qysLPU7KGW6ZGJeGvxJPw3ZUSDN6/RknKQxtjRY79GjB9544w01jpMnTzbp+zdX06dPx+eff67KeN1xxx0qwSENJiURRC3HONE0xomWYZxoGcaJ1sE4YVyME01jnGgZxomWYZxoHYwTRERkKnY6nU5nsu9uYWRluCQy5A9ImUy97bbb1MQ0aY35ZIL+dDKhLL0P6m8Pf/3119Wul9DQUFVyafDgwTY3hF9++aVK8JzO0dGxwc4MubiTyftly5apj0lSTSafJflha44dO4b33nsPu3fvhq+vLwYOHIh7771XJc7q+/PPPzFv3jz1MzlgwAA88cQTNpcEaszbb7+tfu8+/vjjBs9LglZ+Jw8cOKB2u8iFiX4nB7Uc44RhjBMtwzjRcowT54dxom0wThjGONEyjBMtxzhxfhgniIjInDCpQUREREREREREREREFoF1k4iIiIiIiIiIiIiIyCIwqUFERERERERERERERBaBSQ0iIiIiIiIiIiIiIrIITGoQEREREREREREREZFFYFKDiIiIiIiIiIiIiIgsApMaRERERERERERERERkEZjUICIiIiIiIiIiIiIii8CkBpEVO3ToEP744w9Tvw0iIjJTjBNERMQ4QURERJaGSQ0iK7Zs2TI88sgjpn4bRERkphgniIiIcYKIiIgsDZMaRERERERERERERERkERxN/QaIrFViYiJ27NiBgIAA9OvXD+7u7g3Kfcgxbtw47Ny5E8nJyRg8eDBCQkLO+Dq7du3C4cOHERoaql5jb39mLjIpKQnx8fFo164dBgwYAAcHhwYfr6ysVF8nNTUVffr0Qfv27VvpX01ERM3FOEFERIwTRERERC3HpAaRkel0OkyfPh3z58/HkCFDkJmZqZIJP/30EwYOHFhb7uPll19WyQU3NzdUV1erBMi3336LK6+8sjYRccMNN2D16tXq60hSQpIeS5YsQVBQUO33evjhh/Hxxx+rhEdpaSkcHR2xePFieHt7q9fk5eVh5MiRcHFxUY+3bNmC7777rvb7EBFR22KcICIixgkiIiKi86AjIqP66KOPdJ06ddJlZmbWPvfyyy/r4uLiah/PmTNHJ79+b775Zu1zzz//vC4kJERXXFysHs+dO1fn7++vS0xMVI/z8/N1vXr10t1zzz21n/Pee+/p3N3ddTt37qx9buPGjbr09PQG3+fHH3+s/fijjz6qvg4REZkG4wQRETFOEBEREZ079tQgMrLPPvsMvXr1wqpVq/DDDz/g+++/h6enJ/bv3692bOjJzompU6fWPn700UeRnp6OtWvXqseya+OWW25BZGSkeuzl5YVp06apXRZ6X3zxBW677Tb1/fSGDh1au5NDyP1rr7229vGFF16IAwcO8P+diMhEGCeIiIhxgoiIiOjcsfwUkZEdP34c5eXl+PHHHxs8P2nSJPW8nvTI0JeEEpL4kASE1FgXcnvdddc1+BqdOnVCfn4+cnJy4OfnhxMnTuDGG29s8v34+/s3eCzfs6ys7Lz+jUREdO4YJ4iIiHGCiIiI6NwxqUFkZNLL4qKLLsIbb7zR5Otyc3PPqLEuzwUGBqrHcpudnd3gNfLYycmptl+Gr68vsrKy+H9IRGRBGCeIiIhxgoiIiOjcsfwUkZFNmDABX3/9NQoKCho8n5yc3OCxJDCkCbjeH3/8oRqG65uJjxgxAr/++qt6Tk/KWUl5KQcHB/V4/PjxqhxV/R0gRUVFKC4u5v8rEZGZYpwgIiLGCSIiIqJzx50aREb23HPPYcWKFSo5cc8998Dd3R1btmzB0aNHa/tlCA8PD9UPQ/pkSOLitddeU/cjIiLUx5955hmVxLj00ksxceJEbNq0CQsXLmyQCHn22WexdOlSlei4/fbbUVpaim+++UYlSOT7EhGR+WGcICIixgkiIiKic8edGkRGJj0stm7dihkzZiAhIQF79+7F2LFjsXLlygavCw8Px+LFi1V/DHndW2+9hTfffLP248HBwdixYweGDRuG9evXq34b27dvx6BBg2pfIyWqtm3bppIj8fHxyMvLU708pF+H6Ny5My677LIG3zckJET19yAiItNgnCAiIsYJIiIionNnp5NC/kTUpubOnauO/fv3c+SJiIhxgoiIeD1BRERE1EzcqUFERERERERERERERBaBSQ0iE2isLBQRERHjBBER8XqCiIiIqGksP0VERERERERERERERBaBOzWIiIiIiIiIiIiIiMgiMKlBREREREREREREREQWgUkNIiIiIiIiIiIiIiKyCExqEBERERERERERERGRRWBSg4iIiIiIiIiIiIiILAKTGkREREREREREREREZBGY1CAiIiIiIiIiIiIiIovApAYREREREREREREREVkEJjWIiIiIiIiIiIiIiAiW4P8Bp12Z9iRZi1kAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def config_label(tokenizer, vocab_size, max_token_len, pad_layout=\"end\"):\n", + " if tokenizer == \"char\":\n", + " return \"char\"\n", + " label = f\"wordpiece {int(vocab_size)}\"\n", + " if pd.notna(max_token_len):\n", + " label += f\" (max_token_len={int(max_token_len)})\"\n", + " if pad_layout != \"end\":\n", + " label += f\" [{pad_layout}]\"\n", + " return label\n", + "\n", + "\n", + "configs = (\n", + " history_df[[\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"]]\n", + " .drop_duplicates()\n", + " .sort_values([\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"], na_position=\"first\")\n", + " .to_records(index=False)\n", + ")\n", + "\n", + "n = len(configs)\n", + "ncols = min(4, n)\n", + "nrows = int(np.ceil(n / ncols))\n", + "fig, axes = plt.subplots(nrows, ncols, figsize=(4 * ncols, 3 * nrows), squeeze=False)\n", + "\n", + "for ax, (tokenizer, vocab_size, max_token_len, pad_layout) in zip(axes.flat, configs):\n", + " subset = history_df[\n", + " (history_df[\"tokenizer\"] == tokenizer)\n", + " & (history_df[\"vocab_size\"] == vocab_size)\n", + " & (history_df[\"max_token_len\"].isna() if pd.isna(max_token_len) else history_df[\"max_token_len\"] == max_token_len)\n", + " & (history_df[\"pad_layout\"] == pad_layout)\n", + " ]\n", + " for split, color in [(\"train\", \"tab:blue\"), (\"val\", \"tab:orange\")]:\n", + " split_data = subset[subset[\"split\"] == split]\n", + " per_epoch = split_data.groupby(\"epoch\")[\"loss\"].agg([\"mean\", \"std\"])\n", + " ax.plot(per_epoch.index, per_epoch[\"mean\"], color=color, label=split)\n", + " if per_epoch[\"std\"].notna().any():\n", + " ax.fill_between(per_epoch.index, per_epoch[\"mean\"] - per_epoch[\"std\"].fillna(0),\n", + " per_epoch[\"mean\"] + per_epoch[\"std\"].fillna(0), color=color, alpha=0.15)\n", + " ax.set_title(config_label(tokenizer, vocab_size, max_token_len, pad_layout), fontsize=9)\n", + " ax.set_xlabel(\"epoch\")\n", + " ax.set_ylabel(\"loss\")\n", + "\n", + "for ax in axes.flat[n:]:\n", + " ax.axis(\"off\")\n", + "\n", + "axes.flat[0].legend(fontsize=8)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "3109807f", + "metadata": {}, + "source": [ + "*Notes: line = mean across seeds, shaded band = std across seeds (band is flat/invisible\n", + "with only 1 seed). Train and val loss diverging within a config is the usual overfitting\n", + "signal; a val curve still trending down at the last epoch means that config likely hasn't\n", + "converged yet.*" + ] + }, + { + "cell_type": "markdown", + "id": "d1c44955", + "metadata": {}, + "source": [ + "## Loss vs epoch, all configs overlaid (val split only)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7a5eab55", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-07T10:45:12.010969Z", + "iopub.status.busy": "2026-08-07T10:45:12.010821Z", + "iopub.status.idle": "2026-08-07T10:45:12.129188Z", + "shell.execute_reply": "2026-08-07T10:45:12.128159Z" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(8, 5))\n", + "val_data = history_df[history_df[\"split\"] == \"val\"]\n", + "\n", + "for tokenizer, vocab_size, max_token_len, pad_layout in configs:\n", + " subset = val_data[\n", + " (val_data[\"tokenizer\"] == tokenizer)\n", + " & (val_data[\"vocab_size\"] == vocab_size)\n", + " & (val_data[\"max_token_len\"].isna() if pd.isna(max_token_len) else val_data[\"max_token_len\"] == max_token_len)\n", + " & (val_data[\"pad_layout\"] == pad_layout)\n", + " ]\n", + " per_epoch = subset.groupby(\"epoch\")[\"loss\"].mean()\n", + " style = \"--\" if tokenizer == \"char\" else \"-\"\n", + " ax.plot(per_epoch.index, per_epoch.values, style,\n", + " label=config_label(tokenizer, vocab_size, max_token_len, pad_layout), linewidth=1.5 if tokenizer == \"char\" else 1)\n", + "\n", + "ax.set_xlabel(\"epoch\")\n", + "ax.set_ylabel(\"val_loss\")\n", + "ax.set_title(\"val_loss vs epoch, all configs\")\n", + "ax.legend(fontsize=7, ncol=2, loc=\"upper right\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "644f5c19", + "metadata": {}, + "source": [ + "*Notes: same data as the small-multiples grid above, just overlaid for a direct\n", + "side-by-side comparison of convergence speed and final level. `char` is dashed to stand\n", + "out from the WordPiece vocab_size curves.*" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "irrm-codec", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.15" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c6b115624df6a1adbd7d57e9facb0846bb151ce0 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 7 Aug 2026 14:04:14 +0300 Subject: [PATCH 50/70] Fix mixed pad_layout/max_token_len --- .../compare_forward_tokenizers_report.ipynb | 753 ++++++++++++------ 1 file changed, 513 insertions(+), 240 deletions(-) diff --git a/notebooks/compare_forward_tokenizers_report.ipynb b/notebooks/compare_forward_tokenizers_report.ipynb index 596e9cc..34585ac 100644 --- a/notebooks/compare_forward_tokenizers_report.ipynb +++ b/notebooks/compare_forward_tokenizers_report.ipynb @@ -21,10 +21,10 @@ "id": "25047bb7", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:01.633666Z", - "iopub.status.busy": "2026-08-02T09:59:01.633666Z", - "iopub.status.idle": "2026-08-02T09:59:01.653541Z", - "shell.execute_reply": "2026-08-02T09:59:01.653541Z" + "iopub.execute_input": "2026-08-07T10:53:07.657782Z", + "iopub.status.busy": "2026-08-07T10:53:07.657129Z", + "iopub.status.idle": "2026-08-07T10:53:07.661495Z", + "shell.execute_reply": "2026-08-07T10:53:07.660717Z" }, "tags": [ "parameters" @@ -33,11 +33,8 @@ "outputs": [], "source": [ "# parameters\n", - "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_background100k_40epochs_upto30k\"\n", - "# Optional: output of calc_tokenization_stats.py run on the SAME AIRR file used above,\n", - "# with --tokenizers-dir pointing at the same WordPiece tokenizers. Leave as-is if you\n", - "# haven't run that diagnostic yet - the relevant section below will just note that.\n", - "DOMAIN_TOKENIZATION_STATS_PATH = \"../artifacts/tokenizers_1M_integ_on_background100k/tokenization_stats.json\"" + "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs\"\n", + "DOMAIN_TOKENIZATION_STATS_PATH = \"../artifacts/REPLACE_ME_domain_stats/tokenization_stats.json\"" ] }, { @@ -46,10 +43,10 @@ "id": "b314dd93", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:01.653541Z", - "iopub.status.busy": "2026-08-02T09:59:01.653541Z", - "iopub.status.idle": "2026-08-02T09:59:03.331902Z", - "shell.execute_reply": "2026-08-02T09:59:03.331297Z" + "iopub.execute_input": "2026-08-07T10:53:07.663261Z", + "iopub.status.busy": "2026-08-07T10:53:07.662773Z", + "iopub.status.idle": "2026-08-07T10:53:08.202915Z", + "shell.execute_reply": "2026-08-07T10:53:08.202066Z" } }, "outputs": [ @@ -57,7 +54,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Loaded 18 individual runs across 6 tokenizer configs from ..\\artifacts\\compare_forward_tokenizers_background100k_40epochs_upto30k\n" + "Loaded 15 individual runs across 15 tokenizer configs from ..\\artifacts\\compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs\n" ] }, { @@ -83,6 +80,8 @@ " \n", " tokenizer\n", " vocab_size\n", + " max_token_len\n", + " pad_layout\n", " max_len\n", " seed\n", " test_loss\n", @@ -100,102 +99,119 @@ " 0\n", " char\n", " 25\n", + " NaN\n", + " end\n", " 40\n", " 1\n", - " 0.202377\n", - " 0.864400\n", - " 0.191109\n", + " 0.197678\n", + " 0.867836\n", + " 0.192469\n", " 33\n", - " 1122.731938\n", - " 0.549614\n", + " 1148.349279\n", + " 0.551894\n", " 10850856\n", " NaN\n", " \n", " \n", " 1\n", - " char\n", + " wordpiece\n", + " 1000\n", + " 9.0\n", + " anchored\n", + " 11\n", + " 1\n", + " 0.222379\n", + " 0.850060\n", + " 0.219529\n", " 25\n", - " 40\n", - " 42\n", - " 0.200186\n", - " 0.866364\n", - " 0.191719\n", - " 37\n", - " 1121.601178\n", - " 0.565691\n", - " 10850856\n", - " NaN\n", + " 815.802114\n", + " 0.472949\n", + " 10913256\n", + " artifacts/tokenizers_2026-08-01_fine_grid/word...\n", " \n", " \n", " 2\n", - " char\n", - " 25\n", - " 40\n", - " 777\n", - " 0.202525\n", - " 0.864106\n", - " 0.199392\n", - " 36\n", - " 1122.459536\n", - " 0.549595\n", - " 10850856\n", - " NaN\n", + " wordpiece\n", + " 2000\n", + " 9.0\n", + " anchored\n", + " 10\n", + " 1\n", + " 0.235747\n", + " 0.840743\n", + " 0.229570\n", + " 27\n", + " 800.566907\n", + " 0.497766\n", + " 10977256\n", + " artifacts/tokenizers_2026-08-01_fine_grid/word...\n", " \n", " \n", " 3\n", " wordpiece\n", - " 1000\n", - " 40\n", + " 2998\n", + " 9.0\n", + " anchored\n", + " 10\n", " 1\n", - " 0.229882\n", - " 0.844552\n", - " 0.224929\n", - " 36\n", - " 1142.940060\n", - " 0.551867\n", - " 10913256\n", - " artifacts/tokenizers_1M_integ/wordpiece_vocab_...\n", + " 0.242457\n", + " 0.835847\n", + " 0.240230\n", + " 38\n", + " 792.818900\n", + " 0.469587\n", + " 11041128\n", + " artifacts/tokenizers_2026-08-01_fine_grid/word...\n", " \n", " \n", " 4\n", " wordpiece\n", - " 1000\n", - " 40\n", - " 42\n", - " 0.233081\n", - " 0.843024\n", - " 0.225724\n", - " 37\n", - " 1143.059010\n", - " 0.552772\n", - " 10913256\n", - " artifacts/tokenizers_1M_integ/wordpiece_vocab_...\n", + " 3986\n", + " 9.0\n", + " anchored\n", + " 10\n", + " 1\n", + " 0.250418\n", + " 0.830416\n", + " 0.247915\n", + " 38\n", + " 793.682630\n", + " 0.471941\n", + " 11104360\n", + " artifacts/tokenizers_2026-08-01_fine_grid/word...\n", " \n", " \n", "\n", "" ], "text/plain": [ - " tokenizer vocab_size max_len seed test_loss test_cosine \\\n", - "0 char 25 40 1 0.202377 0.864400 \n", - "1 char 25 40 42 0.200186 0.866364 \n", - "2 char 25 40 777 0.202525 0.864106 \n", - "3 wordpiece 1000 40 1 0.229882 0.844552 \n", - "4 wordpiece 1000 40 42 0.233081 0.843024 \n", + " tokenizer vocab_size max_token_len pad_layout max_len seed test_loss \\\n", + "0 char 25 NaN end 40 1 0.197678 \n", + "1 wordpiece 1000 9.0 anchored 11 1 0.222379 \n", + "2 wordpiece 2000 9.0 anchored 10 1 0.235747 \n", + "3 wordpiece 2998 9.0 anchored 10 1 0.242457 \n", + "4 wordpiece 3986 9.0 anchored 10 1 0.250418 \n", + "\n", + " test_cosine best_val_loss epochs_to_best_val train_time_sec \\\n", + "0 0.867836 0.192469 33 1148.349279 \n", + "1 0.850060 0.219529 25 815.802114 \n", + "2 0.840743 0.229570 27 800.566907 \n", + "3 0.835847 0.240230 38 792.818900 \n", + "4 0.830416 0.247915 38 793.682630 \n", "\n", - " best_val_loss epochs_to_best_val train_time_sec inference_time_sec \\\n", - "0 0.191109 33 1122.731938 0.549614 \n", - "1 0.191719 37 1121.601178 0.565691 \n", - "2 0.199392 36 1122.459536 0.549595 \n", - "3 0.224929 36 1142.940060 0.551867 \n", - "4 0.225724 37 1143.059010 0.552772 \n", + " inference_time_sec num_parameters \\\n", + "0 0.551894 10850856 \n", + "1 0.472949 10913256 \n", + "2 0.497766 10977256 \n", + "3 0.469587 11041128 \n", + "4 0.471941 11104360 \n", "\n", - " num_parameters tokenizer_path \n", - "0 10850856 NaN \n", - "1 10850856 NaN \n", - "2 10850856 NaN \n", - "3 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... \n", - "4 10913256 artifacts/tokenizers_1M_integ/wordpiece_vocab_... " + " tokenizer_path \n", + "0 NaN \n", + "1 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", + "2 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", + "3 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", + "4 artifacts/tokenizers_2026-08-01_fine_grid/word... " ] }, "execution_count": 2, @@ -220,6 +236,18 @@ "char_row = next(r for r in summary if r[\"tokenizer\"] == \"char\")\n", "vocab_sizes = [r[\"vocab_size\"] for r in wp]\n", "\n", + "# This notebook assumes one wordpiece config per vocab_size. If RESULTS_DIR mixes\n", + "# multiple --max-token-len/--pad-layout variants for the same vocab_size (e.g. after\n", + "# merging runs), that assumption breaks silently in the plots below - fail loudly instead.\n", + "if len(vocab_sizes) != len(set(vocab_sizes)):\n", + " dupes = sorted({vs for vs in vocab_sizes if vocab_sizes.count(vs) > 1})\n", + " raise ValueError(\n", + " f\"vocab_size {dupes} appears more than once in summary.json (different \"\n", + " \"max_token_len/pad_layout variants mixed in one RESULTS_DIR) - this notebook \"\n", + " \"isn't designed to compare those side by side; filter raw_results.csv/summary.json \"\n", + " \"to a single max_token_len+pad_layout combination first.\"\n", + " )\n", + "\n", "print(f\"Loaded {len(raw)} individual runs across {len(summary)} tokenizer configs from {results_dir}\")\n", "raw.head()" ] @@ -238,10 +266,10 @@ "id": "41f68c7f", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:03.334061Z", - "iopub.status.busy": "2026-08-02T09:59:03.334061Z", - "iopub.status.idle": "2026-08-02T09:59:03.344312Z", - "shell.execute_reply": "2026-08-02T09:59:03.344312Z" + "iopub.execute_input": "2026-08-07T10:53:08.204542Z", + "iopub.status.busy": "2026-08-07T10:53:08.204326Z", + "iopub.status.idle": "2026-08-07T10:53:08.213800Z", + "shell.execute_reply": "2026-08-07T10:53:08.213016Z" } }, "outputs": [ @@ -281,88 +309,205 @@ " 0\n", " char\n", " 25\n", - " 0.2017 ± 0.0013\n", - " 0.8650 ± 0.0012\n", - " 0.1941 ± 0.0046\n", - " 35.3 ± 2.1\n", + " 0.1977 ± 0.0000\n", + " 0.8678 ± 0.0000\n", + " 0.1925 ± 0.0000\n", + " 33.0 ± 0.0\n", " 10850856\n", - " 3\n", + " 1\n", " \n", " \n", " 1\n", " wordpiece\n", " 1000\n", - " 0.2318 ± 0.0017\n", - " 0.8439 ± 0.0008\n", - " 0.2263 ± 0.0017\n", - " 36.0 ± 1.0\n", + " 0.2224 ± 0.0000\n", + " 0.8501 ± 0.0000\n", + " 0.2195 ± 0.0000\n", + " 25.0 ± 0.0\n", " 10913256\n", - " 3\n", + " 1\n", " \n", " \n", " 2\n", " wordpiece\n", - " 5000\n", - " 0.2695 ± 0.0029\n", - " 0.8166 ± 0.0021\n", - " 0.2679 ± 0.0049\n", - " 39.7 ± 0.6\n", - " 11169256\n", - " 3\n", + " 2000\n", + " 0.2357 ± 0.0000\n", + " 0.8407 ± 0.0000\n", + " 0.2296 ± 0.0000\n", + " 27.0 ± 0.0\n", + " 10977256\n", + " 1\n", " \n", " \n", " 3\n", " wordpiece\n", - " 10000\n", - " 0.3090 ± 0.0032\n", - " 0.7883 ± 0.0019\n", - " 0.3077 ± 0.0028\n", - " 40.0 ± 0.0\n", - " 11489256\n", - " 3\n", + " 2998\n", + " 0.2425 ± 0.0000\n", + " 0.8358 ± 0.0000\n", + " 0.2402 ± 0.0000\n", + " 38.0 ± 0.0\n", + " 11041128\n", + " 1\n", " \n", " \n", " 4\n", " wordpiece\n", - " 20000\n", - " 0.3552 ± 0.0008\n", - " 0.7559 ± 0.0010\n", - " 0.3534 ± 0.0032\n", - " 39.3 ± 1.2\n", - " 12129256\n", - " 3\n", + " 3986\n", + " 0.2504 ± 0.0000\n", + " 0.8304 ± 0.0000\n", + " 0.2479 ± 0.0000\n", + " 38.0 ± 0.0\n", + " 11104360\n", + " 1\n", " \n", " \n", " 5\n", " wordpiece\n", - " 30000\n", - " 0.3774 ± 0.0045\n", - " 0.7398 ± 0.0040\n", - " 0.3744 ± 0.0052\n", - " 37.7 ± 2.1\n", - " 12769256\n", - " 3\n", + " 4970\n", + " 0.2559 ± 0.0000\n", + " 0.8263 ± 0.0000\n", + " 0.2540 ± 0.0000\n", + " 36.0 ± 0.0\n", + " 11167336\n", + " 1\n", + " \n", + " \n", + " 6\n", + " wordpiece\n", + " 5951\n", + " 0.2608 ± 0.0000\n", + " 0.8232 ± 0.0000\n", + " 0.2581 ± 0.0000\n", + " 37.0 ± 0.0\n", + " 11230120\n", + " 1\n", + " \n", + " \n", + " 7\n", + " wordpiece\n", + " 6923\n", + " 0.2668 ± 0.0000\n", + " 0.8186 ± 0.0000\n", + " 0.2650 ± 0.0000\n", + " 37.0 ± 0.0\n", + " 11292328\n", + " 1\n", + " \n", + " \n", + " 8\n", + " wordpiece\n", + " 7897\n", + " 0.2746 ± 0.0000\n", + " 0.8128 ± 0.0000\n", + " 0.2728 ± 0.0000\n", + " 38.0 ± 0.0\n", + " 11354664\n", + " 1\n", + " \n", + " \n", + " 9\n", + " wordpiece\n", + " 8855\n", + " 0.2818 ± 0.0000\n", + " 0.8081 ± 0.0000\n", + " 0.2801 ± 0.0000\n", + " 36.0 ± 0.0\n", + " 11415976\n", + " 1\n", + " \n", + " \n", + " 10\n", + " wordpiece\n", + " 9816\n", + " 0.2848 ± 0.0000\n", + " 0.8052 ± 0.0000\n", + " 0.2824 ± 0.0000\n", + " 40.0 ± 0.0\n", + " 11477480\n", + " 1\n", + " \n", + " \n", + " 11\n", + " wordpiece\n", + " 11719\n", + " 0.3012 ± 0.0000\n", + " 0.7935 ± 0.0000\n", + " 0.3033 ± 0.0000\n", + " 40.0 ± 0.0\n", + " 11599272\n", + " 1\n", + " \n", + " \n", + " 12\n", + " wordpiece\n", + " 14550\n", + " 0.3142 ± 0.0000\n", + " 0.7839 ± 0.0000\n", + " 0.3140 ± 0.0000\n", + " 40.0 ± 0.0\n", + " 11780456\n", + " 1\n", + " \n", + " \n", + " 13\n", + " wordpiece\n", + " 16414\n", + " 0.3258 ± 0.0000\n", + " 0.7750 ± 0.0000\n", + " 0.3248 ± 0.0000\n", + " 40.0 ± 0.0\n", + " 11899752\n", + " 1\n", + " \n", + " \n", + " 14\n", + " wordpiece\n", + " 19199\n", + " 0.3343 ± 0.0000\n", + " 0.7684 ± 0.0000\n", + " 0.3346 ± 0.0000\n", + " 39.0 ± 0.0\n", + " 12077992\n", + " 1\n", " \n", " \n", "\n", "" ], "text/plain": [ - " tokenizer vocab_size test_loss test_cosine best_val_loss \\\n", - "0 char 25 0.2017 ± 0.0013 0.8650 ± 0.0012 0.1941 ± 0.0046 \n", - "1 wordpiece 1000 0.2318 ± 0.0017 0.8439 ± 0.0008 0.2263 ± 0.0017 \n", - "2 wordpiece 5000 0.2695 ± 0.0029 0.8166 ± 0.0021 0.2679 ± 0.0049 \n", - "3 wordpiece 10000 0.3090 ± 0.0032 0.7883 ± 0.0019 0.3077 ± 0.0028 \n", - "4 wordpiece 20000 0.3552 ± 0.0008 0.7559 ± 0.0010 0.3534 ± 0.0032 \n", - "5 wordpiece 30000 0.3774 ± 0.0045 0.7398 ± 0.0040 0.3744 ± 0.0052 \n", + " tokenizer vocab_size test_loss test_cosine best_val_loss \\\n", + "0 char 25 0.1977 ± 0.0000 0.8678 ± 0.0000 0.1925 ± 0.0000 \n", + "1 wordpiece 1000 0.2224 ± 0.0000 0.8501 ± 0.0000 0.2195 ± 0.0000 \n", + "2 wordpiece 2000 0.2357 ± 0.0000 0.8407 ± 0.0000 0.2296 ± 0.0000 \n", + "3 wordpiece 2998 0.2425 ± 0.0000 0.8358 ± 0.0000 0.2402 ± 0.0000 \n", + "4 wordpiece 3986 0.2504 ± 0.0000 0.8304 ± 0.0000 0.2479 ± 0.0000 \n", + "5 wordpiece 4970 0.2559 ± 0.0000 0.8263 ± 0.0000 0.2540 ± 0.0000 \n", + "6 wordpiece 5951 0.2608 ± 0.0000 0.8232 ± 0.0000 0.2581 ± 0.0000 \n", + "7 wordpiece 6923 0.2668 ± 0.0000 0.8186 ± 0.0000 0.2650 ± 0.0000 \n", + "8 wordpiece 7897 0.2746 ± 0.0000 0.8128 ± 0.0000 0.2728 ± 0.0000 \n", + "9 wordpiece 8855 0.2818 ± 0.0000 0.8081 ± 0.0000 0.2801 ± 0.0000 \n", + "10 wordpiece 9816 0.2848 ± 0.0000 0.8052 ± 0.0000 0.2824 ± 0.0000 \n", + "11 wordpiece 11719 0.3012 ± 0.0000 0.7935 ± 0.0000 0.3033 ± 0.0000 \n", + "12 wordpiece 14550 0.3142 ± 0.0000 0.7839 ± 0.0000 0.3140 ± 0.0000 \n", + "13 wordpiece 16414 0.3258 ± 0.0000 0.7750 ± 0.0000 0.3248 ± 0.0000 \n", + "14 wordpiece 19199 0.3343 ± 0.0000 0.7684 ± 0.0000 0.3346 ± 0.0000 \n", "\n", - " epochs_to_best_val num_parameters n_seeds \n", - "0 35.3 ± 2.1 10850856 3 \n", - "1 36.0 ± 1.0 10913256 3 \n", - "2 39.7 ± 0.6 11169256 3 \n", - "3 40.0 ± 0.0 11489256 3 \n", - "4 39.3 ± 1.2 12129256 3 \n", - "5 37.7 ± 2.1 12769256 3 " + " epochs_to_best_val num_parameters n_seeds \n", + "0 33.0 ± 0.0 10850856 1 \n", + "1 25.0 ± 0.0 10913256 1 \n", + "2 27.0 ± 0.0 10977256 1 \n", + "3 38.0 ± 0.0 11041128 1 \n", + "4 38.0 ± 0.0 11104360 1 \n", + "5 36.0 ± 0.0 11167336 1 \n", + "6 37.0 ± 0.0 11230120 1 \n", + "7 37.0 ± 0.0 11292328 1 \n", + "8 38.0 ± 0.0 11354664 1 \n", + "9 36.0 ± 0.0 11415976 1 \n", + "10 40.0 ± 0.0 11477480 1 \n", + "11 40.0 ± 0.0 11599272 1 \n", + "12 40.0 ± 0.0 11780456 1 \n", + "13 40.0 ± 0.0 11899752 1 \n", + "14 39.0 ± 0.0 12077992 1 " ] }, "execution_count": 3, @@ -405,16 +550,16 @@ "id": "e9fac0c5", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:03.344312Z", - "iopub.status.busy": "2026-08-02T09:59:03.344312Z", - "iopub.status.idle": "2026-08-02T09:59:03.559127Z", - "shell.execute_reply": "2026-08-02T09:59:03.559127Z" + "iopub.execute_input": "2026-08-07T10:53:08.215191Z", + "iopub.status.busy": "2026-08-07T10:53:08.215056Z", + "iopub.status.idle": "2026-08-07T10:53:08.330467Z", + "shell.execute_reply": "2026-08-07T10:53:08.329650Z" } }, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -464,16 +609,16 @@ "id": "f24dbe8c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:03.559127Z", - "iopub.status.busy": "2026-08-02T09:59:03.559127Z", - "iopub.status.idle": "2026-08-02T09:59:03.713955Z", - "shell.execute_reply": "2026-08-02T09:59:03.713955Z" + "iopub.execute_input": "2026-08-07T10:53:08.331897Z", + "iopub.status.busy": "2026-08-07T10:53:08.331762Z", + "iopub.status.idle": "2026-08-07T10:53:08.474145Z", + "shell.execute_reply": "2026-08-07T10:53:08.473326Z" } }, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -521,16 +666,16 @@ "id": "a718abe6", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:03.713955Z", - "iopub.status.busy": "2026-08-02T09:59:03.713955Z", - "iopub.status.idle": "2026-08-02T09:59:03.888337Z", - "shell.execute_reply": "2026-08-02T09:59:03.888337Z" + "iopub.execute_input": "2026-08-07T10:53:08.476008Z", + "iopub.status.busy": "2026-08-07T10:53:08.475469Z", + "iopub.status.idle": "2026-08-07T10:53:08.567552Z", + "shell.execute_reply": "2026-08-07T10:53:08.566804Z" } }, "outputs": [ { "data": { - "image/png": "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bt262aOPPmolSpSwF154wS644AJbsGCBtWjRwpXZvXt3xHO++OIL69Kli1188cUR2/v06WOTJ08O8BUCAAAAQNG1Oyo2S28Yedd/zLINOw+k+bgGlFdNKm0zbu1U4BKoxXl52Od+4oknuuB5zJgx7r5OpVatWjZgwAAbPXp0TPtISUmx0qVL27hx4+yqq65Ks8zll1/uAvJffvklood7y5YtRxVwJycnu172nTt3WmJiYrb3AwAAAABF1fe/b7XLXp6Tabl3hrbJFwnVshIH5tmQ8m3btrkAuFOnTqFtGtat+999913ML/TJJ5+0hIQE69q1a5plduzYYe+//74NHTo01WPTpk2zMmXKWPXq1a1v3762cuXKo3hFAAAAAICs2rRrf46Wy0/yLODesGGD+3nsscdGbK9SpUrosfQoUFZwrqsKDz/8sL377rtuHnha3nrrLdcLPmjQoIjtDRo0sHfeeccdS0POdXWiY8eO7md6Dhw44IL88BsAAAAAIPuqJMTnaLn8JM+TpkXTsHIF0xnRPG+V27x5s/3tb3+zXr162dy5c9OdJ6453tGBvZ53/vnnuyEAjRs3tokTJ7oh5vqZHg1zV5Dv3zT8HQAAAACQfafWqWCZTc3W4ypX0ORZwF2tWjX3U0FzON2vWrVqTPuoXLmyS7qm7OIKrKMtWrTI3dIaTh6tfPnyVrNmTfv111/TLTNixAjXA+7fVq9eHdN5AgAAAADS9sOf2y0lk8xielzlCpo8C7grVqxoJ5xwgn355Zehbeq1njVrllvqKysOHTqUZq+4gvB69eqlO787eq73mjVrrEaNGumWUXI29YiH3wAAAAAA2beJOdzB0LDuV1991aZMmeKSqN1xxx0u8FUGcd+QIUNC62Pv2bPHLrnkEpdxfO/evbZu3TobOXKkLV261GU2D7d//357++23Xeby6GBcc7F79+5t8+bNc/tcvny5XXrppS75mjKaAwAAAAByR5VCPIc7T9fhVjCtxGPDhg2zjRs3WvPmzV1CtPQSoJUtW9YlP7v11lvdUHHdP+WUU1wveYcOHSLKKjO59n3llVem2VOtYyvg134qVKjgEqZpHriStgEAAAAAckerehWtelK8bdi539IaWa7u02pJ8a5cQZOn63AXdKzDDQAAAABHb9qS9TZswkL3e3iA6o9VHtu/pXVvVj1f/KkLxDrc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2/fff28lSpSwtm3bWoMGDSIenzFjhi1evDhiW+XKle2KK67IgVcFAAAAACjq8rSHW4FzixYtbNSoUfbDDz/YJZdcYv3798/wOY888oh16tTJpk2bZnPmzLHevXtbt27dbP/+/e5xz/Ps/PPPtz59+tjXX3/tgnkF8jpGuMmTJ9vLL79sGzZsCN22bt0a6OsFAAAAABQdedrDffvtt1tCQoLriS5durQtWbLEBeAXX3yxXXjhhWk+p3379vb3v//dihcv7u7/+eefVq9ePfvkk0/c8xRwX3PNNdazZ8/Qc9577z3r27evC+gbNWoU2q5A/IknnsiFVwoAAAAAKGryrIf7yJEj9v7779ugQYNcsC3NmjWzDh062KRJk9J9XseOHUPBtpQrV86KFSsW2qbfw4Nt8Yep//bbbxHb161bZy+88IK99dZb9vvvv+fo6wMAAAAAFG151sO9evVq27Nnj51wwgkR20888USbN29ehs9duXKlGxKenJxsH3/8sevRvuCCC9Itr8Bec7lPOeWUiO3bt29387jXrl1rgwcPtvvuu89GjBiR7n4OHDjgbj4dHwAAAACAfBVw79q1y/0sX758xHbd9x9Lj4JezbnesmWLbd682fWWHz582EqVKpWq7I8//uiGoI8cOdKqV68e2j5s2DAbO3asxcXFufsTJ060yy67zDp37mxt2rRJ87ijR4+2+++/P1uvFwAAAABQtOTZkPIyZcqk2Uu8c+dOK1u2bIbPVa+45l6//vrrrjdcwfLzzz+fqtzy5ctdQrVLL73U9V6H01xxP9gWlalatarNnDkz3eOq91vn59/USw8AAAAAQL7q4a5Tp46bux09d1r3GzZsGPN+atSo4YLnhQsXRmz/5Zdf7KyzzrLzzjvPXnrppYjgOj0adp7RMHGdrz/fHAAAAACAfNnDreBWwbASlqWkpITmZs+ePdst9eWbPn2668mWQ4cO2X//+9+I/WhI+U8//RQxF1xlNDS8R48e9sorr7hEauE0BF3rdEevy71mzRo744wzAnm9AAAAAICiJc7TOlp5RL3Z7dq1c8tztWrVyt59913Xuz116tRQ1vEhQ4a49ba1ZNjBgwfd/Got7dWkSRPbsWOHy2iu3vJPP/3UEhMTbd++fW4fCs6HDx8eEWyfc8457lia763jNWjQwJo2bWqrVq2yt99+22VMHzdu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", + "image/png": "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v6e6sUm5JEmSJEll4BNuSZIkSWog8+bNq3GZlyfNCEePHl/jcrceMygM6du1nrZM5WDALUmSJEkNpJQ+1cMGdAi9ur0bB0gr1iCcXts9KtqHYQN6O0VYE2eTckmSJElqQhgIjam/UDgkWnrN587H3fQZcEuSJElSE8M82zccsXl8kp3Fa953Hu7mwSblkiRJktQEEVTv3L9HGDd5Zpg+d0Ho3rl9GNyni0+2mxEDbkmSJElqomg2PrSfA6M1VzYplyRJkiSpJT7hXrhwYfj73/8epk2bFjbeeOMwZMiQGr/z+eefh+eeey4OqT9gwICw+eabf2OZyZMnh5deeim0bds2rnOttdYqUwokSZIkSWpiT7inT58evvWtb4URI0aEp556Kuy2227huOOOq/Y7V1xxRdhqq63CXXfdFR577LEwfPjwsPfee4dFixbFz3O5XDjwwAPDd77znTBmzJhwxx13hA022CBcdtllDZQqSZIkSZIa+Qn3mWeeGVZYYYX4JHqllVYKr732Wthiiy3CPvvsE/baa6+i39l0003D22+/Hb+H999/P6y77rrhoYceCvvvv38MuA8++OBwzz33hFat/m/Q/D//+c/hiCOOCPvtt1/o169fg6ZRkiRJkrR8arQn3EuXLg333ntvOProo2Owjc022yxsvfXW4e67767yezvttFM+2EbXrl1DmzZt4vrQunXrcMABB+SDbfAUnED8P//5T1nTJEmSJElSoz/h/vDDD8PcuXPDRhttVOl9Xr/yyivVfnfKlCnhwQcfDHPmzAl//etfw/e+97349LoqLEtQztPx6vqS85ewbkmSJEmSmt0TboJtrLLKKpXeX3XVVWsMdufPnx/eeeed8MYbb4SpU6eGzp07559wF3rzzTfDGWecEX72s5+FXr16VbnOCy+8MFRUVOT/evfuXad0SZIkSZLUqE+4UzPyFHgnBNsdOnSo9rs8Bb/22mvzT7s32WST0Ldv33DKKadUWu69996Lg6cxqNoFF1xQ7TpHjhwZTj/99ErbYdAtSZIkSWp2ATfTdK244opx+q6sSZMmhfXWW69W66Hv9/jx4yu9z2BqO+ywQ/y79dZbY9/u6rRr1y7+SZIkSZLUrJuUM/AZ04AxgjgDmuGjjz4KY8eOjU+kk2eeeSbceeed8d+LFy8OH3zwQaX1zJw5M0ycODGOVJ4N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vVbfOf7448Nbb70Vmhu2m0pQqRYsWBC/8/7774fmhECS7Z4yZUrJ3yE45zu1uSHRFKTtnj59esnfIY18pzY3JJqCjz/+OG733LlzS/4OeZfvkJebk7TdX3/9dcnfoUziO83NxIkTww9+8INafeeVV14JJ598cmhuqLCdfvrptfrOc889F0aMGBGaG7Z75MiRtfrOE088Ec4999zQ3FAZ/9WvflWr7zz44IPhoosuCs0N233ppZfW6jv33HNPuPLKK0Nzc9ddd4Vrr722Vt/h5uFNN90Umps//OEP8a82brjhhmZ54/OGG24Id9xxR62+Q/4lHzcHbRt7A/R/uKN6++23xwr6VlttFS+InTt3zu8enh795je/iXet2rdvH0444YSwyy675D8/7bTT4p2hVq1ahdVXXz18+9vfjkFr27ZtKzVN33///WNwxx0zljnnnHNazCE49thjQ69evUJLt8IKK8S0du/ePbR0HTt2jGldZZVVQktHGkkraW7pyLuklbzc0lEmkdblQZ8+fcJRRx0VlgcbbrhhOOSQQ8LyYODAgeG73/1uWB5svvnmYaWVVgrLgyFDhoQ111wzLA+22267WrXCas6GDx8eOnXqFJYHu+66a7Op9xtwNwEXX3xx+OUvfxmD3y222CI+JfjJT34Sfv/73+eXOfvss8Mpp5wS78ITLO+xxx7xCfCAAQPi5yeeeGI4+OCDQy6Xi08QWd/bb78dbrzxxkpN02lyRCDO3erevXtX+1SG76eL7Lx58+JdRQrojTfeON+E6dNPPw277757fM0Trqeffjr+n4tW//79K62Tpl1UyFZdddV442C11VaLBQP4Lda39tprx9/Iotkpdyf32Wef2LSeJy89e/YMw4YNq7QcNyoqKioqvTdr1qwwduzY2Jx5s802C+uvv/430sq2PProo2HTTTeNhXK7du3CfffdF7bddttYqWIdN998c2weTGWSdfAezZPmz58fBg8e/I313nvvvTH9XLhp/sT27rDDDvlmbm+88Ubo27dv/G7WV199Fe/wsd85jhyHtdZaK2yzzTb5Zdq0aRPTmr0hgxkzZoRnn302Nndl//fr169okx3yzyabbBK23377sHTp0jBmzJiw4447xu1hHdxlZB1HHHFEXAfvsQ+5WA0dOjQewyyaYnLMWBdPilgPy6U88s4774R11103rLfe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", "text/plain": [ "
" ] @@ -582,16 +727,16 @@ "id": "70921265", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:03.888337Z", - "iopub.status.busy": "2026-08-02T09:59:03.888337Z", - "iopub.status.idle": "2026-08-02T09:59:04.069254Z", - "shell.execute_reply": "2026-08-02T09:59:04.069254Z" + "iopub.execute_input": "2026-08-07T10:53:08.569035Z", + "iopub.status.busy": "2026-08-07T10:53:08.568901Z", + "iopub.status.idle": "2026-08-07T10:53:08.669496Z", + "shell.execute_reply": "2026-08-07T10:53:08.668734Z" } }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAArIAAAG4CAYAAAC5CgR7AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAjmtJREFUeJzt3Qd4U1UbB/B/d+mmhS7K3nvvvZQhQzYIigw3ijgQF+Lic4GKisgQEQSRDTJEBJS9R9l7FEqhhe7dfM97QkLSpm1a2qZp/7/nKSX3ntx7c5Mmb859z3tsNBqNBkREREREVsbW0gdARERERJQbDGSJiIiIyCoxkCUiIiIiq8RAloiIiIisEgNZIiIiIrJKDGSJiIiIyCoxkCUiIiIiq8RAloiIiIisEgNZIiIiIrJKDGSJ8sjw4cMRFBRU7M/nSy+9BC8vrwK7HxWMwvr88O/OMuegsL4eqPhhIEtk5caMGYNSpUpZ+jCokD9/fJ0QUVHEQJaIiIhy5LvvvsO9e/d41sjiGMgSERERkVViIEuUx8LCwtC/f394eHioS8bPPPMMoqKiMrQ7fPgw+vbtCx8fHzg5OaF27dqYNWuWUZszZ85g4MCBCAgIgKurK+rVq4cvvvgCCQkJan2XLl0wd+5chIeHw8bGRv9z584ds451ypQpsLW1xcWLFzOsmzZtmtrWyZMn1e2PP/7YaB+enp7o3Lkz/vnnH+SnDRs2oG3btnBzc1PnoE2bNvjzzz9zdJ7MbfMw5yc32zfn+SsMr5PC+vzk5O/uk08+Uc/luXPnMtxX9mP4XD7M68Dcc6J7buWYfX194eLigqZNm2LJkiX69Tn9mzP3vSc75jwX6XNkt23bZnSs6X/SP+7sXtNEZtMQUZ544oknNAEBAZq+fftqNm/erImMjNRs2rRJ4+fnp2nbtq0mNTVV33bbtm0aJycnzaBBgzRnzpxRbRcuXKhxdXXVfPTRR6pNcnKypmzZsppu3bppzp07p4mPj9ecOHFC89Zbb2lWrVql39bo0aM1Pj4+uTrmq1evamxtbTXvvvtuhnV16tTRtGzZ0uT9UlJSNBcvXtQ888wzGmdnZ83Jkyf161588UWNp6dnjo/F1P2WLFmisbGx0Tz//POaa9euaa5fv64ZN26cWibny9zzZO65zO35ye32s3v+CsvrpLA+Pzn5u7t165bG0dFR8+qrrxrdPy0tTVO5cmVNixYt8uTvxJxzIrZs2aKOp1evXppjx45pYmJiNAcPHtQMHTpU3Scnf3M5ee/JjrnPhTl/5/J45LVau3btHL2miXKCgSxRHpEPE/luuHLlSqPl8sEmy1esWKFfVrNmTU29evXUh5OhDz74QH1IRUREaE6fPq3u9/vvv2e534cNUOQDKygoyOjDbs+ePWrfc+bMyfb+pUuXVh9yeR3ISoAhx9WoUaMMbSXokA9pOX/mnCdzz2Vuz8/DbD+r568wvU4K6/OTk787CRJLliypiYuL0y/bsGGDajd79uyHfh2Ye05E1apV1fOb/rk1R/q/uZycg+yY+1xk93d+5coVFVz7+/trLl++nKPXNFFOMLWAKA/J5cfHHnvMaFmfPn3UpTXd5cALFy7g1KlT6NevH+zs7IzayiVguXy3b98+lC1bFt7e3nj//fexePFidVk4P4wePRrXr1/HX3/9pV82b948dUlx8ODB+mVyifKNN95AtWrV4OzsrL9kePv2bZw/fz7Pj0sub8pxyXlKTy6f3rp1C8HBwWadp4c5l+acn/x4rgrb66SwPj/m/t2JF198EXfv3jW6fP/DDz9keK3n9nVg7jmR9Ab5kfulf24N5eRvztxzkJ28eD3Jcffs2RORkZFYt24dypcvn6PXNFFOMJAlykPyAWBvb2+0TD6AJGdNl48YGhqqfn/44Yeqrbyhy498EEkunZAPD8mZkw/NChUqYOTIkSrnTXLVPvvsMyQmJubZMcuHXenSpVUOpYiLi1Mf9PIhKzl+OvLhs2DBAnz99de4efMm0tLS5IqOOr7k5GTkNd0HqL+/f4Z1umVyTs05Tw9zLs05P/nxXBW210lhfX7M/bsTrVu3Rv369TFz5kx1++rVq1i/fj0GDRoEd3f3h34dmHtOJJdVlClTJst95uRvztxzkJ2HfS5SUlIwYMAAlTMsgXDjxo1z/JomygkGskR5KCIiQr2RG5I3f+mhkIENQlcz9PPPP1dtU1NT1Y/uQ0p+hg0bptrIh8DGjRtVmZvt27ejffv2eOuttzBx4sQ8O2YHBweMGDECa9asUR94y5YtU8crPVA6N27cwJYtW/Daa6+hR48eKFmypOrpkeOXHqj8IB/MQnqx0tMt051Lc85Tbs+lOefnYbafmcL2Oimsz4+5f3c6L7zwAvbv348DBw6oAUZyTtM/l7l9HZh7TiQgFiEhIZnuL6d/czk5B9l5mOfiueeew+bNmzF9+nT07t07169pIrPlKBGBiDKly1NLPzhFcs3S56lVq1ZN5czlZBCGTuPGjTUNGzbU33755Zc1bm5uD/XMyMAROcbp06dr2rVrp6lRo4bR+pCQELX+66+/Nlr+yy+/qOV9+vTJ8xxZOTdlypTRNG3aNEPbVq1aqXxDGZhi7nnKbRtzzs/DbD+r568wvU4K6/OTk787IYOq5HEMHz5cHWP16tU15srudZCTc5JdjmxO/uZyeg5yI/1zYerv/OOPP1b7e+WVVzLdzsO8polMYSBLlEd0I4cff/xxzd9//62JiorS/PXXX2qwg3yIGX5gychdGdgwcOBAzZEjRzSxsbFqcMQff/yhadOmjWorbYYMGaL5559/NLdv31ZtVq9erXFxcdFMmDBBv62ffvpJfXhIu9wMHNGRkdcyUEW29cUXX5j8IKtYsaLm0KFDaqSxHGuHDh3UiO/8CGTFokWL1GhvWScjueXDXT4k5RjlA12Yc57MPZe5PT8Ps/2snr/C9DoprM9PTv7uDIN6OUb5+fzzz/P078Scc2JYtaB3795GVQuGDRumr1pg7t9cbs5BZsx9LtK/HtavX68etxxXVkGqOa9popxgIEuUR+TDRHpjQkND1Zu59H55e3ur0eJ3797N0D44OFiNopYPG/lAq1Chgmbw4MGaHTt2qPXScyM9Kp07d1ajzWV7Mtr3yy+/NOrpSkxM1IwYMULtSz5I5ANTPoByau7cueq+Dg4OqlRRevJhI+V9vLy81I+Uz5F20qOVX4GsWLt2rfowlg/SEiVKqEBCPlh1zDlP5p7L3J6fh9l+ds9fYXmdFNbnJ6d/d7qR+XIO7O3t1f3y8u/EnHOic+DAAXXMcrzSVnpyFy9enOO/udycg8yY+1ykfz1IUK/7cmDqx1B2r2minLCRf8xPRCAiIrJukptarlw5lcO5cuVKSx8OET0EDvYiIqJiRQZqyQCjsWPHWvpQiOghsUeWiIiKDSm51bFjRzXd68GDBzNMn0pE1oU9skRF0MKFC7Oc91x+ZB734nIcxOdH1KhRA1WqVIGfn5+qcVqcglj+LVJRxR5ZIiIiIrJK7JElIiIiIqvEQJaIiIiIrJLxxMyUIzLqVaYRlDm6i1OuFREREVF+kcqw0dHRCAwMhK1t1n2uDGQfggSxZcuWfZhNEBEREZEJ165dQ1BQELLCQPYhSE+s7kR7eHg8zKaIiIiICEBUVJTqKNTFWVlhIPsQdOkEEsQykCUiIiLKO+akbXKwFxERERFZJQayRERERGSVGMgSERERkVVijmwBlOhKSkrK790QWYyjo2O25VGIiIjyAwPZfCQB7KVLl1QwS1RUSRBbsWJFFdASEREVJAay+VjM9+bNm7Czs1MlJNhjRUV5UhB5rZcrV44TgxARUYFiIJtPUlJSEBcXp2alcHFxya/dEFlc6dKlVTArr3kHBwdLHw4RERUjTGzLJ6mpqeo3L7dSUad7jete80RERAWFPbKFoJgvkTXja5yIqIhLSwWu7AJibgFufkD5VoCtHQoDBrJUaJw5cwb+/v7w9PQ0+z6nTp1CmTJlisTMajl5LEXpcRMRUSF2cg2wcSIQdePBMo9AoNtnQK3esDSmFlCh0blzZ6xduzZH92nZsiX++usvFAU5eSxF6XETEVEhDmKXPmkcxIqom9rlst7CGMgWcqlpGuy+EI7VR0LUb7lND9SqVStHPbhERERkZjqB9MTCVNxxf9nGt7TtLIipBYXYxuCbmLL2JG5GJuiXBXg6Y3KvWuhWJyDP93f37l3cvn0b1apV05cQO3HiBPz8/NTIdBEREaF+qlSpor/fnTt31H3Lly+fYXDb5cuXUaJECbWNq1evqnJNFSpUUOtklPuVK1dUZQdpk57sW7bp6uqKa9euqcvoXl5eRm3mzp2rLrGnJ49DqkZkVfosPDwcMTExah+mmLMNceHCBbi5uanHaEhqCDs5OanHd+7cOSQmJqrtyO30jyOv6M6xPCZTuavyeOVxSaksKQ1n7joiIipmruzK2BNrRANEhWjbVWyLYtsj+8MPP6B69erqg71t27bYt29flu0loHnhhRdQuXJlFTh06tQJW7ZsMWpTqlQpODs7Z/h59dVX9W3GjRuXYX3jxo1RmILY5xceMgpiRWhkglou6/Pa8ePHUbduXcTHx6vbR48eVbcnTJigb/Phhx/i9ddf1weC3bt3R1BQEDp06KCC3R9//NFom2PGjMEzzzyjttOuXTtMmTJFLd+1a5cKaJs1a6bu//TTTyM5OdnovvXr11f7kue5devW8PX1xTvvvJPlJXYJnGU/VatWRfv27dUxzZ8/P0OAKeskoJTXnLQ1fN2Zsw1DX375JZ544okMk2HI62njxo3q9muvvYYhQ4ZgwIABKjCW/UrQmVcOHTqEmjVrol69emq/8kVjx44d+vVSUWDUqFHqHHbt2lX9jXz++efZriMiomIk+hZwZgPwzyfa3lZzyAAwC7JoILtgwQIVJH3yySeq961Ro0bqgzQkJCTT+0hbCX62bduGI0eOqABHgqng4GB9G7n/vXv39D9r1qxRvWG9ez9ISpagqUePHkbtdu/enW+PVXo345JSzPqJTkjG5DUnsurMxwdrTqp25mxP9m2OFi1aqJ44CTKFnONKlSqp3zryfwlaxfjx43Hr1i1VQ1TOufSOypeMgwcPGm1XgrmZM2eqAPHnn39WQd6wYcPQt29f1ZsbFhamlsnv9OS5k+dFvsBs3bpVBY3r1683efzSwyvPqQS3sl3Zn9z/xRdfxIEDB/TP+6OPPqq+OEkbCSbl+GSgmbnbSG/48OHq2OQ86MgxyhcCCVx1j0NeoydPnlSPU4LoV155BXlBzt2gQYPUMcuXCznunj17qmWxsbH6/cvPxYsXcf78eXWsui8OWa0jIqIiKiESuLgN+G8a8PtwYFpt4KtqwOIhwL+fA7cexFVZkioGxTW14LPPPsPo0aP1H/bTp0/HH3/8oXppJWA1JX2Pn/Tw/e9//8PevXtRp04dtUwu5xpauHCh6qHSBWA6cplXemILQnxyKmq9vylPtiVhaWhUAup+YN5gn5MfPgoXx+yfakkLkGBWgjIZeCVB68svv4z3339fBTg+Pj6q11bOY3R0NBYtWoRVq1bB29tb3V+eR+nJnDVrFn766Sf9dnv16oU2bdrob0sPqswE9emnn6rL3xI8f/HFF/jtt98yHJMEkNL7LuRLi+xj9uzZKthMb9OmTSoYk8BSLuWLkiVLomHDhipQa9KkCTZs2KBSAf777z+4u7urNrJ93T7M2UZ6rVq1UpfylyxZou+9lnMjj9uwqoAEyfK4o6Ki0K1bN3Vu88LmzZtVwC29yrqUADm38+bNw+rVq9WXBkkbkL8L3eQcksqh693Oah0RERUByfFA6HEg5BBw45D2d7j2M86YDVC6OlCmMRBQH/j3C2hi78DGRNeaBjawkeoFUoqrOAayklMpvVO6S826wLJjx47YuXOnWduQXlYJmOSDV+5nSmRkJJYtW4bJkydnyBmUAECCMBksJJd65cNfLnMXZxKkSjAnvbgS7MkXCrktwa1cYpdzJZevJaCVNrovDzqSQiC964YqVqxodFsCSTnPhkGe9FBKwGhqMJeh2rVrY/HixZmWpJJjGjp0aIZ1ul5p6XkNCAjIkM+ak22kJ68rCRblC5MEsvKaW7duHX7//Xd9GwnU5VzKFyd5zUkvqgSQEtQ+bAkt+ZIh50/3hUJIzq6cd1kn+vfvr3rDJeB+5JFH0KVLF9VjK89nVuuIiMjKpKYAt08ZB61hJ4G0lIxtvcppg9bARkCZRtrg1UnbySMO33NG/V0vqzDW1iCE0o471+BI7YloaOF6shYLZKVnSkheniG5nf7SdHoSgEpvlwQD8mErgapcAjdFgh65TDpy5Eij5fKhPWfOHJUDKZfFJYdRgtljx47pe+pMBc7yoyNBiLlKONipnlFz7LsUgZE/78+23fynm6JZRW+z9p2TQPbjjz9W6QX29vYqcJRl0jsrgaz0uMoXDhmAJXT5tDoyOEq3Tif9wCHp+Ut/P1PbMnf7hj3KEihKkJ1ZkX5ZL9vIjDnbMEVyZCVQlUBYUiHkGCXlRezfvx9vv/02tm/frnpvxT///KN6vWVg1sOSfZk6d4bnSs657PPs2bPq9y+//KK+REp6juTEZrWOiIgKKY0GiLhoHLTePAqkZPxMgGtp46A1sCHgmvl7vFRJeuFQEOolj8dkhwUIRIR+XSh88GHyCBw9FIQdXTWwM4xyi1vVgvSjweV2djmdEgBITqvkAspl7Mcffxz//vuvycFakrcpubHpe+AmTZpkFDxLMCy9WnJ5eOzYsSb3O3XqVKMe5JyQoMicy/uibdXSqjqBDOwydSbk5eLv6aza5fWLR1ILJICVoEyCfCGB7Ndff63Ok+4LgQzUkh5UGWgnwa5u0JAEvOkHPqUnl+lDQ0Nx+vRp1KhRQy2TwDkhwXhgm5CeYOnt1JFAS+5viqQvyJcL6UGWS/eG5EuPBKmSniBXA2R/uqBSyJcdBwcHs7Zhigy0khxvSSmQQFZ6NGV7ul5gef0Z7i/9AMWHIedD/hbkS5j0lut6vSXdQHeudMcuFSnkR1J6JLiV8yCPM7N1hnnlRERkYVJFwDBovXEYSLiXsZ2TBxDYwCBobQR4Bkkwku0u0tI0uBQei5WHrqsB5zfRDJsTm6CZ7Wn44h7C4IV9aTWQJsOsIhNU51vLyj4odoGsLrCUcj+GZCBMZpd90+e2yuXpjz76CH/++adKMZCg1pB8sMsAHWmTHbksK2WHpFcqMxL8Go7gl4BHRqDnNQlOpcSWVCeQl5xhMKt7Ccr6/PgGpMuTlVxSyVUW8gVBBg1JFQNdnrEEuxLUv/vuu+oytgRA0l7OiQwCy4rkmUrwNHjwYDU6XnJHpaKEqZJPEhhKfrP0lsuXjMOHD+PXX381uV0JJKX6wYgRI1SvsgRxEsxJxQEZhPbYY4+pNhJoS6ApX0xk2xIsS++l3MecbWRGtispBPIaNnzNyeBEWSapK3LZXnpm5YtBXpHnp1+/fqoqggyGk+dm4sSJ6rmSqh7iu+++Uz2skmMsX9gk9UGe6wYNGmS5joiILCQuQhuoqqD1/u9oExWL7JyAgHrGQatPFQmWst1FSmoaLtyORXBIJIJvROJESBRO3IhEbJJxbVgJWvekGaf66YRFZ+yEKhaBrAwckvJG8qEuPapCemLltqn8xKzI/Uz14kpvrASnkveXHQnArl+/rqZIzYwMiEk/kCy/SJ3YmcMbZagj65+PdWR1JCiSwEt6voUEmBJ0SiCr6/HTlTCTNAzJDZVeTlknvZGGuZqSp2nqnErKhwwik0FF8mXgm2++wVdffZWhvqpUO5Bt6gaVSY+sbmCWqQkR5DmXQU7Swy6DwuQ1JtUBpFKBjlw6l6Bb8kIlVUSCPcPBTeZswxR53co25ZgMe18lyJfjl8e4fPlytV6CcXn8hsF7TiZ3SN9WngMZPCkBtPwtyBcFSWfQkS8KMphOHpv0huv+9uTvI6t1RERUAJJigZvHDHpaD2lTBtKzsQV8a2nTAnRBq28twN4x+12kpOHsrWh90BocEoVTN6OQmJIxxc3ZwRZBJUvgfJi28k1WfN0LZtB8Zmw05tZmygcSpLz55pvqQ156AaV3Tnq0pEyRLuf1+eefV6OxJW9WegWfe+451dskl6Ql+JTeJOkZlEu1hlUJJEDRlTiSgMGQrJNL5NLDKpeEJYCVEeRyKVUGKmUVzBqS/UswIYN70g/YkcvkUq9UArmHqYwgOSrSbS/feOTFIjmxlsxFKUjSsyi9g+kv8VPhklevdSKiYiE1Gbh14kHQKj8yOEtjYsyEdyXjnlbpeXU0PU7EUEJyqgpSg29E4cT9wPVMaDSSUzOGfG5O9qgV6IE6gZ6oU8YDdcp4olIpV5US2eazf7JNc9wxsVOexyVZxVeFKkdWglTpyZOeLKl/KUGlBC6GA7ckd1E3wEoGrvTp00cVb5fBONI7Kpd+JZ8xfWktCY7lBEjb9OR+chlVivVL+oGcJLl0LT1/5gaxBUVeHJbMPaGCJ38TmdVSlrxbmUCEiIisgAzoDT9vELQe1JbBSn0wcFzPPeB+0NpQ+1t6XV2yH9Adk5iCkzeijNIDzt+OMTmlvWcJB22wqoJW7U95bxfYZhKIWirN0Wp6ZA3J6G1T04BK/qSsSz/IRg47q1Hlcj8ZfJRdKkB227F0j2xxJjma33//vRqgVZysWLEiw1UEHfmi9ffff6Mw4WudiOh+BYHI68ZBq1QQSDRR4cjZ07inVX5LTdZsRMYlqxxWXWpA8I1IXLoTq3adXik3R22wer+ntXagp0oXyGnMIzOJpk9zDMjnNMec9MgWmkDWGjGQJWIgS0TFVGy4cdAq/481HsCu2JfQ1mc1DFolZSCbgPJOTKLqZT1h0Nt6LcJEWS1oA8va9wPWuvd7Wn3dnXLdUWfpNEerSS0gIiIiKvQSo7W9q4ZB672rGdvZ2msHXxkGraVrAnaZh1vSn3grShu06npapdfVsAfUUDlvF30Pa50ynqgd6IFSbk7FNs2RgSwRERGRTkoicCv4wUAsCVpvn0mXJXqfT1XjoNW/LuBQIsug9frd+AxB652YpAxtpTO1YinXB4OwAiVo9YSni7ZGOWkxkCUiIqLiKS0VuHPWuKc1NBhIS87Y1iPowUAsNZ1rA6CEV+abTtPgcnisUeUACVwj45NN9nhW9XXTpwdIT2vNAA9VUYCyxjNERERERZ8MCbp3RRuw6mbFknSBpJiMbUt4G/e0ym93v4eeWEA42Nmgur+7UeWAGv7ucM7BdPL0AANZIiIiKnqibxlPMCC/4yMytnNwvT+d6/1JBso0BrzKZzoYSzexwAmDygFSszUh2fTEAtKzalg5oJqfOxzts591i8zDQJaIiIisW0KktodVH7QeBqKuZ2xn6wD413nQ0ypBa6lqgK3dQ08s4OpopwLV2gaVA2RiAXs7Bq35iYEsFRpNmzZV06rqpiw2R+3atdVscD169EBxx3NBRMVCcrx2UgHDntbwcyYa2gClqxsErY0AvzqAvVOmEwuooFUC1vupAefCsp9YoLaq1eqBCj6umU4sQPmHgaw1JKJf2QXE3ALc/IDyrTL95mjtbt68qaYhzgmZASsuLg6WJrNtffvtt3j00Uctts3Cci6IiPJMaop2+lbDoDXsJJCWkrGtV7n7QWvj+4Ox6gNO7iY3KwOuDAdgZTWxgI/r/YkFDGbEys3EApQ/GMgWZifXABsnAlE3HiyTmT+6fQbU6m3JIys0Tp48iZIlS1r6MFQQGR8fX+i3SURUaEkUGXHROGiVwVgpJt4HXUsbB62S3+payuRmw2VigfuTCujyWq9GxGU7sYAuaPXzyLuJBSjvMXGjMAexS580DmJF1E3tclmfx7Zs2YKaNWuqKYHFtWvXEBQUhHfffVffZtq0aRg0aJC+Ht4333yjUgIqV66sUgKOHTtmtM2hQ4eq6VZff/111KpVS3/f8PBwjBw5ElWrVkWnTp3w+++/ZzieChUq4JdfflHbkPu2bdtWHaOhrl27YuvWrfrbycnJ+PTTT9G4cWP1WAYPHowzZ6T+H4zaTJ06Fc2aNVNtXnrpJTV7SE62Yahly5aqJ3TMmDHqfDVq1Mjs7cjjbteunep97du3Lw4ePJjlNnM6M8qrr76qzl2NGjXwwgsvqPNuzv6zW0dE9NDk8+3UOmDLh8CCvsBn5YEZjYAVY4A9PwDX9miDWEd3oEJboPV4YNACYHww8Po54ImlQIeJQNWuKoiVz6TQyAT8ffIWvv77LMb8cgAtp25B44//xlPz9uGLTWew/nioPogt610C3ev4441Hq2P+001x4N0u2D2pM+Y81QTju1RDl1p+8Pd0ZhBbyLFHtiC/aSbHmZ9OsOFN08WX1TIbbU9tpQ7mpRk4uGQ7FZ6QYOns2bM4evQoGjZsqAJECYbWrl2Ljz/+WLVZt24d2rRpo/7/2WefqfzUWbNmqWBnxowZKtiUbfj5acuU3L59G0uXLlW5rytWrICPj3ZmkIEDB6rexoULF6qAT4KsGzeMg/br16/jueeew/Tp01UwLYGV5MLK8UlgZupy+hNPPIHQ0FB1H19fXyxevFgFhadOndIfkwSUsg0JyiWQlsf51Vdf4cMPPzR7G4ZWrlypAnk5H5IGYGdnZ9Z29uzZo4L5efPmqS8DEuS+9dZb2Lx5c6bbzAn50nDr1i3Mnj0b9vb2GD9+PB577DHs2rVLvTFntf+s1hER5VhchHYwlm4glpTAignN2M7OSTupgL6ntRHgUwWwtc04sUBEnFHlAPkt07qmx4kFijYbjbwaKM/nAk5ISMClS5dQsWJFODs7A0mxwKeBljnTb98AHF3NatqgQQM8+eSTmDBhAkaNGoVSpUqpXlcJMt3d3eHl5aWCWQlYJSj9/PPPVbAppCdXeh779eunejxFly5dkJSUhH///Ve/DwmSWrVqhXPnzqlgTUhvX5MmTfDrr79i+PDhapkEX88++yy+//57/X07duyo7jNnzhx1W45H/j9gwAC1jRYtWqjgURcwC9mX9Ci++eab2Lt3r2pz4MAB1VOqI8dua2tr1jZMcXNzU0G5tNE9nuy2I8f95Zdf4vTp0xmOw9Q2s2N4LuQcS9AsqRfynIgrV66oc/fnn3+q4Dir/Wd3bFm+1omoeJPPu5vH7get92u23r2UsZ2NrXb6Vt1ALAlaZXpXe8dcTywgY62q+rqrygGSGlA3iBMLFLX4Kj32yJKRDh06YNu2bSqQld9yaV+C0O3bt6ugNjU1VQVIFy9eRHR0tLr0rCNBjtyW3k5D6S+Ly/qAgAB9ECskqHRxccnwbOh6f3UkgN64caPJZ016GuV7mWxL9/1Mft+5cwd16tRRt3fv3q0CS8MgVnfs5m7DHOZsR4L8N954Az179lTBZ+fOnVGuXDnkBTnHpUuX1gexonz58irYlHUSyGa1//w8NiIqQlKTgVsnDILWw9rBWZqMNVVRsqJxT2tAvQydLDKxwMVb0frKARK0nrwRpSoKZDWxgK5yQA1/D5RwLJoDosk0BrIFRS7vS8+oOaRKwaIB2bd7Ypm2ioE5+85BIDt//nxcvnxZ9SY2b95cLZPL7xIYye0SJUogMVF7+cbJybiMidzWrdNJ30sn6x0dHTMepkPG+aPTt5Pb6bdv2DMoA7927NiRYZ2rq/bNMiUlJcMx53Qb5jBnO5IDLD2ekjKxevVqjBs3Dt26dcOSJUtUb/TDkHNk6nEaPj9Z7T8/j42IrJSMnwg/b9zTKmWwUk28J7v53w9a70/pKoOxXLwzTixgMAArq4kFnOzvTyxgMAiLEwuQ4CdSQZEkHTMv76NyJ211AhnYZTJP1ka7XtrlcSmu9u3bq55WyR+Vy+ASOEogK4O1JM9T/q8OsXJllbcpvXuGPauHDx9GvXr1styH5KVKbmtERAS8vbVvbFevXjUacKVz/Phx9O/fX39b9if3z6yOqvR4Ss5stWrVTLaRgU9S5kvyb2UQVW62YYqcC8MsHXO3I7myL7/8svqRY5IAUvJQu3fvnmGbOSE5y/I4JUdZvoDoLtVIT7rh8WS1/6zWEVERJ+89kdeNg1apIJAYlbGts6fxVK7yWz6j0k0scPraPaPKATKxQFJqWpYTC+iC1sqlObEAmcZAtjCS4FRKbEl1AglajYLZ+4O2uv0vX+rJSi9i3bp11QAhXbUCubwvA7jOnz+vXya9ipJDKxUJZPR/mTJlVE+u5KDK4K+sSKUBucz92muvqbbSS/rKK6+YbCv5sVINoX79+li/fj1WrVqVaWqBXC6Xdk899ZTqOZR9SHAs6RESWMrl8UceeUQFs3Lskn8qwfmhQ4dUzuwzzzxj1jZMkcdvWJHAnO1IPrAEq/L4pJdbgkXJQ9UFnum3mROSGiABqwShMmBL9iPpIrLtPn36qDZZ7T+7YyOiIiY23Dholf/H3s7Yzr6Etj6rYdDqXcloQHFsYgpOXo4wa2IBD2f7+zVaPVE7UHpcPVGREwtQDjCQLaykTqyUGTFZR/Z/+VpHVnpdpedT1/sqg44kz1V6WyU/VkcGA0nwJz2y0nMrg8EWLFiQbS6pXJqWS9bDhg1TSdySGysDzExVBBgxYoQa7CRloyQ/VyoLZBZMSuC1adMmVU5LeiR1ObcSTMr2dfuWNnLcEihKQC49vBLsmbsNU9555x08//zz+PrrrxEYGKiC4+y2I+dXqjnIYDk5f1JJQKonyKC3zLZpLnkcy5cvx9NPP60Ggcm2JV9WvgjoUj2y2r88F1kdGxFZscRobe+qYdB672rGdjZ2gF9t46BVBmfZ2RtPLHAxHCf0lQMicZETC1ABYtWCgqpaYEUze8nsWnfv3lXBk24QlNyW3Ep/f/8M7aWMVkxMjBoMlr5otFxel0Aos1GHsl4GX8n9JCdXF9jqgk6pkCC5mXKO5Tymz/uUagrSiyy9hoakUoI8P3JMmZHjltJfmR2bOdswJD2W8ngk4JbBbOZuR9rLelMTO2S2TVMyOxdy7iRFQQLanO4/q3U6rFpAVIilJAK3grUBqy5ovS1XekxNYVXVOGiVMlgOJXI1sYC/h7PKZ9VOLqCdYECWcWIByuuqBQxkC3sgW4wZBrJUePG1TlRISMfHnbPGPa2hwUBaxjJV8Ah6MBBLTefaACih/bIrX3zDohONKgdI2asbkQkmdysTC+hyWSU9QILX0u6ZD6olyg7LbxEVMTKZgpTDMkV6avfv31/gx0REFh6Mdffyg6lc1WQDR4Dk2IxtS3gb97TKb3c/fdAaci8ewRckaL2V5cQColIpV32pq7plPFEr0ANeLhmr0BAVFObIUqElBfzNvaxf1MkALamhawrLYREVA9G3DILW+7/jIzK2c3AFAhtoy13pgtaSFdRgLJlY4EpEHIIvyqQCp/R5rffisp9YQHpbawa4w905Y5lEIktiIEuFlgzGIi3JGzY1YQQRFUEJkdoeVn3QehiIup6xna0D4F/HuKe1dHU1jkJNLHAnFsGXIxG881S2EwtITVZtwOqhelxrcmIBshIMZImIiCwlOV47qYBhT2v4ORMNbbRBqmHQKkGsvZOaWOBcWDROXI1C8J5TKrf1ZA4mFqjq5wYne86GRdaJgSwREVFBVJRJTdFO32oYtIadBNIy9pLCq9yDoFVmyJLarU7u2okFQqMRfD0SJ/adyXJiARc1sYBx5YAqpd1gb6etRkNUFDCQJSIiyomTazKp8f3ZgxrfMhgr4qJx0Cq1W1PiM27PtbRx0Cr5ra6l1MQCMmWrqh6w/6L6nZOJBSr4uMJOkl2JijAGskRERDkJYtWsi+mCSZlSfOkIoGZv7YQDErxKrmt6ju7awVj6oLUR4BmEyIQUVZtVDcA6eA3BIcGZTizg7eqoDVrvB6ySIiAlsFijlYojBrJERETmphNIT6ypyQR0y06tebDIzkk7qYBh0OpTBRHxKdpeVglcD99G8I3zuBLOiQWIcoOBLOXItGnTUKFCBfTr189qztz333+vZqaSKXHzsi0RFTNXdhqnE2SmxYtAvUGAby3cikt7MLHAUelx3ZrpxAJBJUsYVQ6Q/3NiAaKsMZClHFm/fj2aNGliVYHs5s2bERQUZFZwmpO2RFSMKgsc/wPY9plZzf8M98eyTUkIvvEvbkdnP7GALq+VEwsQ5RwDWSIiIlMiQ4D9c4CD801PPpCJX08kYk/abfV/GWtVxddN9a7qAleZDYsTCxDlDQaylMGNGzewcOFCXLt2DXXr1sXIkSPh6Gg8BeG2bdvw999/IzU1FQMHDkSjRo306+S+sl74+PigRYsWePzxx02mKLi7u2PDhg0IDAzE66+/btRGlu/YsQOffPKJ0fLffvtNHdvEiRPN2tfDCg4Oxu+//46IiAjUq1cPTz75JEqUKKFfHxMTg19//RWnT59Wj2Po0KEoV65ctuuIqBCS0VXX9gF7Z2oHdmlStcu9yuFypWFwPjgLvrirAtT0pJhAKHzgUrkNPqoVwIkFiAoAi8mREQkca9SooX5XrFgRBw8eVIGqIQkeP/jgAxU4hoeHq+Dx0KFD+vVyP1kmPx4eHnj11Vfx3HPPZUhRGDduHCZPnqwCu5o1a2Z4JiTw+/TTT3HunHFx8Pfffx9paWlm7+thSDAtQfrNmzdV4P3dd9+hTZs2SEpKUuvlONq1a6eC68qVKyM6Ohq9evXChQsXslxHRIVMSiJwdAnwUwdg3iPAiZXaILZCW2gGL8S/3TbjxcttMDn5KdU8fQUs3e0pySPQp3E5jGhZAY3KlUQJR040QJSvNBY2a9YsTa1atTQ+Pj6aDh06aA4cOJBl+5CQEM24ceM01apV0wQGBmq6du2q2bp1q1GbV155RePq6mr007Rp04fed3qRkZHy1qV+pxcfH685efKk+m0oMTEx05/k5GSz2yYlJZnVNifS0tI0VapU0YwePdpo+bVr1/T/79y5s6Zu3bqalJQU/bKOHTtqXn755Uy3e+7cOY2NjU2G7VSuXDnD40ivTp06mg8++EB/e/fu3Wpbly9fNntfffr00bz44otZ7sdUW935eO211/Tr7969q/Hy8tLMmDFD3T5//rx6DYSGhurbREdHq3ZZrStKMnutE1mFqFCN5p9PNZrPq2g0kz20Px/5ajSrXtTEXj2i+WXXJU2nL7dqyk9cp/95ZtL7mpD3KzxoP9lDE/J+RbVc1u86f8fSj4rIqmUVX6Vn0dSCRYsW4eWXX8b8+fPRsmVLfPHFF+jcuTNOnjypeuNMkZ7AZs2aqZ43e3t7/PDDD3j00UdVj2Dt2rVVm4SEBHTt2lVd0tWxs7N76H3nhalTp2a6rmrVqkaDjL788kskJyebbFu+fHl1yV/nm2++QVxcxvIt0uNpLun5PH/+vOpxNSSDnwx17NjR6HxWr14d168/mAdceiLXrVuHPXv24M6dO+q2ra0tzpw5Y7StLl26wMHBIctjeuKJJzBv3jz945DnrW3bturx52RfuRESEqLOh6QD6Hh5eaFnz57Yvn07XnrpJfj7+6sqB1OmTFE9zNKb7ebmptrKY8tsHRFZmExQsPdHIHgFkHb/fdY9EGg2BlcrDMTPR6KxbM51RCdq39vcnOzRr1EZbDh+E3/FNMPmxCZoZnsavriHMHhhX1oNaGCLAE9nNKvobdnHRlSMWDS1QIK6p59+GkOGDFGBybfffqtyD2fOnJnpfX766SeMGTNGXVIuW7asyp+U4EUCGUMSaEnQoPsxzGnM7b6Lurt376rffn5+WbZLfy7lXEuurM7w4cPxyiuvqOUNGzZUl/0luJRL64YkKMyOBLISTO7fvx8pKSkqV1W2n9N95UZYWJj6XapUKaPlcvvWrVvq/66uriqolf116tRJfQl64403kJiYmOU6IrKA1GQgeDkwpyswuyNw7HdtEFu2OdL6/4x/e27B0+fbot33x/HzzsuITkxR1QWm9K6NPW93xod96uCjvnXUpiRo3ZNWC2vSWqnfcltM7lWLs2kRFSCL9cjeu3cPJ06cUD2sOhKAyAe+5GeaQ3or58yZA2dnZ3To0MFonQxE8vX1haenp+rBk4A3ICAgz/adW5MmTcp0nRyDofSDnwyln8FFgrmHpevBlBxOyQfNbTC8ePFiHDhwAI0bN1bLJI927NixudqefFmR5096YqXHNSoqSp+zm9f7MrVvceXKFX0PsO624YAtGRCn6/2XgFvyYOXLgDx/Wa0jogISGw4c/BnYPxeIvl8H1tYBqNMfcY3G4I8bpfHLpsu4eOew/i4dq5fGyNYV0bZKKdgajOzqVicAM4c3wpS1J3HToB6sv6ezCmJlPREVg0BWRsYLCTYNyW0ZYJQVCVL79u2L+Ph4NcBnxYoVajCNYQAiPavt27dXl4claJABOkePHlW9s7ndt/SkGfamSVCVU+lH/1uibWbKlCmjBifJAKvWrVurLwhiy5YtKu0iJwx7RLNKpzCH9Lq+9957CA0NVZf10/fk5uW+DJUuXVqdD0nbkNePfNE4deqUGqi2ZMkS1eby5cuq51bSXUTTpk1VkCsBdVbriKgAhAZrqw8c+wNIvf/e7eoLNB2NKxUG4edj8Vj283XEJGqvvrg72WNgk7J4smV5VCjlmulmJVjtWssf+y5FICw6Ab7u2nQCO1OlDIioaJffSt8LKbc1piaXTpejKUGN9NDNmjVLlVv677//1KVl8c477+jbyuXc5cuXqyBNgg9JS8jtviVIknzHouyXX35RwaLkczZv3lzlmsr5NjeQlZxQqRogz0m3bt1w8eJFlbPs5OSU62OSHljJMV26dKl6LvNzX+lJDvYjjzyiKhdUqVJFfYmSPGZdiS/Jg5XecEl7kFxhOV+3b99WxyU53JmtI6J8nEb2zHpgz4/AFYMrbAENkNb8Ofzr2AY/77mJ7RtP6VdVLu2Kka0q4PFGQSoX1hwStLas7JMfj4CIcsBGRnzBAiQIlR4v6U01rPspNTovXbqkAlNzSQArQdePP/6Y5UAq2c/nn3+e632b6pGV3t/IyEjVM2xIAirZluTy6no2rYUEXnIOpOe6fv36qFNHmxOmK0clOaLSu6ize/duxMbGqsFbhsskt1XSOSTtQ1ID5LfuEr2p7WRlzZo1qndTnqP0vc/Z7UuCT8lXlUF92THVVgbR/fPPPyqVQerIyjlJT9Ibzp49q9IGpBfXcBBbVuuKAmt+rVMREn8XOPQrsH82cO+qdpmNHVCrD2IbjsHS0AAs2HMVl+7EalfZAJ2q+2Jk6wpoU6VUhnQtIrIcia8kNdRUfFVoAlldcPnYY49h+vTp+mUSfAwaNEhVETCX9JZJjuTs2bNNrpei9JI28OGHH+pzE/Ni31mdaH64U3HB1zpZ1O0z2uoDUgM2+X7llhLeQJOncbnSEPx8LAnLDl5HbJJ2QKq7sz0G3U8fKO+TefoAEVlHIGvR1ILx48erwU+S7yo9qhJASq+b4aVXKXG0b98+9SO9fnJbZnSqVq2ayo38/vvvceTIEVWqSkiPqaQPyHblcq70KsplabncbFjaypx9U9Eil/WzGmwnqSPSU09EhZxMiHJ+szaAvfDPg+V+dZDW7Bn869QBc/eG4r/NDyZTkWlin2pVAf0aloGrmekDRFT4WfSv+cUXX1QDX+TyvkTd0ksql5ANB25Jb4+uPqpc8pWasRKQyqAbyUFs0KCBGnwjFQeEBKzS0yoDhKQmrIuLixr1LpefDevDmrNvKlrktSHlubJaT0SFWEIUcOQ3YN8sIOKidpmNLVC9h0ofWBJWHgv+uYIr4cHaVTZA5xp+eLp1BbSq7MP0AaIiyKKpBelLaZnKHZQeVqkTm752qdQtTT/JQXrmtMlq39lhagERUwuoAIRfAPbNBg4vBJLuVylx8gQajcDlysMwN1iD5YeuI+5++oCHsz0GNy2LES0qoJyPC58iIitjNakFhjILJDPrJTMnQDWnTVb7JiIiC5E+lotbgb2zgLOb1BQESqlqSGv2LLY7dcK8A7fx39bL+rtU89OmDzzesAxcHAvNxxsR5SP+pRMRUeGRFKsduLXvJ+D26QfLqz6C2IZjsfhOJSzYdg1XI7Tls6R0a5eafqp8lpTDYvUBouKFgSwREVmelMyS9IFDvwAJkdpljm5AgydwufITmH3SFisWhyA++Yxa5VnCAUOalsXwFuVR1pvpA0TFFQNZIiKyXPrAlV3a2bdO/wlo0rTLS1ZU1Qe2lngE8w7cwc5/r+vvUsPfXaUP9G1QBiUczUsfI6Kii4EsEREVrOQEIHiZdvatW8cfLK/UAbENxuK3u9Xwy7/Xcf3uGX36wCO1/FUA26KSN9MHiEiPgSzliMz4JVPDGs72VdRJ6TapmiGl3ojoIUTdAPbPBQ7+DMSFa5fZlwDqD8GlyiPw02lHrPpD0ge09V+9XCR9oByGtyiHoJJMHyCijBjIUo5MmTIFTZo0wf/+978COXM7d+6Em5ubyWlhC2qbn332GYKCgvDdd9/l2TEQFSvX9mvTB06uBtJStMs8yyKt6VhsdXkUcw7cw+6dofrmNQM8MLJVefRpUAbODkwfIKLMMZClQk1m26pSpQq+/vrrQr1NIkonJQk4uUo7+1bIwQfLy7dWkxcsvFsbC3aEIOTeBbXYztYGj9b2w1MtK6BZRaYPEJF5GMiSSceOHcO1a9dUCkH58uUzrI+JiVFTA8ukE82aNTOasOLw4cO4cEH74eTj44N69eqp36ZSFKSnU6YfdnZ2Rrt27YzaHDhwAKGh2l6aZcuWqd8ys5u7u7v6v+z/+vXrqFSpEmrVqpXhGOUYzp49q2Z0q1u3LmxtbbPdprlkEg057oiICHWOKlasaNb+zVlHZNViwoADPwMH5gIxt7TL7JyAugNxsfIT+OmsG1YtD0FC8nm1qqSLA4Y2k/SB8gj0Mp74hogoOwxkycitW7fQv39/nDlzBg0bNlQB1xNPPIEPP/zQ6NK85IvKdL66gHXXrl3w9fVV/9+/fz/++usv/fYk4Jw5c6aaNtgwRUFmbZNAtHr16mjevHmGQHbv3r0ICQlRM3ssWbJELWvVqhXi4+PV1MI3btxAzZo1cfz4cdSuXRvLly9X0xiLl19+GQsWLFDtw8LCVKC8atWqTLeZk0BWHnP37t2RkpKiAtg9e/bgmWeewfTp0/VtMtt/qVKlslxHZLVuHNH2vgYvB1KTtMvcA5DaeBS2uffETweisHdPBIC7alUtSR9oXQG96wcyfYCIrH+KWmuUmylqk5KS9LOJ6Qp3S6+m/EivnL29fZ62NXd2M51u3bqpx7Nx40b12OTlIUGWBI6iS5cuOHr0qApOy5Qpo/YruaaDBw/GBx98YHKba9euVcGw9PDKNnXbkR5N2Zap3kydxx57LEMaQK9evVQP79y5c9Xjk3PdqVMndOjQAZ9++qkKcOXYgoODVYArZF9+fn6qd9nUNrPSt29foxxZ6cGVcyyPS863BO4tW7bEunXr1PnLav/SPqtjs0aZvdapGEhNAU6v1c6+dXX3g+VBTRHTYAwWRtXHgr03cCMyQZ8+0K22vwpgm5QvyeoDRFR0pqgtLiQ/U7z++uv63kPp4dy6davqAe3du7e+7ZdffqkuYb/yyivw8vJSyyRo2rRpk7oc3a9fP33bb775BnFxcXj++ef1PaMSbDZu3NjsY5NL7rLtDRs26ANOCdh0QayO3JZgTDg6OqJNmzY4fdpgBh7pc7l7V/WU3rlzRwXUcmwnT55UAZ9Onz59sgxiTZEeTAkYP//8cxVISqAtP1WrVsWWLVtUGwnwJdCXY9IFi5L+kBfkcUlvs+xLN7Vx06ZNVQC7ePFi9Tur/cvx59exERWYuAjg4Hxg/xwgKkS7zNYBqP04LlYejh/Pe2H1qhtITLmoVnm7OmJoM+3kBQGeTB8gorzDQJb0rly5on7Lpf6seHt7G912cnLC7du39bd/+uknvPbaa6hRo4bKAdUFfBLEGZJ1OXX5snZe9W3btqk0AUO6oF0CeUllePHFFzFhwgR07NgRTz75pOq1fVjS8ygkL9eQ9PBKbnB2+8/PYyPKd7dOaHtfjy0FUuK1y1xKIa3x09jq3guzDsVh335JH4hRq+qU8VCDt3oxfYCI8gkD2QI2adIk9VsX3InWrVujRYsWGQb8SK9t+rbS+9eoUaMMbaXXNn3bnNY91fXChoeH57inVEfyXseNG4dFixZhwIAB+kvPLi4uqufUUG7mRNflsr7zzjsqxzQzkrM6ZswYNWhNem4lp9XwmHJLN2jt3r17Rstl0JfhgLas9p9fx0aUL9JSgbMbtfmvl/59sNy/HmIajsXCmMb4ZV8obkZqZ9+yl/SBOv54unUFNCrH9AEiyl8MZAuYXIpPT/I8TeWy5kXbnJCe2HLlymHhwoWqVqyOBLbpqw5kRtpK3qzusrlYuXJlhiDWXFLvVYJjHenllVxS6fVNH8hKaoS/v7/KqZHzoZvEQH6kB1cGpEmwmH6bOVG2bFl1juQx6b4oSNqE5BRPnDhR3c5q/127ds3y2IgKjfh7wOGFwL6fgHvaqzWwsQNqPoaLlUdg5oXSWL32JpJStFdJfFwdMax5OTzRvDz8PZkrTUQFg4EsGfWQzpo1Sw1uklxQGTwl1QtkYJLkpZpD0gXkEv+oUaPw3HPP4eLFi+pSek6Dah3Z1owZMzB//nwVgMpAqzlz5qj82ujoaPTs2VMd659//qkGkL399ttqUJnkD8sANAnOJR9VAsX33nsv022aW7VAesKnTZuGoUOHquoJ1apVU4POJNCXdAGR1f6zOzYii7tzTps+cOQ3IDlWu6xESaQ2fBJbPXpj1pEk7D8klQe0ubF1y3hiZKsK6FkvgNUHiKjAMZAlIzJYSQaJ/fzzz/jnn39URYKlS5fq10uJLCm7ZUgGqUkvpY4MGPv222/VoKiAgAD8+++/+OSTT/QDxDLbjilSqkrSJWQwXGxsrOqFlYBVgmsJRGXQlQTPkydPRvv27dV9pK6rtJfHIMcgFQEkWJTjzGybWQWyst6wR1rKk0kv6m+//aa2IYG/BO26EfvZ7T+rdUQWkZYGXNiiTR84//eD5b61ENNgNBbGNsf8/WEIjbqlTx/oUTcAT7WS9AEvVh8gIoth+a0CLr9FVNTwtW7FEqOBo0u0PbDh5+4vtAGqd1fpA99fCsTaYzeRlJqm1pRyc7qfPlAOfh58XyOi/MHyW0Rmkh5ZKTeWGRmIpSuTRlRkRFwC9s0GDv8KJEZplzl5ILXBcGz17IuZR1NxcMWD9IH6QZ6q9qv0wjrZ5y5NiIgoPzC1gIo1ybPVzfBlitTIZSBLRYIMuJSqA5I+cEa+vN0fgOlTBdH1R2NhQmvMP3Abt6LuqMUOdjboeT99oGG5kpY9diKiTDCQpWJNqhwsW7bM0odBlH+S4oDjS7XpA2EnHyyv0kWbPnClHNZuuoWkVG35rNLuTip1QFIIfN2ZPkBEhRsDWSKiokjqukr6wKFfgHhJE5BuVlek1h+KbZ6P47vjNji8Wuoh31SrGpbzUtUHutcJgKO9cZ1qIqLCioEsEVFRSh+4ugfYOxM4tQ7QpGqXe5VHdINRWJjQFvMO3sXt6Eh9+kCveoEqfaB+We002ERE1oSBbD7L7UQARNaCr/FCICURCF4O7JkJhB57sLxiO1ys/CRmXKuIdZvDkJwaqhb7ujtheIvyGNqsnEolICKyVgxk84luAgCZ5UpmcSIqquQ1LnI76QU9hOhQYP9c4ODPQOxt7TJ7Z6TWHYztXo/jm2BHHF0n6QPa+q9S83Vk64roVtuf6QNEVCQwkM2vE2tvDxcXF9y+fVsV35cZoYiKmrS0NPUal9e6vOapgFw/qE0fOLESSEvRLvMIQky9kViQ1B7zDkXhTkycTKAMRztb9KofqPJf6wZ58ikioiKFnzz5ON2rzGolkyJcuXJ/nnKiIki+pMnMbvKap3yUmgycXK1NHwg5oF+sKdcSlyoPx7ch1bHun9tISdP2zPp5OGFEi/IY0qycmsiAiKgoYiCbjxwdHVG1alX9pVeiovo65xWHfBR7BzjwM3BgLhCtrTAAO0ek1u6v0ge+PumKYxtk8FaYWtWkfEk1eKtbHX842PFKEBEVbQxk85l8wHOKWiLKsZvHtJMXHF8GpCZql7n5IabuU1iY3BFzjsTiTox8SY5U+a6976cP1CnD9AEiKj4YyBIRFRapKcCZP7WTF1zZqV+sCWyEy1VG4JvQOli3/Q5S0rR1YQM8nVX1gSFNy8KH6QNEVAwxkCUisrS4CODQAmD/HCDymnaZrT1Sa/bB9pL9Me2UB4L/igKgzX9tVsEbI1tXwCO1/GDP9AEiKsYYyBIRWUrYKW3v69ElQEq8dpmLD2LqjMDClC746WgCImIlfSAKTva26NNAO3lB7UCmDxARCQayREQFKS0NOLdJm/96cZt+scavDi5XeRJf36qPdTsikJomPbBAoKQPtJT0gXLwdnXkc0VEZMDiQ1oXLFiAxo0bIygoCN27d8exYwaz0pggNSvffPNN1K9fH5UrV0bv3r2xa9cuozbHjx/H008/jerVq6N27dp49tlncePGDaM2r7/+OkqVKmX007Zt23x5jERESIgCdv8AzGgELB6iDWJtbJFa/TH803I+Hkuaio5bgrA6OBypaRo0r+iNmU80wr9vdsQLHaowiCUiKmw9skuXLsWYMWPw008/oWXLlvjyyy/RsWNHnDx5En5+fibvM3HiRDRq1AhLlixRBdhnzpyJzp074/Dhw6hRowZSU1MxYsQIvPrqq5g0aRLi4uIwYcIE1ebQoUP6WbZiYmLQqlUrzJs3T79tFnQnojx35zyw7yfgyCIgKUa7zNkTMbWfwMK0RzDraDLuxiXLNF0qfeDxhmXwZMsKqBXowSeDiCgbNhoLTpQuvaotWrTArFmz1G0JQgMDA/Hcc89hypQpJu8jh2tYeF3uI+WtfvzxR4wePdpkmwsXLqBKlSr4559/VKAsZB937tzBsmXLcn38UVFR8PT0RGRkJDw8+KFDRPo3KuDCP9r0gXN/PXj/Kl0DlyuPwDe3G2DtqSjV8yrKeJXAiJblMbhJWZRk+gARFXNROYivLNYjKwcnaQTvvvuufpnM1d6pUyf8999/md7PMECVgPWXX35RU8AapgWkn2EoPl47iCJ9PdetW7eqGYnkZMn9JXguXbp0njw+IiqGEmOAY0u0A7junL2/0AapVR7Bfz798dmZAJzaFq1qv4qWlXzU4K0uNX1ZfYCIKBcsFsjqclbTpxDI7SNHjmR5X+lZHTRokEoPkFSBVatWoVq1aibbSrAr6QiSdtCkSRP9cpk+VlIZ2rdvj5CQEJV327p1a7VvmTfelMTERPVj+I2BiAh3LwP7ZgOHfgUStUEqHN0RU2sIFmoexY/HNbgXrE0fcHaQ9IEgPNWqPGr480oOEZFVBrK6jAbphTUkeappMqo3C9J7evr0aZUaIGkJAwYMwM6dO1G3bt0MbSU/Vtb9+++/qudWZ/Lkyfr/V6pUCatXr0bZsmVV7u2oUaNM7nfq1KmZpjwQUTEj72GXd2jTB86sBzTa9y2NdyVt+sCdJlizNxppmiR9+oAEr4OalIWXC6sPEBFZdSCru4QvVQgMye3sLu9LQKqrNDB9+nTVQyuDvn744Qejdm+99ZYazLV582bUq1cvy236+vqqNAMJkDMjg8ckMDbskZXgl4iKkeR44Pgf2vSBW8H6xakVO2KHzwD871wQTv0Xq3pfRavKPmrq2M41/WBna5z2REREVhzIVqxYETt27EDfvn31y6XntF+/fjnalgS2SUnaXg+dt99+WwW3f/31F5o1a5btNqS6gaQ7ZBVEOzk5qR8iKoYiQ7Qzbx2cD8RHaJc5uCCmxkD8hm74PtgekackfSAWJRzs8HijMniqZQVU93e39JETERVZFq0j+/LLL2POnDnYu3cvUlJS8Pnnn6tgUuq+6kgZLd1ALgk2n3/+eVy+fFndTkhIwLRp01RZrcGDB+vv89577+H7779XQWzz5s0z7FfyXMeOHYuLFy/qe4FHjhyp0hqGDh1aAI+ciKwmfeDqXuCPkcDXdYEd01QQq/Eqh8uNJ2F84G+od+BRfLpfg8j4ZJT1LoF3e9bEnkmd8enjdRnEEhEV5Tqyr7zyCsLCwtClSxcVXJYpUwYrVqwwGrgVHR2Nu3fvqv/LwC4JTHv06IGrV6+q4FfyYleuXImuXbuqNuHh4fj4449Vz2nPnj2N9vf1119j+PDhal2bNm3w2GOP4cqVK2qd3JZqCTIxAxEVcymJwImVwJ6ZwM0Hg09Ty7XBDp/++N+Fiji1M06+XqvlbaqUUtUHOtXwZfoAEVFxqSOrI4O7YmNj4e6e8RKcVCaQgNXLyytDSS0pp5W+1JY8HAlmTZHtp08NkF7d9GW5zMU6skRFTPQt4MA87U9smHaZnRNiqvfHEtvu+DbYCVEJKWqxi6Md+t1PH6jqx/QBIqJiVUfWkK2trckgVri5uZlcrpuhKz0JbGUQmLlyG8QSURESckhbfSB4BZAmea6Axj0QVyoPwzd3W2HV4QSVZQCkoJy3C55sWR4Dm5SFZ4kHlVCIiKjgFYpAloiowKUmA6fWAHt+BK7ve7A4qBl2+QzAJxer4PSeBLluo5a3rVoKT7eugA7VfGHL6gNERIUCA1kiKl5iw4GDPwP75wLR2olZYOuA2Kq9scS2B74+5Y7o85I+kKDSBwY0DsKTLSugiq/pq0NERGQ5DGSJqHgIDQb2zgSO/QGkamfo07iWxtVKQ/DNvbZYeSxFnz5QwUfSBypgQJMgeDgzfYCIqLBiIEtERVdaqnbWLZm84PJ/+sWp/vWxu/RAfHK5Jk7tl6BWO4CrfbXSavIC+c30ASKiwo+BLBEVPfF3gcMLgX0/AfeuapfZ2CG2cg/8bvcYpp/2QvTlVKkqDVdHOzVwa0TL8qhcmukDRETWhIEsERUdt89oe1+PLgaStTVeNSW8ca3iIHwT1R4rTmjupw+komIpVzzVsjz6Nw6CO9MHiIisEgNZIrJuaWnA+c3a8lkX/tEvTi1dC3tKD8RHV2vj9CFJHdCWzO5YvbSavKBdVaYPEBFZOwayRGSdEqOBI79pe2AjLtxfaIPYSo/iD7vH8OXZ0oi5JukDKXBzssfAJtrqA9ITS0RERQMDWSKyLuEXgH2ztTmwSdFqkcbJA9cqDsS3Ue2x7KTubS0VlUq7qsFb/RoFqWCWiIiKFr6zE1HhJ4mtF7dp0wfObtKnCaT6VMVeSR+4Vg+njqSpZTJrdcfqviqAbVOlFKsPEBEVYQxkiajwSooFjv2uTR+4fVq/OLZ8Jyy3fwyfnwtATIgEtWlwV+kDZdX0sRWYPkBEVCwwkCWiwkdKZkn6wKEFQMI9tUjj6IaQ8o/j25hOWHrG6X5DDSpL+kDriujXsAxcmT5ARFSsMJAlosKTPnBll3b2rdN/AhptqkCaV0Xs8x2Aj643wInjNvr0gc41fFX1AUkfsJEFRERU7DCQJSLLSk4Agpdp819Dj+sXxwW1xQqHx/C/C+UQE6rNiXV3tsdglT5QAeV8XCx40EREVBgwkCUiy4i6CeyfAxz8GYgLV4s09iVwo1xvzIjrjCXndbNsaVDV1031vj7O9AEiIjLAQJaICta1/dr0gZOrgTSZqABI8wjCAd/+mBLSBCdO2qllki3QpaYfnm5VAS0r+zB9gIiIMmAgS0QPLy1Vm98acwtw8wPKtwJstQGpkpIEnFylTR8IOahfHB/QHCudemHqxUqIDtMu83C2x5Bm5TCiRXmU9Wb6ABERZY6BLBE9nJNrgI0TgagbD5Z5BALdPgPKtQAO/AwcmKsNciVRwM4RN8o+hu/jOuO3SyX1d6nu567SB/o2DISLI9+aiIgoe/y0IKKHC2KXPgkNNDCsG6CJugGbpSMAW/sH6QOufjgk6QOhTXH8tLZ8lq0N0LWWnwpgW1Zi+gAREeUMA1kiyn06wcaJGYJYob+dloL40g2wukQffHqpGqLCtWs8SzhgSLOyKn0gqCTTB4iIKHcYyBJR7khOrPS8ZtPs6ZDHsCetuvp/DX93NXVsnwZlUMLRIIeWiIgoFxjIElGupEWHwtaMdr64h+51/FX6QPOK3qw+QEREeYaBLBHlyul79qhlRrshnZqiVZfGPMtERJTnGMgSUc7dPoMy+z/RzyxraobYNA0QCh/c9mnEM0xERPnCnCuDRETQR62HFwE/dYBn9DlEakrog1ZDuttTkkfA18OVZ4+IiPIFA1kiMk9iNLDyWWD1C0ByHC55NEGXxK/wXPJ4hMLbqKn0xL6QPB7H3NuhWUXjdURERHmFqQVElL2bx4BlTwPh56GxscVil+F4N+wRpMEWm9Ka4e/EJmhqe1oN7AqDF/an1VDrZvaqBTspFktERJQPGMgSUdapBPvnAJveAVITkVDCD88nvIit4VXg7mSPzwbUU5MaTFl7EnsiHwz9CvB0xuRetdCtTgDPLhER5RsGskRkWvw9YM044NQadfOsZ2sMvjUCd+GBekGe+G5oI5Tz0U5m0LWWP/ZdikBYdAJ83Z1VOgF7YomIKL8xkCWijK4f0KYS3LsKja0D5pUYiY9udVBzdo1qXRFvda8BR/sHKfYStLas7MMzSUREBYqBLBE9kJYG7Pke+PsDNb1snGsQRse+gN3hFeDhbI8vB9bHI7X9ecaIiKhQYCBLRFqx4cCq54Bzf6mbJ7w6YUjoMETDBQ3KeuG7YQ0RVFKbSkBERFQYWLz81m+//YbmzZujQoUK6NWrF4KDg7NsHx4ejrfffhuNGzdG9erV0a9fP+zduzdX283pvomKrMs7gB9bqyBWY+eE711fQs/Q0SqIHdu2IpY+25JBLBERFToWDWSXLVuGkSNHYuzYsfjzzz9RqlQpdOjQAWFhYZne57XXXoOvry/mz5+PVatWISgoCB07dsSZM2dytN3c7JuoyElLBbZ/DvzSC4i+iRj3ShiQ8jG+CG8FLxdHzH2qCd7pWcsoH5aIiKiwsNFopL6OZTRo0ABNmzbF7Nmz1e2UlBQEBgbixRdfxOTJk03eRw7XxmA+zNTUVDg7O+PHH3/E6NGjzd5ubvadXlRUFDw9PREZGQkPD4+HPBtEBSw6FFgxFrj0r7p5qGR3DL85EHFwRpPyJfHt0IYI9NLO3EVERFRQchJf2VryII8ePYquXbvql9nb26Nz587491/tB6sphkGsBLWLFi1S92vTpo3Z283tvomKjPN/AzNbqyA2zcEFX7q8in43R6gg9vkOlbH4mRYMYomIqNCz2GCvkJAQ9dvPz89oudw+cuRIlvfdunUrhg4diujoaDg6OmL16tUqX9bc7eZ234mJiepHRwJiIquSmgxs/QTYMV3djPSojifuPYvgaH94uzpi2qD66FDd19JHSUREZBaL9cjqMhqkJ9SQ3JZ0gay0bt1aBZwyyGv48OEYNGgQTpw4YfZ2c7vvqVOnqq5u3U/ZsmVz8IiJLOzeNWB+T30Qu8enL5qFTUJwkr+awGD9y20ZxBIRkVWxWCBbunRp9fvOnTtGy2/fvq0Gc2VFemH9/f1Rp04dzJgxQwWUP/zwg9nbze2+J02apPI1dD/Xrl3LwSMmsqDTfwI/tgGu7UWqozs+cZmIISGDkGTjiHGdquC3Mc3h7+nMp4iIiKyKRQNZKXu1Y8cOo+X//fcfmjVrlqNtyWCvhIQEs7eb2307OTmppGPDH6JCLSUR2DARWDIMSLiHCK866J7wCWZH1EcpN0f8Oqo5XnukOuztWJWAiIisj0U/vV566SXMmTMHBw8eVJf0p02bhuvXr+OZZ54xKrclZbFEXFwcxo0bp9qIpKQkfPvtt+r+AwcOzNF2zWlDZNXCLwBzuwJ7f1Q3t/sMRvPQN3E2qRRaVvJRqQRtqpay9FESERFZ58xeEyZMwK1bt9CuXTukpaWpnlKp71qjRg19G7mEr0sBKFGiBOrXr49OnTqp+8nAq5o1a6r7dOvWLUfbNacNkdU6vgxYOx5Iikaqkxcm247DwpCasLUBXu1cDS91qgI7uUFERGTFLFpHVkdquEoFAi8vL6PyWrrKAMnJyfDx8TFaHhMTowJbOzu7XG03J20ywzqyVOgkxQEbJwKHFqibt70bY8DtUbiSXBKl3Z3w7ZCGaFnZ+G+JiIioMMlJfGXRHlnDagElS5Y0uS6zB+Dm5vZQ281JGyKrEHYa+GMkcPsUNLDBZp8ReD6kK1Jhh7ZVS2H64AYo5eZk6aMkIiLKM4UikCWihyAXVQ4vBNa/AaTEI6VEabyFcVgWUkWlErzxSHU8374ybJlKQERERQwDWSJrlhgNrJsAHF+qbt4s1RL9Q5/CjRQP+Hs4q2lmpUYsERFRUcRAlsha3TwK/PE0EHEBGhs7rPUZhVeut4cGtuhQvTSmDWqgZusiIiIqqhjIElljKsH+OcCmt4HUJCS5BmJC6jisu15eVSJ449HqeKZtJaYSEBFRkZdngezly5fVrFguLi55tUkiSi/+LrD6JeD0OnXzWun26H9zOMJSXBHo6YwZwxqicXmmEhARUfGQqwkRZBIBmZhAZ/jw4ahYsaKaNnbXrl15eXxEpHNtP/BjOxXEamwdsKzUi2h77RkVxHap6Ys/X27LIJaIiIqVXPXIvv766/joo4/U/4ODg7F27Vrs2bMHf/31FyZNmoTt27fn9XESFV9pacDuGcCWD4G0FCS6l8NLSS9j8/VA2Nva4K3uNTC6TcUc10EmIiIqloHsgQMH0LhxY/V/CV4ff/xxNG/eHLVr18aXX36Z18dIVHzF3gFWPgec36xuXvR7FP2vD8Ld1BIo41UC3w1riIblWAeZiIiKp1ylFshkBJITK9atW6emjBUyA4M5ExUQkRku/Qf82EYFsRp7Z/xaegI6XXlSBbGP1PLD+pfbMoglIqJiLVc9sgMGDEDPnj1Rp04dHDlyBL169VLLN23ahO7du+f1MRIVL2mpwL9fANs/AzRpSPCsjGcSxuHfa75wtLPF2z1q4KlWFZhKQERExV6uAtlp06ahSpUquHLlCqZMmaKf4vX06dOYPHlysT+pRLkWdRNYMRa4/J+6eSagDwZc6YvoNCeU83bB98MaoW6QJ08wERERABuNRopSPrziWH4rKioKnp6eKqXCw8PD0odD1u7c38DKZ4G4O9A4uGCu18v4+Fo9tapn3QBM7V8XHs4Olj5KIiKiQhNfsfwWkaWlJgOb3wcW9VdBbJx3TQzFZyqIdbS3xUd966hBXQxiiYiIjLH8FpEl3bsKLBsFXN+vbgaXGYiBlx5DfJoDKpZyVQFs7UCmEhAREZnC8ltElnJqHbD6BSAhEmlOHvjBfTy+vFBDrepdPxCf9qsLNyfOIk1ERJQZ+4cpv1WzZk1VfmvkyJFqOctvEZkhOQHY/B6w7yd1M6ZUfQyPfBZHrnvByd4WH/SujSFNy7IqARERUTZYfouoIIVfAP4YCYQeUzcPBY3A0AtdkaixR6XSrqoqQc0ADhwkIiIyB8tvERWUY38A68YDSTFIc/bGNLcJ+O58JbWqX8MyalCXK1MJiIiICr78VnHE8ltklqQ4YMObwOFf1c1I32YYGjEGJ2Pc4Oxgiw/71MHAxkFMJSAiIkLO4quHGkly/vx5nDp1ChIL16pVS02SQEQGwk5pUwlun4YGNthbdjRGnG+PZI0dqvq64YcnGqGqnztPGRERUS7kKpCVCHnUqFFYsWIFbG21pWjT0tLQr18/zJs3T0XRRMWaXOiQHtj1bwIp8Uh19cXUEq9hzrmyavWgJkGY0rsOSjjaWfpIiYiIrFauJkQYP348Lly4gP/++w8JCQnqR/4vPbSvvvpq3h8lkTVJiAKWjwHWjFNB7N2AtuiWMBVzrpeFi6Mdpg2qj88H1GcQS0REZIkcWW9vb+zcuVOV3zIkaQZt2rRBeHg4igPmyFIGN44Ay54GIi5CY2OH/8o+h5HnWiJNY4sa/u74blgjVPF144kjIiKyVI5sfHw8SpUqlWG5j48P4uLicrNJIusm3welLuxf7wKpSUh1D8JkxwlYeNZfrR7arBwm96oFZwemEhAREVk0taBly5Z49913kZSUpF+WmJiId955R60jKlbi7wK/D9dWJkhNwp0yXdA59iMsDPGHq6Mdvh3aEFP71WUQS0RElMdy1SM7ffp0PProo1i1ahXq16+vlh05ckQN/Nq0aVNeHyNR4XVtH7BsFBB5DRo7R/xddhzGnm4kWTuoFeCB759ohIqlXC19lEREREVSrgJZCV7PnTuHX375BSdOnFD1L3v37o2nnnoK7u4sJUTFQFoasOsbYMtHgCYVKZ4V8LbdBCw9rU25GdGiPN7pWZO9sERERPmIEyI8BA72KqZibgMrnwUubFE3Q8v1RP9rgxAS7wB3J3t8NqAeetQNsPRREhERWaV8Gex1+vRpsw+gRo0aZrclsiqX/gWWjwViQqGxL4H1QePx4uk6KpWgbhlPfDesIcr7MJWAiIioIJgdyKYvtZUVznpLRU5aKrD9M2D75/IKR7J3NbymGY81p73U6pGtKmBSjxpwsmdVAiIiokIXyF67di1/j4SosIq6oe2FvbJD3bxeoT/6X+6DWwn28HC2xxcD6+PR2toyW0RERFQIA9mgoKD8PRKiwujcZm0+bFw4NI5uWFHmdbx2qppa1aCsF2YMbYiy3i6WPkoiIqJiKVd1ZPPS8uXL0b59e5VXO3DgQJw5cybL9jI17rhx49C4cWM0b94cr732Gu7cuWPUpnbt2qhQoUKGH6l9qyM1b9Ovl5JiREpqMvDXe8CiASqITSpVB8+5TtMHsWPbVsTSZ1syiCUiIrK28lt5ZfXq1RgyZIiqSysTKUybNg3t2rVTJb1MzRyWmpqKnj17qkD26aefVrOIvfnmm+jcuTP27dsHJycn1W7Dhg1Ik/JI9x04cEAFyYaTNcg0urVq1cIPP/ygX+bo6Jjvj5mswN0r2tqwIQfUzcuVn0D/890RnmgLLxcHfDmgPrrU8rP0URIRERV7Fi2/Jb2qUpN23rx56nZycjICAgIwfvx4o97T9MGsnd2DATVnz55F9erVsW3bNtWza8pzzz2HP//8E5cvX9bfV5ZJT+6yZctyffwsv1UEnVwDrH4JSIyExtkTSwLexKRTFdWqxuVLqlm6yniVsPRREhERFVk5ia8slloQHR2NQ4cOGV3Od3BwUL2rEpRmxjCI1QW2ppbrSK/t4sWLMXr06Axt/vvvP9UrKz210rMrJ4yKqeQE4M/XgaUjVBCb4NcYo5ym6YPY59pXxpJnWjCIJSIiKkQsllpw/fp19dvf33i0t9w+duyY2duRnttKlSqhWbNmJtf/8ccfiImJwahRo4yW+/j4qPtKL25ISIjKmV2/fj0OHjyoT1FILzExUf0YfmOgIuDOeWDZSCD0uLp5rupoDDzbGfcSAW9XR3w1qD46Vve19FESERFRYQlkdTms9vbGhyC9srpe1uxIILpp0ybVg5tZfuvcuXNVr2+5cuWMln/00UewtdV2SNerV0+lOMiAryVLlqipdk2ZOnUqpkyZYtaxkZU4thRYOx5IjoXGxQe/+L2FD46XUauaVfBWqQT+ns6WPkoiIiIqTIGsbjCXDLoyJHmrpUuXzvb+H3/8Mb7++mvVi9qkSROTbc6dO6fSB1asWJFhnS6I1QkMDET58uVx8uTJTPc5adIkTJgwwahHtmzZstkeKxVCSbHA+jeBIwvVzfgyLTE6+lnsOuUIGxvgpY5V8ErnqrC3s3hhDyIiIipsgayfn5/qJd21axd69+6tX75z505VmSArn3zyieodlQFcUuUgM9IbK/vp1atXtseTkJCAmzdvwtvbO9M2knKQWdoBWZFbJ4E/RgJ3pNSbDU5VfwEDT7VBTJIGpdwcMX1wA7Stmv2XKSIiIrIsi3Y3vfDCC5gzZw6Cg4PVtLZSCksqC4wdO1bf5q233jIaEPa///1PBbHSE9uhQ4dMt52SkoIFCxaoMl3p0xeSkpLw6quvIiwsTN2WHNpnn31WHcPgwYPz5bFSISAFOg7OB2Z3VEGsxs0fsypMR/ejrVUQ27KSD9a/3JZBLBERkZWwaB3ZN954Qw20ktQA6el0dnbGb7/9piY0MEw1kDYiIiJCXd53dXXNkMf62WefGQWhEuiGhoaqagXpSR5ulSpV1H7j4+NVioD8f+vWrSpPloqghChg3XggeLm6GVu2A56+Nwr7TturVIKXO1XFy52rws7WxtJHSkRERNZQR1ZHgsl79+6pNID0uauSQyuVAiSHVQaIXb16NdOcWzc3N/1t2Z6U+Mouh1W2LzXKJLjNKdaRLYTSUoEru4CYW4CbH1C+FRB6DPjjaeDuJcDWHkerv4yhwU0Rl6xBaXcnfDO4AVpVyTgBBxERERW8nMRXhSKQtVYMZAvhZAYbJwJRNx4sc/IEkmIATSrSPIIww3sSpp8uqVa1qVJK5cNKMEtERETWF19ZNLWAKE+D2KVPQgMNjJIDErWTXMT7NsCQuDdw9LQNJHtgQtdqeKFDFdgylYCIiMhqMZClopFOsHFixiD2PrnkcPfWNRxP1MDPwxnfDmmI5pV8LHCgRERElJcYyJL1k5zYqBsmg1ghywNtwjG2XCieefJJ+LgxlYCIiKgoYCBLVi8tOtSsOnJvtPKEPYNYIiKiIoPTFpHVOxVl3hSyZ2Jd8/1YiIiIqOAwkCXrlhyPksHzs2ySpgFuaHxw3qVugR0WERER5T8GsmS9YsOBBX0QGPo3kjW2auIuCVoN6W5PSR4BXw/2yBIRERUlDGTJOkVcAuY9AlzbC42zJ8bifTyXPB6h8DZqFgofvJA8Hsfc26FZReN1REREZN042IusT8hB4LfBQOxtaDyDML/il9i2J02t2pzYBM1sT8MX9xAGL+xPq4E02GJmr1qcfpaIiKiIYSBL1uXMRmDZ00ByHDT+dfGd/6f4ak+0WtWvURnsvhCOPZG19M0DPJ0xuVctdKsTYMGDJiIiovzAQJasx4F5wJ+vAZo0aCp3wv/cJ2HWnttqlQSrT7euiNQ0DfZdikBYdAJ83Z1VOoEdZ+8iIiIqkhjIUuEno7j++Qj47yvtzQZP4P20sfh1zw11+5PH6+CJ5uXV/yVobVmZs3YREREVBwxkqXBLSQLWvAQc+13dTGs3EW+F98DSgyGwsQE+618Pg5qUtfRREhERkQUwkKXCKyES+H0EcGk7YGOH1J7T8fqF+lh5OASSLfDVoPp4vGGQpY+SiIiILISBLBVOkSHAooFA2AnAwRUpA+bjlYOl8OexEJU+8M2QBnisXqClj5KIiIgsiIEsFT63TgALBwDRNwA3PyQP/h0vbUvFphM34WBng++GNcKjtf0tfZRERERkYZwQgQqXi9uBed20QWyp6kh8ahOe3ZKCTSduwdHeFrNGNGYQS0RERAoDWSo8jv4OLOwPJEYB5VohfsR6jFkThn9Oh8HJ3hZznmyCTjX8LH2UREREVEgwkKXCUV5LSmutfAZISwZqP464IX9g1O/n8d+5OyjhYIefn26KdtVKW/pIiYiIqBBhjixZVmoKsOEN7WQHouVLiG73Pkb9chD7L9+Fm5O9CmKbVvDmM0VERERGGMiS5STFAstGAWc3ArABuv0PkfVH46l5+3Dk2j24O9tjwahmaFiuJJ8lIiIiyoCBLFlGzG3gt0HAjUOAvTPQbzbulu+GEXP2IDgkCl4uDlg4ujnqlPHkM0REREQmMZClgnfnPLCoP3D3MlCiJDD0d9zxboDhs/fgdGg0fFwdsXBMc9QM8OCzQ0RERJliIEsF6+peYPEQID4C8CoPDF+OMMeyeOKnPTgXFoPS7k74bUxzVPVz5zNDREREWWIgSwXn1Fpg+RggJQEIbAgMW4rQVA8M+2kPLt6Jhb+HM34b2xyVSrvxWSEiIqJsMZClgrF3FrBhotTaAqp1AwbMw/VYGwybvRtXI+JQxquECmLL+7jyGSEiIiKzMJCl/JWWBmx+D9j9nfZ246eBHl/i6r0kDJ29ByH34lHO20UFsUElXfhsEBERkdkYyFL+SU4AVj0HnFipvd35faDNBJVGMGz2XoRGJaBSKVcsGtscAZ4l+EwQERFRjjCQpfwRFwH8Phy4shOwdQD6fA/UH4xzt6IxbM5e3I5ORFVfNywa0xy+Hs58FoiIiCjHGMhS3rt3FVg4ALhzBnDyAAb/ClTqgFM3ozB8zl6Exyahhr+7KrFVys2JzwARERHlCgNZyls3jwKLBgIxtwD3QGD4MsCvNoJDIjF87l7ci0tGnTIe+HVUc5R0deTZJyIiolxjIEt55/zfwNKngKQYwLcW8MQywLOMmm72ybl7EZWQgvplvdS0s54lHHjmiYiI6KHYwsJWr16Nzp07o06dOhg6dCjOnz+fZfvLly/j1VdfRfPmzdG6dWtMnDgRERERRm3ef/99VKlSxeinR48eD71vysKhX4FFg7RBbMV2wKiNKog9cDlCpRNIENukfEksHM0gloiIiIpAILtu3ToMGDAAvXr1wty5c6HRaNC2bdsMgalOamoqHn30UVSoUAEzZszAJ598gm3btqlgNDExUd8uLCwMVatWxcaNG/U/s2bNeqh9UyY0GmDrVGDNS4AmFag7CHhiOeDsid0XwvHkvH2ISUxBi0re+GVUM7g7syeWiIiI8oaNRiI4C2nSpAnq1q2Ln3/+Wd1OSkpCQEAAJkyYgHfeecfkfVJSUmBv/yAj4syZM6hRowa2b9+Odu3aqWXPPfcc7ty5g2XLluXpvtOLioqCp6cnIiMj4eHhgWInNRlYOx44slB7u80EbYktGxvsOHcHYxbsR0JyGtpWLYWfRjRBCUc7Sx8xERERFXI5ia8s1iMbHR2NQ4cOqR5WHUdHR3Tp0kX1smbGMIgVujjcxsbGaPmOHTtQr1491cv69ttvq/097L7JQGI08NtgbRBrYws8Nh3oMlkFsVtPh2HUL9ogtmP10pj9JINYIiIiKkKDva5fv66CUH9/f6PlcvvYsWNmb+e9995TqQbNmjXTL/P29la5s+3bt0dISAjeffddlUpw4MABFbDmdt+SvmCYwiDfGIql6FBtZYLQY4CDCzDgZ6B6N7XqrxOhePG3Q0hO1aBrLT98N6whnOzZE0tERERFKJBNk6lLATg4GOdMSqApubDm+OCDD7B+/Xr8888/cHJ6UI/0o48+gp2dNnhq1KgRGjZsiIoVK2LJkiV48sknc73vqVOnYsqUKSjWwk4DiwYAkdcAl1LAE0uBMo3Vqj+P3cQrSw4jJU2DnnUD8PWQBnCws/h4QiIiIiqiLBZllCpVSv0ODw83Wi65rbp1Wfnf//6HL774QvW0SgUDQ7ogVicoKEj12p44ceKh9j1p0iSVr6H7uXbtGoqVyzuBeY9og1jvysCYzfogdvWREIxbfEgFsX0bBOIbBrFERERUVANZPz8/lC1bFrt37zZavnPnTjUQKyufffYZPvzwQ6xduxYdO3bMdl+SDhAaGgovL6+H2rf0+krSseFPsRG8HPi1L5AQCQQ1A0ZvBrwrqVV/HLiG8b8fQZoGGNA4CF8NagB79sQSERFRPrPodV+pLjBnzhycPn1a3f7pp59w8eJFjB07Vt9GBmoZ1oD98ssvVRArPbGdOnXKsE2pPvDGG2/oe1vj4uLwwgsvqJSBwYMH52jfdL+81s5vgWWjgNQkoMZjwFNrAFcfdXp+23sVbyw7ppoNa14On/evBztb44F3REREREVuZi8ZkCUDr+rXrw9XV1eVErBw4UJVFsuwJuzVq1fV/+/evauCVDc3NzzzzDMZ8lcHDhyo8l4llUAqFkgurNxHtr9lyxZUqlQpR/su9tJSgY2TgH33a/A2exboNhWw1aZu/LLrMiav0aZrjGxVAZN71cpQPYKIiIioSNaR1YmNjVUTEUgd1/TltW7fvo2EhASVCiCBqfSamuLr65vhUv+tW7dUHTJnZ+dc7btY15FNjgeWjwFOr9PefuRjoOVLqryWmP3vRXyy/pT6/zPtKmFS9xoMYomIiOih5SS+KhSBrLUqsoFsbDiweAhwfR9g5wg8/iNQp79+9fdbz+OLTWfU/1/qWAWvPVKNQSwREREVeHxl0dQCKoQiLgILBwARF9Q0sxiyGKjQWq2S7zxf/30O32w5p25P6FoNL3euauEDJiIiouKKgSw9cP0g8NsgIO4O4FkWeGIZ4FtDH8R+vukMZm67oG5P7FYDz3eozLNHREREFsNAlrTObAD+eBpIiQf86wFP/AG4++uD2I//PIW5Oy6p2+/2rIkxbR8MnCMiIiKyBAayBOyfC6x/HdCkAZU7A4N+AZzc1ZlJS9Pgg7UnsGD3FXX7oz61MaJlBZ41IiIisjgGssWZTNX7z4fAjuna2w2HA499Ddg56IPYt1cex5L911SxgqmP18WQZuUse8xERERE9zGQLa5SkoDVLwLHl2pvd5gEtJ+oL6+VmqbBm8uOYfmh65D5Db4YUB/9GwdZ9piJiIiIDDCQLY5kmtnfhwOX/gVs7IBe3wCNRuhXp6SmYcLSo1hz9IaapWv64AboXT/QoodMRERElB4D2eIm8jqwaCAQdhJwdNPmw1bpol+dlJKGV5YcxobgUNjb2mDG0IboXjfAoodMREREZAoD2eIkNFgbxEbfANz8tJUJAurrVyempOLFRYfw96kwONrZ4ocnGqFLLT+LHjIRERFRZhjIFhcXtwG/jwASo4BS1YHhywCvBwO3EpJT8eyvB7H97G042dti1ojG6FDd16KHTERERJQVBrLFwdEl2oFdaSlA+dbAkEVAiZL61XFJKRi74AB2ng+Hs4Mt5j7VFK2rlLLoIRMRERFlh4FsUabRAP99BfzzkfZ27X7A4z8C9k76JjGJKRg1fz/2XYqAq6Md5o1siuaVfCx3zERERERmYiBbVKWmAOtfAw7O195uNQ7o8iFga6tvEpWQjJHz9uHQ1Xtwd7LH/FHN0Lj8g55aIiIiosKMgWxRlBSrnW723CYANkD3z4Dmzxo1iYxLxpPz9uLo9Uh4ONvj19HNUb+sl8UOmYiIiCinGMgWNTFhwG+DgBuHAXtnoP8coGYvoyYRsUkYPmcvTt6MQkkXBywc0xy1Az0tdshEREREucFAtii5cw5Y2B+4dwUo4Q0M+x0o28yoye3oRDwxZw/O3opBKTdHLBrTAtX93S12yERERES5xUC2qLi6F1g8GIi/C5SsADyxHChVxajJragEDJu9Bxdux8LX3Qm/jW2BKr5uFjtkIiIioofBQLYoOLkGWDEWSEkAAhsBw5YCbqWNmty4F6+C2MvhcQjwdFZBbMVSrhY7ZCIiIqKHxUDW2u2ZCWycJLW2gGrdgQFzAUfjAPVaRByGzt6D63fjEVSyBBaPbYGy3i4WO2QiIiKivMBA1lqlpQGb3wN2f6e93WQU0P0LwM74Kb18J1b1xN6ITEB5HxfVE1vGq4RljpmIiIgoDzGQtQZpqcCVXUDMLcDNT5s+sPoF4OQq7frOk4E2rwI2NkZ3Ox8Wo4LYsOhEVCrtqnpi/TycLfMYiIiIiPIYA1lryH/dOBGIuvFgmZ0jkJoE2DoAfb4H6g/OcLczodGqOsGdmCRU83NT1QlKuz+Y0YuIiIjI2jGQLexB7NIntfmvhiSIFW1fMxnEnrgRqerE3o1LRs0ADywc3Qw+bgxiiYiIqGh5MF8pFb50AumJTR/EGjr8q7adgWPX72HYbG0QWy/IE4vHNmcQS0REREUSA9nCSnJiDdMJTIkK0ba77+CVu3hi9l5ExiejYTkvNWOXl4tj/h8rERERkQUwtaCwkoFdOWi392I4Rs3fj9ikVDSr4I15TzeFmxOfXiIiIiq6GOkUVlKdwMx2O8/fwZhfDiA+ORWtKvtgzlNN4OLIp5aIiIiKNqYWFFblWwEegQCMS2o9YAN4lMH2xKqqJ1aC2HbVSmPeyKYMYomIiKhYYCBbWNnaAd0+u38jfTCrvX20zlsY++thJKakoXMNX/w0ojGcHewK/FCJiIiILIGBbGFWqzcwaAHgEWC83CMQh1t+g/7bSiEpNQ3davtj5nAGsURERFS8MJGysKvVG6nVeuD03k2IvxuCEiXL4FyJunhtWTBS0zToVT8Q0wbVh4Mdv5MQERFR8cJAtpDbGHwTU9aexM1IuVXm/tLj6t9+Dcvgi4H1YWebWR4tERERUdFl8UB248aNmDFjBm7duoW6deti8uTJqFChQqbtQ0JC8N1332HXrl2wt7dHmzZtMGHCBHh6euaozUcffYTff//daNtVq1bFypUrUZiC2OcXHsp0SoQuNf0YxBIREVGxZWvpILZXr15o27YtvvrqK9y7d08FnfLblNTUVLRr1w5eXl4qEH3jjTewdu1adO3aFUlJSWa30QW7gYGBWLJkif7niy++QGEhaQPSE5tZECt9sB/9eVK1IyIiIiqOLNojK72vQ4YMwVtvvaVut2jRAv7+/vjxxx/1ywzZ2dnh5MmTcHJy0i8rV64cateujX379qkg2Jw2Oh4eHqhTpw4Ko32XInAzMiHT9RK+ynpp17KyT4EeGxEREVGx7pGNiYnB/v370aNHD/0yCT67dOmCrVu3Zno/wwBVSOqASEtLy1EbsXv3bjRr1kz11n744YeIi4tDYREWnZCn7YiIiIiKGov1yMqlfY1Gg4AA49JScvvEiRNmb+eDDz5A2bJlVUCakzbSG/vSSy+hffv26likd3j16tXYs2cPHBwcTG4nMTFR/ehERUUhv/i6O+dpOyIiIqKixmKBbEpKivrt6OhotFx6U5OTk83axtSpU9XgrL///hvOzs45avPpp5/qe2qFBLlVqlRRA8CGDx+e6bamTJmCgtCsojcCPJ0RGplgMk9WcmT9PZ1VOyIiIqLiyGKpBT4+2rzO8PBwo+Vyu1SpUtnef/r06SodYNWqVWjdunWO2xgGsaJ8+fLqJzg4ONN9Tpo0CZGRkfqfa9euIb9ISa3JvWplMa8X1HqW3iIiIqLiymKBrAzqkqoBe/fuzZC32rhx4yzv+8033+Dtt99WPa2PPvportsYkl7gsLAwlXKQGektlvWGP/mpW50AzBzeSPW8GpLbslzWExERERVXFq1a8Oyzz+KHH37AqFGjUKlSJSxYsABnz57F4sWL9W0kd/XYsWP6+q5Sc1YqGsjtbt26mdxudm2kDJeU5nrzzTfh7u6u8l7Hjx+vlg8cOBCFiQSrXWv5q+oEMrBLcmIlnYA9sURERFTc2WhkxJUF82SfeeYZLFy4UKUTSNUA6Ul96qmn9G3GjBmjBmDJJf+7d++qlAQJPmXwliFJIejXr59ZbeQhf/7556p2raurq+qJlfzYb7/9Vg3+MpcM9pJJFiTNIL97Z4mIiIiKg6gcxFcWDWR1JPi8c+eOqveavnTWjRs3VIArgaZMdnDq1CmT2yhTpgxKlixpVhsdeehXr15Vy3ITiDKQJSIiIirmgay1YiBLREREZLn4yqJT1BIRERER5RYDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqtk8UD277//Rp8+fdCiRQuMHTsW165dy7J9aGgo3nvvPXTu3BmPPvooPvroI0RHR+dquzndd2aSkpKg0Wj0t1NTU9WylJSUDO3yo21ycrJanpaWpl8m/5dlsq6wtZXjl+XyeHLTVs6J7vzkV1tT5z0nbS353Bfl10lBPPc5aWvJ557vEYXvuS+MrxO+RxS+1wnfI8z/fCj0gezmzZvRvXt3NG3aFJ988glu3bqF1q1bIzIy0mR7eRG0atUKzs7OeOeddzBu3DgsX74cXbt2NToh5mw3p/vOyldffYW4uDj97Z07d2Lq1KlYv369Ubsvv/xSLTfcx/79+9WyNWvWGLX95ptv1PLbt2/rlx05ckQtW7ZsmVHb77//Xi2/efOmfllwcLBatmTJEqO2s2fPVsuvXr2qX3b27Fm17NdffzVqO3/+fLX8/Pnz+mWXLl1Sy+bOnWvUdtGiRWr5qVOn9MuuX7+ulv34449GbZcuXaqWHz9+XL8sLCxMLZsxY4ZR25UrV6rlBw8e1C+LiIhQy6ZNm2bUdt26dWr5nj179MvkS44s++yzz4zabtq0SS3/77//9MsSExPVMvkx/EPasmWLWia/dWS9rq3cT0e2J8tk+4Zk/7Lc8EuXHKcsk+M2JI9Llsvj1JHHL8vkfBiS8yXL5fzpyHmVZXKeDcnzIMvledGR50uWyfNnSJ5fWS7Pt468DmSZvC4MyetGlsvrSEdeX7JMXm+G5PUoy+X1qSOvW1kmr2ND8jqX5fK615G/B1kmfx+G5O9Hlsvfk478ncky+bszJH+Xslz+TnXk71f3fKb/sivLtm3bpl8m7zW6tobvO9JGlsl9DOna8j2C7xGC7xF8j+B7xCWz4whz2MOC3n//fQwePBjvvvuuui2BZEBAAGbNmoU333wzQ3s7OzucPHlSBbI6FStWRJ06dbBv3z51f3O3m9N9ExEREVHhYqMx7PcuQDExMfDw8MDChQsxbNgw/fIBAwaoXqv0PVqZkV6iqlWrqt6Q9u3bm7XdvNp3VFQUPD09VS+Rj48PbGxs9D3H8mNrawt7+wffFXSXJBwcHPK0rfQKydMoy2SdrsdQLl/IfWUbhamtLJN18sVEfnLaVvaj6wlzdHTMl7amzntO2lryuS/Kr5OCeO4f9nVSUM893yMK33NfGF8nfI8ofK8TvkekZfv5IHGaxFdyZU3itULZIxsSEqIOWHpBDQUGBmbods/KlClTEBQUhObNm5u93dzuWy4hG15GlkBW96LWvVCF4QvakOGLPy/bGr4QdOQPxdQ2CkNbwzfZ3LSVc12QbU2d95y0Lejnvii/Tgr6uX/Y14koDG0Lw/PJ94isnyO+R+TN64TvEUXrPaJQ58jqvq04OTkZLZfb6ROAM/PFF1/gjz/+UHkVunQDc7ab231L7oZ8Q9D9lC1b1qzjJCIiIqK8Z7FAVi7Fi/DwcKPlclu3LisyyEWqF6xYsQLt2rXL0XZzu+9Jkyapbm7dT26rHBARERGRFQeycllfLuXLIC1DMpK7cePGWd5XRje/8cYbqmJBjx49crzd3O5bemwlV8Pwh4iIiIgsw6Llt6R265w5c3D58mV1+7fffsPp06cxevRofZsPP/xQDcLSmTlzJl577TUVxPbs2TPX2zWnDREREREVXhYtvyW1YC9evIjq1avDz88P9+7dU3UnGzVqZFSPUgJMcffuXbz44ouqJ1TuKz86kydPxuOPP272ds1pQ0RERESFl8XKbxm6c+eOKmFVoUIFlChRwmid5KFKIXEJOKVshWERfUPlypWDt7e32dvNSZvsym+ZUx6CiIiIiPI2vioUgay1YiBLREREZLn4yqI5skREREREVpkjW1TILCu6mVYMZTZ7hynpZ7jISVvdbBgF2VYYFjTOSVvdTCh50dZw1pT8aqubjSUv2pqagcuSbXWzamXG1OxrlmxrOGPOw7Y1/PvMr7bZ/S3zPeIBvkdo8T0i498y3yOKXxyRlMWxp8dANg989dVX+gkZDMnUuYZT4H755ZeZfgCWL18eI0eO1N/+5ptvVG6wKVI6TKouGJYjk+53U0qXLo0XXnhBf1sGtElOsCnSjT9+/Hj97fnz5+PGjRsm27q4uKgSaDoyKcWVK1dMtpUX9dtvv62/vXTpUpw7dw6ZkYF7OitXrsTJkyezrO2r+0NYt24djh49mmnb119/Ha6urur/Mg3xgQMHMm37yiuvwMvLS/1/y5Yt2L17d6Ztn3/+efj6+qr///fff9i+fXumbceMGYMyZcroy71lNZPcU089pXK3xcGDB7Fhw4ZM2w4dOhTVqlVT/5c88tWrV2faVqqA1K5dW/3/1KlTWLZsWaZt+/TpgwYNGuing168eHGmbbt3745mzZrpB2n+8ssvmbbt0qULWrdurf5/8+ZNVUEkMzL1dIcOHdT/5bUrlUsy07JlSzzyyCPq//I3IX9HmWnSpIm+8on8rcnfZ2bq16+Pvn37qv/L37BMjpKZWrVqYeDAgfrbWbXle4QW3yMe4HuEFt8jivd7REJCAszF1AIiIiIiskoc7JUHycjyzcRUMjIvGz7Ay4ZavGyoxcuGfI9Ij+8RfI8wxPeI4v0eERUVpXqCWbUgn7FqAREREVHeYtUCIiIiIirymCNLRERERFaJgSwRERERWSUGskRERERklRjIEhEREZFVYiBLRERERFaJgSwRERERWSUGskRERERklRjIEhEREZFVYiBLRERERFaJgSwRERERWSUGskRERERklewtfQDWTKPRqN9RUVGWPhQiIiKiIkEXV+nirKwwkH0I0dHR6nfZsmUfZjNEREREZCLO8vT0RFZsNOaEu2RSWloabty4AXd3d9jY2Jj8RiFB7rVr1+Dh4cGzWEB43i2D553nvbjha57nvTiJKsCYRkJTCWIDAwNha5t1Fix7ZB+CnNygoKBs28kTzkC24PG8WwbPO897ccPXPM97ceJRQDFNdj2xOhzsRURERERWiYEsEREREVklBrL5yMnJCZMnT1a/qeDwvFsGzzvPe3HD1zzPe3HiVEhjGg72IiIiIiKrxB5ZIiIiIrJKDGSJiIiIyCoxkCUiIiIiq8Q6svk4WcLJkyeRmpqKOnXqwM7OLr92VeTcvXsXJ06cyLC8adOmGZLMIyMjce7cOfj7+2da0zev2hRVV65cUQWuGzdujBIlSphsc/HiRfW81KhRA66urhZvUxTcvHkTFy5cQN26dTPUS5Tlst6QnIuGDRtm2I48d7du3UK1atUyre2YV22snRRZl3ObnJyMSpUqZTpoJTQ0VJ0PaePj42PxNkXlfUYK6leuXBkuLi5G68LCwnD27NkM92nVqlWGYvjh4eHqPUIK88v7tSl51aYoiIiIwOXLl1GmTBn4+fll+fkn6zObqbQg2+SYzOxFeevEiROaKlWqaPz9/TVlypTRlCtXTrN//36eZjOtXbtWY2Njo2ndurXRz82bN43aTZ8+XePs7KypWbOmpkSJEpoBAwZoEhIS8qVNUbRt2zZN9+7dNT4+PjK7n+bUqVMZ2ty7d0/TsWNHjbu7u6ZatWrq96JFiyzWpiiQ94L+/ftrSpcurc771q1bM7R59tln1fNi+PofMWKEUZv4+HhNv3791Gu2Ro0a6ve3336bL22Kgh9++EG9F1euXFm9vry9vTXz5883apOamqp55plnNE5OTppatWqp32+//bbF2hQFv//+u6Z69erq3NeuXVvj5uam+eKLL4za/PzzzxpHR8cM7/lxcXFG7d5//32j8zV69Gh1HvOjjbU7d+6cpmfPnhpfX19No0aNNK6urppu3bppIiIijNrJ37r8zes+/+S9IP3nX0G2yQ0GsnlM/hjkj1WCobS0NLXsqaee0pQvX16TmJiY17srsoGsvLlkZceOHSrY/fPPP9Xta9euqS8O7733Xp63KapmzJihWbdunWbv3r2ZBrIjR45Ub/YSZIqZM2dqHBwcNOfPn7dIm6JAPrSXLl2quXjxYpaBrAS7WXnrrbc0QUFBmhs3bqjbK1euVNvbs2dPnrcpCqZMmaK5fv26/vbs2bM1dnZ2mmPHjumXfffddxpPT0/938KuXbvUa3D58uUWaVMUSNB69uxZ/W15r5X33E2bNhn9TUinT1ZWrVqlzs/OnTvV7dOnT6vz98033+R5m6Lgr7/+MnpvuXPnjqZixYqaF198Ub9M/sbluVizZo26HRISogkMDNRMmjTJIm1yi4FsHpM3I/kQOHLkiH6ZfBDLsg0bNuT17op0IHvy5En1ISM9RumNGjVK06RJE6Nl8oFs+GaYV22KOukhNBXISm+I9FT/+OOPRl/U/Pz8NJMnTy7wNkWNfGnKKpCV3pSDBw+q9w9TvUVybj744AOjZXXq1FH3zes2RZF0NEhAM2vWLP0y6bkaM2aMUTvpxZLnwhJtiqoKFSoYdRZIIBsQEKA5fvy4Jjg42GSnT+/evdX5MSTnr379+nnepqjq3bu3pm/fvvrbckWgQYMGRm3effdd9Z5giTa5xcFeeezw4cOwt7dHvXr19MskJ8jb21utI/MkJibiscceQ79+/VCyZEl88MEHGc6z5HQaatasGUJCQnD79u08bVNcnTp1CgkJCUbnR/LV5LbutVyQbYqbTZs2YeTIkWjZsiXKly+P9evX69fduHFD5bOaeu3qzldetSmqjh49qnJlq1Spom7LeIbjx49neS4Ksk1RJa85+dGddx3JCe/fv79635fPy+nTpxutz+y9Ojg4WD2PedmmKNm1axf++ecffPLJJ9i9ezfeeOMN/brMzoW8J+hy9AuyTW4xkM2HxGr5I7SxsTFaLkn8so6yJ0np+/btU4MyJCl89erV+PTTTzF79myj85x+YITutu4851Wb4kr3+E2dH8PzV1BtipNHH31UfZk6duyYepMfOnQoBg4cqP4mBM/7w4mLi8OoUaPQpk0bdOzYUS2Ljo5WgUxWr8GCbFMUSQAv571ixYoYNGiQfnnVqlVVIHnmzBlcunQJ8+bNw2uvvYaVK1fq22T2Xi3blEFkedmmKHnvvffw+uuvq89Q+aJQv359i3yO5udnLQPZPObg4KB6ltKLj4+Ho6NjXu+uSJKR2VKhQOeRRx5RPbNLlizJ8jzLORa685xXbYorOTfC1PkxPH8F1aY4efzxx+Hr66v+LxVPpk6dqs7RmjVr1DKe94e72iPvJ7GxsVi2bJm+04Gv9/yv5CNBrPSEr127Fs7Ozvp1rVu3Ru3atfW3Jcjt1KkT3/PzwJYtW3Do0CH1BWHHjh0YM2aMRT5H8/OzloFsHpNLgPKtTr5x6yQlJanL1OXKlcvr3RUbUqpDeqgMz7PhbSG35UM/MDAwT9sUV3JuhKnzo3stF2Sb4kxej9J7oTs/UrZGUi+yOl951aYokfdiCWKl7NLWrVuNyhFJeTPDc2zqXBRkm6JExuNIAPXXX3+p8y49sHn1nu/l5QV3d/c8bVMU+fr6qlSlDRs26Jdldi7kPUFXhrIg2+QWA9k8JpepJEdWvnEa5rrJG2iXLl3yendFkvSUGJJLPvLmJ/V4dbp27YrNmzcbfcOTFIR27drpa0PmVZviqkKFCiqPTdcLKOQyt6R9yHkr6DbFhXzo63oqdCTFRupw6v4GpA6n1Ng0PF/yd/P333/rz1detSlqQaycS3k/MfVFVR6z4Xu3vPf8+eefRueiINsUpSBWcrwlV1PqQ2f3ni+vf+k9TP+eL9uQ82T4Xp3+nOZFm6IgNt05FefPnze6vC+PWf7WJdXG8FxID7mupnhBtsm1hx4uRhm88cYbqgbkvHnzNL/++qsajSkj9sg8Q4cO1bz22muqTMqyZcs0jzzyiCqPYlgmR0o0ychXGX26evVqzeuvv65GIEs5rbxuU1TJqPn//vtPM2fOHDV6Xmq2ym3Der1y/u3t7TWffPKJZsWKFZpmzZqp0dbJyckWaVMU3Lp1S51neYxy3qW2oty+cuWKWi8jtqXO4ldffaXZuHGj5qefflKv0aZNmxrVXJQ6wPJalSob8trt0qWLqpEaHR2d522Kgscff1zVMJW6pnK+dT+6866rAS71NuX9WsoEDRw4UNX7NSzbVZBtioJx48ap15e8jg3Pu9Q51enRo4fmnXfeURVr5PmRGrJS/1RK1OlIeThZJqUt5XxJVQ0XFxdV6SCv2xQFw4YNU59nUk5Pyiy++uqrqtzcggUL9G2ioqI0lSpVUp+x8rc/ceJE9R68fft2i7TJLRv55+FCYTKVCzRnzhz1bUP+36NHDzz//POqp5bM6zmR8yff3nQzo7388ssZZiWRHrv//e9/apCAzMzy0ksvqRHe+dGmKFq0aBFmzpyZYbmMau3Tp4/RFQV5PmS2LcldnjhxoroMZ6gg21g7ubQnI4jTk/xB+dG9JmfMmKFG+krVjrZt26peLV0ep87OnTvx/fffq5G/MkPYW2+9lWGWorxqY+06d+6s8mOzOu9CqglMmzYNV69eVZfA33zzTTXrlqGCbGPthgwZguvXr2dY3qtXL/X3LaSX7scff8T27dtVGo0MSJL3fHntG5I8z88//1wNCpMUjFdffdVo8FJetikKn6Nz585Vn6NyxVGqJ8l7iGFFJd3McvL5J69F+Yx98cUXVS+ppdrkBgNZIiIiIrJKzJElIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiIiMgqMZAlIiIiIqvEQJaIiIiIrBIDWSIiIiKySgxkiYiKKJmOVabjzA9SVN5walsiIktgIEtEVETJTGkTJkzIl23LLEwvvPBCvmybiMhcDGSJiCjHKlasaDSVMRGRJdhbZK9EREVUREQE/vrrL/Tu3RsuLi765eHh4di8ebOaY97V1VUtO3bsGM6fP4+AgAA0b94ctrYZ+xauXbuGw4cPq7nJmzRpouai181bvm3bNvX/EiVKoHr16qhRo4bJY0pOTsbRo0cREhKi9uPv72/245HjPnjwIOzt7dX+PTw81HKZo/7RRx/Vt1u5ciUSExMz3L9///5wcHBQ/79y5QqOHDkCHx8fNGrUyOj8EBHlBgNZIqI8JEHq888/j5SUFAwfPly/fN68efj+++8xePBgtW7QoEEqEG3RooUKaCW43LBhA0qXLq3aazQavPLKK5gzZ44KPhMSElQw+eeff6pg8tatW1i1apVqGxsbi507d6J79+5YuHAhbGxs9Pu9d++e2ocEu2lpaSqQXLJkiQq0syPbf/LJJ9G4cWM4OjriwoULmDVrFjp37qxSC9599139duTYo6Ki9PcNDg7GiRMnEBkZqY57/Pjx6tjkWO7cuYObN29i+fLlaNq0KV9/RJR7GiIiylOjR4/WdOvWzWhZ/fr1NZMmTVL//+677zTe3t6aK1euqNtRUVGaevXqacaOHatv//3332tcXFw0R48e1S/btWuXJiwszOQ+b9++rQkICNAsW7ZMv2zGjBkaeZv/4osv9MsmT56s8ff318TFxWX7OJo0aaL59NNP9bfDw8M127ZtU///+eefNWXKlDF5v0uXLmlKlSqlefPNN9Xtn376SVO5cmXNnTt39G0+/vhjTY0aNbI9BiKirDBHlogoj0lPrKQRhIWFqdvSMymX9nU9tNIjKv+Xy/PC3d0dL7/8Mn7//Xf9Nn755RfVG1qvXj39spYtW+p7bHUpA3v27MGKFSvw999/o2zZsti3b5/RsTg5OWHcuHH626+//ro6rn///TfbxyG9uGfPnlW9wcLb2xvt27fP8j7SOyy5s9LTOnXqVLXs559/Vo9j69at+OOPP7B06VK4ubnh9OnTqmeWiCi3mFpARJTHJNgLDAxUgakEkYsWLULDhg1Rq1Ytfa7ogAEDjO5TuXJldWn+7t27KFmyJK5evYohQ4Zkuo/jx4+jR48e+vxYSWmQdANd8Kwj+bcSzOpIACnBsBxDdmbMmIGxY8eq9q1atVJpBGPGjDHaniFJhxg5cqTKlV28eLE+5/fy5ctISkrCsmXLjNpLmoUsJyLKLQayRER5THJUhw4dqgLYl156Cb/99pvqcdUpVaqUGhRmSG7LoCjdYCovLy810Coz77zzDjp16qR6bnW6deumgklDkiNrSNbLMjmG7NSvX1/18Eqv6ZYtWzBlyhSViyuPx5SPP/5Y9Qzv3bsXnp6e+uXymORYP//882z3SUSUE0wtICLKB5I6IAGdBJrXr19Xga1OmzZt1EAqGXylI5fcJXVAV5XgkUceUT26hj2Wctk+Li5OX7VAemJ15LYEmelJ0KqrbiBkggTZrzmDrKTKga5XVx6PBOOSymDK6tWr8eGHH6qe2GrVqhmtkwBbgvro6GiT2yciyi32yBIR5YO6deuqH0ktkN5ICQZ1ZLS/BK6SGtCvXz/s3r1bBYKGAed7772HjRs3quD2qaeeUnmqEiRKICplq/r27YuvvvoKzs7OqiqApAHI7/Qk5UBybSUIlQD2f//7n/q/5NNmR46tdu3aqmpCfHw8pk2bZhSQGwbYI0aMUCkVEjhLDrBh+a33339f9ehK8CypCnL8EuRfvHjRrFxdIqLM2MiIr0zXEhFRrklAJz2vkjcqvZKGJJ9VSllJHVkpvTVq1KgMdWClB1PKdknJLMm5lTaSSyskKJVyVlIGS3JWH3vsMTVtrOSlSvkvIfVsZXYv2b8cy40bN1SwKYGxYYmuzMhgMulJlUBbym9JQC4DuWQfsl8ZtCUlxeQ4JUA1RY5fAlcJhOV4JYCV4FvKcEkOsKngm4jIXAxkiYiIiMgq8aswEVExJakL6QeD6UiVBcMcXCKiwoiBLBFRMSV5qzIFrilSpouBLBEVdkwtICIiIiKrxPJbRERERGSVGMgSERERkVViIEtEREREVomBLBERERFZJQayRERERGSVGMgSERERkVViIEtEREREVomBLBERERFZJQayRERERARr9H+Tc2JHhafCgQAAAABJRU5ErkJggg==", + "image/png": "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", "text/plain": [ "
" ] @@ -641,16 +786,16 @@ "id": "11901b9c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:04.069254Z", - "iopub.status.busy": "2026-08-02T09:59:04.069254Z", - "iopub.status.idle": "2026-08-02T09:59:04.222734Z", - "shell.execute_reply": "2026-08-02T09:59:04.222734Z" + "iopub.execute_input": "2026-08-07T10:53:08.670964Z", + "iopub.status.busy": "2026-08-07T10:53:08.670831Z", + "iopub.status.idle": "2026-08-07T10:53:08.759832Z", + "shell.execute_reply": "2026-08-07T10:53:08.759105Z" } }, "outputs": [ { "data": { - "image/png": "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UaNGmdW9v/76a4/HGzZsmFy4cMG5HT16NNV5AgAAAJDOXaH69Okj9erVk8OHD8u9994rOXLkMPt1HYv27dun6lg6E5QeQ6eQXbRokelSldLYjIIFC5puUZ7ooPCE09YCAAAACLDAQtWqVctsrh599NE0BRUaTCxevNgEFwlX8758+bLkzZvXuW/37t1y6NAhuf3229OadQAAAACBEljs2LFDPvroIzlw4IB89tlnzq5Qbdq0SbHVQensTtqFShe/0+5PP/zwg/OxypUrm25WOpVt3bp1pXv37nLbbbeZMRb/+c9/zFoZnTt3TmvWAQAAAARCYLF8+XITQOi4CF28zrU1QbtHDR06NMVj6LSyOtWsLnz33//+1+2xQYMGmcAie/bssnr1ajML1IwZM8xYi1dffdWsk+FYnA8AAABAJg0sXnzxRbMQns7OpAOqHXTgdqtWrbwKLDSoWLFiRYrpChcubFboBgAAABBks0L98ssvpsVCuQYWJUuWZAYmAAAAIAtKU2ChrQ26tkTCwELXmtAuTAAAAACyljQFFjpwun///nLmzBlzXwdZf/vtt2bxurSsYwEAAAAgCwYWY8aMMQOrixYtaqaE1WliddrYatWqyciRI32fSwAAAADBN3hbp5NdsGCBmXJ28+bNJrioWbOm1KhRw/c5BAAAABC861gonSpWNwAAAABZW5q6QimdKlanli1btqzZWrduLStXrvRt7gAAAAAEb2ChC9a1bNnSLFg3YMAAs+XPn98smKeraAMAAADIWtLUFWr06NHy4YcfSteuXd32t2jRwiyO16tXL1/lDwAAAECwtlhcvHhRHnjggUT7dV90dLQv8gUAAAAg2AOLWrVqydKlSxPt1321a9f2Rb4AAAAABGNXqLlz5zpvN27cWHr06CHLly+XOnXqiGVZZtrZjz/+WF544YX0yisAAACAzB5Y9OvXz+1+njx55PPPPzeb677JkyfLqFGjfJtLAAAAAMERWJw9ezZ9cwIAAAAg661j4Y2IiIj0PDwAAACArBBYXL58OT0PDwAAACArBBYAAAAAsgYCCwAAAAC2EVgAAAAAsI3AAgAAAIBtBBYAAAAAAjuwmD9/fnoeHgAAAEBmWyAvoWvXrsncuXNl9+7dYlmWVK5cWR5++GHJmTOnM02HDh18lU8AAAAAwdZisWfPHrn11lulf//+smrV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hw6VzZs3m0Dhs88+k8uXLydKo2M3ihcvLm+99ZZzHzNPAQAAAEEQWBQqVEiWLVsm27dvl127dpkF8nS62erVq6fqOK+88orkypVLjh07Js8884zHdPny5TMtFQAAAACCcIE8DSRSG0y40qDCGzrrVN26dSUyMlIaN24sgwcPNi0lAAAAADLxGAulYyN0rIXOAqVb69atZeXKlb7N3f+3VvTr108mTJggTz31lFmUT4OLGzdueHxOTEyMREdHu20AAAAAAqzFYsqUKWa9ik6dOjnXrdCB182bN5dJkyZJr169fJbBMWPGSFjY39nUlovy5cvLvHnzpFu3bkk+Z+zYsTJq1Cif5QEAAABAOgQWo0ePlg8//FC6du3qtr9FixZmQLYvAwvXoEKVLl3abK4zUiU0bNgwGThwoPO+tlhERUX5LE8AAAAAfNAV6uLFi/LAAw8k2q/70rvbkXaBOn36tOki5YmupaGPu24AAAAAAiywqFWrlixdujTRft1Xu3Zt8ZXr16/LiBEjTCDjGDvRv39/s79jx44+ex0AAAAAfugKpYOndYG85cuXS506dcw6FroexccffywvvPCCGWDt8PDDD3s8zoIFC+Sll16S2NhYc//xxx+XPHnySJ8+fcyWPXt2iYiIkHLlypn92lKh4ys0gKlQoUJasg4AAAAgUAKLyZMnm4r+559/bjYH3aePuUousGjSpIlbEOJQpEgR87+ujzFkyBATrBw5ckQKFChAtyYAAAAgWAKLs2fP+uTF8+fPb7aUaIChA7YBAAAABNk6FgAAAABgO7DYsWOHPP/889K+fXvnvjlz5siVK1fSekgAAAAAWSmw0EHb9erVk/3797uNsdi9e7e8/fbbvswfAAAAgGANLF588UV5//333YIK1aVLF5k2bZqv8gYAAAAgmAOLX375Rdq0aeMcWO1QsmRJOXr0qO9yBwAAACB4Awtdyfr3339PFFhs2rRJihcv7rvcAQAAAAjewKJz585mBewzZ86Y+3FxcfLtt99Kz549TXcoAAAAAFlLmgKLMWPGmFWxixYtKvHx8WZ17HvvvVeqVasmI0eO9H0uAQAAAATfAnm5c+eWBQsWmClnN2/ebIKLmjVrSo0aNXyfQwAAAADBGVg4VK1a1WwAAAAAsjZW3gYAAABgG4EFAAAAANsILAAAAADYRmABAAAAwDYCCwAA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5v6pU6esPHnymEDBQSuBTzzxhFuZaxpHYHHlyhXr5ptvtkaOHOl8fPz48ZZeB0ousND8vf322877R44csUJCQqyNGzc69+lraMBy4cIFr95TSuWSlNGjR5vKvystF63Unjlzxtw/ceKEeY9vvfVWiufeN998Y4KhS5cuOfd9+eWXVlxcXKLAIqFBgwZZhQsXtg4dOmRdv37dVNy1LB1Onz5tKutz5syxvJGa80DLIDo62uOxvClbb84nb8vfU37+97//mfwDgC8weBtAlqfdjI4ePSqvvfaas5uJdhe6//77ze1169aZx4cNG+Ysqx49ekiRIkVMNxNXOhA7d+7c5rY+rt12fv31V6/LeO3atabry6BBg5z7+vTp4zymJ9odpkCBAs77UVFRcuedd8r//vc/5z69rWMStCuSN+8ppXJx0JmLli5dKvPmzTMDx3fu3GnGfLh6/PHHTVctdfPNN5vX0hmsUpIrVy7T5ci1DNu0aSOhocn/+Zo1a5a8/fbbZuYj7Sr13XffyeHDh837033z5883+7QrlP7vjdScB/p+PXUJS03ZenM+eVv+SeVHzxktX+3eBQB2McYCQJanFTOtbCfVv11phTR//vxSsGBB5z7tr162bFnzmCvXNErHW1y7ds3rMtbK5k033eRWCcyRI4cZa5Ec7X+fcOrQrl27yvDhw+Wtt94yFU0d2K2VT2/fU0rl4piV6cMPPzTjAzRwuHr1qtl/5swZ59gHVaZMGbfn3XLLLfLxxx+nWB733HOP9O/f3/yv+WjatKk89dRTZtCxJzqORWdU0sBCgyt16NAhU45fffWVW9oSJUpIxYoVxRupOQ8SjplJyJuy9eZ88rb8PeVHzxkN0lIKXAHAGwQWALI8rSxeunTJXLnViltCWmHTK7q6TkRY2N8/m+fOnXNehfcVrUhGR0dLfHy821V5HdybHK0cHzx40G1fx44dTcVTB/ieOHFC8uTJIy1atPD6PaVULjoQWKe41UHTjkHQOjBaB6lrV1tXCfOv970tu7Fjx5oZr3Rgtg5S1wHp27Ztk9tuuy1RWh303rZtW3OFvnfv3s79WonXgdvTp083QVhapOY8SGlgekpl643UlL+n/Og5U758ebcB4QCQVnSFApDlNWnSxFQUXbsNOa76Kr0arI8vWLDA+diePXtk165d0qhRI5+Wn76WVgqXLFni1gXnjz/+SPZ5eiVf0yWsvLZs2dK8L906derkXOPCm/eUUrloJV67KrleGdduRknRNTsc9P1p16GGDRumWB76GnFxcSbfOiOStkJoa05Ssz9p4NCuXTtTUZ44caLbY3fddZdpsXjvvffc9uuxteuZg86+lLBVw8GX50FKZeuN1JS/J3rO6PTHAOALtFgAyPK0z/8bb7whTz/9tOzYscNMQ6rTiepVaN2v3UhefPFFcxVcK5JasR03bpy5Mn733Xf7tPy0a452/enevbsMGTLEVD61Mq1X2ZO7Cv7Pf/7TXNnXLjY6nahDt27dzLG0+4xe9Xfw5j2lVC46ta3mSwOW1q1bm+lxdexCUrTyret16PSw2iVr3759XlWCteKr+dbn6vvS8RBaDto1KiEdr6ALDY4fP95tnRDHdLMTJkwwLTj6fnWaWJ2+VtONGTPG5F/NnDnTBBYPPvhgouP78jxIqWy9kZryT4pOuatjM9JzET4AWQstFgAgYirzjkG8uq6AVhT/85//OMvm5ZdfNleXdQyEXtUeOXKkc7yCg14td716rPRqcJUqVZz3df2GhGtLJFwgT19XK6y7d+82g7K1oqsVyOQGA+vrahAxadIkt/2tWrWShx56yAQe+tquvHlPyZWLDvzVrjfaQvD999+bir+un9G5c2fT7cq1XD7//HMTVGhLg3bb0gDANQDypH379jJnzhyz3oOuwaGvpXl1lJfrAnk6YF3T6wB4bSFxbFpxV9o1St+DdjfTfCqtiDuCCqXvR9+zJ2k9D9JyzqV0PqWm/JPKz7Rp00yA5mmNDQBIrRCdGirVzwIApBvts+86aFcrsFr50wqya5CSkHbp0RmL3n33XWeXJ3hPg5e+ffuacQtZofz69esnAwYM8LjoIgCkFoEFAASYqVOnmulI9eq0tlhoVyi9sqwDl4ONdkfSFoakaOVeWyAAAJkDgQUABCAd3Pztt9+a2Xp0kLP2ow9GOi5Ax0QkRdd1mDFjRobnCQCQNgQWAAAAAGxj8DYAAAAA2wgsAAAAANhGYAEAAADANgILAAAAALYRWAAAAACwjcACAAAAgG0EFgAAAABsI7AAAAAAYBuBBQAAAACx6/8APU4dimTIqEkAAAAASUVORK5CYII=", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAgjhJREFUeJzt3QeYFEXisPEiCYgCihHFnA4D5nx6glnMmPOZE5gV9cSM4cx65jPncCaMeJ45YjjBnDFHgoHc3/PWfTX/3mHDzM7CBt7f8wzszPR0V1dXV1dVV1W3yrIsC5IkSZJUgdaV/FiSJEmSrFhIkiRJahDesZAkSZJUMSsWkiRJkipmxUKSJElSxaxYSJIkSaqYFQtJkiRJFbNiIUmSJKliViwkSZIkVcyKhSTVw0cffRRatWoVrrnmmhYXfy1538rx448/xni48MILw4weX3/88Uc48MADwzzzzBP3dc899wxffvll/PvSSy9t7OBJaiKsWEhSM9HSC3Itff+as/POOy/ceuut4amnngpZloXrr7++sYMkqQlq29gBkCRJTdvQoUPDyiuvHP70pz8VPpt//vljJUOSEu9YSJKkWn3//fehY8eOxpKkWlmxkNRkTZw4MQwePDj07NkzdOjQIcw+++xhhx12CJ999lm1/dtvuummsPjii8dlV1hhhTBkyJCp1jlq1KgwYMCAsMACC4SZZpop9OjRIxx66KHx8+Jtn3322WHZZZeNBSpaZ/fee+/w1VdfTbXOe+65J7bktm/fPiy33HLhsccem2qZiy66KK5rlllmCd27dw9bbbVVeOONN0qOi+eeey6GFYSXfeZ1yCGHlL1v5SglTks5TnXFQSn7V5vffvstdO7cOfb9LzZhwoQw55xzxjAlbdu2LWyDuFpkkUXC0UcfHddTidrii3V37do17LrrrlP9bty4cWGOOeYI22+/fa3rLyVdlpIO8udNben3oYceisu9++67cV9SnOVfxV3Xvv3227DzzjvHfeW1++67hzFjxsQ4Oeyww+odt5KagUySmqDJkydnm222WTbHHHNkt99+e/bLL79kH374YbbJJptk8847b/bdd9/F5fiMrGzLLbfMDjrooOzLL7/MRo4cme27775Z69ats0ceeaSwznHjxmUrrLBC/P1jjz2WjR49Ohs6dGg233zzZcstt1z2+++/x+UmTZqUbbTRRlnXrl2z66+/Pvv++++zr7/+OrvuuuuyQYMGVdnudtttl/Xv3z9uk2W22GKLrGPHjtm3335b2O4VV1yRtWvXLu7HmDFjsh9//DF78MEHs5133rmsOGEbbPOSSy6Z6rtS960U5cRpqceplDiobf9Ksc8++2Qzzzxz3Pe8u+66K66XeKkO4Xn44YdjePfYY4/C5z/88EP83QUXXNBg8TVgwICsffv2MU3lkc5Yx6OPPlrjdkpJl6Wmg3LSL5Zccsl4nPOqO16s/09/+lO26KKLZs8991zcPsd51113jfvN/ktquaxYSGqS7rjjjlhooVCYN2rUqFiwOvbYY6sUkJZffvkqy02ZMiXr2bNnLEwlV111VVz2gQceqLIsBb98Aenmm2+O72+99dYaw5e2u+qqq1b5/PPPP4+fn3feeYXPdtxxx1jYqlRtBe9S960U5cRpqceplDiotGLx0ksvxd9feeWVVT7feOONswUWWCBWgmpz6aWXxopAKnyXW7EoJb7ef//9rFWrVtlZZ51VZdnVVlst69GjR61hLCVdlpoOykm/5VQsLr/88vjZ008/XWXZa665Jn5uxUJq2ewKJalJevDBB2M3ji222KLK5126dImDSJ9++ukqn2+++eZV3tNFg9/+97//jdOG4sknn4zr3Gyzzaosu/HGG8fuOXyPhx9+OHaV2W677eoMZ/G66H4y66yzhk8++aTwWa9evWJXErqBDBs2LEyePDk0tFL3rRylxGmpx2l6xMFqq60WlllmmfDPf/6zykxTjz/+eNhrr71C69b/d8njsw033DB069Ytfp66XU2ZMqXKsWvo+FpiiSVCnz59wpVXXhm3BbqDvfzyy1OFsVgp6bLcdFBK+i0Hs0bRJW2dddap8nlx+pDUMlmxkNQk0U+bvvEzzzxzLEy1adOmUABkhpqffvqpyvJzzz33VOtIn6Vl+X+uueaqtvDGsqnwx0BV3rPdusw777xTfUbBKt+f/cgjjwwnn3xyuP/++2Nhm8Jsv379wuuvvx4aSqn7Vo5S4rTU4zQ94gCMN6CQPmLEiPieaVG5O0+hPXnmmWfCJptsEhZaaKHw0ksvxWc05KdQZRxDfZQSXzjooIPCp59+Gh599NH4/h//+EeMr3wYq1NKuiw3HZSSfsuRtl+M8SO1VZoktQye5ZKaJAoiFHAotE6aNCm2cNPC+/+7cIYPPvigyvLffffdVOtIn1GIBYOKKZxVN0Umy7JNMNCX92y3LhQI69KuXbswaNCgWJjkdcEFF4Thw4fHVl1a1BtCqftWjlLitNTjND3iALvttltsseeuRaosrL/++mHBBRcsLHPzzTfHgc9XXHFFHGjNoGUQrkqUEl+p9Z4B1VQoRo8eHZ8PwV0MKjq1KSVdlpsOSkm/5WA/2X4xKjTpDo2klsuKhaQmiW4lzCSTWnXrwuw1eRSs6KbDLDepMEXhjQIwXUry6Bbz66+/xu/Rt2/fWHi76667QkOj8EjL9N///vc4S1A5LfadOnWK/48fP36q70rdt3KUEqflHqfa4qC2/SunYMtsU8zOxL5//PHH8S5GMSof+UI1FSIK+JUoJb7AXZ399tsvPPLII/Euzu+//15tGIuVki6nRToox3rrrRfTA7N81RY3klqoxh7kIUnVYRBr3759sznnnDO74YYbsm+++SbO3jNs2LA4IPjcc8+tMgiV2WwOOeSQOCMPr/333z8OxB0yZEhhnX/88UfWq1evOEPOE088Edf373//Ow6aXWaZZbLffvutxtl32H51s0JdffXVU4Wd9e+yyy6F97vvvnt28cUXZ++9916cteezzz7Ltt1222yWWWbJvvrqq7ISQPfu3bNNN900Do7OK3XfSlFOnJZ6nEqNg5r2rxzMhkT42ffZZ589bi+PWYr4/oQTTojbYX+ZHalfv37x8zfeeKNeg7dLia+EWZdmmmmm+LvqwlidUtJlqemgnPRbn1mhFl988eyFF16I22f/d9ttN2eFkmYAViwkNVkUpC688MJsxRVXjNOIdunSJVt55ZVjYTUVPPMFpH/+85/ZIossEgtsFK7uv//+qdb5888/ZwcffHAsPLVt2zYWZA888MDsp59+qrLc+PHjszPOOCMWkljf/PPPn+29996FQnA5BbNPPvkkO/zww7Ollloq69ChQ9wmBdlUgC0H05FSQEyFUval3H2rS7lxWspxKjUOatu/UjEb00ILLRR/z1Sq1WHmqCWWWCKGhWN84403ZrfddltFFYtS4yvZaaed4u8OPfTQkvetrnRZajqYVhULMG0ts4B17tw5vphqljC1adMmO+aYY0reV0nNTyv+aey7JpJUXzzoi37yV199ddhnn32MSDUbBxxwQJwd6s0334yzZrVkPMCPh/mdf/754fDDD2/s4EiaRhxjIUnSdMZYCZ54vcoqq7T4SgXYV6y77rqNHRRJ01DdcylKkqQGrVScd955caaka665psXF7Kmnnhqf18FAbgaqM5D8b3/7W9hyyy3Diiuu2NjBkzQNecdCkhrZYostFmcoqulVyvM0mtJ2GlpzDXd1br/99jj1LjNiUQCnsN3SMOUvs0CtuuqqYb755gunnHJKOPjgg+O+S2rZHGMhSZIkqWLesZAkSZJUMSsWkiRJkirWfDqmVmDKlCnh66+/DrPOOmuVJ61KkiRJqhlPphg7dmzo3r17aN269nsSM0TFgkpFjx49GjsYkiRJUrM0cuTI+DyaMKNXLLhTkSKkc+fOjR0cSZIkqVkYM2ZMbKBP5ekwo1csUvcnKhVWLCRJkqTylDKcwMHbkiRJkipmxUKSJElSxaxYSJIkSaqYFQtJkiRJFbNiIUmSJKliViwkSZIkVcyKhSRJkqSKWbGQJEmSVLEm84C8jz/+ODzyyCNh+eWXD2uvvXaV78aPHx8ef/zx8N1334Vll102rLbaao0WTkmSJElNtGJBxWHbbbcNH374Ydh3332rVCy+//778Je//CX+3atXr3DMMceEbbbZJlxzzTWNGGJJkiRJTa5iccQRR4Q111yz2u+OO+640K5du/DSSy+Fjh07hjfffDOstNJKYcsttwybb775dA+rJEmSpCZYsfjXv/4V/v3vf4dhw4ZNVbmYMmVKuPvuu8Mpp5wSKxWgqxTL3XHHHWVXLCZMmBBfxVq3bh3atv2/qKhumaRVq1axolOfZSdOnBiyLJuuy2KmmWaq17KTJk2Kx6AhliW8hHtaLjt58uT4aohlSQ+ki6ayLHFAXNSkTZs28dVUliWNkdYaYtn8+Tmtlq3rXDaP+D/mEf9jHjH1uWweYTnCPKJl5hG1XR+n2mZoRCNHjgwHHnhgePjhh8PMM89c7fdjx44Nf/rTn6p8zvvXXnut1q5VvJIxY8bE/88777zQoUOHqZZffPHFw84771x4//e//73GAsmCCy4Y9txzz8L7iy66KPz+++/VLtu9e/fYtSu57LLLwujRo6tdds455wwHHXRQ4f3VV18dfvjhh2qX7dKlSzjssMMK76+//vrw9ddfV7ss8Xr00UcX3t9yyy3h888/r7Hgffzxxxfe33nnnbF7Wk0GDRpUpYL4zjvv1LjswIEDCwWShx56KLz11ls1LnvUUUeFTp06xb8fe+yxWo/1gAEDQteuXePfTz75ZHjxxRdrXJa0Ntdcc8W/n3322fD000/XuOw+++wT5ptvvvg3d8uGDh1a47J77LFHWGihheLfVJAZK1STnXbaKSyxxBLx77fffjvcf//9NS7br1+/sPTSS8e/33333VjJrgl38Kh046OPPgq33XZbjctusskmYdVVV41/f/HFF+GGG26ocdn1118/rLXWWvHvb775ptYuiOuuu26h2yJp9/LLL69x2TXWWCNsuOGG8W/OCc6jmqy88sphs802i39zrnF+1oTukltttVX8m3N48ODBNS7bs2fPsN122xXe17asecT/mEf8H/OIaZtHkK/PMccchXO5putWU8kjuNZyzc+PG62pEa8plCMocKbrVipv5ctNTbEcscgiixQKyYy5pXxYE8sRDVuOGDduXGjyFQtqWBTmDz/88LDiiitWu0xKNKngmMw222yFykJ1OPm5yyFJkpqGC4d+EPZ89Lf4d9dWf4Stp27nKxgyZEh44okn/rds165VGtOK3fTS5+HgZ4fEv9uHiWHn/3VwqNiQt78JRw/733qxVy3rpZs2Y0ATCtf5u3t5L33yUzj5uP9b704dJoQO/7uZXpEPvhsbFsqtd6v2Y8NsNcz9+eOPP4YTTzyx8J7KS2pMK/bzbxOqrHfjmX4K8/6vYbti+fX+ZaZvwsK1rHfvvfcuNPpSOUyF4OqseNoTYXz4X8+O1dt9Hv7U6P1zZhytstr6xUxDN954Y+jfv3849dRTCzXQs846K7YMMpD74IMPDp988klYbLHF4oxQG2ywQZWW5+effz7897//LfmORY8ePWLNvXPnzlMtbzeH/2M3h5Z3C7MxlrUrlN0lYXfJGTOP6HnSo9UuOyW0ClMKs9xnoW2o2s11/PefhYk/ffG/ZbP/vQr72jqEdt0WCO3nWqjs9b5z6sZ1dpesLsxZaBUm52blbxsm1xheSlKTSwxvXevNh7emrs/VhzeEyeH/SuZtwuRQXF/Jh3lSLpratGJbNYd5UpX1EuNZteGt6byvKU3Utt7awtu61f9eNYeX+P3f3reOqaPqevNhtkt13ec95WjuiHG3rLpydF6j1eG4BbfrrruGDz74oPAZlYFffvklvPfee/HEWWCBBWIC/fTTT6v8lgoHFZCatG/fPr6K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V7j//vtDq1atwl577RUWXnjhcPPNN4c999yzEUMvSZIkqUncschXKsCdiilTpoS55porvp84cWJ49NFHw0477RQrFejevXtYb731wgMPPNAoYZYkSZLUBMdYvPPOO+Hiiy8OY8aMieMtzjvvvLDBBhvE7z7//PMwYcKEeIcij/fPP/98jescP358fCWsW5IkSVILnhVq1llnDcsvv3zo2bNnHJBNN6hUEfjjjz8Ky+R17tw5/P777zWuc/DgwaFLly6FV48ePabxXkiSJEkztkavWFDoZ2zFiSeeGF5++eUwYsSIcMEFFxQqEMgP5sYvv/xS+K46AwcODKNHjy68Ro4cOY33QpIkSZqxNXrFIo87E0sssUT46KOPCpUOPqO7VB7vmZq2Ju3bt48Vj/xLkiRJUgusWDB24sknn6zy2QcffBCGDRsWVllllfi+devW8bkW1113XaHrE9+/8MILYccdd2yUcEuSJEmqYPD2l19+WeqiYf75569zGWZ5uvDCC+N0soyvoLsTFY1tt902do3Kj5dgFqgVVlghTjv7xBNPhH333TdsttlmJYdHkiRJUhOpWJQzADrLsjqXadeuXXjwwQdjt6Y33ngjdOrUKVx00UVTzQDFcy1ef/31MHTo0PjkbSoiK620UslhkSRJktSEKhbvvvvuNAkAdyt41YbZojbddNNpsn1JkiRJ07FisdRSSzXA5iRJkiS1RE1qVihJkiRJM9CTtxlDcf3114e77rorfPHFF2HSpElVvn/vvfcaKnySJEmSWuodi3POOSc+0G7NNdeMD7TbZ599wnLLLReni91www0bPpSSJEmSWl7F4pprrol3K6hc4Kijjgp33nlnuOSSS8KHH37Y0GGUJEmS1BIrFp9++mnhIXYdOnQIY8eOjX/vtttu4bnnnmvYEEqSJElqmRWLyZMnx+dQYMEFFwwvv/xy/Puzzz4rfC5JkiRpxlGvwdt5jK/YYYcd4tOxuVux3XbbNUzIJEmSJLXsisUvv/xS+JvxFfPOO2948cUX45iL/fffvyHDJ0mSJKmlVix4Cvcaa6xReL/LLrvElyRJkqQZU73GWKy11lphscUWC4MGDXIWKEmSJEn1nxVq7733Dvfcc09YYoklwmqrrRanmv3hhx+MUkmSJGkGVK+KBTNBDRw4MAwfPjy8+eabYd11140PzevevXvYbLPNGj6UkiRJklr2rFC9evWKT93u27dv6N+/f3j44YcbJmSSJEmSWvYdi2TEiBHh+OOPDwsvvHDo3bt3mGuuucINN9zQcKGTJEmS1HLvWJx77rnhlltuCW+99VZYaaWVwoABA8JOO+0U5plnnoYPoSRJkqSWWbG44oorws477xzuuOOOsOSSSzZ8qKTpiHFC3H2rydJLLx2WX355j4kkSVJDVyw+/vjjkpbr169fuPvuu+uzCalsCx03pF6x9u2tx4XxI4fX+H37HsuEeXY+q+z1fnaWExlIkqQZR8WDt2vDdLRSUzdbn/3CxB8/r/H7dnMsOF3DI0mS1BxN04qF1By0n3uR+JIkSVIjzQolSZIkSVYsJEmSJDUI71hIkiRJqpgVC0mSJEmNU7HYaqutSvpu7733rl+oJEmSJLX8isX9999f7edTpkwJDz74YOH9NddcU/+QSZIkSWqZ081+++231f6dKhXPP/98mHfeeRsudJIkSZJaXsUiX2morgLRtm3bcP755zdMyCRJkiS1zIrF22+/Hf9fdtllC38n7dq1C/PNN1+YZZZZSl7fuHHjwi233BJeeOGFWClZe+21w8477xzatGlTWOaKK64Ijz76aJXfLbjgguGiiy4qJ+iSJEmSmkrFYplllon/f/PNN2Geeeap8t2PP/4YOnToUPK66DrVs2fP0KdPn7DWWmuF33//PZxwwgnhzjvvDA888EBo1apVXO7NN98M33//fTjmmGMKv+3cuXM5wZYkSZLUlCoWyQ8//BDOPffccN5558X3BxxwQLjyyitDt27d4t2FlVdeuc51UHHgTkW+gsLv1lhjjfDaa6+FVVZZpfB59+7da52JSpIkSVIznBXqyCOPDH379o1/v/vuu7E709ChQ8O+++4bjj322JLWQcWi+K4HXakwevToKp//97//jV2kDjzwwHDrrbeGLMvqE2xJkiRJTemOxUsvvRRWW221+Pfjjz8e7ybQpYm7DAsssEC9A3PhhReG2WabLay66qr/F8C2bcOf//znsO6664avvvoqHHbYYeH222+PU96m7lLFxo8fH1/JmDFj6h0mlY/uayNGjKjx+6WXXjosv/zyRq0kSdKMXrGYeeaZYyF/8cUXD0OGDAk77bRT/JxxEh07dqxXQG677bZYsWCMRX4MxRlnnBG6dOlSeL/pppuGFVZYIVYsauoe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XXRR4f1nn30Wzj///PDxxx+HhRdeOBx22GFlhZe46Nu371SfE+4NN9yw8J40d8kll4R33303PriI49i7d++y18MU3nfddVec0pu4v+yyy0J9kC6uvPLKmC5mm222eCxXXnnlwvekA87Np556Kvz6668x7R188MFV0t7PP/8c08Qrr7wSZp555rg/u+22W0xnCQ9JJZ/gvJkwYUJYfvnlw/7771/WFORnnHFGDEexbt26xXhIaOAhzF988UXcJ9Lx9ttvH1q1alVlmX/+859xGY43D2/NH+9St1UXzoMrrrgivPHGG/E9+00cs55yltlqq61i/OfttddeYZdddilrmVKwf1w/fvnll7DKKqvEc4EH3ybMHXPPPfeEBx98MB57ngxOPrHqqqtWWQ/nHfvF/2eddVaVdJVPFxyHoUOHxhml/vrXv1Y5H6pDOiM/5JzlOLP9cpap6RwD6ZZzstRtcX0l/P/5z39i3rjeeuvFY5c/P77//vu4zL///e/40GCujzVhO5wX5Jn8JiG/5flgxZjWP51DpSyTwvP3v/89Hpd55503ns+kufw5z7HlfOUcJn+tzueffx7znffeey8sueSS4eijjw5zzTVXtcumfJi8j2tGuduqaz2lpLW60nVDrqeUZZocZoXS9PfDDz9kgwcPznbdddfs+OOPz7788svCd8cee2zWp0+f7KWXXsqOOuqo7K9//Wt2yy23VPn90KFDs2233Ta+9thjj+zcc8/Nfv311yrL3Hzzzdkpp5ySPf/889mBBx4Yt1WulVdeOdtss82yXXbZJevSpUu1y5xwwglZ165ds3/84x/Z1Vdfnc0555zZIYccMk2Wqcviiy8ef3PbbbdlN954Y/anP/0pW3PNNbMJEyYUlnn99dezjh07ZgcccEB2xx13ZBtssEG20EILZb/88kuDL1MXjv3666+fXXbZZdl9992X7bnnnlmHDh2y1157rbDMK6+8ks0000xxOyzDMZ1lllmyZ555pqxl3nvvvfgZx/L+++/PrrrqqmzeeefNdtttt7LieKWVVsqOPvro7J577smuv/76bJlllslWWWWVbNKkSfF74nq11VbLevXqld16663xOCy55JIxDeYRXxyvG264IfvXv/6VbbLJJtlcc82VffPNN4VlPv7442y++eaL3919991xeyuuuGL2+++/Z+UaO3ZsDAfb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dZZ8kHOCtMjxppJDvJO2uXbly3LkIRxT0ktqaEljH6e7TC3CL7/8Qkkie/XVV2td7oorrsiWWmqpKp/xu8MOO6zw/tdff81mnnnm7IEHHojvP/zww6x169bZnXfeWeV3X331VcnreP/997M2bdpkjz32WGGZ1VdfPf7u7bffrrKeffbZp/D+p59+ytq2bZstvPDC2fjx4+Nnu+yySzbXXHPF9X3//ffxsxVWWCHr2LFj9scff8T3a665Zta9e/e4vvRZCu/BBx+czT///PGVvsPOO++cbb/99oX3a6yxRrbbbrsV3t92220xHo4//vjCZ4RljjnmyMaOHVv4rG/fvnG5l156Kb5/4oknYjh69OiRXXLJJfGzm2++OX72r3/9K76/6qqrsvbt28fPrr766vjZhAkTsh9++CF78cUX4+e8HnroocJ2Hn/88fjZb7/9Ft9feeWVWZcuXbKff/65sEy7du1i+CZOnFglLLfffnthGdZJHO+///6Fz+abb75smWWWyVZaaaX4fvLkyVmHDh0K79lGp06d4vbWWmutqdLEkksumXXt2jXr169f4TvWQRz84x//iO9//PHHbJZZZsmuvfbaKseA8LFv+bBsvPHGhffjxo3LZp999rjt0aNHx89OOOGEmN6I95Settpqq/ieOEzrJt2wftI0SD/EzeDBg7N55pkn7tN3331X2BbHetVVVy2832mnnbJ11103mzJlSnz/yiuvxPXl95OwzDTTTNnnn39e+Ozwww+Pn6V4Z/v8jnPxyCOPjJ+99dZb8bOTTjqpcHxbtWoVP2OdYLvffPNNfKU0cemllxa288EHH8TP3nnnnfie843zhM8TzgvCwrmVD8tZZ51VWGb48OFx27179y58xnFeZJFFsm7duhU+m3vuubN55503hmvSpEnx+BLHHLPiNLHRRhvFba+yyiqF+Evn6jHHHBP/5liwjr/97W+F708++eR4HDlH8mHp2bNnTFMpXpZeeum4r1988UX8jPOI/SKdPPjgg/Gz4447Ln42YsSIwvHlez7j3ADn8pgxY+L5TnrgO+IjIRzsYzJw4MBs0UUXjecr0rHp1atXYZkUlpQn4MILL4znVIp38iKWWX755bNtt902fjZq1Kj4WcqXCDfHheNH3lMcx3zO8uxnwjrIB9I5xfnBOp5++unCMpzXfJbSSQrLIYccUliG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CAqWqQtWqagApL7JFAymx9O3KaBTaKEilp+hqhRUJimAgYrE9Hj6NgW61GefBo26BksXo4BLQReEd1oP+qQgne4UUokq9ynnFM7SjFBUVKbH07cp8KduusWVylJQUaNQS6Vqejx9mwJl6npLg1eapahUqdANrpXT+unbqXIGKib5Br7pcX2vD9Jw6jZZ3MDXFFE5S3fZqfAXzy7XUKxYSJIkSaqYg7clSZIkVcyKhSRJkqSKWbGQJEmSVDErFpIkSZIqZsVCkiRJUsWsWEiSJEmqmBULSZIkSRWzYiFJ0xkPVeLBerfffnvhydfpAWWV4MmrPPCPhyI2JTxNlicJTwvEIw/ha4mmZbyBB5LxtGpJaihWLCRpOnrttdfiU3CvuOKKcN9998WKxR577FF4unQlLrvssvjUaJ603pTsu+++8enQ08Khhx4a/v3vf4eWaFrGG3hS8RlnnDHN1i9pxtO2sQMgSTMSCv7rr79+vEuR9OvXL8w///wVrff3338Pp556anjooYfCjGTzzTcPiy66aGMHo1k67rjjwvLLLx8OP/zwMOecczZ2cCS1AFYsJOn/owvRK6+8En755ZewyiqrhLnnnrtK3IwdOza2II8fPz6sttpqU31P15WVVloptG/fPrz55pthlllmCauvvnpo06ZNoYWYOxYdOnSI3aCSjTfeOMw777xTdZd6+eWXQ/fu3UOvXr1iqzwF6MUXX7za43XrrbeGOeaYI6yxxhrx/TPPPBO3s+qqq1ZZ7umnn46fE/5S9qmueBk6dGj48ccfQ6tWreI+rLDCCmHWWWetNoxff/11eOutt0Lnzp3DmmuuGX9Tqtdffz18+eWXcf//9Kc/FT7fcMMNw4ILLhj//vDDD8OwYcOm+i13iAgXJkyYEF566aUwevTo0LNnz3pVSkpNB+wf4V5ggQUK2y83zeG7776rNj2VGv81hYd4WW655cK1114bKxmSVLFMkpS9/vrr2UILLZQtssgi2aabbhr/vummmwoxM3To0Kxr167ZSiutlK277rpZx44ds8svv7xKzHXr1i3baKON4jr69u2bzTvvvNmf//znbNKkSfH7AQMGZAsssED8focddii82rZtm/3rX/8qrOfee+/NOnTokK2++urx9yussELWvXv37JJLLqnxSG255ZbZAQccUHh/1llnZYsuumiVZcaPH5/NNtts2bXXXlvyPtUVLyeeeGLch+233z5beeWVs7nmmit79tlnp4qXDTbYIJtvvvmyTTbZJJtjjjmyPn36ZOPGjasz5bHMeuutl/Xo0SPu4zLLLJNtvfXW2ZQpU+L3Cy64YHb11VfHvx977LEq8dqvX7+sTZs22RFHHBG/f+ONN+LyxCfHh3Dsv//+ZaX+UtPBhhtuGLe11VZbZTfccEO166orbutKT+XEf03hOe6447K11lqrrDiQpJpYsZA0w6PwSsF1zz33LBTa/vjjj+zRRx8t/M33Rx11VCGurr/++qx9+/bZJ598UqUAt+qqq2a//fZbfP/dd99lnTp1ihWFhELg3nvvXSXOWSZVLH7//fdsnnnmyQYNGlT4/oILLshoB6qtYkH4Lr744sL7L774ImvVqlX20ksvFT5jG1RYRo8eXdI+1RUv1TnjjDNi4T+PeKFQ+8MPP8T333zzTdzH888/v86099BDD8XK0K+//lr47L777ssmT548VcWi2JFHHpnNOeec2WeffZZNmDAhFtyJy+T777+PhfXbbrstK0U56YA4GDNmTI3rKiVuS0lPpcZ/TeG55ZZbYvglqSE4eFvSDI9uRiNHjgxnnXVWoZsJ3YU22mij+Pfzzz8fvx84cGAhrnbfffcw11xzxW4meQzEnnnmmePffE+3nffff7/kOH7uuedi15cjjzyy8NlBBx1UWGdN6A4z22yzFd736NEjrLPOOuGWW24pfMbfjEmgK1Ip+1RXvCTMXPTYY4+FO+64Iw4cHz58eBzzkbfXXnvFrlqYZ5554raYwaouHTt2jF2O8nG45ZZbhtata7983XzzzeHiiy+OMx/RVeqpp54Kn3/+edw/PrvrrrviZ3SF4v9SlJMO2N+auoSVE7elpKdS47+68JBmiF+6d0lSpRxjIWmGR8GMwnZ1/dtBgbRr165h9tlnL3xGf/VFFlkkfpeXXwaMtxg3blzJcUxhs1u3blUKgTPNNFMca1Eb+t8XTx26yy67hBNPPDGcf/75saDJwG4Kn6XuU13xkmZluu666+L4ACoOf/zxR/z8hx9+KIx9wEILLVTldwsvvHC46aab6oyP3r17h/79+8f/CUefPn3CfvvtFwcd14RxLMyoRMWCyhU+++yzGI8PPPBAlWXnm2++sMQSS4RSlJMOisfMFCslbktJT6XGf03hIc1QSaur4ipJpbBiIWmGR2Hx119/jS23FNyKUWCjRZfnRLRt+3/Z5s8//1xohW8oFCTHjBkTpkyZUqVVnsG9taFw/Omnn1b5bLvttosFTwb4fvPNN6FTp05hk002KXmf6ooXBgIzxS2DptMgaAZGM0idrrZ5xeHnfalxN3jw4DjjFQOzGaTOgPQ33ngjLL300lMty6D3rbbaKrbQH3DAAYXPKcQzcPuaa66JlbD6KCcd1DUwva64LUU58V9TeEgziy22WJUB4ZJUX3aFkjTDW3fddWNBMd9tKLX6gtZgvr///vsL37333nthxIgRYe21127Q+GNbFAofffTRKl1wfvrpp1p/R0s+yxUXXjfddNO4X7y23377wjMuStmnuuKFQjxdlfIt43Qzqg7P7EjYP7oOrbXWWnXGB9uYPHlyDDczInEXgrs51c3+RMVhm222iQXliy66qMp3f/nLX+Idi6uuuqrK56ybrmcJsy8V39VIGjId1BW3pSgn/mtCmmH6Y0lqCN6xkDTDo8//ueeeGw488MDw9ttvx2lImU6UVmg+pxvJ8ccfH1vBKUhSsD3vvPNiy/h6663XoPFH1xy6/uy2227h2GOPjYVPCtO0stfWCv7Xv/41tuzTxYbpRJNdd901rovuM7T6J6XsU13xwtS2hIsKS9++feP0uIxdqA6Fb57XwfSwdMn66KOPSioEU/Al3PyW/WI8BPFA16hijFfgQYMXXHBBleeEpOlmL7zwwngHh/1lmlimr2W5M888M4YfN9xwQ6xYbLHFFlOtvyHTQV1xW4py4r86TLnL2Ixp+RA+STMW71hIUgixMJ8G8fJcAQqK55xzTiFuTjrppNi6zBgIWrUHDRpUGK+Q0Fqebz0GrcHLLLNM4T3Pbyh+tkTxA/LYLgXWd999Nw7KpqBLAbK2wcBsl0rEJZdcUuXzzTbbLGy99dax4sG280rZp9rihYG/dL3hDsF//vOfWPDn+Rk77LBD7HaVj5d77703Viq400C3LSoA+QpQTbbddttw2223xec98AwOtkVYU3zlH5DHgHWWZwA8d0jSi4I76BrFPtDdjHCCgniqVID9YZ9rUt90UJ80V1d6Kif+qwvP1VdfHStoNT1jQ5LK1Yqpocr+lSRpmqHPfn7QLgVYCn8UkPOVlGJ06WHGoiuvvLLQ5Umlo/Jy8MEHx3ELM0L8HXLIIWHAgAE1PnRRksplxUKSmpgrrrgiTkdK6zR3LOgKRcsyA5dbGrojcYehOhTuuQMhSWoerFhIUhPE4OYnn3wyztbDIGf60bdEjAtgTER1eK7D9ddfP93DJEmqHysWkiRJkirm4G1JkiRJFbNiIUmSJKliViwkSZIkVcyKhSRJkqSKWbGQJEmSVDErFpIkSZIqZsVCkiRJUsWsWEiSJEmqmBULSZIkSaFS/w9gh5spfj9vrQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -662,13 +807,17 @@ "source": [ "inferred_total_epochs = int(raw[\"epochs_to_best_val\"].max())\n", "\n", + "group_cols = [\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"]\n", "conv = (\n", - " raw.groupby([\"tokenizer\", \"vocab_size\"])[\"epochs_to_best_val\"]\n", + " raw.groupby(group_cols, dropna=False)[\"epochs_to_best_val\"]\n", " .agg([\"mean\", \"std\"])\n", " .reset_index()\n", - " .sort_values([\"tokenizer\", \"vocab_size\"])\n", + " .sort_values(group_cols)\n", ")\n", - "conv_labels = [\"char\" if t == \"char\" else str(int(v)) for t, v in zip(conv[\"tokenizer\"], conv[\"vocab_size\"])]\n", + "conv_labels = [\n", + " \"char\" if t == \"char\" else f\"{int(v)}\" + (\"\" if pl == \"end\" else f\"\\n[{pl}]\")\n", + " for t, v, pl in zip(conv[\"tokenizer\"], conv[\"vocab_size\"], conv[\"pad_layout\"])\n", + "]\n", "\n", "fig, ax = plt.subplots(figsize=(8, 4.5))\n", "ax.bar(conv_labels, conv[\"mean\"], yerr=conv[\"std\"].fillna(0), capsize=3)\n", @@ -697,10 +846,10 @@ "id": "305a88cc", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:04.222734Z", - "iopub.status.busy": "2026-08-02T09:59:04.222734Z", - "iopub.status.idle": "2026-08-02T09:59:04.242945Z", - "shell.execute_reply": "2026-08-02T09:59:04.242945Z" + "iopub.execute_input": "2026-08-07T10:53:08.761641Z", + "iopub.status.busy": "2026-08-07T10:53:08.761063Z", + "iopub.status.idle": "2026-08-07T10:53:08.775646Z", + "shell.execute_reply": "2026-08-07T10:53:08.774743Z" } }, "outputs": [ @@ -727,6 +876,8 @@ " \n", " tokenizer\n", " vocab_size\n", + " max_token_len\n", + " pad_layout\n", " seeds_hitting_ceiling\n", " n_seeds\n", " fraction_hitting_ceiling\n", @@ -734,73 +885,193 @@ " \n", " \n", " \n", - " 3\n", + " 12\n", " wordpiece\n", - " 10000\n", - " 3\n", - " 3\n", - " 1.000000\n", + " 14550\n", + " 9.0\n", + " anchored\n", + " 1\n", + " 1\n", + " 1.0\n", " \n", " \n", - " 2\n", + " 13\n", " wordpiece\n", - " 5000\n", - " 2\n", - " 3\n", - " 0.666667\n", + " 16414\n", + " 9.0\n", + " anchored\n", + " 1\n", + " 1\n", + " 1.0\n", " \n", " \n", - " 4\n", + " 10\n", " wordpiece\n", - " 20000\n", - " 2\n", - " 3\n", - " 0.666667\n", + " 9816\n", + " 9.0\n", + " anchored\n", + " 1\n", + " 1\n", + " 1.0\n", " \n", " \n", - " 5\n", + " 11\n", " wordpiece\n", - " 30000\n", + " 11719\n", + " 9.0\n", + " anchored\n", + " 1\n", " 1\n", - " 3\n", - " 0.333333\n", + " 1.0\n", + " \n", + " \n", + " 0\n", + " char\n", + " 25\n", + " NaN\n", + " end\n", + " 0\n", + " 1\n", + " 0.0\n", " \n", " \n", " 1\n", " wordpiece\n", " 1000\n", + " 9.0\n", + " anchored\n", " 0\n", - " 3\n", - " 0.000000\n", + " 1\n", + " 0.0\n", " \n", " \n", - " 0\n", - " char\n", - " 25\n", + " 2\n", + " wordpiece\n", + " 2000\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 6\n", + " wordpiece\n", + " 5951\n", + " 9.0\n", + " anchored\n", " 0\n", - " 3\n", - " 0.000000\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 5\n", + " wordpiece\n", + " 4970\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 4\n", + " wordpiece\n", + " 3986\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 3\n", + " wordpiece\n", + " 2998\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 9\n", + " wordpiece\n", + " 8855\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 8\n", + " wordpiece\n", + " 7897\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 7\n", + " wordpiece\n", + " 6923\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", + " \n", + " \n", + " 14\n", + " wordpiece\n", + " 19199\n", + " 9.0\n", + " anchored\n", + " 0\n", + " 1\n", + " 0.0\n", " \n", " \n", "\n", "" ], "text/plain": [ - " tokenizer vocab_size seeds_hitting_ceiling n_seeds \\\n", - "3 wordpiece 10000 3 3 \n", - "2 wordpiece 5000 2 3 \n", - "4 wordpiece 20000 2 3 \n", - "5 wordpiece 30000 1 3 \n", - "1 wordpiece 1000 0 3 \n", - "0 char 25 0 3 \n", + " tokenizer vocab_size max_token_len pad_layout seeds_hitting_ceiling \\\n", + "12 wordpiece 14550 9.0 anchored 1 \n", + "13 wordpiece 16414 9.0 anchored 1 \n", + "10 wordpiece 9816 9.0 anchored 1 \n", + "11 wordpiece 11719 9.0 anchored 1 \n", + "0 char 25 NaN end 0 \n", + "1 wordpiece 1000 9.0 anchored 0 \n", + "2 wordpiece 2000 9.0 anchored 0 \n", + "6 wordpiece 5951 9.0 anchored 0 \n", + "5 wordpiece 4970 9.0 anchored 0 \n", + "4 wordpiece 3986 9.0 anchored 0 \n", + "3 wordpiece 2998 9.0 anchored 0 \n", + "9 wordpiece 8855 9.0 anchored 0 \n", + "8 wordpiece 7897 9.0 anchored 0 \n", + "7 wordpiece 6923 9.0 anchored 0 \n", + "14 wordpiece 19199 9.0 anchored 0 \n", "\n", - " fraction_hitting_ceiling \n", - "3 1.000000 \n", - "2 0.666667 \n", - "4 0.666667 \n", - "5 0.333333 \n", - "1 0.000000 \n", - "0 0.000000 " + " n_seeds fraction_hitting_ceiling \n", + "12 1 1.0 \n", + "13 1 1.0 \n", + "10 1 1.0 \n", + "11 1 1.0 \n", + "0 1 0.0 \n", + "1 1 0.0 \n", + "2 1 0.0 \n", + "6 1 0.0 \n", + "5 1 0.0 \n", + "4 1 0.0 \n", + "3 1 0.0 \n", + "9 1 0.0 \n", + "8 1 0.0 \n", + "7 1 0.0 \n", + "14 1 0.0 " ] }, "execution_count": 9, @@ -814,7 +1085,7 @@ " return pd.Series({\"seeds_hitting_ceiling\": hit_ceiling, \"n_seeds\": len(group)})\n", "\n", "ceiling_df = (\n", - " raw.groupby([\"tokenizer\", \"vocab_size\"])\n", + " raw.groupby([\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"], dropna=False)\n", " .apply(summarize_convergence, include_groups=False)\n", " .reset_index()\n", ")\n", @@ -836,16 +1107,16 @@ "id": "95004f13", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:04.242945Z", - "iopub.status.busy": "2026-08-02T09:59:04.242945Z", - "iopub.status.idle": "2026-08-02T09:59:04.438527Z", - "shell.execute_reply": "2026-08-02T09:59:04.438527Z" + "iopub.execute_input": "2026-08-07T10:53:08.776991Z", + "iopub.status.busy": "2026-08-07T10:53:08.776861Z", + "iopub.status.idle": "2026-08-07T10:53:08.877121Z", + "shell.execute_reply": "2026-08-07T10:53:08.876437Z" } }, "outputs": [ { "data": { - "image/png": "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BSvebsMbGnRrCsQzzzwjw4cPN19cDhw4kOA6GkTWqVPHtLx+8803cuXKFY/0geRsPyXPO6F9J7QfX+nrUis8xD4+ba2253t7fElZBgg0BLAATCBy1113mdJIGsReuHBBPvvsszhbktKatrC988475tarfmj36tVLrl27Jm+88YZHfudvv/0mkyZNMgGuBjhdunSRli1ber2flNiGt55//nm58847TTD2/fffm9vOes3Xr19vykHNmjXLLKe5nnq7XvMg9Zx92UZCNI932rRp5pa0BnEaeM2ZM8eUBrO/1CREA9YtW7aYHE3N19TXUEpsPyXO25t9J7QfX73wwgvmVn+PHj1k8+bNEhkZaYLXl19+Wdq1a2ce3h5fcn8/QEZGAAvA0FY0vXVer1490/FIOy5pDUp/e/bZZ82tVw2QtGOMBivaAqu3+92X0YBWA/CCBQuaPMERI0bcFlAltp/kbsNbOXPmlLVr15o8Ut2H5qdqJyStbarXv3Pnzma5vHnzyoQJE2TZsmXmdrJ7nVJvt5GQd999V1avXm3yfjUlQ4Mr/d3rtNit0XHRfWvKwLFjx+JsffV1+ylx3t7sO6H9+EpzXTds2GBer9qBUlMGhg4dKk8//bTMnz/flWLizfEl9/cDZGRBWorA3wcBALFprp+2QP3888/SvHlzLhAAwIUWWAAAADgKASwAAAAchQAWQJqyBwiI76G9rQF/4jUKpH/kwAIAAMBRaIEFAACAoxDAAgAAwFH+N1YifKK1KU+cOGHGOk/p4TMBAACcxrIsM7x0sWLFJFOm1GsnJYBNBg1edUQUAAAA/B8d4KREiRKSWghgk0FbXu1fko7iAgAAEMgiIyNN454dI6UWAthksNMGNHglgAUAAPif1E6tpBMXAAAARPv2HDp0SK5evXrb1bh165bs379fLl++nCbzCGABAACQoHnz5kmpUqWkdevWUqRIERk9erRr3u7du6VcuXLStGlTKVq0qMyYMSPeebNmzfJpPfd53qAFFgAAIMCdPn1adu7cKQcOHJANGzbIq6++KteuXTPzhg8fLg899JDpvL5ixQoZPHiwXLlyJc55+tyWlPXc53mDkbiSmagcFhYmERER5MACAABH+/vvv+Xs2bOybNkymTNnjmzatMmUxQoNDTWpBcWLFzfL1a1bV95++21p06bNbfNq164t27dvlwsXLkihQoW8Xs+e165dO6+OlU5cAAAAkAkTJpgUgHPnzsnUqVNNRywNaDVXVeu62rTKgAa7ulzseVo6SwPY8PDwJK1nz/MWKQQAAACQt956S/bt2yerV6+Whx9+WI4fPy4hISGmc9eNGzdcVyg6OlqyZcsW7zyVNWvWJK+n8whgAQAA4JWbN2+6fq5Ro4bkz5/f1LnXVEn9edeuXWaephT88ccfUr58+Tjn7dmzx/yc1PXsed6iBRYAACDAtWnTRr7//nvZuHGj6WClraN33nmnmffoo4/Kc889J2vWrJGXXnrJ9Pu5++6745znPoBBUtZzn+cNOnElA524AABARrBt2zbTiUrzUKtXr26C2AoVKph5Wo3glVdekVWrVkmZMmXk3XffjXeeVi+oU6eO6eCeJUsWr9dzn+cNAthkIIAFAABI+9iIFAIAAAA4CmW0AAAAMqhbMZZsOnRezlyKkkK5QuXusvkkc6YgcToCWAAAgAxoya6T8ubCP+VkRJRrWtGwUHm9U1VpX72oOBkpBAAAABkweB00Y6tH8KpORUSZ6TrfyQhgAQAAMljawJsL/xQrjnn2NJ2vyzkVASwAAEAGsunQ+dtaXt1p2KrzdTmn8nsAu2DBAmnVqpWpOdarVy/Zv39/gstfunRJRo0aJc2aNZO77rpL+vXrJzt27PBYpmbNmqaWWOzH66+/7lrmX//6123zO3TokGrnCQAAkBbOXIpK0eXSI7924lq0aJF069ZNxowZIw0aNJCxY8dKkyZNzHBi+fLli3OdQYMGSZUqVeSdd96R4OBgmThxojRu3Fi2b9/uGoLsu+++M2Ps2rZu3So9evSQevXquaadOXNGKlasKB9//LFrmo7NCwAA4GSFcoWm6HLpkV8HMqhbt64Zb/fzzz83z69fvy5FixaV559/3ozOEN9YvRq42m7duiWhoaHy6aefSv/+/eMNehcuXChHjhyRzJkzm2kDBw6Uc+fOydy5c30+fgYyAAAA6c2tGEsav7vSdNiKK8jTIlpFwkJl7fCWKV5SK8MPZKCpANoy2q5dO9e0rFmzSuvWreWXX36Jdz334NVOQQgKCop3/Fwdquzrr782wa0dvNrWrl1rxvnVVt+XX37ZHBMAAICTZc4UZEplqdjhqf1c5zu5HqzfAtjjx4+LNv4WKVLEY7o+13kJWbNmjclZLVSokDz22GPy/fffmxzauGgLqwamupw7TVHQcX6/+OILGTZsmPzwww/SqFEj0wocn+joaPPNwv0BAACQ3rSvXlQm9K1jWlrd6XOd7vQ6sH7LgbVzVLNkyeIxXVthNS0gIdp5a8mSJSYF4LPPPpOHHnpI1q1bJ5UqVbpt2SlTpkibNm2kdOnSHtNHjhzpapGtU6eO1K5dW8qWLSvffPON6RgWl9GjR8ubb76Z5HMFAABIa+2rF5U2VYtkyJG4/NYCW6BAAfN/eHi4x3QNSu158cmePbtpgb3nnntMgFqwYEEZP378bctpRYPVq1fL448/ftu82OkEJUqUkDJlypgOZPEZMWKEyemwH8eOHUv0PAEAAPwlc6YgaVA+v9xfq7j5PyMEr34NYAsXLiwlS5aU9evXe0zXllTt3OUtzX/VJOG48lenTp1qgtv77rsv0e1oesCpU6ckT5488S6jVQp0X+4PAAAABFAdWK0EMHnyZNmzZ495rukABw8e9Ggx1c5Vdn3Wq1evmlbQCxcuuNIQNEjdtGmTdOnSxWPbmoYwbdo0eeSRR25LU9A816FDh7paf3W7//znP806Wm4LAAAA6Zdf68BqJyrtsKUDD+TIkcPc1p8xY4YpreVer/Xo0aPm52zZspmWW+2wpR3AtBOVlt3SjlixW1l//PFHOXHihAwYMOC2/WpAqykDWoFAg2ANiPUYVqxYIeXKlUuDMwcAAIAj68Darly5IufPnzfBaOwyWWfPnpWoqCiTbuDu9OnTkjNnThP4xkW3p3mq2jErIbodrVemtWSTijqwAAAAaR8bpYsA1qkIYAEAAAJoIAMAAADAFwSwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjkIACwAAAEchgAUAAICjEMACAADAUQhgAQAA4CgEsAAAAHAUAlgAAAA4CgEsAAAAHIUAFgAAAI5CAAsAAABHIYAFAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOEqwvw8AAACnsyxL5s2bJ5s3b5by5cvLQw89JKGhoa7569evl/nz50u+fPnk8ccfN/+n5jwgo6MFFgCAZOrWrZt88803kjdvXvnyyy+lZcuWrnmrVq2S9u3bS9asWWXTpk3SvHlziYmJSbV5QCAIsvRrI3wSGRkpYWFhEhERIblz5+YqAkCA2r9/v1SoUMH8fO3aNcmTJ4+ZVrJkSbn//vtNgPncc8+Z+TVr1pRRo0ZJx44dU2UeEAixES2wAAAkkx28qqNHj0qOHDmkSJEi5vmOHTukadOmrvn6s05LrXlAICCABQAghVy4cEF69uwpn376qWTJksU1TVukbNoqdf78+VSbBwQCAlgAAFLA2bNnpU2bNua2fvfu3V3TCxYsKOfOnXM9Dw8Pl0KFCqXaPCAQEMACAJBMJ0+elFatWsngwYOlX79+HvPuueceWbRokfk5Ojpali1bZqal1jwgENCJKxnoxAUAUPXr1zedVlq3bu26IMOGDZNSpUrJzp07pUmTJtK2bVs5cOCA5M+fX5YvX26WSY15QCDERgSwyUAACwBQ06dPN58J7nr06GFu9avjx4+bVlKt1aqVAuz82NSaB/gLAawDEMACAACkfWzESFwAAMTjVowlmw6dlzOXoqRQrlC5u2w+yZwpiOsF+BkBLAAAcViy66S8ufBPORkR5ZpWNCxUXu9UVdpXL8o1A/yIKgQAAMQRvA6asdUjeFWnIqLMdJ0PwH8IYAEAiJU2oC2vcY2zbk/T+bocAP8ggAUAwI3mvMZueXWnYavO1+UA+AcBLAAAbrTDVkouByDlEcACAOBGqw2k5HIAUh4BLAAAbrRUllYbiK9Ylk7X+bocAP8ggAUAwI3WedVSWSp2EGs/1/nUgwX8hwAWAIBYtM7rhL51pEiYZ5qAPtfp1IEF/IuBDAAAiIMGqW2qFmEkLiAd8nsAe/36dVmxYoWcPn1aatSoIXfddVei65w/f17WrVsnly9flmrVqsmdd97pMX/NmjXyxx9/eEzLly+fPPjgg8neNwAgcGiaQIPy+f19GADSUwB79uxZadmypQkkNQh97rnnpEePHjJx4sR41/nwww/lo48+klq1aklwcLAMGjTIbGPWrFmSJUsWs8zMmTNl+fLl0qZNG9d6xYsXT/a+AQAAEOAB7IgRI8z/27Ztk+zZs8uWLVukXr160qlTJ+nYsWOc69xxxx2ye/duyZo1q3m+b98+qVSpkixcuFC6du3qWq527doJBqO+7BsAAAAB3IkrJiZGZs+eLY8++qgJIJXewm/YsKF888038a7Xtm1bV/CqChUqJJkzZ5Zbt255LHfmzBmZPn26LFiwQE6cOJEi+wYAAEAAt8AeO3ZMLl26JFWr/q9UiU2f//bbb4mu+8MPP0hkZKTMmTNH+vTpI126dPFY5siRI7JkyRL5+++/ZdOmTfLuu+/Ks88+m6x9R0dHm4dN9w8AAIAAaYG1g788efJ4TM+bN2+igaEGn9u3bzeBqQaoBQsW9JivLasHDhyQr776SlatWiX//e9/TY6rpgkkZ9+jR4+WsLAw16NkyZJJPGsAAAA4NoDNli2bKxh1pwGkfVs/PtpSqvmtc+fOlV9//VUmTZrkke9av35908HLPaAtUKCALFu2LFn71rzZiIgI10NbcgEAABAgAWzp0qVNLuuhQ4c8puvzChUqeL2dMmXKmA5bGzduTHC50NBQuXDhQrL2HRISIrlz5/Z4AAAAIEACWC151b59e9NpyrIsM007W/38889y3333uZbTFADtcKVu3rwpR48e9diOBqVa87V8+fLmuXbmOnz4sMcya9euNetpJ62k7BsAAADpT5BlR3B+sGfPHhNUNm7cWO655x5TNUCrCqxcudKVAjBgwADZsGGD7Nq1y3Sgqlu3rkkR0DSCixcvmjzXXLlymXU0h1WDXG2R1ZJYOsiBBq5TpkyRzp07y5dffilBQUFe7zsxmnKgubCaTkBrLAAACHSRaRQb+TWAVcePHzfBoz0aVr9+/TzKZM2YMcPc2n/ttdfMcx14QHNftX5rjhw5TLCqtVszZfq/xuQbN26Y6gS6jAa1TZo0MY+k7jsxBLAAAAABGMA6GQEsAABA2sdGfsuBBQAAAHxBAAsAAABHIYAFAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAAByFABYAAACOQgALAAAARyGABQAAgKMQwAIAAMBRCGABAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjkIACwAAAEchgAUAAICjEMACAADAUQhgAQAA4CgEsAAAAHAUAlgAAAA4CgEsAAAAHIUAFgAAAI5CAAsAAABHIYAFAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAAByFABYAAACOQgALAAAARyGABQAAgKMQwAIAAMBRCGABAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjuL3AHbq1KlSs2ZNKVKkiLRp00a2bduW4PKnTp2S559/XqpVqyalS5eWDh06yJo1azyW2b59uzz00ENSvnx5qVy5sjz22GNy/Phxj2V0G3ny5PF4NGzYMFXOEQAAABkkgP36669l0KBBMnToUFm3bp0JOFu2bCknT56Md51XX31VKlWqJPPnz5dffvlFqlevbgLf3bt3m/m3bt0yAWv79u1l+fLl8u2338qRI0ekVatWcvXqVdd29OdmzZrJ4cOHXY+lS5emyXkDAADAd0GWZVniJ3feeadp9Zw4caIr+CxevLg88cQT8u9//9urbeg6oaGhZhsauMbl4MGDJjhesWKFCZDVwIED5dy5czJ37lyfjz8yMlLCwsIkIiJCcufO7fN2AAAAMoLINIqN/NYCe/HiRfn9999Ny6gtc+bMJsBcu3at18HrlClTJCQkxLSmxufy5cvm/2zZsnlM14C2WLFicscdd5ig+fTp0z6fDwAAANKG3wLYEydOmP8LFy7sMb1QoUKuefHRwFNzVrXldfjw4fLdd99JhQoV4lw2JiZGhg0bZoLUevXquaZrS+9HH30kGzZsMHm4f/75pzRq1EiuXLkS736jo6PNNwv3BwAAAAKsE1emTJ6HEBwcLIllNdi5q5r3OmDAAOnatavs2LEjzmWHDBkimzZtktmzZ5tt21577TXT0atUqVLSoEEDEwQfO3ZMvvnmm3j3O3r0aNMsbj9KliyZ5PMFAACAQwNYbWlVmofq7syZM6558dFAVFtgtdV1zJgxJr/VzqN19+KLL8qXX34py5YtM529ElKwYEFT1eCvv/6Kd5kRI0aYnA77oQEvAAAAAiSALVCggJQrV+62ElirV6+W+vXrJ2lbGtDeuHHDY5qmDUyePNkEr3Xr1k10G5o6oKW2EgqeNddWE5LdHwAAAAigFILBgwebIFNLaF2/ft3cotc6r08++aRrmWeffdZVn1WDzMcff1z2799v0gz0+XvvvSdbt26Vnj17erSUTpo0yZTRcs97dc9lffTRR2Xv3r1mO1q2q1+/fpI1a1bp1atXGp09AAAAfPF/SaF+8Mwzz5gUAh2MQIPRMmXKmPquFStW9KjXaneWypEjh8l/1ZxXDWKVDoKwcOFCad26tXkeHh4u77zzjglGtT6su48//tjkvWpLqi7frVs32bdvn2TJkkWaNGliAmnt3AUAAID0y691YG16CFFRUbeVuVLXrl2TmzdvSq5cuTyma4utBqlxbUvzU+OSPXv229aJbzveoA4sAABA2sdGfm2BtQUFBcUZvKr4pscXdOq2tIOXt3wNXgEAABCgZbQAAACApCCABQAAgKMQwAIAAMBRCGABAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjkIACwAAAEchgAUAAICjEMACAADAUQhgAfjd+vXrpXPnzuYxevTo2+avWbNGHnnkERkwYIBs2bIl1ecBANI3AlgAfle6dGkTTJYoUUI2btzoMe+PP/6Qjh07SvXq1aVs2bLSunVrOXHiRKrNAwCkf0GWZVn+PginioyMlLCwMImIiJDcuXP7+3AAx5s8ebIsWrRI5s+f75r27LPPSnBwsHzwwQfmef/+/aVcuXLy6quvpso8AED6j41ogQWQru3evVvuvvtu1/N69eqZaak1DwCQ/hHAAkjXLl26JDly5HA915/1m31qzQMApH8EsADStcKFC8vp06ddz/XnokWLpto8AED6RwALIF1r3ry5zJo1SzRd/+bNmzJ37lxp0aJFqs0DAKR/dOJKBjpxASnj6NGjpmPVkSNH5NSpU1K/fn159NFH5f777zd/Zw0bNpRMmTLJjRs3JF++fPLLL79IlixZUmUeACD9x0YEsMlAAAukDM1JXbFihcc0LXFVoUIF8/P169dl3bp1pnKABp6ZM2d2LZca8wAAviGAdQACWAAAgLSPjYJTbcsAICK3YizZdOi8nLkUJYVyhcrdZfNJ5kxBXBsAgM8IYAGkmiW7TsqbC/+UkxFRrmlFw0Ll9U5VpX11ev0DAHxDFQIAqRa8Dpqx1SN4Vaciosx0nQ8AgC8IYAGkStqAtrzGNU61PU3n63IAACQVASyAFKc5r7FbXt1p2KrzdTkAAJKKABZAitMOWym5HAAA7ghgAaQ4rTaQkssBAOCOABZAitNSWVptIL5iWTpd5+tyAAAkFQEsgBSndV61VJaKHcTaz3U+9WABAL4ggAWQKrTO64S+daRImGeagD7X6dSBBQD4ioEMAKQaDVLbVC3CSFwAgBRFAAsgVWmaQIPy+bnKAIAUQwoBAAAAHIUAFgAAAI5CAAsAAABHIYAFAABAYASwERERrp/Pnj0rEydOlOXLl6fUcQEAAAApV4Vg2rRpsmrVKpk6darcvHlTmjVrJuHh4Sao/eijj+SJJ57wZbMAAABA6rTAjhkzRoYPH25+1kA2Ojpajh07JosWLZJx48b5skkAAAAg9VpgDx48KKVLlzY/r1y5Ujp37ixZs2aVxo0by+HDh5O0rUuXLsn8+fPl9OnTUqNGDWnXrl2i6xw5csTs9/Lly1KtWjVp0aKFBAUFJXm7vuwbAAAADmyBLVmypMl31ZbXOXPmSOvWrc10DV7twNYbx48fN4Hjxx9/LAcOHJBHH31UunfvLpZlxbvOyJEjpUOHDrJhwwbZs2ePPPTQQ9K8eXO5du1akrbry74BAACQDlg+mDJlipU5c2YrV65cVu3ata3r16+b6SNGjLBGjx7t9XZ69+5t1a1b17X+nj17zHbnzJkT7zobNmywYmJiXM+PHz9uBQUFWbNmzUrSdn3Zd2wREREa7Zr/AQAAAl1EGsVGPrXA9u/fX3bt2iVz586VtWvXSpYsWcz0WrVqyeDBg73axq1bt8zt+379+rnWr1y5sjRp0sRsNz7169f3SBfQ1AV9HhIS4vV2fd03AAAAHJoDq4oWLSpVqlRxldH69ttvpXz58pItWzav1j969KhcvXpVKlWq5DFdn2/cuDHRHNyvvvpKIiMjZenSpTJkyBC57777vN6ur/vWlAl92HT/AAAASFuZfC2j9dxzz5mf7TJar7/+unTq1Ek+++wzr7ahHbBUWFiYx/Q8efK45sVHW1CjoqJMAHn+/HlTwssOLL3Zrq/7Hj16tFnHfmguMAAAAAKkjFaOHDnibMXUWrL2vPhUrFhR3nrrLTN4wpYtW2ThwoUyfvx4r7fr675HjBhhlrEfes4AAABwQACbEmW0SpUqZdIN9u/f7zF93759Jh/VW4UKFTLVBLZv3+71dn3dt+bZ5s6d2+MBAACAACmjFRwcbFIOvvzyS5OGoLSc1erVq6Vr166u5X744QdXWsKNGzfkjz/+8NjOqVOnZMeOHaYerLfb9XbfAAAASH+CtBRBUlfSIWR1uNjs2bNLhQoVTMcn7c3/8ssvm1bJl156yavtaMDbqFEjKVeunNSrV89UAKhZs6YsWLBAMmX6X2w9YMAAU/NVqx5cv37dVArQDmRVq1aVixcvms5jGrx+//33kjNnTq+3680yidEUBM2F1XQCWmMBAECgi0yj2MinAFbpIALam1/TBjSQVbNnzzYtm95WIlAXLlwwrbj2aFhaTcA9gNRyV5pr+swzz5jnerja+rtt2zaTr1q7dm0TiCZ1u94ukxACWAAAAAcFsCCABQAA8EcA63Md2EuXLplyWrt37zatonpL/+GHH5ZcuXKl7BECAAAAyW2B3blzp7Rt29bUY9W8UR0JS6sAZM6cWZYtWyZ33nmnBAJSCAAAABySQtCyZUspW7asfPLJJxIaGmqm6cACTz31lBw6dMiU1goEBLAAAAAOCWC1k5Z24CpYsKDH9DNnzpgyWteuXZNAQAALAACQ9rGRT3VgNYDVIVxj0yFdk1KBAAAAAEiTAPb++++X3r17m/qsOriAPtavXy99+vQx8wAAAIB0FcCOGzfOpAo0aNDA5MDqo2HDhlKmTBkzDwAAAEhXZbQ0t2HevHmyb98++fPPP00VgjvuuEMqVqyY8kcIAAAApEQdWKUBK0ErAAAA0mUAm5TUgCFDhvh6PAAAAEDKlNGqXr26eGvXrl0SCCijBQAAkI6Hkg2UoBQAAAAZsAqBt7RzFwAAAOCYABYAAABIaQSwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAGT+AvXnzpk/zAAAAAL8EsFmyZPFq3uLFi307KgAAACAtUgiio6MlJCTE9bx9+/YpuXkAAADA+5G41Pjx4+P8WcXExMimTZukatWqXFYAAACk/wBWUwfKlCkjn332WcodHQAAAJCcAHbPnj3m/8aNG8vatWuTsioAAADgvxxYDV4jIiJcz8+ePSsTJ06U5cuXp8xRAQAAACnRAmubNm2arFq1SqZOnWrKZjVr1kzCw8NNUPvRRx/JE0884ctmAQAAgNRpgR0zZowMHz7c/KyBrFYfOHbsmCxatEjGjRvnyyYBAACA1AtgDx48KKVLlzY/r1y5Ujp37ixZs2Y1ubGHDx/2ZZMAAABA6gWwJUuWNPmu2vI6Z84cad26tZmuwasd2AIAAADpJoDV9IEuXbpIwYIFJWfOnK4Advr06fLwww+n9DECAAAAyevE1b9/f2nYsKEcPXrUpA3Yw8fWqlVLOnXq5MsmAQAAAK8EWZZlebcoYouMjJSwsDBTfSF37txcIAAAENAi0yg28imFQG3cuFEGDRok7dq1c03TslqXL19OqWMDAAAAUiaAXbhwobRo0UKuXLkiy5Ytc00/ceKEfPDBB75sEgAAAEi9APb111+XGTNmmE5b7h588EHTCgsAAACkqwB2z5490r59e/NzUFCQa3qxYsVMKywAAACQrgLYvHnzmgoEsQPYtWvXmhqxAAAAQLoKYPv06SP//Oc/XaNuXbt2TRYsWCADBgyQhx56KKWPEQAAAEheADty5EgpWrSolC1bVmJiYsxgBjqcbPPmzeWVV17xZZMAAABA6tWBvXnzpgQHB8vBgwdly5YtJoitXbu2VKpUyTUvEFAHFgAAIO1jI58iTR15S+PecuXKmUdc85JKg+BMmbxvENZ9uOffuouOjo7zGDSwtoNrDbT14U73nzVr1iQfOwAAANKOzwMZxBc4hoSEJGmd0aNHS+HChU3gW6NGDVm5cmWCyy9dulTatGljont9dOzYUXbv3u2xTPHixSVPnjwej2zZsskLL7zgWubpp5+WHDlyeCzToEGDJJ4xAAAA0lqSWmDHjx8f5892C+qmTZukatWqXm9v4sSJMmrUKPnuu+/knnvukTFjxsg//vEP+eOPP0x+bWy3bt2SsWPHyksvvST169eXqKgo05lMA9o///zT1VR97tw5j/WWL18ubdu2NXVq3XXp0kXmzp3r9fEicL3xxhumfJytW7du5qG0JX/ChAkmnUZf/4MHD3Z9kfN1HgAASKEc2CpVqpj///rrL6lcubLHPG1BLVOmjBnkoG7dul5tT3NmO3ToIOPGjTPP9VBKly4tvXr1knfffderbRw7dkxKlSplRgTTQDYuPXv2lJ07d5og1zZw4EAT6M6ePTtJqQvuyIENHI0bNzavL/t1X716dfNQ2rL/yy+/yOOPPy7ffPONlC9fXqZMmZKseQAAOFFkGuXAatCYZI0aNbKS69y5cxo4W/PmzfOY3rdvX6tJkyZeb2fjxo1mO5s3b45zfnh4uBUSEmJ98MEHHtOffPJJK1u2bFZwcLCVN29eq1OnTtbevXuTdA4RERFm3/o/MjZ9za9Zs+a26deuXbNy5szpeu3o6y179uzm9e3rPAAAnCoijWIjn5oedcCC5Dp9+rT5v2DBgh7TCxUq5JqXmOvXr8uQIUPk7rvvlrvuuivOZXTIW9WvX7/bWpO1du3ly5fNLVxt/W3WrJlcuHAhwRxf/Wbh/kDg0DsF2lqqraR2B0Ad0EM7/lWsWNE8z5cvn7kTsXfvXp/nAQCANOzE5QvNnY39PL7qArGXe+SRR0wgMGvWrHjX0WBDc13z58/vMV0DX70lrDmHmm87c+ZMuXjxotlWQh3O7M5j+mDUscDx5ptvmpzXOnXqmPxvfe0pvUWidZDd6XOd7us8AACQML8VbNWBENSZM2c8puvzIkWKeBW8av7gqlWrTMtVXH777TeT+6odvxKjeRolSpSQAwcOxLvMiBEj5Pnnn3c91xZYgtjA0KpVK9fPOmiH5l1PnTrVVNDQXGr3MnD2a1hbVX2ZBwAA0mkLbN68eU3P659//tk1TT/M9XmjRo1c0/RWraYKuC/Tv39/+emnn8yy9i3Y+FpfK1SoIC1atEj0eM6fP29aczWIjY+21mqg6/5A4Nm/f79kz57ddFzU14sGsT/++KPrS9OVK1fkjjvu8HkeAABIhOVH06ZNs0JDQ625c+daf//9tzV48GArV65c1rFjx1zLPPbYY1a1atXMzzExMVb//v2tQoUKWTt27DAdYezHzZs3PbZ99epVKywszHrnnXdu229UVJR17733WqtWrTKdZrZu3Wq1aNHCKlKkSJI60dCJKzBoB6sePXqYR9u2ba3cuXNbU6dOdc3/6quvzGutXbt2Vr58+awJEyYkex4AAE4UkUaduHwaSjYl/fe//zWdY7Tjlg5k8P7775sar7ZBgwaZ+rLa0So8PNwMUhBfTVk7L1F9/fXXpsONpgRoS1dsOmDCO++8I9u2bTOtwU2aNDF5jgm1wMZGGa3AcO3aNdPhT+mAFzpscuzXlA6rvGPHDtOCapebS+48AACcJjKNymj5PYB1MgJYAACAtI+N/NaJC0gPbsVYsunQeTlzKUoK5QqVu8vmk8yZEq+CAQAA/IcAFgFrya6T8ubCP+VkRJRrWtGwUHm9U1VpX/1/VTIAAED64/c6sIC/gtdBM7Z6BK/qVESUma7zAQBA+kQAi4BMG9CW17iSv+1pOl+XAwAA6Q8BLAKO5rzGbnl1p2GrztflAABA+kMAi4CjHbZScjkAAJC2CGARcLTaQEouBwAA0hYBLAKOlsrSagPxFcvS6TpflwMAAOkPASwCjtZ51VJZKnYQaz/X+dSDBQAgfSKARUDSOq8T+taRImGeaQL6XKdTBxYAgPSLgQwQsDRIbVO1CCNxAQDgMASwCGiaJtCgfH5/HwYAAEgCUggAAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjkIACwAAAEchgAUAAICjEMACAADAUQhgAQAA4CgEsAAAAHAUAlgAAAA4CgEsAAAAHIUAFgAAAI5CAAsAAABHIYAFAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAAByFABYAAACOQgALAAAARyGABQAAgKMQwAIAAMBRCGABAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjhLs7wM4efKkzJgxQ06fPi01atSQ3r17S5YsWeJd3rIsWbZsmfz6668SHBwsjRs3lhYtWngsM2vWLFmzZo3HtGLFisnLL7+crH0DAAAgwFtg9+7dawLHn3/+WXLlyiVvv/22tG3bVm7duhXn8jExMVK7dm0ZN26cZM6cWa5cuSJdu3aVJ554wmM53d66deukSpUqrkfZsmWTtW8AAACkD0GWNmn6SZcuXeTChQsmiAwKCpLjx49L+fLlZdKkSdKvX7/bltdD3bVrlwk8bT/99JO0adNGtm/fLjVr1jTTBg4cKOfOnZO5c+em2L7jEhkZKWFhYRIRESG5c+f26RoAAABkFJFpFBv5rQX2xo0bsnjxYnPbXgNIVaJECWnevLksWLAgznV0OffgVVWrVs38f+rUKY/p+/fvl2HDhpmW1dWrVyd73wAAAEgf/BbAHj16VKKjo2+7tV+uXDnZt2+f19uZOnWqZM+eXerWreuapkFp4cKFJU+ePHLixAlp3769DBo0KNn71nX0m4X7AwAAAAHSievatWvmf80/dafNzVevXvVqG5o+8MYbb8jHH38s+fPnd03XzlolS5Z0PX/wwQdN66rmy2q6ga/7Hj16tLz55pteniEAAAAyVAtszpw5zf8XL170mK55qd7kTGiVgc6dO8trr71mcl7duQevqlmzZmba2rVrk7XvESNGmJwO+3Hs2LFEjxMAAAAZJIAtVaqUCSR3797tMV2fV61aNcF1tcJAhw4d5IUXXpB//etfXu3v+vXrcvPmzWTtOyQkxAS47g8AAAAESACbKVMm6d69u3zxxReuW/paSUDru/bo0cO13FdffSWjRo1yPdf5mtP6/PPPx3k7X4PUFStWeEybPn26qfXarl27JO0bAAAA6Y9fy2idOXPG5KaqWrVqyZIlS0x5qylTpriWGTBggGzYsMGUz7p8+bIUL15cQkNDTQDqrk+fPtKgQQNTx7VTp06mjJZWKNAOW+vXrzcttS+99FKS9p0YymgBAACkfWzk1wDW7tm/dOlS12hY99xzj8d8rdOqJbJ69eolUVFRMnny5Di307JlS4/b/zt37pRt27ZJ3rx5pV69elK0aNEk7zsxBLAAAAABGMA6GQEsAABAAA1kAAAAAPiCABYAAACOQgALAAAARyGABQAAgKMQwAIAAMBRCGABAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjkIACwAAAEchgAUAAICjEMACAADAUQhgAQAA4CgEsAAAAHAUAlgAAAA4SrC/DwDpx4IFC2TOnDnm506dOkmPHj085i9dulTmzZsn+fLlk2eeeUaKFSuW7HkAAABJRQssXMqXLy/t27eXCxcuyLZt2zyujAahvXr1kkqVKsnp06elefPmcvPmzWTNAwAA8AUtsHCpXr26eWzfvv22q/Lhhx/KyJEj5amnnjLP69WrJ4sWLZLOnTv7PA8AAMAXtMDCK7t27ZKGDRu6njdo0MBMS848AAAAXxDAwisRERGSM2dO1/NcuXLJxYsXkzUPAADAFwSw8EqhQoXk7NmzrudnzpyRwoULJ2seAACALwhg4ZUmTZrI3Llzzc9XrlyRJUuWSNOmTZM1DwAAwBdBlmVZPq0JiYyMlLCwMHObPHfu3I6/Ips3bzadrrZu3SqZMmWSWrVqyYsvvmj+/+uvv6RRo0ZSu3ZtOXLkiOnspaWxlK/zAABAxhKZRrERAWwyZLQA9ujRo7J69WqPaS1atJDixYubn8PDw2XVqlWmnqu2omqQa/N1HgAAyDgiCWDTv4wWwAIAADghNqIObAC4FWPJpkPn5cylKCmUK1TuLptPMmcK8vdhAQAA+IQANoNbsuukvLnwTzkZEeWaVjQsVF7vVFXaVy/q12MDAADwBcmIGTx4HTRjq0fwqk5FRJnpOh8AAMBpCGAzcNqAtrzGVWLCnqbzdTkAAAAnIYDNoDTnNXbLqzsNW3W+LgcAAOAkBLAZlHbYSsnlAAAA0gsC2AxKqw2k5HIAAADpBQFsBqWlsrTaQHzFsnS6ztflAAAAnIQANoPSOq9aKkvFDmLt5zqferAAAMBpCGAzMK3zOqFvHSkS5pkmoM91OnVgAQCAEzGQQQanQWqbqkUYiQsAAGQYBLABQNMEGpTP7+/DAAAASBGkEAAAAMBRCGABAADgKOkiheD69esSGRkp+fPnl6Cg+Ao/ebpy5YoEBwdLSEiIT8tcvHhRLl++7DEtS5YsUrhwYR/OAAAAAAHRAhsTEyMvvPCC5MmTR8qUKSMlSpSQ7777LsF1Zs6cKbVr15aiRYua9erXry+bN29O8jIvvfSSVKpUSe655x7Xo0+fPqlyngAAAMggAez7778vn3/+ufz666+mBXb48OHSo0cP2b17d5zL37p1SxYvXixffPGFREREmFbUmjVryr333ivnz5/3ehlbhw4d5Pjx467HTz/9lCbnDQAAAN8FWZZliZ9oq+uDDz4o7733nmtahQoVpFOnTjJ27FivtnHixAkpXry4LFmyRNq1a+f1MgMHDpRz587JZ599Jjlz5pSsWbMm+fg16A4LCzOBcu7cuZO8PgAAQEYSmUaxkd9aYM+cOSNHjhyRRo0aeUxv3LixbNq0yevt7N+/3/xfpEiRJC+j6Qply5Y1AWzDhg1l69atSTwLAAAApDW/BbBnz541/xcoUMBjuj635yXm6tWr8uyzz0qLFi1MmkBSlqlbt6789ttv5huC7q9cuXLSpk0bOXXqVLz7i46ONt8s3B8AAAAIkAA2U6b/7frmzZse02/cuCGZM2f2qnJBt27dTID61VdfJXmZAQMGmI5eSpu6J02aZALUuXPnxrvP0aNHm2XtR8mSJb06VwAAAGSAAFZzUlXsFs/Tp0+75sXHDkz37t0rK1eujDN9wJtl3GXLls1ULTh8+HC8y4wYMcK02NqPY8eOJXKWAAAAyDABrCb21qpVS5YvX+6apq2xK1askKZNm7qmXbhwwQS17i203bt3lz///FN++eUXU3orNm+Wid137eTJkyYnV1MJ4qP1ZPW43R8AAAAIoDJar732mkybNk0+/fRT2blzp/Tv399MHzRokGuZoUOHSqtWrVx1Y3v27CkbNmyQGTNmmGl2CSxNE/B2GU0V0E5b8+bNk7/++ssE0Vr5QAPdvn37pvl1AAAAgEPKaKlZs2bJhx9+aFpZa9SoIaNGjZKqVau65g8bNsxUB9Aardoaq8vEZcyYMdKrVy+vllHbt2835bu2bdsmefPmlSZNmpjBDfRnb1FGCwAAIO1jI78HsE5GAAsAABBAdWABAAAAXxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAAByFABYAAACOQgALAAAARyGABQAAgKMQwAIAAMBRCGABAADgKASwAAAAcBQCWAAAADgKASwAAAAchQAWAAAAjkIACwAAAEchgAUAAICjEMACAADAUQhgAQAA4CgEsAAAAHAUAlgAAAA4CgEsAAAAHIUAFgAAAI5CAAsAAABHIYAFAACAoxDAAgAAwFEIYDO4CRMmSHR0tL8PAwAAIMUQwGZwI0aMkGvXrvn7MAAAAFIMASwAAAAcJdjfB4CUs2XLFvO4evWqtGjRQmrWrGmm6/OVK1eaVIIuXbpIaGiomT59+nQ5f/685MyZU+rXry81atTwSD148MEHZfXq1ZI3b15p3rw5vyoAAJAu0AKbQQwdOlQ6d+4smzdvlsOHD8ulS5dc83r27Ck//PCDjB8/Xrp27eqa/vfff5tldZ1OnTrJ119/7ZF6cN9998miRYskPDw8zc8HAAAgPkGWZVnxzkWCIiMjJSwsTCIiIiR37tx+u1oHDhyQevXqyd69e6VAgQIe8/LkySPz5883LajaAps/f345e/asZMuWzeTGLl682ASyf/31l9mOPrfXmz17trRt29ZPZwUAAJwmMo1iI1IIMgANXPX2f+zg1VarVi3zf0hIiAlM9UUVExMjtWvXlnLlykn58uXlwoULcu7cOY/17rrrrjQ5fgAAgKQggM0ASpcubVpQtUVVW1a9sX37dsmXL58sWbLEPJ82bZoJhN1lzpw5VY4XAAAgOQhgM4CqVauaFIGmTZuaTlrZs2f36MQVF2113bNnjwwbNkwyZcokc+fONa2zAAAA6R2duDII7YClHbm085Z7J65BgwaZ1AHbgAEDJEeOHFKkSBFTmUDnlSxZ0uTJ9u7d27Vc7PUAAADSCzpxZYBOXAAAAIEUG9ECCwAAAEchBzad02oBR48eNSkBuXLlklKlSpmcVQAAgEBFAJuO7d6921QJ0OZ4mzbHt2/fXu644w6/HhsAAIC/0JSXjoNXHUjAPXhV+lyn63wAAIBA5PcW2H379snkyZPl9OnTphj/wIEDTS/5+Ny4ccMEcL/++qsEBwdL48aNpVu3bhIUFJTk7SZ132mZNmDXZ42Pzq9cuTLpBAAAIOD4tQVWi+nraFAnTpwwQ6HOnDnT1DK9fv16vIGd1jzV4K1atWqm/NPgwYOle/fu4j4irjfbTeq+05LmvMZueY1N5+tyAAAAgcavZbQ0l1NbThcvXmye61Cm2klp7Nix8uSTT962vB7q8ePHTeBqW7dunWmF/e2331xDn3qz3aTuOy1LRfz+++8yb968RJfr2rWraTkGAABIDzJ8Ga3o6GhZsWKFaT21FShQQFq2bCk//PBDnOtowOkevNrDqKrz5897vV1f9p2WtNpASi4HAACQkfgtgNXb3zdv3jStnrED0oMHD3q9nfHjx5tI/+677/Z6u77uWwNf/Wbh/kgNelyJfWvR+bGPHwAAIBD4LYCNiooy/+fMmdNjuj635yXm22+/lTFjxsiECRNMEOvtdn3d9+jRo81+7Efs1uCUonVeNcUhITqferAAACAQ+S2AtQNO+9a/LTw8XPLkyZPo+nqrv0+fPvLhhx9Kr169krRdX/c9YsQIk9NhP44dOyapReu8Pvjgg7e1xOpznU4dWAAAEKj8VkZLWy81WNy1a5d06NDBowNTYh2TfvzxR3nggQdM6+vTTz+d5O36uu+QkBDzSCsapGqpLEbiAgAASActsNohq3fv3jJlyhRXLunatWtl06ZN0rdvX9dyn332mQwdOtT1XEto2cHrM88849N2vd13eqBpAmXKlDGBtf5P2gAAAAh0fi2jdfHiRZPLqaWxtL6rDk7w1FNPybvvvutaZsCAAbJhwwbTWnrp0iUpVKiQ6X2vFQPcaemrFi1aeL1db5ZJL6UiAAAAnCAyjWIjvwaw9uAEGqDao2FVqFDBY/7mzZtNbqoGmzrIQHz1UbUKQbly5bzerrfLJIQAFgAAIAADWCcjgAUAAAiggQwAAAAAXxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAAByFABYAAACOEuzvA3Ayu4SuPRwtAABAIIv8/zFRag8zQACbDDq0rSpZsmRK/T4AAAAyRIwUFhaWattnJK5k0KFoT5w4Ibly5ZKgoCAJ9G9cGsgfO3YsVUfecBKuCdeE1wp/P7yn8D4baJ89lmWZ4LVYsWKSKVPqZarSApsM+ospUaJEyv02MgD9YyGA5ZrwOuHvh/cU3mf57Ancz+OwVGx5tdGJCwAAAI5CAAsAAABHIYBFiggJCZHXX3/d/A+uCa8T/n54T0l5vM9yTXid/B86cQEAAMBRaIEFAACAoxDAAgAAwFEIYAEAAOAo1IGFhIeHyxdffCHz58+Xhg0byrvvvpsi60RERMg777wjGzZsMDXhHn30Ubn//vuTvIy/CkF/+eWXMmfOHKlcubJ8+umnKbLOTz/9JF9//bUcPnxYSpcuLU8++aTUr1/f43q0a9futvXeeustad26tfjT1atXzbF/9dVXUrBgQfnmm29SZJ177rnntmkvvviidOvWzfX8+vXr8tFHH8nSpUslODhYunbtKgMGDPD7ACLR0dEyd+5cmT59ujmWJUuWJHsd/VsYMmRInOvqNbj77rvNz+3bt5eLFy96zNdrog9/unnzpixcuFCmTp0qZ8+elXXr1knmzJkTXOevv/4yfy+///675MuXTzp37iw9e/a87fer12zWrFkSFRUlrVq1kueff15CQ0OTvIw/Br3R1+7kyZPl77//lh9//NGcZ0L0PWLixImydetWU8vz3nvvlUceecTjWnqzzD//+U8z313Lli1l1KhR4m+//PKL+b0fOnTIvEeUK1cuweVPnjwpEyZMkE2bNkn27NnNeTzxxBOSNWtW1zIvv/yyrFy50mO9OnXqyH//+1+Pafp3N2nSJDl//rzUrVtXRowYkejvJC3o37/+Tvfs2WOOWY89sc/iiRMnyq+//mreGxs3bixPPfWUuT42vU76Xhxbly5dZPjw4ebn9957T+bNm+cxv3z58jJz5kxJrwhgA5yO1KEBRI8ePczoGfpBkhLr3Lp1S9q2bWt+fuWVV2Tfvn0mIPn888+lb9++Xi/jD5cvX5YqVaqYD9Fs2bLJH3/8kSLrvP/+++ZNs1evXtKnTx9ZsWKFCf6/++47ue+++8wyN27ckI0bN5oP4YoVK7rWdf/ZX/T8NIjWN/nt27en2Dp6vhqY1atXzzWtbNmyHsvoFxsNhPRN9sqVKyYoOXLkiAns/UmPuVq1alK0aFFZtGhRiqxzxx13yLhx4zymjR8/XhYsWGDm2X777TcT6Lp/sUkPA6voFzAdnbBMmTLm/BIbD33z5s0m6NLAu0OHDrJ//37zAbxlyxb5z3/+41pu9OjR5qF/R3nz5jWBigYy+iU6Kcv4g75X6shENWvWNEGCfiFLiF4DvRZ6TfTLnAa9+h65Zs0a03Dg7TLqzz//NK8b/bJsy58/v/jbwIEDTZDWvHlz88U2rgArdqCmwZm+F+jrXgPPV1991Xwx+P77711fdvbu3WtGgBo2bJhr3djF/PV3oL+TkSNHmr9FbYDR49C/KfdgOK3p708bOfQL+rRp00yjSEJu3bplgm/9vNS/Gb2GWg1Ir8fPP/9sAlql56fLur8mHnvsMfO6sR08eNAEve5fbNyD4HTJQkCLjo62rl27Zn5+4IEHrPvvvz9F1pk9e7aVKVMm6/jx465pL7zwglWyZEkrJibG62X84ebNm9bly5fNz08++aTVqFGjFFnn0qVLt03r3r271aJFC9fzs2fP6qe9tW3bNiu9uXjxovn/lVdesSpXrpxi6+j5Ll++PN5t7Ny50yzz888/u6ZNmjTJypo1q3X+/HnLn+zzGzt2rJU/f/5UWefWrVtWqVKlrAEDBnhM13W//vprK72xz0+PTX9vN27cSHD5K1eumHN098knn1ghISHW9evXzXP928qePbv18ccfu5ZZv3692f6GDRu8Xsbf10Rf53o8J0+eTHD5qKio267brFmzzLrh4eFeL6OaNWtm/v7SG/ua6HudHvPvv/+e4PJ6rnrO7lasWGHW/euvv1zT9DNJ34MTou9FTz31lOv5mTNnrCxZslhffPGFlR6uybFjx257z4vP5f//uWPbsWOHWXfdunXxrjNkyBCrYMGCrr8vpddMr52TkAMb4PTbZlJvr3mzjrYu6q2P4sWLu6ZpaoC23uo3ZG+X8Qe9/ZYjR44UXydnzpxxTourNea5555z3R6LffvPX3wZGtDbdd544w1p0aKF9O/f37QgudPXibagNG3a1ON1otdt9erVklGviU1bZI4ePSqPP/74bfPGjh1rWo4efvhhr9IX0kJSz09beWKPl65/F9pipOkIav369aZ1qVOnTq5l9C5Q4cKFzfXxdhmnXBOt92q3nsV+/9AUFG+XseldnmbNmpm0DG3ZS6xVPD1eEz3X2HXG7fON/R6q7xn6d9G9e3eTcuDe+nj8+HFz19D9daLpTQ0aNHDc60TF/tyJ75rYdPqMGTPMXY8sWbLcdjdEP3c0teCDDz5I9E6BvxHAIlXo7V29jePOfq7zvF0mI9NbgJqrp2kH7jQnVgM5zU3SLwv6XG8fZ1R33nmnOV+93VugQAGTt6hpJDZ9LRQpUsQjyNEPHH3zDYTXyZQpU8w1snNfbZUqVTK3U/U2qt6u1w8d91vuTqXBl6YAaCqCpuMo+/esaRfu9Ln7+0liyziVBmDaV0DfC2KfX2LLFCpUyHzBee2110yQ9sILL5jXTUagt7v178A9tSZPnjzy0EMPmdvxml6jaUbu/Srs10Jcnz1Of52ot99+2/z+Y79f2PSz5Ny5c7flyusXSU1FeOmll0xK2yeffGIaFdyD//SGHFikCs3l1Dw4d/aHkc7zdpmMSvO59E1CW4jcO+xo3t7atWtdLSv6Ia6dUfRDJz10bksNmqNot6y0adPGBKqa46otBJrXpq+FuEZ407sAgfA60Q+cuAJTzXGzr4t+UOvfkn5oDxo0KMl3ENIL7eykv3f9gNWOTjb9PevrInaLkb5fuL+fJLaMUz377LOya9cu08qc1GW0Y6n760Q7mGpnL33fqVWrljjVv/71L1m+fLmsWrXKo9OaBl7u7xd33XWXyTvX1lU9f/u1EPs9JSO8Tj766CPz+168eHG8+av6hVhb4zXwd6e54+7XpEmTJqYPg3ZK1pb79IgWWKQK7bSjSfaxP4zdOxB4s0xGpOesgZqeowYn7rcB9Y049m1BfdM9cOCA6SiWEcX+INHz1d71ets8vteJ3trSTjEZ+XWi9FafBmVxdWqM67rpddGOMU4NXrVjifZM117k7qlF+hrQ+VqlI/b7hfv7SWLLOJF2tNEe+hqsafCZ1GViv070FrF+MdyxY4c4ld1RTzsJaiemhM5X5+uteft87UoDcX32OPl18tlnn8nQoUNl9uzZ5i5WXDQ9T18jcaUjxb5uFSpUMHd20vPrhAAWqUJzW7XXuZ3DZvc219YR7fXp7TIZzYULF0zwqt+O9VtyXHmxsZ06dcpcE3/2jk1Ler7KbkHQ18mJEyfMw73VVtWuXVsyMm0t0cocelvU2+vmxNZXzcnUD1X9m9DgNXYQZpcS0hw994BDe07brwFvlnEa7UmvpbeWLVtmWhJ9XcbdmTNnzPV24uvE7lGv1QO0VJve4k6MVi3RL//2+eprS392f53o9dAKBE59nUyePFmeeeYZU7IwdkqaOy1tp8H8Aw88kOg29XNZ74Sk59cJASwSpR8Aeqvb/Q8+MVomSt84tPyP0nIgWhrowQcfdKUNeLNMeqXf3vWaJCXpX1uGNHjVW1Xa4Sau4FXLu2zbts31XFvT9PaxllVJ7wGs5krpNdEap97S66DlsdzrWuqHk7YgaJ6rXe9U89P+/e9/u95YNc9LP6y1LFF6p79z/YBJKg3StS5qXK0l2tFNW1Lcg1fNhdVbwnrbL73TW5JaEs0OHrSzoqYMaFqEez6je2uQduLTlje7Y4nmNmpgb5eg82aZ9EzLXGkeuE1zEbVOqf6e3UvMuUtsGX3vdu+0pe+3gwcPNi2N+rpM77QfgNaxtel7ob4PaMurtiTHpgGXphDYeZuaT62pFdq6aHfa0p/1s0c/d+xWWG291MC+X79+kt7p61uP3z0o1RJaGrzq50R89DWgfQs0Pzh2J2z9e9EvBvbfjb7H6rXXTpHeBLt+4+8yCPC/1q1bW/Xr17fy5ctn5c2b1/ys02xa3iR2qaPE1lHffvutlSdPHqts2bJWzpw5rebNm99W9sibZfyhW7du5pwKFSpk5cqVy/ysDy2XpbQMjl4T9zJGia0zdOhQs0716tVd8/TRoUMH1za2b99uNWzY0CpevLhVpUoVUyqqf//+VkREhOVvjz32mDlePbbQ0FDX8dsle7TMjZ6fexmjxNbR8jf6uilcuLBVtWpVc74PPvigdfr0aY99axkkLa9WrFgxUz6qWrVq1r59+yx/07Jvej6lS5e2goODXed34MAB1zJhYWHW66+/nqR11BNPPBFv6bGjR4+a8nUFChQwrye9th07drSOHDli+duoUaPM+VSoUMG8Huzz27Rpk2sZPS+71NEPP/xgltNSYe5/F/o4fPiwax09t1q1apn3mxIlSlhFixa1Vq1a5bFvb5bxBy0Lpudzxx13mHOtU6eOee7+nqql9+wyRhs3bjTL6es99jXRMkneLhMZGWmus16PGjVqmPelevXqWVu2bLH8bebMmeZY9bj0PO68807zfM6cOa5l9DWuZcCU/n3oclr+Kfb52r9jLbP1/PPPm88l3a5+tuh7xerVqz32rdelXbt2puxa+fLlzXXR4/G3RYsWmfOpXbu2OVd9vehzLRvo/p6q56QuXLhgSlHan8HujwULFljuli1bFm+5Mi1b+eqrr5r3Vn0/0f/1uvz4449Wehak//g7iIZ/6a0T99v4SvMw7dyia9eumTyYqlWrugpCJ7aOTTsgaSui3raIXZw+KcukNU1t0OOKb9QoTfbXQus6wICdN5XYOtrDVUeSiU1bVmOPtnL69GnTmqDXI70Uk9bBGTTvNDZtCbU7zugoMnrMWrrI23XsW716bTTnKr60Cm1V2b17t3md6W1Af4/CpbQcj6aFxKYtw3aHRP1b0SoK9iAD3qyjdu7cae5EJPQ3obnCmtemo7rFLtbuL9rqp61Zsbm/f+j7if6s56bXIr4BVLRFOXZrkZbY05Y1bamNnS+elGXSkv6OdKCB2NzfP7S4vP5N6DT9m4lvABVNr9LXhTfL2LQlTfPo9XVo39nwN/17j6vXv/v7h/4e9XNGXzv63hrfYCj6fqAdYG26rFZ50aomes7x0Tx7bYXVDk3p4X1WR67T31Ns+t5hv3/o35emRNx5553m2uj7S1x0FC3337WWD9M7NbE/o91pC6wOKKTXUisZpIf32IQQwAIAAMBRyIEFAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAABzF/wXyAAAAkCZ+/fVXMzqgDs89e/bsJNeQ1jrlDz/8cJzzBg0aJPfff7+kBerAAgBSlA7CoAXimzdvzpUF0pFevXqZIbtr164tEyZMMIMn6IAPSaGDG61atcpjmg5n/MEHH5hBSnSQhbRAAAsASFEvvfSSGSHop59+4soC6cipU6fM6GRLliyRe++9N94Adt68eTJ//nwTrOqIeIMHD453lETVsWNHM3rkxo0bJa2QQgAgQ9q2bZsZcrFevXpmCEoddlV/tofutIe+1eES69ev75qmQ3rqrbXWrVt7bEeHYNTt6Jt048aNzXCLOkTnunXrzHINGzaUHDlyJOnYdEhd/VmHU23SpIkZTtmmQzrqcMVKhwWtXr26GTI2vu3obUH9uXPnzkla19fz0mF9dQjYYsWKmdYce2hgnabz9DbjN998Y6bpdu2hMONbL6HzUToUq7bu6DXS+bGHmAWQuISG1rW98MILsnDhQvN/vnz5ZObMmXL33XfL1q1b4/y707/NpUuXysSJEyUtEcACyJCmTZtmbmtpgKrBkgaJOs64TtMASI0fP16Cg4M9AlhteVi0aJErgNXtaGuFjhOuY6brmOI6jvvYsWPlzTffNNMOHTokt27dks2bN0uePHm8OrZly5aZscxLlixpWkE0aNb92GOV6za1BURFRETImjVrTCvI22+/fdt2LMsyAaKOI68Bn7fr+nJeOs583759TYCrx6rL6DXWD7wyZcqY4FkfmkJgH4Mel7byJLReQufz0UcfySuvvCKNGjWS6OhoOXPmjMyaNcsE5gBSzq5du+TDDz80f5/63qS6du0qVapUMYHsY489dts6X3zxhWTLlk169uwpacoCgAxo8ODBVnBwsLV582bXtC5dulhdu3Z1Pe/Tp4/18MMPe6w3cuRIq379+rdtZ+vWreb5zZs3rWrVqlkhISHWrl27zLTr169bZcuWtd5//32vj03ffr/77jvzPCYmxurbt6911113xbvOnj17rGzZslnbtm3z2E5QUJC1evXqBPcX37q+nNewYcOsxo0bW1evXnUd+6OPPmp17NjRtczw4cOtVq1aeRyDN+vFdz558+a1Zs+e7Xp++PBh67fffkvwnAHEb/HixeY96OzZsx7Tx44da4WGhpq/yw4dOpjHvffeaxUsWNB67rnnbtuO/h2XL1/eevzxx620RgssgAxLUwbsFk3VrFkzmTRpUpK3o7fP9Ha3ypw5s9lu4cKFpVq1amaa3gbXVt29e/d6vc0KFSq4bo9rS+SwYcNM5wdtJS5fvryZfuXKFXPbTvPWtCW0UKFCpjVUc9Js+rOmH8Tmzbq+nNfnn38u3bp1kx9++MG0lOpDb0tqb2b9Wc8lLt6uF9f56G3LP/74w7QE6XFqOkTslAgAyad3bDSN6Omnn75tXqlSpW6b9ssvv5j3rK+//lrSGgEsgAxL87fchYSEmFvgSaVv6LG3E9e0pGzbvm1u09vl6siRIyaA1Zyy3r17m9t4uqwGcZoTqrfP3RUtWvS2bXu7blLPS3NjNd1B84Q1RcDdP/7xD5OOoMvHlpT14jqf6dOnmw9UTSVo2rSpdO/e3ZxffMEyAN/o+5C+T2haVez3grhMmTJFatasab78pjUCWAABK1OmTBITE+MxzZcA1xeakxvXc7tH8HPPPSdDhgyR1157zaPVVlsr3cUVxHm7blJpIJw1a1YTPD7xxBOpsl5c56P5yHv27DF5eZq3q+enHcH+/e9/+3QeAOKmd4WGDh0qzzzzjAlO7S+W+qVY786438HRjrHffvut/Oc//xF/YCQuAAGrePHisn///ttuiaUF7fmv9RjdO48VLFjQdJ5Seuu/cuXKHj30Dx486NW2k7NuYgF/mzZtTBqGpiXE7ols03I77l8EvF0vLjdu3HC1HGvrkBZK11qWWkECQNLoAAbt27eXV1991Tzv0aOHeb527VrzXAc1+PHHH026kaYMaDqPdqjUjl36/uROO3XpF84+ffqIP9ACCyBgaYugth7o7WltWdDqA5rvWa5cuVTft35Q6AeH7ltLTo0ZM0bGjRvnKlOjLSFaTzU8PFwuXbpkqgMkVIfRXXLWTYweo+YSa2ksvX7agq1FzXX7eqtfad7xqFGjzC1/zb3VZb1ZL74AVkt5ac1K/R1pKoJWK9DrBSBp7IA0tooVK7p+1rx3veOhFQk05UfnaSWX2PRv+eeff/aq8kpqIIAFkCHVqVPntjddvY2uOZe2GjVqmHqjM2bMMDVGdXhEfWjnp4S2o/leGhi6a9CggWlp9JYGZcOHD5cFCxaY9IE5c+ZIp06dXPO1puKnn34qmzZtMrVPtYVWW0bsDlbxHVty1vXmvPQa6gebls7R66QfXo888ojcd999rmU0MNeWHg1Q9fpqy6nm1CW2XlzHlD17dtNareutX7/eBP7fffedtGjRwutrDeB/9M6M+92Z+GjLqr4/JkRzX/2JkbgAII1pfqqmLmiLLwAg6WiBBYAUpq2psXM9bXGVvAIAJA0BLACkMB1dSktDxUVvwcd36x8A4B1SCAAAAOAolNECAACAoxDAAgAAwFEIYAEAAOAoBLAAAABwFAJYAAAAOAoBLAAAAByFABYAAACOQgALAAAARyGABQAAgDjJ/wO3b+HkqvSIYgAAAABJRU5ErkJggg==", + "image/png": "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E5R+9dVXZoatN954w0xUYAWuVsBZtWpV873G2T169DDfnz592uVYGrS6uw0AAADsyaOZ16yMzCsAAEDKePUkBQAAAEBKEbwCAADANgheAQAAYBsErwAAALANglcAAADYBsErAAAAbIPgFQAAALZB8AoAAADbIHgFAACAbRC8AgAAwDYIXgEAAGAbBK8AAACwDYJXAAAA2AbBKwAAAGyD4BUAAAC2QfAKAAAA2yB4BQAAgG0QvAIAAMA2CF4BAABgGwSvAAAAsA2CVwAAANgGwSsAAABsg+AVAAAAtkHwCgAAANsgeAUAAIBtELwCAADANgheAQAAYBsErwAAALANglcAAADYBsErAAAAbIPgFQAAALZB8AoAAADbIHgFAACAbRC8AgAAwDYIXgEAAGAbBK8AAACwDYJXAAAA2AbBq42tXbtWNm7c6OmHAQAAkGkIXm1s8eLF8vPPP3v6YQAAAGQaglcAAADYRqCnHwDcc+bMGVm5cqWcPHlSChYsKL1793au09KBbdu2SdOmTaVSpUpm2ZYtW2T16tUSEBAgZcuWlfbt20tgYKCz3CBHjhwSExNjths8eDC/BgAAYAsErzbw559/SocOHUxwWrp0aYmMjHSumz17tqxatUqKFi0qw4cPlw0bNpgA9tKlS3Lo0CEToC5atEjef/99WbFihfj5+ZlyA72VLFlSbr/9do8+NwAAAFsFr5cvX5aFCxfKqVOnpEaNGtKuXbtk99Es4++//24yiXfddVeCAVhqjptVvfDCC/Lyyy/L0KFD463T5z5nzhzz/RNPPCE//PCDCV6bN28uOXPmNOfqtttuk3HjxsmRI0ekTJkyZtvKlSvLt99+m+nPBQAAwLY1r8eOHTOB5UcffSQHDhyQhx9+WO6//35xOBwJbq/L27RpI/3795cdO3aYy9933HGHvPTSS2k6bla3Z88eadWqVYLrateu7fy+WLFicuHCBfP9K6+8Ij169JA//vjDZGA143r27FnntvXq1cuERw4AAOBFmdfnnntOChcubILQbNmyyTPPPGMyifPnz5f77rsv3vYafOo+d999t3NZly5d5N5775WePXtKlSpVUnXcrE6zpVqbWrVqVbf3+eabb0xmVYPba9euyaxZs1yCd62FBQAAsBuPZV6jo6PNZf2+ffuaANO6lK11nfPmzUtwH39/f5fAVWnZgDp48GCqj5vVvfjii/LUU0+ZmtYJEyaYQDQ5NWvWNNtruUDbtm1N7SsAAIDdeSzzqvWXmhG0Rsdb9L5e6nbX3LlzTZBat27dNB03KirK3Cw64Cmr0OBTOwd89913cvjwYefjbNKkialrtTRs2NAE7+rTTz+Vzz77zNT+vvvuu7Ju3TozqCuh/QAAAOzCY8HrlStXzNeQkBCX5fny5XOuS462iNISgTFjxjgDs9QeVzOUY8eOlaxKyx7iDkzr2LGjy32tB7bkyZNHhg0b5hLYJrYfAACAXXisbCB37twJZjgjIiKc65KiA7bCwsLMYCwdjZ/W444ePdpsY92OHj2a4ucEAAAALw1etV+pXrrev3+/y/J9+/aZGtWk7Ny504y+1w4CEydOTJfjatP+vHnzutwyg9aiajcADcatvqwAAADIYmUD2qO1U6dO8sUXX8ijjz5q7mtbq19//dUssyxdulSOHz9utlF//fWXCVy1a8DHH39sWkCl5rhZwe7du2XZsmUuWWINmjWjnJLOAgAAAL7Cz+HB5qeaaWzcuLFpoq/9WrUbQK1atczAJO0soAYOHCjr16832VYdiKXb6kPWhvyxA1et47R6nrpz3ORoQKl1s1pCkBFZWA1cdbBZYh544AECWAAAYCuXMjh+8nif17Jly5qgVHuS6kxYH374oXTu3NklwNSgVANPiwazKnZnAGWNsnf3uJ6kpQGacU2Krtcyh6zymAEAAMTXM6+++slBM8MzZsxIdrt+/fqZQBwAAMAOLmVC5pW0ngdo79X03A4AAMBXELx6QHBwcLpuBwAA4CsIXj1A23kll0rX9bodAAAA/ofg1QN0EJa2w0qKrmewFgAAgCuCVw/RPq7aDituBlbv0yYLAAAgC7bK8nUawGo7rCNHjpjBWVrjqqUCZFwBAAASRvDqYRqo0g4LAADAPZQNAAAAwDYIXgEAAGAbBK8AAACwDYJXAAAA2AbBKwAAAGyD4BUAAAC2QfAKAAAA2yB4BQAAgG0QvAIAAMA2CF4BAABgG0wPmwiHw2G+Xrp0KTN/HwAAALZ16f/jJiuOyggEr4m4fPmy+VqqVKkMO/kAAADeGkeFhIRkyLH9HBkZGttYTEyMnDhxQoKDg8XPz898ktBA9ujRo5I3b15PPzyvw/nl/NoVf7ucXzvj75fzm940rNTAtXjx4uLvnzHVqWReE6EnvGTJkvGWa+BK8JpxOL8Zi/PLubUr/nY5v3bma3+/IRmUcbUwYAsAAAC2QfAKAAAA2yB4dVOOHDlkzJgx5ivSH+c3Y3F+Obd2xd8u59fO+PvNGAzYAgAAgG2QeQUAAIBtELwCAADANgheAQAAYBv+vjoBwffffy/33nuv3HnnnRIREeHWfnPnzpXOnTtLq1atzOCtq1evuqy/cuWKvPnmm9KpUydp3bq1PP7447J7927xNXoeJk+ebM5T3759022fqKgoGT9+vNx9991yzz33yPTp08UXHTlyRF588UW566675OOPP06XfW7duiUzZsyQHj16SNu2bWXYsGFmH1/0xx9/yMMPP2xeG/78889032fOnDlmu3fffVd8jf6dffvtt9KxY0dzDtJzH/171b9bfQ3R38WePXvE11y4cEEmTJggzZo1M+civfbZtWuXeT/T9zV9f3vrrbfivf/5gn379smIESOkUaNG8uWXXya7vb5nffrpp3LfffdJWFiYjBo1Sk6ePBlvu/3798vAgQOlefPm5v1v69atGfQMvIdPBq/6h/TRRx9J+fLlzZvOzZs3k91n0qRJ0q9fP/PG/uSTT8qCBQvMi2nsCco0GNaASrd7/vnnzYuCvtgeOnRIfEV0dLRUqlTJvIFrQ+bt27en2z49e/aUqVOnymOPPSbdunWTp556Sl577TXxJatXrzYvcNmzZ5fw8HC3Akx39tFzq9t17drVvDjrTHK1a9eWf/75R3yJfijV/9/VqlUzrw3ufLBNyT765vfss8+a2fsOHjwovkY/eH7xxRdSpkwZc67Sa59t27aZv9czZ87I6NGjpX379tKrVy/xJadPn5bq1aubv6vAwEC3Eifu7HPgwAHzPqYJBn1f69Onj3z22Wdy//33iy/RD1CaNClSpIjs3bvX/B9OjsYI+repSYFnnnnGBKX16tWTU6dOObc5duyYOb/Xr183wW3u3LmlSZMm8tdff2XwM7I5hw+6ePGi+frDDz9o5Ok4c+ZMktvfvHnTUbBgQcerr77qXLZ7926z77Jly8z9K1eumPtz5sxx2S8wMNAxdepUhy+JiIgwX4cPH+6oVatWuuzz559/mvO7bt0657KPPvrIkTNnTselS5ccvuLy5cuOW7dume9vv/12x3PPPZcu++g2sen2JUuWdPz73/92+OJrQ3h4uPl7W758ebrtExUV5ahbt65j9uzZjnr16jmGDh3q8DXWufriiy/MuUqvffR8durUyWXZ9evXHb7kxo0bjmvXrpnve/Xq5WjXrl267PPpp586cuTI4XwNsX4Xfn5+jsjISIev0PeZmJgY833RokUdb7/9drL7xH1d1b/J4OBgxwcffOBc9tRTTzkqVarkiI6Odi678847HT169EjXx+9tfDLzmtJpy/TT0rlz58zlEkuVKlVMtvDnn3829/XTUtWqVWXdunXObdavX28ys/pJy5ekZgq85PbR81yoUCGXy4ZdunQxn1Z///138RV58uSRgICAdN9Ht4lNt8+ZM6fcuHFDfElqpjR0d5+RI0ea1wjNcvuqjDi/mi3ctGmTDBkyxGV5UFCQ+JJs2bKZ/7PpvU/dunXN1Uk9x0rf0/Q1t2bNmj7V9zw4OFj8/PxStE/c11W9+qW32K+rK1askA4dOpgp6S1anrh8+fJ0eNTeK9DTD8AODh8+bL4WL17cZbnet9ZZf4RaklC6dGnzgquXBpYuXSq1atXK9MfsbfQ8xz3/oaGh5sUk9u8A6eObb74xdVj6Ioq0W7JkiXz33XfUsmUArcdU+fPnN5e0jx8/bhIL//rXv8xXpE39+vXN365eMtfXXC2HK1eunPz000+c2hTS+lctK9JzmdR7m97XhNm1a9ckV65cnOcE+GTmNaWsmti4nzL1E2vselmtVzl//ry8/fbbZjBGmzZtZOjQoW7VxiD530Hc8681Wnpzp2YZ7tMMy4ABA0ztoA7wQtpoMKXnU+s2U5N5RNIiIyPNVx3o0rJlS1OXqVdk6tSp45ODttKb1shrTbfWEev7mr6/6aAjHQAK9/3yyy9mQJwOdtMrMEm9t1nZcN7bEkfm1Q0FChQwXzUwjX15Wz8Z1ahRw/mGP3PmTFM2YF3a1oEGFSpUMCM59Q8Wafsd6PmP7fLly+Y/d8GCBTm16URLZHRQYv/+/eX111/nvKZT1lVHZutAOMvff/9tBmps3LhRfv31V3MpEWl7fR4+fLg88sgj5nvtOPDbb7+ZAZ689qbN+++/b8oLtBuJddm8ZMmS0rRpU3niiSdM+QCStmbNGlN2qAmBuB0dEnpv09hCz7mWKiBhBK9u0FGsWo+io+HLli1rlmk6f+fOnc62TtYfX4kSJZz76T7FihWL94eJlNO6q/fee0/Onj1ral+VNfJYMyxIO+3yoB+4HnroIfnwww85pelEO2PELR3SVk46ylsDLn2TQtpeG/S1NvalV71ftGhRc4kbaaPvX1aJlsU617y3JW/t2rWmplX/r2tnkoT+fuO219P3Nn3NiF0HC1ecmURoz7V///vf5nttjaEtL/RyiQatSr/XQS0PPPCAM4DS4mxtwWW1z9Kids2s6CdU/I9e0tPs9KJFi9w+LXr+NcNqtcbSjOu4ceOkcePGUrlyZU5vnMtTen61bZC79IOY9nDUli4TJ07kfCZBM3l6ntylrx/6+4h90wGeGlzp9ykdBOLttAVTSnrg6nnUwZvavskaCKNv/vraqx/GIPHaMmlA5S7t/6rn00oWaJ90fZ/Tq5CM53ClLTT1/Fp/h3olVssttP567NixCZ5fLSnSAcnWwGN9LZ4/f75ZjiQ4fNCHH37oaNiwoaNKlSqm9Yq2WdH7K1eudG6j9x988EHn/VOnTjkaNWrkyJs3r6NMmTKOQoUKOb7//nuX4y5atMhRokQJc6tWrZojKCjIMWzYMGd7DV/Rp08fc/5CQ0MduXLlMt/rzWobol/1vH/22Wdu76PWrFnjKF68uDm/+fPnd9SsWdNx8OBBhy85d+6c89xomzA9H/r9gAEDnNt888035vwePXrU7X30b9vf39+5nXUbPXq0w5do6zt93trSSs9h1apVzf1PPvnEuc3gwYMdlStXTtE+cflqq6xXXnnFnJvy5cubc2X9nW3atMm5ja6LfW7c2UfbHTZv3ty8Lms7OH0NefHFFx2+pkOHDubc6HkICQkx3zdr1sy5ft++feYcLl682O199P1L2znp+5m+r+nrh7bRW7p0qcOXHDhwwPm3ly1bNkfp0qXN99re0TJp0iRzfq02bRUrVnRkz5493uvqm2++6XJsbUmo7ci0ZZZu//jjj/tc3JBSfvqP+GABekKDqHRkqlU/pQ2CtYhaa1bjNmzWZs1acJ1QnZo23NfRg5qh1RGZmmHxNTt27Ehw9pU77rjDZKv1k/uGDRvMJBGFCxd2a5/Ys+1oaxz93fjiSOLYLWti09qo22+/3XkpT5to6+Uo/Rt1Zx/9tK9/13FptrtixYriK7QsRbssxKU1fnpT2tD90qVLzqyTO/vEpedbr9RYZUi+Ql8/E7oioBM8WOMJtO46X758znPjzj4WnRBGa+H1tcUXR2lv3rw5Xns7vfTcoEED54xPW7ZsMa0e9Ry7s49FXx/0/Op7mnbUSWnLPm+4YqgTDsSlXS6sq3866YNO7NKwYUNzRUXPtZ7zhK4WaHwQm5a46PnV1wzrfRGJ88ngFQAAAPZEzSsAAABsg+AVAAAAtkHwCgAAANsgeAUAAIBtELwCAADANgheAQAAYBtMDwsAAOAjfv/9d5kyZYrpdz937tx4/ZKTc+rUKenXr1+C64YMGWJmvMto9HkFAKSaTjqib4A6FWuhQoU4k0AW9tBDD5nJEHRK+0mTJpkJQFL6/1YnbFi9erXLsuXLl8t7771nJnKoWbOmZDSCVwBAqkVGRkrOnDllzZo10qRJE84kkIWdPHlSihUrJsuWLZP27dsnGrx+++23snDhQhOo1q5dW55++mkzK2Bi7rnnHjPb4B9//CGZgbIBALanU+DOnz9f2rVrZ6Zu1elX9QW6Xr16LtNbLlmyRDp16uQybbNmDZs1a2a2j32cixcvmmmidXn9+vXNtjo1sU69q9NB6hSbKX1sOgXkrl27pHjx4mb63tgWLFhgppLUqTlLlSplMiNBQUEJHkenodTHVqNGDTN9b0r2Tc3z0qmb161bZ46jWZUSJUq4PG61YsUKOXbsmJl2NCwsLNn9kno+Os22vgnqVMfVq1f3uWl0gYxSrFixZLcZPny4LF682HwtUKCAzJ4920wXrFMJx35dsRw/flx+/PFH+eSTTyTT6PSwAGBnFy5c0GmuHR07dnRUrlzZfM2XL5+jT58+zm327dtntjl48KDLvgEBAY4ffvjB5TjNmjVzVKlSxdGhQwdHzpw5HQMHDnQMHjzYUa1aNbMsKCjI8eGHH6bosbVv395RtmxZR1hYmCM4ONjRr18/l+0GDRrkePDBBx333Xefo2rVqo7y5cs79uzZE+84+vMrVKhgtvvxxx9TtG9qnteyZcschQoVcjRu3Ng8h5CQEMe4ceOc6/Uc67Fbt25tHsOIESPc2i+x53PmzBnzePT32LlzZ0fFihUd//rXv9w61wDco695+v9P/7/FtmPHDvOaeOTIEeeyW7dumf+jU6ZMSfBYr732miNPnjyOy5cvOzILwSsA27MCoe7du5sXWrV161azbPv27SkOXh944AFHdHS0WfbVV1+ZZRqkxcTEmGWfffaZCcas++48tjvvvNNx7do1s2znzp2O7NmzOxYtWpTgPnrcRx55xNG1a9d4x9Hg98aNG4n+vKT2TenzOnXqlAm0Fy9e7DzW7t27Hbly5XJs2LDB3L9+/bo5zpo1a5zbuLNfYs9nwoQJjurVqzsfp1qwYEGy5xlA2oPX999/33yIveeee8wHS73ph8/ChQs7hg0bFu84+lqhH5b1A3RmomwAgNd49NFHJSAgwHxfq1Ytcwl7z5495nJ0SgwcONBcgleNGjUyXwcNGiR+fn7OZREREWbUrTuX4dQTTzxhakPV7bffLh07djQlC1rGYNFL9/v27ZPLly9L/vz5TV1aQqN5s2XLFm+5O/um9HnNmzdPsmfPbupav/nmG7ONJj207GHVqlVyxx13JPhcU7Jf3Oej50gfw+HDh6VcuXJmWdeuXd06xwDSRv/v6euHvl7FVbp06XjL9P/zgQMH5KuvvpLMRPAKwGtofVZsOXLkMAFUSumLd+xjJLYsJceOW7epgdmGDRvM97du3ZL77rvPvBFobZkG3VoHqre4QkNDXe6nZN+UPi8dlWwFo7FpLbEGoolJyX5xn0/fvn1l/fr1ptZV61/btGkjjz/+uDOQBZBx9P+ZvnY0bNjQ5bUhMVOnTjWJgsQ+yGYUglcAPsHKOGprJ8uNGzdc7mckHawV9741yldH9v72229y8OBB5xvGrFmzzLK4rCypJSX7ppT2f9QM6pw5czJsv7jPRweETJs2Tf7zn/+YIFYHgejgtv3790vBggVT/BwAuE+vcjz77LPy5JNPmsDU+kCrA7KKFi1qOg9YdPCnDrp85513JLMxwxYAn6AZPw2UNAiyaK9CvZydGbTtjEUzm99//700btzY2b6mSJEiLpmOuFnLxKRl3+Ro14Dw8HBZtGiRy3Jtn2MF4/rmppf9Y2eh3dkvMTpy2SofaNmypQle9U1Syz8ApI1OTqD/P1988UVz/8EHHzT3rQ+7+sFTX5v+/PNPUybQtGlTKVmypHzwwQdSuHBhl2NpFwJ9Te3Vq1em/1rIvALwCZrRu//++00tl7aAOXfunHzxxRfxMn8Z5bvvvpPAwEDTxmrmzJmSK1cuU++p9M1j5MiRMnjwYHPp/4cffojXBDwxadk3OdpKS4+tb3BDhw6VqlWrmvo2zbZoLasGzHr+NDP6/vvvm1pZzY5ajymp/RKjtXMa6Hfu3Nm8WWogXqFCBZeMD4DUsYLRuLREJ3Z5z99//21aDmq7Ol2XUJmQ9nX+5ZdfTKlSZiPzCsD29BK1Bkpxa171EljsWlMNGjVg1FpTLRdYuXKlmXHGqrtM6DiaAdRlsV+gg4ODzbLY/WKTo0FYpUqVzM9u1aqVuSSuAazS5doPVQNsq9n/0qVLzc9I7jmmdl93n9ebb75pAmLtvarZmZCQEFNfG3sWHR14psGlbqf9Xt3ZL7HnM2LECHn77bfNh4u1a9dK69atTc9X61wBSD3t5awfLuPetCQgNv1QqgNdmzdvnmh9u9a6am2sJzDDFgBkIL3krZlGvQxnTQoAAEg9ygYAIA10diqdzzshGrR6KjMBAN6K4BUA0kB7q8YejBWblixojVlCl8cBAKlD2QAAAABsgwFbAAAAsA2CVwAAANgGwSsAAABsg+AVAAAAtkHwCgAAANsgeAUAAIBtELwCAADANgheAQAAYBsErwAAABC7+D899/0ne70ISAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -894,10 +1165,10 @@ "id": "46065c2c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:04.438527Z", - "iopub.status.busy": "2026-08-02T09:59:04.438527Z", - "iopub.status.idle": "2026-08-02T09:59:04.446964Z", - "shell.execute_reply": "2026-08-02T09:59:04.446964Z" + "iopub.execute_input": "2026-08-07T10:53:08.878575Z", + "iopub.status.busy": "2026-08-07T10:53:08.878437Z", + "iopub.status.idle": "2026-08-07T10:53:08.884134Z", + "shell.execute_reply": "2026-08-07T10:53:08.883386Z" } }, "outputs": [], @@ -919,16 +1190,16 @@ "id": "dfe53dfa", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:04.446964Z", - "iopub.status.busy": "2026-08-02T09:59:04.446964Z", - "iopub.status.idle": "2026-08-02T09:59:04.586200Z", - "shell.execute_reply": "2026-08-02T09:59:04.586200Z" + "iopub.execute_input": "2026-08-07T10:53:08.885992Z", + "iopub.status.busy": "2026-08-07T10:53:08.885393Z", + "iopub.status.idle": "2026-08-07T10:53:08.966904Z", + "shell.execute_reply": "2026-08-07T10:53:08.966129Z" } }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAARMpJREFUeJzt3QmcTfX/+PH3MPYx9n0bo83OV2WLyL5LSpGWr8IX8Y18Q6JNqKiob31DqUh9LVEUQskSEkJRJIzs24xtxjLn/3h/vv97f/fO3Jk5d86dMXPv6/l4XOae87nnfs7nnHvveZ/PFmZZliUAAAAA4EAOJy8GAAAAAAILAAAAAAFBjQUAAAAAxwgsAAAAADhGYAEAAADAMQILAAAAAI4RWAAAAABwjMACAAAAgGMEFgAAAAAcI7AAgkSDBg2kZcuWIfv+2cUtt9wiXbt2lWA2ffp0ufHGGyVnzpxSvHhxs6xOnTrStm3bDHk/Pe/69Okj15Ov8z9UPhPpLf9GjRrJoEGDJKuaOXOmhIWFyd69ewO63RUrVpjt6v8Zuc0PP/xQSpQoIWfPng3Y+wBpIbAAMklGXlhllmDYB2SsrVu3St++fWXkyJGSkJAgJ0+ezND3++KLL+T777+XZ599VjIa539gy//FF1+U//znP/Lrr78G5PjA24MPPijFihUz5QxklvBMeycAGWrDhg0h/f7IGlauXCmWZckDDzwg4eH/9xOzbdu2DHm/l19+WTp16iRRUVGS1YTCZ8JJ+bdo0UJuuOEGefXVV+WDDz7IkPyFMq0x7N+/v4waNUpGjx4tRYoUud5ZQgigxgIAEDDHjx83/+fLly/DS1WDlY0bN0rv3r0z/L2QMeXfq1cv+eyzz+TMmTMUcQbQAF9rDj/66CPKF5mCwALIBIULF5aff/5Zli1bZtrB6sPzDp+r3f3OnTtNe+UCBQqYO01Kl7teo3egSpYsKd27d5fffvstzfbcru1qWl2XP39+KVeunKka17vKgdyH1N5/x44d0rRpU7Nf1atXl2+++cZ9YdKsWTOTL93WJ5984vO9v/zyS7nzzjulYMGC5oK1cePGsnz5cvHXt99+K3fddZdp91+oUCFp2LChzJkzJ1lZ2H2/xYsXm+1p2eijVatWsm7dOlt50bJs0qSJ2feKFSvKCy+8IImJie71d999t5QqVUouX76c7LU9evSQokWLmguG1NjJ3zvvvCO1atWSvHnzmjuanTt3NnlLz3mk54TefXb9nfSRtBndtWvX5Pnnnzf7r+V8xx13mKZUen7rney06HHS7eo55IudfYuIiPDZzl/3V/fb7vnvS0p9LOycX6l9J/iSWnq7++jvd0Zq5W/3s6ZpLl26ZLu/QVplN2bMGMmRI4csWbLE63XDhw8335+e7/PXX39Jv379zPmn50i1atXklVdeSfVz9dRTT3nVxLksXbrUlMV3333ntXz9+vUmj5rXChUqyGuvvZbitjU/jz/+uCnv3Llzm/NLaxuS5sefbep3iH7napM1IFNYADJF7dq1rTZt2vhcd/PNN1t33HGH1bZtW2vLli3W0aNHrf/+97/J0iUkJFjbtm2zWrRoYUVFRVlxcXHudfXr1zfLk263SZMm1t13321eFxsba02aNEl/2a05c+YEdB9Sen/dL33/X375xTp16pTVr18/K1++fNb69eut9u3bWzt27LBOnz5tDRgwwMqRI4f1+++/e21j6tSpVlhYmPXss89aMTEx1okTJ6wXX3zRypkzp7V48WLbed+7d6+VN29ea8iQIdaRI0esCxcuWJs2bbJ69uxp/fHHH36/3+uvv27SDR061Gxby3blypVW9+7dU82Hlknjxo3NsdZjcubMGWv69OlWnjx5rMGDB7vTffPNN+Y4zZ492+v1mvdcuXJZgwYNSvV97ORv+PDhZr8mT55snTx50tq9e7fVqlUrK3/+/NbWrVvTdR4NGzbMLLdz7gwcONDs94wZM0w5bN++3erQoYN5rypVqlhpad26tXXjjTf6XGd33woUKGDykVSXLl3Mfqe1D6md/76W2T2/7H4n2Envzz76c6xTKn+7nzUVHx9v9j2t89lu2V27ds1q2bKlVaRIEevPP/80yz7//HOTf03rsn//fqtUqVLmmK5evdp8l+7atcsaMWKE9fXXX5s0H3zwgXndnj17vM5vfb+k9DWa9ttvv3Uv0+Og5dC5c2dTJsePH7eee+45q2vXriatfsZdDh48aJUpU8a6/fbbrY0bN1rnzp0z26pYsaI5TunZpkufPn3Md+6VK1fSLGPAKQILIIsEFvpjlfRHNyX6o6g/IvPmzUvzwj537tzmR9hTzZo1rebNmwd0H1J6f71w/Ouvv9zLzp49ay6M9Ydff0xd9Idd044cOdK9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qVKl5PHHH5dbbrklQ9LAngEDBsjx48e9lnXu3Fkeeughr2Vff/21LFiwQK5evSpt2rSR+++/P9m2ApUGyWnXxJUrV8rs2bMlX7588u9//9tnMc2dO1e++uoryZkzp3Tp0kU6dep0XdOEuitXrshnn30m69atM8PQN2rUSB544AFTZp727Nkj7733nhw5ckSqVasmgwYNSjYXU2amgchff/0lH374oezevVtKlixprjcaNGiQ7PhqWerNTp1zQb83b7/99uuWJlRRYwEEma1bt8qNN94oP/zwgxkFbdu2bcnSJCQkSJMmTWT+/PnStGlTU+NUr14989pAp4F9emFYokQJc4HvetStW9crzZtvvin33HOPVKpUSWrWrGkuRJ588skMSQPf6tSpIy+//LIJAvWY+TJy5Ejp16+fVK9eXaKjo82xnDhx4nVLAzGjQerNFj1+evPjmWeeMQFYYmKiu3h27txpvsP0Ql+/07744gsTgFy8ePG6pMH/WkW0bdvW/N60atVKcuTIYcpLL+w9aUCt32sNGzaUXLlySePGjZN9PjMzTcjSUaEAO/78809r69atVkJCgtfyQoUKWXPnzjXLd+zYYR04cCDZa7dt22atWbPGWrt2rbVv3z7r2rVrydL88MMP1smTJ63z589bP/74o3k/+O/UqVPW2bNnzd/16tWzhgwZkizNv//9b6tAgQLW6dOn3ctat25ttWnTJuBpYF+lSpWsadOmpbg+Li7OlPeUKVPcyxYsWGDlyJHD2rt3b0DTIGX6HaZefPFFc8ySOnjwoJUzZ07rv//9r9dnJW/evO7PSmamwf/ExMR4FcWWLVt0VEzz2+TSuXNn66677nI/1+/SggULWq+//vp1SYP//aZduXLFqyj69+9v1a1b1/38q6++Msfyt99+cy/r27evdfPNN1+XNKGMwAJp2rNnj3XrrbdakZGRVq1atayyZctaX3/9tVdg0atXL6t8+fJWnTp1rPz581sPPPCA1zb69OljNW7c2GrUqJFVpkwZq2rVqtbOnTu90uh29HWlS5e2brvtNuutt97i6DiUUmDRsWNH86Pmafr06VZ4eLgVHx8f0DSwTy9SW7RoYT5PI0aMsDZt2uS1fvHixeYH7fDhw+5lGtDrZ+7tt98OaBqkLaXAQj8DuXPnti5duuRepjdNtMznz5+f6Wng2/Hjx005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8WIJJZ06dZIqVapc72xkSyNGjJA6derIk08+KSVKlLje2QGQxRFYAIAftAnRpk2b5MyZM3LbbbdJqVKlvNafO3fO3EFOSEiQ+vXrJ1uvTVfq1asnefLkkW3btklERIQ0aNBAcubM6b5DrDUWefPmNc2gXNq2bStlypRJ1lxq48aNUrZsWaldu7a5K68X0DfeeKPPvH/yySdSvHhxadiwoXn+/fffm/e5/fbbvdKtXr3aLNf829mntMplxYoVcvLkSQkLCzP7ULduXSlYsKDPPB4+fFh+/vlniYyMlEaNGpnX2LVlyxY5dOiQ2f+qVau6l7du3VoqVapk/t6zZ4/89NNPyV6rNUSaL3X58mXZsGGDxMbGSrVq1dIVlNg9D3T/NN8VK1Z0v7+/55w6duyYz/PJbvmnlB8tl1q1asmMGTNMkAEAqbIAALZs2bLFioqKsqKjo6327dubvz/++GP3+hUrVliFCxe26tWrZ915551Wvnz5rHfeecdrG8WKFbPatGljttGxY0erTJkyVpMmTayrV6+a9UOGDLEqVqxo1vfo0cP9CA8Ptz7//HP3dhYsWGDlzZvXatCggXl93bp1rbJly1pTp05NMf9dunSx+vfv734+YcIEq0qVKl5pEhISrCJFilgzZsywvU9plcvo0aPNPtx3333WrbfeapUsWdJas2ZNsnJp1aqVVa5cOatdu3ZW8eLFrRYtWljx8fFpHhdN07x5c6tChQpmH2vUqGHdfffdVmJiollfqVIla9q0aebvZcuWeZVr9+7drZw5c1pDhw4167du3WrSa3nq8dF89OvXz/KH3fOgdevW5r26du1qffjhhz63lVbZpnU++VP+KeVnxIgRVuPGjf0qAwChicACAGzQi1e9cH3kkUfcF22XLl2yli5d6v5b1z/11FPu18ycOdPKkyePtW/fPq8LuNtvv926cOGCeX7s2DGrQIECJlBw0YvAPn36eL2/pnEFFhcvXrRKly5tjR071r3+9ddft/ReUWqBheZvypQp7ucHDx60wsLCrA0bNriX6XtowBIbG2trn9IqF1/GjRtnLv49abnoRe2JEyfM8yNHjph9nDx5spWWxYsXm2Do/Pnz7mULFy60rl27liywSGrYsGFWiRIlrP3791uXL182F+5ali7Hjx83F+tz5syx7PDnPNAyiIuLS3FbdsrWzvlkt/xTys/s2bNN/gEgLXTeBgAbtJlRTEyMTJgwwd3MRJsLtWnTxvy9bt06s37kyJHu1zz00ENSsmRJ08zEk3bEzp8/v/lb12uznd9++832cVi7dq1p+jJs2DD3sgEDBri3mRJtDlOkSBH38woVKkjTpk1l9uzZ7mX6t/ZJ0KZIdvYprXJx0ZGLli1bJp999pnpOL5z507T58PTo48+appqqdKlS5v30hGs0pIvXz7T5MizDLt06SI5cqT+Ezdr1iyZMmWKGflIm0p9++23cuDAAbN/umzu3LlmmTaF0v/t8Oc80P1NqUmYP2Vr53yyW/6+8qPnjJavNu8CgNTQxwIAbNALM73Y9tW+XekFaeHChaVo0aLuZdpePTo62qzz5JlGaX+L+Ph428dBLzaLFSvmdRGYO3du09ciNdr+PunQob169ZLRo0fL5MmTzYWmduzWi0+7+5RWubhGZfrggw9M/wANHC5dumSWnzhxwt33QUVFRXm9rnLlyvLxxx+nWR533XWXDB482Pyv+WjRooX07dvXdDpOifZj0RGVNLDQ4Ert37/flOMXX3zhlbZcuXJy0003iR3+nAdJ+8wkZads7ZxPdss/pfzoOaNBWlqBKwAQWACADXqxeP78eXPnVi/cktILNr2jq/NEhIf/31fr6dOn3XfhA0UvJOPi4iQxMdHrrrx27k2NXhz/+eefXsvuvfdec+GpHXyPHDkiBQoUkHbt2tnep7TKRTsC6xC32mna1QlaO0ZrJ3Vtjuspaf71ud2yGz9+vBnxSjtmayd17ZC+detWqV69erK02um9a9eu5g59//793cv1Il47bk+fPt0EYenhz3mQVsf0tMrWDn/KP6X86Dlzww03eHUIBwBfaAoFADbceeed5kLRs9mQ666v0rvBun7RokXudbt375ZffvlF7rjjjoCWsb6XXhQuXbrUqwnOqVOnUn2d3snXdEkvXtu3b2/2Sx/33Xefe44LO/uUVrnoRbw2VfK8M67NjHzROTtcdP+06VDjxo3TLA99j2vXrpl864hIWguhtTm+Rn/SwKFbt27mQvnNN9/0WtesWTNTY/Hee+95Lddta9MzFx19KWmthksgz4O0ytYOf8o/JXrO6PDHAJAWaiwAwAZt8//qq6/KP/7xD9mxY4cZhlSHE9W70Lpcm5GMGjXK3AXXC0m9sJ00aZK5M968efOAlrE2zdGmP71795ann37aXHzqxbTeZU/tLvjf//53c2dfm9jocKIuDz74oNmWNp/Ru/4udvYprXLRoW01XxqwdOzY0QyPq30XfNGLb52vQ4eH1SZZe/futXURrBe+mm99re6X9ofQctCmUUlpfwWdaPD111/3mifENdzsG2+8YWpwdH91mFgdvlbTvfzyyyb/6sMPPzSBRefOnZNtP5DnQVpla4c/5e+LDrmrfTMychI+AMGDGgsAsEkv5l2deHVeAb1QfOWVV9zrx4wZY+4uax8Ivas9duxYd38FF71b7nn3WOnd4Bo1arif6/wNSeeWSDpBnr6vXrDu2rXLdMrWC129gEytM7C+rwYRU6dO9VreoUMHufvuu03goe/tyc4+pVYu2vFXm95oDcF3331nLvx1/owePXqYZlee5bJgwQITVGhNgzbb0gDAMwBKyT333CNz5swx8z3oHBz6XppXV3l5TpCnHdY1vXaA1xoS10Mv3JU2jdJ90OZmmk+lF+KuoELp/ug+pyS950F6zrm0zid/yt9XfqZNm2YCtJTm2AAAT2E6NJTXEgBAlqdt9j077eoFrF786QWyZ5CSlDbp0RGL/vOf/7ibPME+DV4GDhxo+i2EQvkNGjRIhgwZkuKkiwDgicACALKhd9991wxHqnentcZCm0LpnWXtuBxstDmS1jD4ohf3WgMBALj+CCwAIJvSzs0rV640o/VoJ2dtRx+MtF+A9onwRed1mDlzZqbnCQCQHIEFAAAAAMfovA0AAADAMQILAAAAAI4RWAAAAABwjMACAAAAgGMEFgAAAAAcI7AAAAAA4BiBBQAAAADHCCwAAAAAOEZgAQAAAECc+n9+LCV9gbfFnAAAAABJRU5ErkJggg==", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAf4pJREFUeJzt3QWUFMfCuP0igRAhClFCjDjE3YW4End39xuI5yY37rlx4u7uLiTEc+NuxIgCUQihv/PU/635eobZ3d6dXWB3n985AzszPd3V1dXVVdVV1R2yLMuCJEmSJNVgglp+LEmSJElWLCRJkiQ1C+9YSJIkSaqZFQtJkiRJNbNiIUmSJKlmViwkSZIk1cyKhSRJkqSaWbGQJEmSVDMrFpIkSZJqZsVCaiOWXnrpsNpqq7Xb7bcW8847b+jbt29oywYMGBDmmmuuMOGEE4Zu3brFzxZeeOGw1lprtcj2SHe77LJLGJeqpf/2ck40Nf6XXXbZsO+++4bx1VVXXRU6dOgQPv7442Zd72OPPRbXy/8tuc6rr746TDvttGHo0KHNth2pIVYspLGkJQtWY0tb2Ae1rNdffz3svvvuoX///mHEiBHhxx9/bNHt3XPPPeGZZ54JRx99dGhppv/mjf8TTjghXHLJJeHdd99tluOjcttuu23o2rVrjGdpbOk41rYkqUUNGjSoXW9f44fHH388ZFkWttpqq9Cx4/9/iXnjjTdaZHsnnXRSWH/99cNss80Wxjft4ZyoJf779OkT5pxzznD66aeHK6+8skXC155xx3DPPfcMRxxxRDjqqKPC1FNPPa6DpHbAOxaSpGbz/fffx/8nmWSSFo9VKisvvvhi2G677Vp8W2qZ+N9mm23CzTffHH755RejuAVQwefO4TXXXGP8aqywYiGNBVNNNVX43//+Fx5++OHYD5ZXvoUv9bt/++23Y3/lySabLLY0gc/Tb2iBmm666cKmm24aPvjggwb7c6f1sizfTTrppKF79+7x1jitys25D/Vt/6233gorrrhi3K9evXqFRx99tFQwWXnllWO4WNcNN9xQddv33ntvWGmllcLkk08eC6zLLbdceOSRR0JjPfnkk2HVVVeN/f6nnHLKsMwyy4Qbb7xxjLgour377rsvro+44bX66quHgQMHFgoLcbnCCivEfZ9lllnCv//97zB69OjS9xtttFGYfvrpw8iRI8f47RZbbBGmmWaaWGCoT5HwXXTRRWHBBRcME088cWzR3GCDDWLYmpKOSBO0Pqe/K1+V3ej++eefcPzxx8f9J56XX3752JWK9E1LdkM4TqyXNFRNkX3r0qVL1X7+7C/7XTT9V1PXGIsi6au+PKGa+pYvuo+NzTPqi/+i5xrL/Pnnn4XHGzQUd8ccc0yYYIIJwv3331/2u8MOOyzmn/ntfP3112GPPfaI6Y80Mv/884fTTjut3vPq0EMPLbsTlzz00EMxLp566qmyz59//vkYRsLao0ePcMYZZ9S5bsKz2267xfieaKKJYvribkNleBqzTvIQ8ly6rEljRSZprFhooYWyNddcs+p388wzT7b88stna621Vvbaa69l3333XXbLLbeMsdyIESOyN954I+vTp08222yzZcOHDy99t9RSS8XPK9e7wgorZBtttFH83bBhw7IzzzyTK3t24403Nus+1LV99ovtv/POO9lPP/2U7bHHHtkkk0ySPf/889k666yTvfXWW9nPP/+c7b333tkEE0yQffjhh2XrOP/887MOHTpkRx99dDZ48ODshx9+yE444YRswgknzO67777CYf/444+ziSeeODvggAOyb7/9Nvv999+zl156Kdt6662zTz75pNHbO/vss+NyBx98cFw3cfv4449nm266ab3hIE6WW265eKw5Jr/88ks2YMCArHPnztn+++9fWu7RRx+Nx+n6668v+z1h79SpU7bvvvvWu50i4TvssMPifp111lnZjz/+mL3//vvZ6quvnk066aTZ66+/3qR0dMghh8TPi6SdffbZJ+735ZdfHuPhzTffzNZdd924rZ49e2YNWWONNbK55pqr6ndF922yySaL4ai04YYbxv1uaB/qS//VPiuavormCUWWb8w+NuZY1xX/Rc81/PXXX3HfG0rPRePun3/+yVZbbbVs6qmnzj777LP42Z133hnDz7LJ559/nk0//fTxmD799NMxL33vvfeyfv36ZQ8++GBc5sorr4y/++ijj8rSN9urxG9Y9sknnyx9xnEgHjbYYIMYJ99//3123HHHZX379o3Lco4nX375ZTbjjDNmSy65ZPbiiy9mv/76a1zXLLPMEo9TU9aZ7LLLLjHP/fvvvxuMY6lWViyk8aRiwcWq8qJbFy6KXERuu+22Bgv2E000UbwI5y2wwALZKqus0qz7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FYtddtmlJVcvSZIkqbVXLEaMGBEef/zxcNlll5U++/rrr8uWGTBgQG2hkyRJktR2KxafffZZWGihhcJGG20Udt9999LnBx10ULjzzjubM3ySJEmS2mrFggrE6quvHn755Zeyzw855JBw6qmnNlfYJEmSJLUSHZvyo2effTZ89NFHYcIJJyz7vFevXuGNN95orrBJkiRJast3LEaOHBlGjx4d/+7QoUPp88GDB4cuXbo0X+gkSZIktd2KxaqrrhrOP//8sorF8OHDw8EHHxy7SEmSJElqX5rUFerMM88MK664Yrj//vtDlmVh/fXXDy+88EKYeOKJw8CBA5s/lJIkSZLaXsVizjnnDG+//Xa4/PLLQ8+ePWO3KAZuM0NU165dmz+UkiRJktpexQLTTDNNOOyww5o3NJIkSZJapRZ98rYkSZKk9qFJFYvPP/88Phxv2mmnDR07dhzjJUmSJKl9aVItYIcddgidOnWKM0NNNdVUzR8qSZIkSW2/YvHSSy+Fr776yoHakiRJkpreFWrmmWeOz62QJEmSpCZXLI488siw2267xSln//zzz/DXX3+VvSRJkiS1L03qCjXvvPOGV199NSywwAJVv+eheZIkSZLajybdseBuxfLLLx/uvffe8Oyzz47xam5ffPFF2H777WMXrLnnnjucccYZ8aF8eZdeemno1atX6NatW1hllVVixadSkWUkSZIkjaU7Fh9//HF45plnwtRTTx1aGoPEl1pqqbDqqquGJ598Mkw66aThv//9b3j++edj5QbXX3992H///cNVV10VlllmmXD66aeHPn36hHfffTfMNNNMhZeRJEmSNBbvWPTs2TP89NNPYWxgPAcVmGuvvTbMNddcoXv37uHkk08uVSrA+5122ilsueWWYdZZZw3nnXdemGSSScJFF13UqGUkSZIkjcWKxa677hp23HHH8PLLL4dffvklDB06tOzVXOjudNddd4Wtt946TDjhhFWXYXvvvPNOvPuQTDDBBPEOx3PPPVd4GUmSJEljuSvUQQcdFP9fcsklW3Tw9g8//BCntZ1iiinCWmutFcdE0G2JB/QdeOCBsXLwzTffxGWnm266st/yPo2hKLJMNSNGjIivxCl2JUmSpGasWHCnYmz4559/4v9HH310HBtB96cXX3wx3sGgwN+/f//SslQy8nhfWcEpskwe3aeOP/74ZtobSZIkqe1qUsVi8cUXD2MDszd17NgxbLXVVmHjjTeOn62//vph5513DjfeeGOsWKS7ENzdyON9+q7IMtWw/oMPPrjsjkWPHj2acQ8lSZKkdjbGgtmZeOX/ruvVXCaaaKKw2GKLhU6dOpV9zvt0N4PKx5xzzhlnqcp7+umnw9JLL114mWo6d+4cu2HlX5IkSZJqqFjQUp9a69Pfdb2a06GHHhqnin3hhRdityW6YdEtarPNNistw3iLyy+/PFYUePL3CSecEL7//vuw5557NmoZSZIkSS3cFeq9996r+ndL23TTTWOXJf4fMmRI7Lq09957h6OOOqq0zD777BOnv91oo43CsGHD4rS099xzT5wWtzHLSJIkSWrhisW8885b+rtfv35xGthq+vbtW+d3TbXXXnvF16hRo+KYi2qOOeaY+Pr777/H6DrVmGUkSZIkjaXnWNx99911Pnfi3nvvDS2lrkpFXpEKg5UKSZIkaRzOCvXdd99V/TtVKgYOHBhmnHHG5gudJEmSpLZXschXGqpVILijcNZZZzVPyCRJkiS1zYrFW2+9Ff9fYIEFSn/nuxd17949dOnSpXlDKEmSJKltVSx69+4d///222/DDDPM0ODyzOR02223NT10kiRJktru4O0ilQrcfvvtTVm9JEmSpPZQsZAkSZKkPCsWkiRJkmpmxUKSJElSzaxYSJIkSaqZFQtJkiRJ43fFYpdddmnJ1UuSJElqjc+xyPv777/DZ599Fn7++ecxvlt66aXj/wMGDKgtdJIkSZLabsXimWeeCVtttVX45ptvqn6fZVmt4ZIkSZLU1rtC7bvvvmHjjTcOX375Zfj111/HeEmSJElqX5p0x+KTTz4Jzz//fOjSpUvzh0iSJElS+7hjMddcc9XZDUqSJElS+9OkisWBBx4Ydtppp/Dyyy+HX375JQwdOrTsJUmSJKl9aVJXKCoVWHLJJat+7+BtSZIkqX1pUsWCOxWSJEmSVFPFYvHFF2/KzyRJkiS194rFV199Ff+feeaZS3/XhWUkSZIktR+FKxY9evQojZ9If9fFMRaSJElS+1K4YvHee+9V/VuSJEmSClcs5p133qp/S5IkSVKTnmMhSZIkSTXPCsUYiquuuirceuut4csvvwyjRo0q+/79999vymolSZIktac7Fqeddlo46qijwrLLLhveeeedsOuuu4YFF1wwfPjhh2GNNdZo/lBKkiRJansViwEDBsS7FVQucOihh4ZbbrklnH/++eGjjz5q7jBKkiRJaosVi88++ywsscQS8e+JJ544/Prrr/Hv7bbbLjz33HPNG0JJkiRJbbNi8c8//4ROnTrFv2edddbw4osvxr8///zz0ueSJEmS2o8mDd7OY3zFFltsEVZZZZV4t2KzzTZrnpBJkiRJatsVi19++aX0N+MrZpxxxvDCCy/EMRd77LFHc4ZPkiRJUlutWAwaNCistdZapffbbLNNfEmSJElqn5o0xmK99daLz7KQJEmSpCZXLOaYY47w3nvvGYOSJEmSml6x6NevX9h+++3DU089Fb7//vswdOjQspckSZKk9qVJYyx22WWX+D8zQVVjNylJkiSpfWlSxeLll19u/pBIkiRJal8VixNPPDHcddddVb/r27dvnd9JkiRJapuaNMbi7rvvrvr56NGjw7333ltrmCRJkiS15TsW3333XdW/U6Vi4MCB8WF5kiRJktqXRlUs8pWGahWIjh07hrPOOqt5QiZJkiSpbVYs3nrrrfj/AgssUPo76dSpU+jevXvo0qVL84ZQkiRJUtuqWPTu3Tv+/+2334YZZpghjG3ffPNNeOaZZ8I888wTFllkkTG6Yr344othyJAhMZxzzjnnGL8vsowkSZKksTR4e1xUKkaNGhU23XTTsMMOO4Srr7667Lthw4aF5ZZbLn5/wQUXhIUWWig+xK+xy0iSJEkai9PNjgvHHHNMmGOOOcIff/wxxndHHnlk+Pnnn8O7774bppxyyvDcc8+FFVZYIay++uqhT58+hZeRJEmSNBbvWIxtjz/+eLjpppvinYZqT/m+/vrr49PAqTBg+eWXD0suuWS47rrrCi8jSZIkqQ3fsfj+++9j96cbb7yxVCnI++qrr8LQoUNL4z8SBpi/8cYbhZepZsSIEfGVDB8+vBn2SJIkSWp7xus7FtxpoFLBi25L1TB2AtNMM03Z5127do2ViaLLVHPyySfHykx69ejRo+Z9kiRJktqi8bpicfPNN4cXXnghzDvvvLErFC8qAh9++GH8m4pH586d47K//fZb2W95P/HEE8e/iyxTTf/+/WOlJL0GDx7cAnspSZIktX7jdVco7jCstdZa4f777y99RgH/k08+CXfddVfYfPPNwyyzzBIfzPfll1+W/faLL76Ig71R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xx13XDj++OPHYkglSZKk8c/gwYPDzDPPXO8y7eKORYoEppnN43337t3r/F3//v3DwQcfXDaz1M8//xzvfDBOozWi1tmjR4+YOKaYYoowPjOsxq3pwHPM/MA04HXB621rTQOtMbzVcA/i119/jTOqNqRdVCwmn3zysOiii4aHH344bLHFFvGzv//+Ozz++OPxrkVdOnfuHF95TFfbFpC4W0sCN6zGrenAc8z8wDTgdcHrbWtNA60xvJWmnHLKQsu1i4oFmF520003DYsttlhYZpllwplnnhkmnHDCsNdee43roEmSJEmtXruYFQobbrhhuOmmm8LNN98cn1/BoOxnnnkmDuCWJEmSVJt2c8cCm2yySXy1Z3TtOvbYY8fo4jU+MqzGrenAc8z8wDTgdcHrbWtNA60xvLVqF7NCSZIkSWpZ7aYrlCRJkqSWY8VCkiRJUs2sWLRRhx9+eLjrrrvGdTAkSZLUTrSrwdvtCc/omHrqqcd1MCRJktROWLFQi/rpp5/ClVdeGR555JGw0UYbVX1uCMucccYZ4a233grTTz99XGbxxRdvkWXq88Ybb4Rrr702fPzxx/Fp7TvttNMYv//nn3/CJZdcEvdnookmirOMpYcuNvcy9eGp8QMGDAivvfZafODO2muvHTbffPOyJ8KPHDkybmPgwIHx7zXWWCPstttu8fktjVnmr7/+CldccUV49tlnwx9//BHmnnvuGLdzzDFH4fDee++94e677w4//vhj/P3uu+8e5pxzzjGWufPOO8MPP/wQFlpoofjU+2mmmaZsmfvvvz/cfvvt4fvvv49PAN1mm23CSiutVLbM6NGjw3XXXRceeOCBGB9bb711WH/99UNjkZ522GGH0LFjxzHu/r3zzjsx3j777LPQvXv3sM8++4QFFlig9P1///vfqncMO3XqFB588MGyJ7LyTJ1XX301Tn296667huWXX75wGPv27Rt+++23ss9It8RL8ssvv4Tzzjsv/O9//4uzkpDO+F1j10Oa5RhxjpA+brnlltBYv//+e4y35557LjZ8VJ6jbIP84sknn4zhWXnllWPcco4kP//8c0z7L730Uph00knDqquuGrbbbruyNMsDUAknDSyk64UXXjjssccehacXP+igg2I+UmneeeeNxzYhnDfccEM8H6ebbrr4rCTOxTzCwFTn3377bZhvvvliup5x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cGsIU2lef/31Max1Pe26OZAGSAsJ09wydSdxW23K4LqmDmWfmdZ56aWXbrGwcm5xjiVMM5ryrsbELU8jHjp0aPwtT29vCeRZxAnnBpj+le2R/9LQURTplWmT+W21KZebC9cEwpYst9xycdpZKrhFMdUt+8xvizzxu6m41nLNTSik0zBGmuW8Keraa6+N1y6mbm4p5P2333576T3Tc3Ms+XxQI65hYwMNQxy/1EDEFMCE9ddff22xRmQrFiq7sKdW7tZgiy22CGusscZY2x4tk5tvvnmTfkvhriXvWFSiEMH2mlIopIWI39b1TITmxnM82B7PAWgsnp/Abynsjy3rrbfeGM9hKWrDDTcMG2ywQRhbiJftttuuSb+lFZa4bezzH5qK5xmwvaYUCplbn98yV/3Ywp2gup6jUh+eV0NYef7H2EIrdZ8+fZr027XXXjtsuummYWyh8Er8NOXZM7TE89tqz8lpCTwTo6nboxLMb1uygllpyy23bNTznfLIR1qycawSFfem5pWk9a233jqMLTQYcSyrPaNmfENlmLDSMNtSOrbYmtXq0WL0n//8p1TL5eTZeeedy1qyaaW54447woEHHhi7JPCQLVpkuejmTzJaeG666abYVYEHgaXuGXncVq5vHXQnufzyy0utGrRY5x+uRPcUHibEw9VoDWU7LE94aWm8+OKL490DMisuCHxGa9xee+0VH1pD2GjhoWDDb9kODzDiVnXlQ/LoJsCtWu705NeRjB49Om7r2WefjS0DlQ/s4bb9FVdcES+EtIJReDvyyCNjKwvbpNWF9c8333zxrgytRixD5s5ndAe75JJLYpxQAaB1MrVMsExlBkcLNGHJryOPFmKOI3FAAZ/9S5USuskdcsghsWWN9RI+Kljsc2opPO+88+LDe9Zaa63YTYBw8TcvPiesdHVhHam176qrrgrHHnvsGHdG2BfuROTXkUcLHL/lYU/E7Q8//FB64BPxwsWTbbCtn376Kcw777yxixdotT/nnHNiqxJdF3jwEA9rozJN1xbunhBX7DMX/skmmyymywcffDCss846YzzAjrsspBke6JRfR8IdDY4zrergoWCkz2TbbbeNt/nJ5AkHlXu6f5Cm2C/SL11miAP2h/1jX/fcc8/4Py2fpBUKq4SXOGE9HBPCW9kCTVj4TX4dCXHBvj/++ONxHZVplmNI10P2k5Z6tkkXRsJGeuH8/u9//xsL+VS8iPvUAED3JlrKSdPEGWk23fVjveQrlZVguhvykLH8OirTCXc6CW+6K5QqJZy7++yzT4xPPuM4UEBO3Rc4p0kHxDH5AemF8FFwossQrbrEFQ+wJN4JG+c0dxs4fpUPdSMfoAWT9aV15BGfrI87ghwHjiPHGKTzjTbaKLa2UzFiHWyT+AStoJxf3IWgsERYyLsoINJljHOa9Hr33XfHfI18iIeEsj7iqLLSzbE7++yzY0twfh0J5+s111xT6lbGvuVbf+liwvbIo8lnKVSTLjjP2BfSK8d0xRVXjPvDMhwHuqiwz5wDxAVxTF7DceYcI/+pjDfSJOmb/civI4+0zjrYH+KN36RKCdeT4447Lhbeybf4jnxrk002icfhtttui2mWOCO8xBlpge9pSGJ/OB85Xqw7tZyTn9CtqLISzPlH3OTXkcc5RZgIL3feybPTQ++4i8D+ca0lPBwnwpS6q5BHk2bJ/0gvhJ9ziQoqXXRJn8QVeRvnF8eU9dMljkaCyp4IqacAaTOtI4/zgfwn3T1kuxxjcL6vu+668bpEGiIc5CWcH2yXZek2RT5OdybyUeKQ9EC+w3vOBcLGwwy5BnCuse/cyamsdHNun3/++THt5NeREB62TZolXfEwVhqAkn79+sVjTR7C+UWDFPHKe/IGrieUD+iRQFohzXJcdtppp3jXlwcDXnbZZTEcnPtcS1kPeT/Xm8pK8M033xyPQ34deeRZ9913XzzXuBPEOvIPyKX7NHkex4i8jGW4VqQ8mvyLBjnSR2Xli/0hnyXMHJvKBy6OFeP60d8aP5x99tlZr169yj4bMmRIduWVV8bXhRdemK2//vrZTDPNFB9Vn/DdJJNMks0777zZiSeemJ122mnxkfOHHHJIaZnffvstW2KJJbK55porO+mkk7ITTjghW2ihhbJPP/208DqGDRuWzTHHHNkyyyyTHX744TwtPuvcuXP23HPPlZbZbbfdsk6dOmXTTjttttRSS8XvH3jggeyVV17JunXrlm211Vbxd126dInf9e/fP4ZrkUUWict17Ngx23PPPbPll18+m2CCCbJJJ500W3jhhbNVV101u/766+M2Bg8eHNfBNvbff//s/PPPL63jn3/+KYVlyy23jHF1yimnZJNNNlkM16mnnlr6/sYbb4zrmXrqqbMll1wym2KKKeL62E/iZvXVV49xQFj57dZbbx1fhOnll1/Opp9++rjMTjvtFMM68cQTx+923HHHbNdddy1th9/zed++fbP//ve/pXV88cUXpWUuu+yybKKJJorxzX7wG9advPPOO9kMM8wQwzjffPNlPXr0yBZccMFs9OjRcVscV44LvyMcrOOII46Iccx+9unTJy7Tr1+/GBdsi30nrOxrssIKK2QTTjhhtuiii2ZnnXVW2TqSN998M5t88smzTTbZJO4L388444zZt99+G7//5Zdf4vEiLMQ/6+fvr7/+Oh7DaaaZJttoo41inBEW3pMmZ5555myXXXbJTj755Pg5aWP22WeP4WEba6+9dgwX2wfHnX3o2bNndtxxx8XwpnUkf/75Z9a7d+8YHyzD8qSxhx56qLTMoYceGsNCelp66aVj/F1zzTXZu+++G+N8m222KaXZdIxWXnnleC488cQT8TPica211so6dOgQjy3n0brrrpudd955pXCktLb77rvHdJDW8ddff5XCsu+++8b44Pwk7RGWww47rPT9Y489Ftcz5ZRTZosttlhclmPAOjhnlltuuRhnHB/CteGGG5bOyRdeeCGbbbbZ4jJ77bVXKV5Z3x577BGPZ0LaZtukQeI5rSPFPW6//fb42T777BPTDfHDefj333/H7z/55JNszjnnjGmW/zlOhG3kyJExHZKGV1lllRhf5D1zzz13PEash21uscUW8XgeeeSR2VRTTRW3RVg5HhzT33//PW6HcBPvfHb66adnxx9/fGkdyWeffRbzH9IQ+8Lx5lh89NFH8fs//vgjxhVhYd+JW/b//fffz+6///647GabbRa3T9yyfvJJzil+l85f0hJ5OHHLPnGMyQeffvrpuJ177703rmPWWWeN59a5555bWkdCHsYxIg1xLrA868ufg5wvfM4+kWbZ1jnnnJN9+eWX2SyzzBLDSjpPedfee+8d0yfpedCgQfH82nzzzeN5mNIsx2PjjTfO/v3vf5e2w3ccvx122CGm2bSO4cOHl5Y56qijYpwce+yxcb8IC3GcvPjiizEsrIe8nHS9zjrrZKNGjYrrI67nn3/+UpolzXEe8Jsnn3wyfrf44otnBxxwQNyXlGY5j9Zcc83SdjiX+P2KK64Yz7u0joEDB5aWeeSRR+Iy5Jn8lnhg/Rz/dG0hXyWsnCvzzDNPzNtIa1xH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oEGDwrBhw8L888/fpEpJ0XTA/hHuWWaZpbT9xqY5DBkypGp6Khr/dYWHeFlwwQXD5ZdfHisZklSvTJJUyGuvvZbNNtts2RxzzJGts8468e9rr7229P1jjz2WTTXVVNliiy2WrbTSStkkk0ySXXTRRWXr6Nq1a7bmmmvGday33nrZjDPOmK2wwgrZqFGj4vcHHHBANssss8Tvt9hii9KrY8eO2Z133llazx133JFNPPHE2dJLLx1/v8gii2QzzTRTdv7559cZ/g033DDbc889S+9POeWUrGfPnmXLjBgxIpt66qmzyy+/vPA+NRQvRx11VNyHzTffPFt88cWz6aabLnv22WfHiJfVV1896969e7b22mtn3bp1y/r06ZP99ddfDR4XlllllVWyHj16xH3s3bt3ttFGG2WjR4+O388666zZZZddFv9++OGHy+J10003zSaccMLs4IMPjt+//vrrcXnik+NDOPbYY4+sMYqmgzXWWCNuq2/fvtnVV19ddV0NxW1D6akx8V9XePr165ctt9xyjYoDSe2TFQtJKoDCKwXXHXfcsVRo+/PPP7OHHnqo9DffH3rooaXfXHXVVVnnzp2zTz/9tKwAt+SSS2a///57fD9kyJBssskmixWFhELgLrvsUrZ9lkkViz/++CObYYYZsmOPPbb0/dlnn53RVlRfxYLwnXfeeaX3X375ZdahQ4ds0KBBpc/YBhWWYcOGFdqnhuKlmv/85z+x8J9HvFCo/eGHH+L7b7/9Nu7jWWedlTXkvvvui5Wh3377rfTZXXfdlf3zzz9jVCwqHXLIIdm0006bff7559nIkSNjwZ24TL7//vtYWL/xxhuzIhqTDoiD4cOH17muInFbJD0Vjf+6wnP99dfH8EtSQxy8LUkF0M1o8ODB4ZRTTil1M6G70Jprrhn/HjhwYPy+f//+pd9sv/32YbrppovdTPIYiD3ppJPGv/mebjsffPBB4ePw3HPPxa4vhxxySOmzvffeu7TOutAdZuqppy6979GjR1hxxRXD9ddfX/qMvxmTQFekIvvUULwkzFz08MMPh5tvvjkOHH/77bfjmI+8nXbaKXbVwgwzzBC3xQxWDZlkkklil6N8HG644YZhggnqv8Rdd9114bzzzoszH9FV6sknnwxffPFF3D8+u/XWW+NndIXi/yIakw7Y37q6hDUmboukp6LxXy08pBnil+5dklQfx1hIUgEUzChsV+vfDgqkU001VZhmmmlKn9FffY455ojf5eWXAeMt/vrrr8LHgcJm165dywqBE000URxrUR/631dOHbrNNtuEo446Kpx11lmxoMnAbgqfRfepoXhJszJdeeWVcXwAFYc///wzfv7DDz+Uxj5gttlmK/vd7LPPHq699toG42PVVVcN+++/f/yfcPTp0yfsvvvucdBxXRjHwoxKVCyoXOHzzz+P8XjPPfeULdu9e/cw99xzhyIakw4qx8xUKhK3RdJT0fivKzykGSppDVVcJcmKhSQVQGHxt99+iy23FNwqUWCjRZfnRHTs+P9nrT///HOpFb65UJAcPnx4GD16dFmrPIN760Ph+LPPPiv7bLPNNosFTwb4fvvtt2GyySYLa6+9duF9aiheGAjMFLcMmk6DoBkYzSB1uuPmVYaf90Xj7uSTT44zXjEwm0HqDEh//fXXQ69evcZYlkHvffv2jS30e+65Z+lzCvEM3B4wYECshDVFY9JBQwPTG4rbIhoT/3WFhzQz55xzlg0Il6Rq7AolSQWstNJKsaCY7zaUWn1BazDf33333aXv3n///fDOO++E5ZdfvlnjmG1RKHzooYfKuuD89NNP9f6OlnyWqyy8rrPOOnG/eG2++ealZ1wU2aeG4oVCPF2V8i3jdDOqhmd2JOwfXYeWW265BuODbfzzzz8x3MyIxF0I7uZUm/2JisPGG28cC8rnnntu2Xcrr7xyvGNx6aWXln3Ouul6ljD7UuVdjaQ500FDcVtEY+K/LqQZpj+WpIZ4x0KSCqDP/+mnnx722muv8NZbb8VpSJlOlFZoPqcbyRFHHBFbwSlIUrA988wzY8v4Kqus0qxxTNccuv5st9124fDDD4+FTwrTtLLX1wq+8847x5Z9utgwnWiy7bbbxnXRfYZW/6TIPjUUL0xtS7iosKy33npxelzGLlRD4ZvndTA9LF2yPv7440KFYAq+hJvfsl+MhyAe6BpVifEKPGjw7LPPLntOSJpu9pxzzol3cNhfpoll+lqWO+mkk2L4cfXVV8eKxQYbbDDG+pszHTQUt0U0Jv6rYcpdxma05EP4JLUd3rGQpIIozKdBvDxXgILiaaedVvr+mGOOia3LjIGgVfvYY48tjVdIaC3Ptx6D1uDevXuX3vP8hspnS1Q+II/tUmB977334qBsCroUIOsbDMx2qUScf/75ZZ+vu+66YaONNooVD7adV2Sf6osXBv7S9YY7BE899VQs+PP8jC222CJ2u8rHyx133BErFdxpoNsWFYB8Bagum2yySbjxxhvj8x54BgfbIqwpvvIPyGPAOsszAJ47JOlFwR10jWIf6G5GOEFBPFUqwP6wz3VpajpoSpprKD01Jv6rheeyyy6LFbS6nrEhSXkdmBqq7BNJ0niPPvv5QbsUYCn8UUDOV1Iq0aWHGYsuueSSUpcnFUflZZ999onjFtpD/O27777hgAMOqPOhi5KUZ8VCklqhiy++OE5HSus0dyzoCkXLMgOX2xq6I3GHoRoK99yBkCSNe1YsJKmVYnDz448/HmfrYZAz/ejbIsYFMCaiGp7rcNVVV431MEmSxmTFQpIkSVLNHLwtSZIkqWZWLCRJkiTVzIqFJEmSpJpZsZAkSZJUMysWkiRJkmpmxUKSJElSzaxYSJIkSaqZFQtJkiRJNbNiIUmSJCnU6v8DB6BB7RuUl0EAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -938,13 +1209,17 @@ } ], "source": [ + "group_cols = [\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"]\n", "time_stats = (\n", - " clean.groupby([\"tokenizer\", \"vocab_size\"])[\"train_time_sec\"]\n", + " clean.groupby(group_cols, dropna=False)[\"train_time_sec\"]\n", " .agg([\"mean\", \"std\"])\n", " .reset_index()\n", - " .sort_values([\"tokenizer\", \"vocab_size\"])\n", + " .sort_values(group_cols)\n", ")\n", - "time_labels = [\"char\" if t == \"char\" else str(int(v)) for t, v in zip(time_stats[\"tokenizer\"], time_stats[\"vocab_size\"])]\n", + "time_labels = [\n", + " \"char\" if t == \"char\" else f\"{int(v)}\" + (\"\" if pl == \"end\" else f\"\\n[{pl}]\")\n", + " for t, v, pl in zip(time_stats[\"tokenizer\"], time_stats[\"vocab_size\"], time_stats[\"pad_layout\"])\n", + "]\n", "\n", "fig, ax = plt.subplots(figsize=(8, 4.5))\n", "ax.bar(time_labels, time_stats[\"mean\"], yerr=time_stats[\"std\"].fillna(0), capsize=3)\n", @@ -969,22 +1244,20 @@ "id": "b82b3da1", "metadata": { "execution": { - "iopub.execute_input": "2026-08-02T09:59:04.586200Z", - "iopub.status.busy": "2026-08-02T09:59:04.586200Z", - "iopub.status.idle": "2026-08-02T09:59:04.764447Z", - "shell.execute_reply": "2026-08-02T09:59:04.764447Z" + "iopub.execute_input": "2026-08-07T10:53:08.968253Z", + "iopub.status.busy": "2026-08-07T10:53:08.968122Z", + "iopub.status.idle": "2026-08-07T10:53:08.974932Z", + "shell.execute_reply": "2026-08-07T10:53:08.974113Z" } }, "outputs": [ { - "data": { - "image/png": "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wcdTUVGBHTt2yP/79++PwMBAudzLy0vOda8NZDds2IDMzMwG648ZM0a3Tl5eHrZv3y7X6devH3x9fQ3eDyIia8VAloishggk3333XezatQtvvvmmbvnff/+NqVOnIj09Xd5/9tlnZTsRwKalpaG0tBSrVq1Cr169dOssWLAAM2fORM+ePeHm5oasrCz89NNP6Ny5M1QqlS6QFakDu3fvlgHy2rVrZZBZ17XXXovU1FQEBQXh33//xYsvvoj//e9/5z0WEfyOHTsWERERCA4Olveffvpp3HPPPbrUgpycHPj7+2PLli04dOiQbl1xnOJ3bdq0SQayH3/8MWbNmoWBAwdCURTs2bMHCxcuxA033GCSficislgKEZEV+eCDD5QOHTooarVat+z2229XJkyYIH/+999/FRsbG2Xz5s3yvmg3efJkZdCgQYpGo9Fr88MPP+i2kZiYqBw8eLDR36lSqZThw4crs2fP1i0T2xcfoVOnTtVt9+eff1bs7e2VhISE8x7HjBkzlBtuuEHvd/z+++/y53379slt5+TkNFivtLRU6d27tzJ+/Hh5bNu3b1c8PDyUQ4cO6dqI7Yhl2dnZ590PIiJrxhxZIrIqN954I7Kzs+XpdkGclhcjqWJEVhBX+48cOVKmGWhHccVopUghOH36tFz21VdfYfDgwZg8ebJuuyJ9QIzO1iVSE1auXCm3L0ZkxTbqe/LJJ2FjYyN/FukAHTt2lO3PR6QxiJFVkRIgODo6YuLEiedcR4y2Tps2TR6zOE5xbF9++SViYmLkxWci7eK7776TI9DV1dVyJJmIqC1jagERWRVxqv3SSy/FsmXLZI7ob7/9JgM8EUQKycnJMpisq1OnTnqPpaSkyBSCpojgUvyOM2fOoG/fvjLPNiEhodG2UVFRevdFQCx+z/k888wzmDFjBsLCwmRO6/jx4/HAAw+cM7f15Zdfxh9//CHzarUpDiINoaioSOYI13XVVVfJlAkioraMgSwRWR0x+nrffffho48+kgHtNddcA1dXV12gqx3lrHtRl/Yxwdvbu0Gbut577z35v8h9tbev/ZgU+asiR7a+goICvbxZcV/7e85F5MX+/vvvMggVua6vv/46vv32W8THxzfa/tdff5X5t+L/Ll266JaLIFsE6mKEloiovWFqARFZHTHaKCoVfP311zK41KYVCCKl4J9//pEBpZY45S4uitKOworRVnGBmLgQrG5FBG1wKyoEiOBQG8TW1NTIFIPGaC8K046O7t27F8OHDz/vMWgvTBNB8BVXXIFXX30VR48ebbR2rAhuxTGKNhMmTNB7TIzkijQLkVpQf8IGTqhARG2djUiUNfdOEBE112233Yaff/4Z7u7uMiC1s7OTy0WAO3ToUFl5QFQAEGkE77zzDhYtWiTX0QamIh9VBIgPPfSQHM1dsWIFXnrpJVx88cWywoFIVRCjsOLUvwiYjxw5gsjISJk3K4iqASIXt0OHDpg+fbocYX3//fdlFYI///zzvPsv1hEjxaJygSgN9umnn8LPzw/r1q2Tv0OkNGirFojUg5KSErl/dYnUCrGOGJHetm0bHn74YYSEhMgKB6tXr5ZBtYeHB19cRNRmMZAlIqskaqaKElujR4+WAWtd5eXl+Oyzz3SBnChDJYLOukQwK07lb9y4UbYRExCIWrJaIqAUo63ioimxrkhHEMHi/Pnz5ePHjx/H3LlzZUqAuHjs1KlT6N69u8xz1dajPR+R3yuCXhF0DxgwQI66iqBW5Ng+9dRTMvgW+ya22VgqxJw5cxAXFydHk0VQ/9dff8n9FTVvRdDOIJaI2joGskRERERklXixFxHRBRoxFjmzTVU6qDv6S0RExmEgS0R0AYjZtTZv3tzoYyJVgYEsEVHLMbWAiIiIiKwSy28RERERkVViIEtEREREVomBLBERERFZJQayRERERGSVGMgSERERkVViIEtEREREVomBLBERERFZJQayRERERGSVGMgSEREREazR/wHTJrePCkKv6gAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "Not found: ..\\artifacts\\REPLACE_ME_domain_stats\\tokenization_stats.json\n", + "Run scripts/calc_tokenization_stats.py on the same AIRR file used for the results above (pointed at the same --tokenizers-dir) to produce this file, then re-run this cell.\n" + ] } ], "source": [ @@ -1041,7 +1314,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "irrm-codec", "language": "python", "name": "python3" }, From b6c4fe32df3167929fa63595dc1d74f080e27122 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 7 Aug 2026 14:59:55 +0300 Subject: [PATCH 51/70] Add --hidden-dim/--num-conv-blocks, tracked like pad_layout --- irrm_codec/train_forward.py | 7 +++ scripts/compare_forward_tokenizers.py | 62 +++++++++++++++++++++------ 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/irrm_codec/train_forward.py b/irrm_codec/train_forward.py index 298f6ce..320d891 100644 --- a/irrm_codec/train_forward.py +++ b/irrm_codec/train_forward.py @@ -40,6 +40,11 @@ def parse_args(): parser.add_argument("--lr", type=float, default=1e-3) parser.add_argument("--weight-decay", type=float, default=1e-4) parser.add_argument("--dropout", type=float, default=0.2, help="Dropout used in ForwardModel's conv blocks and MLP head.") + parser.add_argument("--hidden-dim", type=int, default=192, help="Width of ForwardModel's conv blocks.") + parser.add_argument( + "--num-conv-blocks", type=int, default=4, + help="Depth: number of dilated conv blocks. Dilations are 2**0, 2**1, ..., 2**(n-1) (default 4 -> 1,2,4,8).", + ) parser.add_argument("--train-fraction", type=float, default=0.8) parser.add_argument("--val-fraction", type=float, default=0.1) parser.add_argument("--seed", type=int, default=42) @@ -155,6 +160,8 @@ def main(): output_dim=merge_stats["embedding_dim"], max_len=args.max_len, dropout=args.dropout, + hidden_dim=args.hidden_dim, + dilations=tuple(2**i for i in range(args.num_conv_blocks)), ).to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) num_parameters = sum(param.numel() for param in model.parameters()) diff --git a/scripts/compare_forward_tokenizers.py b/scripts/compare_forward_tokenizers.py index d719de2..3a6587d 100644 --- a/scripts/compare_forward_tokenizers.py +++ b/scripts/compare_forward_tokenizers.py @@ -49,8 +49,11 @@ wordpiece_vocab_size, ) +DEFAULT_HIDDEN_DIM = 192 +DEFAULT_NUM_CONV_BLOCKS = 4 + RESULT_FIELDS = [ - "tokenizer", "vocab_size", "max_token_len", "pad_layout", "max_len", "seed", + "tokenizer", "vocab_size", "max_token_len", "pad_layout", "hidden_dim", "num_conv_blocks", "max_len", "seed", "test_loss", "test_cosine", "best_val_loss", "epochs_to_best_val", "train_time_sec", "inference_time_sec", "num_parameters", "tokenizer_path", ] @@ -69,6 +72,11 @@ def parse_args(): parser.add_argument("--lr", type=float, default=1e-3) parser.add_argument("--weight-decay", type=float, default=1e-4) parser.add_argument("--dropout", type=float, default=0.2, help="Dropout used in ForwardModel's conv blocks and MLP head.") + parser.add_argument("--hidden-dim", type=int, default=192, help="Width of ForwardModel's conv blocks.") + parser.add_argument( + "--num-conv-blocks", type=int, default=4, + help="Depth: number of dilated conv blocks. Dilations are 2**0, 2**1, ..., 2**(n-1) (default 4 -> 1,2,4,8).", + ) parser.add_argument("--train-fraction", type=float, default=0.8) parser.add_argument("--val-fraction", type=float, default=0.1) parser.add_argument("--num-workers", type=int, default=0) @@ -187,6 +195,8 @@ def run_one(spec, seed, args, logger): output_dim=prepared["merge_stats"]["embedding_dim"], max_len=args.max_len, dropout=args.dropout, + hidden_dim=args.hidden_dim, + dilations=tuple(2**i for i in range(args.num_conv_blocks)), ).to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) @@ -212,9 +222,17 @@ def run_one(spec, seed, args, logger): tokenizer_label = "char" if tokenizer_info["tokenizer_type"] == "char" else f"wordpiece_{vocab_size}" filter_suffix = f"_n{row_max_token_len}" if row_max_token_len is not None else "" layout_suffix = f"_{row_pad_layout}" if row_pad_layout != "end" else "" + # Architecture applies to every tokenizer (char included) - only stamp the filename + # when it differs from ForwardModel's own defaults, so default-architecture runs keep + # producing the exact same filenames as before this option existed (resume stays intact). + arch_suffix = ( + f"_h{args.hidden_dim}_d{args.num_conv_blocks}" + if (args.hidden_dim != DEFAULT_HIDDEN_DIM or args.num_conv_blocks != DEFAULT_NUM_CONV_BLOCKS) + else "" + ) history_dir = Path(args.output_root) / "history" history_dir.mkdir(parents=True, exist_ok=True) - history_path = history_dir / f"{tokenizer_label}{filter_suffix}{layout_suffix}_seed{seed}.json" + history_path = history_dir / f"{tokenizer_label}{filter_suffix}{layout_suffix}{arch_suffix}_seed{seed}.json" save_json(history_path, history) logger.info("wrote per-epoch history path=%s", history_path) @@ -223,6 +241,8 @@ def run_one(spec, seed, args, logger): "vocab_size": tokenizer_info["vocab_size"], "max_token_len": row_max_token_len, "pad_layout": row_pad_layout, + "hidden_dim": args.hidden_dim, + "num_conv_blocks": args.num_conv_blocks, "max_len": args.max_len, "seed": seed, "test_loss": test_metrics["loss"], @@ -246,21 +266,27 @@ def _mean_std(values): def summarize(rows): - """One aggregated row per (tokenizer, vocab_size, max_token_len, pad_layout), mean +/- std across seeds.""" + """One aggregated row per (tokenizer, vocab_size, max_token_len, pad_layout, hidden_dim, + num_conv_blocks), mean +/- std across seeds.""" groups = {} for row in rows: - key = (row["tokenizer"], row["vocab_size"], row["max_token_len"], row.get("pad_layout", "end")) + key = ( + row["tokenizer"], row["vocab_size"], row["max_token_len"], row.get("pad_layout", "end"), + row.get("hidden_dim", DEFAULT_HIDDEN_DIM), row.get("num_conv_blocks", DEFAULT_NUM_CONV_BLOCKS), + ) groups.setdefault(key, []).append(row) summary = [] - for (tokenizer, vocab_size, max_token_len, pad_layout), group_rows in sorted( - groups.items(), key=lambda kv: (kv[0][0], kv[0][1] or 0, kv[0][2] or 0, kv[0][3]) + for (tokenizer, vocab_size, max_token_len, pad_layout, hidden_dim, num_conv_blocks), group_rows in sorted( + groups.items(), key=lambda kv: (kv[0][0], kv[0][1] or 0, kv[0][2] or 0, kv[0][3], kv[0][4], kv[0][5]) ): summary.append({ "tokenizer": tokenizer, "vocab_size": vocab_size, "max_token_len": max_token_len, "pad_layout": pad_layout, + "hidden_dim": hidden_dim, + "num_conv_blocks": num_conv_blocks, "max_len": group_rows[0]["max_len"], "n_seeds": len(group_rows), "test_loss": _mean_std([r["test_loss"] for r in group_rows]), @@ -281,15 +307,17 @@ def _fmt(mean_std, precision=4): def write_markdown_table(summary, path): lines = [ - "| tokenizer | vocab_size | max_token_len | pad_layout | max_len | test_loss | test_cosine | best_val_loss | " + "| tokenizer | vocab_size | max_token_len | pad_layout | hidden_dim | num_conv_blocks | max_len | " + "test_loss | test_cosine | best_val_loss | " "epochs_to_best_val | train_time_sec | inference_time_sec | num_parameters | notes |", - "|---|---|---|---|---|---|---|---|---|---|---|---|---|", + "|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|", ] for row in summary: notes = f"n={row['n_seeds']} seeds" max_token_len = row["max_token_len"] if row["max_token_len"] is not None else "-" lines.append( - f"| {row['tokenizer']} | {row['vocab_size']} | {max_token_len} | {row['pad_layout']} | {row['max_len']} | " + f"| {row['tokenizer']} | {row['vocab_size']} | {max_token_len} | {row['pad_layout']} | " + f"{row['hidden_dim']} | {row['num_conv_blocks']} | {row['max_len']} | " f"{_fmt(row['test_loss'])} | {_fmt(row['test_cosine'])} | {_fmt(row['best_val_loss'])} | " f"{_fmt(row['epochs_to_best_val'], precision=1)} | {_fmt(row['train_time_sec'], precision=1)} | " f"{_fmt(row['inference_time_sec'], precision=3)} | {row['num_parameters']} | {notes} |" @@ -298,17 +326,20 @@ def write_markdown_table(summary, path): def _load_completed_runs(csv_path): - """(tokenizer_path or None, max_token_len, pad_layout, seed) tuples already present in raw_results.csv.""" + """(tokenizer_path or None, max_token_len, pad_layout, hidden_dim, num_conv_blocks, seed) tuples + already present in raw_results.csv.""" if not csv_path.exists(): return set(), [] with open(csv_path, newline="", encoding="utf-8") as f: existing_rows = list(csv.DictReader(f)) - # .get(..., default) covers resuming from a CSV written before --max-token-len/--pad-layout existed + # .get(..., default) covers resuming from a CSV written before these columns existed completed = { ( row["tokenizer_path"] or None, int(row["max_token_len"]) if row.get("max_token_len") else None, row.get("pad_layout") or "end", + int(row["hidden_dim"]) if row.get("hidden_dim") else DEFAULT_HIDDEN_DIM, + int(row["num_conv_blocks"]) if row.get("num_conv_blocks") else DEFAULT_NUM_CONV_BLOCKS, int(row["seed"]), ) for row in existing_rows @@ -318,6 +349,8 @@ def _load_completed_runs(csv_path): row["vocab_size"] = int(row["vocab_size"]) row["max_token_len"] = int(row["max_token_len"]) if row.get("max_token_len") else None row["pad_layout"] = row.get("pad_layout") or "end" + row["hidden_dim"] = int(row["hidden_dim"]) if row.get("hidden_dim") else DEFAULT_HIDDEN_DIM + row["num_conv_blocks"] = int(row["num_conv_blocks"]) if row.get("num_conv_blocks") else DEFAULT_NUM_CONV_BLOCKS row["max_len"] = int(row["max_len"]) row["seed"] = int(row["seed"]) row["test_loss"] = float(row["test_loss"]) @@ -332,11 +365,12 @@ def _load_completed_runs(csv_path): def _spec_key(spec, args): - """(tokenizer_path or None, max_token_len, pad_layout) identity matched against a CSV row.""" + """(tokenizer_path or None, max_token_len, pad_layout, hidden_dim, num_conv_blocks) identity + matched against a CSV row.""" if spec == "char": - return None, None, "end" + return None, None, "end", args.hidden_dim, args.num_conv_blocks path = spec.split(":", 1)[1] - return path, args.max_token_len, args.pad_layout + return path, args.max_token_len, args.pad_layout, args.hidden_dim, args.num_conv_blocks def main(): From 4f234613414cfa7e766d73e7a4851700071ca780 Mon Sep 17 00:00:00 2001 From: maria Date: Fri, 7 Aug 2026 15:04:30 +0300 Subject: [PATCH 52/70] Add architecture-sweep scripts (hidden_dim / num_conv_blocks) Four steps on top of the anchored + max_token_len=9 + individual max_len base: narrower only, shallower only, both together, then narrower still - to isolate width vs depth as separate capacity levers, per the coworker's suggestion to try shrinking the network. --- scripts/run5_all_sequential.sh | 6 ++++ scripts/run5a_hidden128.sh | 53 ++++++++++++++++++++++++++++++ scripts/run5b_blocks3.sh | 53 ++++++++++++++++++++++++++++++ scripts/run5c_hidden128_blocks3.sh | 53 ++++++++++++++++++++++++++++++ scripts/run5d_hidden96_blocks3.sh | 53 ++++++++++++++++++++++++++++++ 5 files changed, 218 insertions(+) create mode 100644 scripts/run5_all_sequential.sh create mode 100644 scripts/run5a_hidden128.sh create mode 100644 scripts/run5b_blocks3.sh create mode 100644 scripts/run5c_hidden128_blocks3.sh create mode 100644 scripts/run5d_hidden96_blocks3.sh diff --git a/scripts/run5_all_sequential.sh b/scripts/run5_all_sequential.sh new file mode 100644 index 0000000..7b93aab --- /dev/null +++ b/scripts/run5_all_sequential.sh @@ -0,0 +1,6 @@ +#!/bin/bash +export PYTHONPATH="$PWD" +bash scripts/run5a_hidden128.sh +bash scripts/run5b_blocks3.sh +bash scripts/run5c_hidden128_blocks3.sh +bash scripts/run5d_hidden96_blocks3.sh diff --git a/scripts/run5a_hidden128.sh b/scripts/run5a_hidden128.sh new file mode 100644 index 0000000..2286101 --- /dev/null +++ b/scripts/run5a_hidden128.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -e +export PYTHONPATH="$PWD" + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --hidden-dim 128 --num-conv-blocks 4 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d4_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 11 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 128 --num-conv-blocks 4 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d4_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 128 --num-conv-blocks 4 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d4_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 9 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 128 --num-conv-blocks 4 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d4_40epochs diff --git a/scripts/run5b_blocks3.sh b/scripts/run5b_blocks3.sh new file mode 100644 index 0000000..1161fed --- /dev/null +++ b/scripts/run5b_blocks3.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -e +export PYTHONPATH="$PWD" + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --hidden-dim 192 --num-conv-blocks 3 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h192_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 11 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 192 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h192_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 192 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h192_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 9 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 192 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h192_d3_40epochs diff --git a/scripts/run5c_hidden128_blocks3.sh b/scripts/run5c_hidden128_blocks3.sh new file mode 100644 index 0000000..2328d51 --- /dev/null +++ b/scripts/run5c_hidden128_blocks3.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -e +export PYTHONPATH="$PWD" + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --hidden-dim 128 --num-conv-blocks 3 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 11 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 128 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 128 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 9 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 128 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d3_40epochs diff --git a/scripts/run5d_hidden96_blocks3.sh b/scripts/run5d_hidden96_blocks3.sh new file mode 100644 index 0000000..2e5ecbf --- /dev/null +++ b/scripts/run5d_hidden96_blocks3.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -e +export PYTHONPATH="$PWD" + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 40 --batch-size 512 --epochs 40 \ + --hidden-dim 96 --num-conv-blocks 3 \ + --seeds 1 \ + --configs char \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h96_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 11 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 96 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_1000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h96_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 10 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 96 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_2000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_3000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_4000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_5000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_6000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_7000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_8000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_9000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_10000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_12000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h96_d3_40epochs + +python scripts/compare_forward_tokenizers.py \ + --airr-path data/raw/trb_background_100k.tsv \ + --embeddings-path data/raw/trb_background_embeddings.parquet \ + --locus beta --max-len 9 --batch-size 512 --epochs 40 \ + --max-token-len 9 --pad-layout anchored \ + --hidden-dim 96 --num-conv-blocks 3 \ + --seeds 1 \ + --configs wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_15000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_17000/tokenizer.json \ + wordpiece:artifacts/tokenizers_2026-08-01_fine_grid/wordpiece_vocab_20000/tokenizer.json \ + --output-root artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h96_d3_40epochs From 16df0810d5f3555a036526b96183a44ce469553c Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Sat, 8 Aug 2026 17:38:20 +0300 Subject: [PATCH 53/70] Add extra-seed array, end-to-end speed benchmark and a significance test The pretraining question was unanswerable from three seeds: the IRRM arms spread by 0.03-0.06 RMSE across seeds, larger than the scratch-vs-pretrained difference itself. pgen_seeds_array adds seven seeds for those two arms on the full split, and collect_pgen now reports Welch's t-test alongside the difference of means. benchmark_speed times the full sequence-to-prediction path for every arm on one device. The speeds recorded during training covered only the trained head, which omits the encoder for the frozen arms - the dominant cost - and head and encoder timings came from different machines, so they could not be combined. Co-Authored-By: Claude Opus 5 --- benchmark/benchmark_speed.py | 200 ++++++++++++++++++++++++ benchmark/collect_pgen.py | 55 +++++-- benchmark/slurm/pgen_seeds_array.sbatch | 81 ++++++++++ 3 files changed, 324 insertions(+), 12 deletions(-) create mode 100644 benchmark/benchmark_speed.py create mode 100644 benchmark/slurm/pgen_seeds_array.sbatch diff --git a/benchmark/benchmark_speed.py b/benchmark/benchmark_speed.py new file mode 100644 index 0000000..3b44436 --- /dev/null +++ b/benchmark/benchmark_speed.py @@ -0,0 +1,200 @@ +"""End-to-end inference speed for every Pgen arm, measured on one device. + +The per-arm speeds recorded during training cover only the trained head. For the frozen +arms that omits the encoder, which is the dominant cost and the reason those numbers +looked orders of magnitude faster than they are in practice. Encoder timings were also +collected on a different machine than the heads, so the two cannot be combined. + +This script times the full path a new sequence actually travels — string in, log10 Pgen +out — for every arm on whichever device is requested, so the quality-versus-speed +comparison rests on one set of measurements. +""" + +import argparse +import json +import time +import warnings +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.pgen_model import PgenModel +from irrm_codec.tokenization import PAD_ID, encode +from irrm_codec.utils import setup_logging + +ARMS = ("irrm", "tfidf_ridge", "sceptr_mlp", "tcr_bert_mlp", "esm2_8m_mlp") + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--output-dir", default="results/pgen") + p.add_argument("--device", default="auto", choices=("auto", "cpu", "cuda")) + p.add_argument("--n-sequences", type=int, default=5000) + p.add_argument("--batch-size", type=int, default=256) + p.add_argument("--repeats", type=int, default=3) + p.add_argument("--threads", type=int, default=8) + p.add_argument("--arms", nargs="+", default=list(ARMS), choices=list(ARMS)) + return p.parse_args() + + +def timed(fn, sequences, repeats): + """Fastest of several passes, so a stray scheduling hiccup does not set the number.""" + fn(sequences[: min(64, len(sequences))]) # warm up lazy initialization + best = float("inf") + for _ in range(repeats): + started = time.perf_counter() + fn(sequences) + best = min(best, time.perf_counter() - started) + return { + "sequences_per_second": len(sequences) / best, + "ms_per_sequence": best / len(sequences) * 1000, + "seconds_total": best, + } + + +def make_irrm(args, device): + """Tokenize and run the sequence encoder: the whole pipeline for this arm.""" + model = PgenModel(max_len=40).to(device).eval() + + @torch.no_grad() + def run(sequences): + for start in range(0, len(sequences), args.batch_size): + batch = sequences[start : start + args.batch_size] + tokens = torch.tensor([encode(s, max_len=40) for s in batch], dtype=torch.long).to(device) + model(tokens, tokens.ne(PAD_ID)) + if device.type == "cuda": + torch.cuda.synchronize() + + return run + + +def make_tfidf_ridge(args, device, train_sequences, train_targets): + from sklearn.feature_extraction.text import TfidfVectorizer + from sklearn.linear_model import Ridge + + vectorizer = TfidfVectorizer(analyzer="char", ngram_range=(1, 3)) + features = vectorizer.fit_transform(train_sequences) + model = Ridge(alpha=1.0).fit(features, train_targets) + + def run(sequences): + model.predict(vectorizer.transform(sequences)) + + return run + + +def make_frozen(args, device, representation): + """Encoder plus the regression head, which is what predicting a new sequence costs.""" + from benchmark.train_pgen_arm import RegressionHead + + if representation == "sceptr_mlp": + import sceptr + + head = RegressionHead(64).to(device).eval() + + def encode_batch(batch): + frame = pd.DataFrame({"TRBV": ["TRBV20-1"] * len(batch), "CDR3B": batch, "TRBJ": ["TRBJ2-7"] * len(batch)}) + return torch.from_numpy(sceptr.calc_vector_representations(frame)) + + elif representation == "esm2_8m_mlp": + import esm + + encoder, alphabet = esm.pretrained.esm2_t6_8M_UR50D() + encoder = encoder.to(device).eval() + converter = alphabet.get_batch_converter() + head = RegressionHead(encoder.embed_dim).to(device).eval() + last = encoder.num_layers + + def encode_batch(batch): + _, _, tokens = converter([(str(i), s) for i, s in enumerate(batch)]) + tokens = tokens.to(device) + states = encoder(tokens, repr_layers=[last])["representations"][last] + keep = ( + (tokens != alphabet.padding_idx) + & (tokens != alphabet.cls_idx) + & (tokens != alphabet.eos_idx) + ).unsqueeze(-1).to(states.dtype) + return (states * keep).sum(1) / keep.sum(1).clamp_min(1e-9) + + else: + from transformers import AutoModel, AutoTokenizer + + tokenizer = AutoTokenizer.from_pretrained("wukevin/tcr-bert") + encoder = AutoModel.from_pretrained("wukevin/tcr-bert").to(device).eval() + head = RegressionHead(encoder.config.hidden_size).to(device).eval() + special = set(tokenizer.all_special_ids) + + def encode_batch(batch): + enc = tokenizer([" ".join(s) for s in batch], return_tensors="pt", padding=True) + enc = {k: v.to(device) for k, v in enc.items()} + states = encoder(**enc).last_hidden_state + keep = enc["attention_mask"].bool() + for token_id in special: + keep &= enc["input_ids"] != token_id + keep = keep.unsqueeze(-1).to(states.dtype) + return (states * keep).sum(1) / keep.sum(1).clamp_min(1e-9) + + @torch.no_grad() + def run(sequences): + for start in range(0, len(sequences), args.batch_size): + head(encode_batch(sequences[start : start + args.batch_size]).to(device)) + if device.type == "cuda": + torch.cuda.synchronize() + + return run + + +def main(): + args = parse_args() + warnings.filterwarnings("ignore") + torch.set_num_threads(args.threads) + + device = torch.device( + ("cuda" if torch.cuda.is_available() else "cpu") if args.device == "auto" else args.device + ) + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / f"benchmark_speed_{device.type}.log") + + frame = pd.read_parquet(Path(args.dataset_dir) / "dataset.parquet") + test_rows = pd.read_csv(Path(args.dataset_dir) / "manifests" / "test.tsv", sep="\t")["row_index"] + sequences = frame.junction_aa.iloc[test_rows].tolist()[: args.n_sequences] + train_rows = pd.read_csv(Path(args.dataset_dir) / "manifests" / "train_10k.tsv", sep="\t")["row_index"] + log.info("device=%s sequences=%d batch=%d", device, len(sequences), args.batch_size) + + builders = { + "irrm": lambda: make_irrm(args, device), + "tfidf_ridge": lambda: make_tfidf_ridge( + args, device, + frame.junction_aa.iloc[train_rows].tolist(), + frame.log10_pgen_1mm.to_numpy()[train_rows], + ), + "sceptr_mlp": lambda: make_frozen(args, device, "sceptr_mlp"), + "tcr_bert_mlp": lambda: make_frozen(args, device, "tcr_bert_mlp"), + "esm2_8m_mlp": lambda: make_frozen(args, device, "esm2_8m_mlp"), + } + + results = [] + for name in args.arms: + log.info("timing %s", name) + measurement = timed(builders[name](), sequences, args.repeats) + results.append({"arm": name, "device": device.type, **measurement}) + log.info( + "%-13s %9.1f seq/s %7.3f ms/seq", + name, measurement["sequences_per_second"], measurement["ms_per_sequence"], + ) + + table = pd.DataFrame(results).sort_values("sequences_per_second", ascending=False) + path = output_dir / f"speed_end_to_end_{device.type}.csv" + table.to_csv(path, index=False) + + log.info("=" * 56) + for _, row in table.iterrows(): + log.info("%-13s %9.1f seq/s %7.3f ms/seq", row.arm, row.sequences_per_second, row.ms_per_sequence) + log.info("wrote %s", path) + + +if __name__ == "__main__": + main() diff --git a/benchmark/collect_pgen.py b/benchmark/collect_pgen.py index cd10108..d2f1db5 100644 --- a/benchmark/collect_pgen.py +++ b/benchmark/collect_pgen.py @@ -15,6 +15,7 @@ from pathlib import Path import pandas as pd +from scipy import stats METRICS = ("rmse", "mae", "r2", "pearson_r", "spearman_rho", "bias") SUBSET_ORDER = {"1k": 0, "10k": 1, "all": 2} @@ -105,16 +106,44 @@ def to_markdown(summary): return "\n".join(blocks) + "\n" -def pretraining_delta(summary): - """RMSE improvement from IRRM pretraining, per target and training size.""" - pivot = summary[summary.arm.isin(("irrm_scratch", "irrm_pretrained"))].pivot_table( - index=["target", "train_subset", "subset_order"], columns="arm", values="rmse_mean" - ) - if not {"irrm_scratch", "irrm_pretrained"}.issubset(pivot.columns): +def pretraining_delta(runs): + """Does IRRM pretraining help? RMSE difference with a significance test. + + Seed spread for these two arms is comparable to the effect being measured, so the + difference of means alone cannot answer the question. Welch's t-test does not assume + the two arms have equal variance, which they do not. + """ + rows = [] + for (target, subset, order), group in runs.groupby(["target", "train_subset", "subset_order"]): + scratch = group.loc[group.arm == "irrm_scratch", "rmse"].to_numpy() + pretrained = group.loc[group.arm == "irrm_pretrained", "rmse"].to_numpy() + if len(scratch) < 2 or len(pretrained) < 2: + continue + # Lower RMSE is better, so a positive delta means pretraining won. + delta = scratch.mean() - pretrained.mean() + _, p_value = stats.ttest_ind(scratch, pretrained, equal_var=False) + rows.append( + { + "target": target, + "train_subset": subset, + "subset_order": order, + "n_scratch": len(scratch), + "n_pretrained": len(pretrained), + "irrm_scratch": scratch.mean(), + "irrm_pretrained": pretrained.mean(), + "rmse_delta": delta, + "relative_improvement": delta / scratch.mean(), + "p_value": p_value, + "verdict": ( + "no detectable effect" + if p_value >= 0.05 + else ("pretraining helps" if delta > 0 else "pretraining hurts") + ), + } + ) + if not rows: return None - pivot["rmse_delta"] = pivot["irrm_scratch"] - pivot["irrm_pretrained"] - pivot["relative_improvement"] = pivot["rmse_delta"] / pivot["irrm_scratch"] - return pivot.reset_index().sort_values(["target", "subset_order"]) + return pd.DataFrame(rows).sort_values(["target", "subset_order"]) def main(): @@ -130,13 +159,15 @@ def main(): (output_dir / "pgen_summary.md").write_text(to_markdown(summary), encoding="utf-8") print(f"runs: {len(runs)} arms: {runs.arm.nunique()} targets: {runs.target.nunique()}") - delta = pretraining_delta(summary) + delta = pretraining_delta(runs) if delta is not None: delta.drop(columns=["subset_order"]).to_csv(output_dir / "pretraining_delta.csv", index=False) print("\nDoes IRRM pretraining help? (positive rmse_delta means pretraining wins)") print( - delta[["target", "train_subset", "irrm_scratch", "irrm_pretrained", "rmse_delta", "relative_improvement"]] - .to_string(index=False) + delta[ + ["target", "train_subset", "n_scratch", "n_pretrained", "irrm_scratch", + "irrm_pretrained", "rmse_delta", "p_value", "verdict"] + ].to_string(index=False) ) print(f"\nwrote {output_dir}/pgen_runs.csv, pgen_summary.csv, pgen_summary.md") diff --git a/benchmark/slurm/pgen_seeds_array.sbatch b/benchmark/slurm/pgen_seeds_array.sbatch new file mode 100644 index 0000000..fdaa9f2 --- /dev/null +++ b/benchmark/slurm/pgen_seeds_array.sbatch @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# Issue 3, follow-up: extra seeds for the two IRRM arms on the full training split. +# +# The main array ran three seeds per arm. For the frozen-embedding arms that is plenty +# (their RMSE spread across seeds is about 0.005), but the IRRM arms train a full encoder +# and spread by 0.03-0.06 — larger than the scratch-vs-pretrained difference they are +# meant to measure. Seven more seeds take the standard error from 0.033 to 0.018 and make +# the pretraining question answerable. +# +# Only the arms and the split where the comparison matters: 2 arms x 2 targets x 7 seeds. +# Results land in the same output directory, so collect_pgen picks them up with no changes. +# +# mkdir -p /mnt/tank/scratch/mpodsytnik/irrm-codec/logs +# sbatch benchmark/slurm/pgen_seeds_array.sbatch + +#SBATCH --job-name=irrm-pgen-seeds +#SBATCH --partition=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=24G +#SBATCH --time=01:00:00 +#SBATCH --array=0-27%2 +#SBATCH --output=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.out +#SBATCH --error=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.err + +set -euo pipefail + +SCRATCH="${SCRATCH:-/mnt/tank/scratch/mpodsytnik/irrm-codec}" +REPO="${REPO:-/nfs/home/mpodsytnik/irrm-codec}" +CONDA_ROOT="${CONDA_ROOT:-/mnt/tank/scratch/mpodsytnik/miniconda3}" +CONDA_ENV="${CONDA_ENV:-irrm-codec}" + +DATASET_DIR="${DATASET_DIR:-$SCRATCH/data/benchmark/trb}" +REPRESENTATIONS_DIR="${REPRESENTATIONS_DIR:-$SCRATCH/data/benchmark/trb/representations}" +PRETRAINED_CHECKPOINT="${PRETRAINED_CHECKPOINT:-$SCRATCH/artifacts/benchmark/forward_encoder/best.pt}" +OUTPUT_DIR="${OUTPUT_DIR:-$SCRATCH/artifacts/benchmark/pgen}" + +TRAIN_SUBSET="${TRAIN_SUBSET:-all}" +EPOCHS="${EPOCHS:-60}" +BATCH_SIZE="${BATCH_SIZE:-256}" +PATIENCE="${PATIENCE:-8}" + +# Seeds 42-44 already ran in the main array; these continue the sequence. +CONFIGS=() +for target in log10_pgen log10_pgen_1mm; do + for arm in irrm_scratch irrm_pretrained; do + for seed in 45 46 47 48 49 50 51; do + CONFIGS+=("$arm $target $seed") + done + done +done + +if [ "${SLURM_ARRAY_TASK_ID:-0}" -ge "${#CONFIGS[@]}" ]; then + echo "task ${SLURM_ARRAY_TASK_ID} is past the end of the ${#CONFIGS[@]}-run list" >&2 + exit 1 +fi +read -r ARM TARGET SEED <<< "${CONFIGS[${SLURM_ARRAY_TASK_ID:-0}]}" + +mkdir -p "$OUTPUT_DIR" + +source "$CONDA_ROOT/bin/activate" +conda activate "$CONDA_ENV" + +echo "job=${SLURM_JOB_ID:-local} task=${SLURM_ARRAY_TASK_ID:-0} node=${SLURMD_NODENAME:-?}" +echo "arm=$ARM target=$TARGET subset=$TRAIN_SUBSET seed=$SEED (${#CONFIGS[@]} runs total)" + +cd "$REPO" +export PYTHONUNBUFFERED=1 +srun python -m benchmark.train_pgen_arm \ + --arm "$ARM" \ + --target "$TARGET" \ + --train-subset "$TRAIN_SUBSET" \ + --seed "$SEED" \ + --dataset-dir "$DATASET_DIR" \ + --representations-dir "$REPRESENTATIONS_DIR" \ + --pretrained-checkpoint "$PRETRAINED_CHECKPOINT" \ + --output-dir "$OUTPUT_DIR" \ + --epochs "$EPOCHS" \ + --batch-size "$BATCH_SIZE" \ + --patience "$PATIENCE" \ + --threads "${SLURM_CPUS_PER_TASK:-4}" From 53ae4194b77d0262029ed414f0fd987c9020edcb Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Sat, 8 Aug 2026 18:13:41 +0300 Subject: [PATCH 54/70] Call training directly instead of through an inner srun --- benchmark/slurm/pgen_array.sbatch | 5 ++++- benchmark/slurm/pgen_seeds_array.sbatch | 5 ++++- benchmark/slurm/reconstruction_array.sbatch | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/benchmark/slurm/pgen_array.sbatch b/benchmark/slurm/pgen_array.sbatch index 409e091..8a7ba39 100644 --- a/benchmark/slurm/pgen_array.sbatch +++ b/benchmark/slurm/pgen_array.sbatch @@ -72,7 +72,10 @@ nvidia-smi --query-gpu=name,memory.total --format=csv,noheader || true cd "$REPO" # Slurm redirects stdout to a file, where Python block-buffers by default. export PYTHONUNBUFFERED=1 -srun python -m benchmark.train_pgen_arm \ +# Called directly rather than through srun: the batch task already holds its own +# allocation, and an inner step has to request the GPU again, which fails outright when +# the per-user GPU quota is busy elsewhere. +python -m benchmark.train_pgen_arm \ --arm "$ARM" \ --target "$TARGET" \ --train-subset "$SUBSET" \ diff --git a/benchmark/slurm/pgen_seeds_array.sbatch b/benchmark/slurm/pgen_seeds_array.sbatch index fdaa9f2..8608782 100644 --- a/benchmark/slurm/pgen_seeds_array.sbatch +++ b/benchmark/slurm/pgen_seeds_array.sbatch @@ -66,7 +66,10 @@ echo "arm=$ARM target=$TARGET subset=$TRAIN_SUBSET seed=$SEED (${#CONFIGS[@]} ru cd "$REPO" export PYTHONUNBUFFERED=1 -srun python -m benchmark.train_pgen_arm \ +# Called directly rather than through srun: the batch task already holds its own +# allocation, and an inner step has to request the GPU again, which fails outright when +# the per-user GPU quota is busy elsewhere. +python -m benchmark.train_pgen_arm \ --arm "$ARM" \ --target "$TARGET" \ --train-subset "$TRAIN_SUBSET" \ diff --git a/benchmark/slurm/reconstruction_array.sbatch b/benchmark/slurm/reconstruction_array.sbatch index 6eecf76..80ccb54 100644 --- a/benchmark/slurm/reconstruction_array.sbatch +++ b/benchmark/slurm/reconstruction_array.sbatch @@ -64,7 +64,10 @@ cd "$REPO" # Slurm redirects stdout to a file, where Python block-buffers by default and the log # appears only in bursts. Unbuffered output keeps the .out file usable for monitoring. export PYTHONUNBUFFERED=1 -srun python -m benchmark.train_decoder \ +# Called directly rather than through srun: the batch task already holds its own +# allocation, and an inner step has to request the GPU again, which fails outright when +# the per-user GPU quota is busy elsewhere. +python -m benchmark.train_decoder \ --dataset-dir "$DATASET_DIR" \ --bottleneck-dir "$BOTTLENECK_DIR" \ --output-dir "$OUTPUT_DIR" \ From 1950f3b8d1363ab625a10a1c8e7a8fe745a1146f Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Sat, 8 Aug 2026 19:07:57 +0300 Subject: [PATCH 55/70] Extend the extra-seed array to the 1k and 10k splits --- benchmark/slurm/pgen_seeds_array.sbatch | 30 ++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/benchmark/slurm/pgen_seeds_array.sbatch b/benchmark/slurm/pgen_seeds_array.sbatch index 8608782..6d0b5e3 100644 --- a/benchmark/slurm/pgen_seeds_array.sbatch +++ b/benchmark/slurm/pgen_seeds_array.sbatch @@ -7,11 +7,15 @@ # meant to measure. Seven more seeds take the standard error from 0.033 to 0.018 and make # the pretraining question answerable. # -# Only the arms and the split where the comparison matters: 2 arms x 2 targets x 7 seeds. -# Results land in the same output directory, so collect_pgen picks them up with no changes. +# All three training sizes, so the low-data question gets the same statistical treatment +# as the full-data one: 2 arms x 2 targets x 3 subsets x 7 seeds. Results land in the same +# output directory, so collect_pgen picks them up with no changes. # # mkdir -p /mnt/tank/scratch/mpodsytnik/irrm-codec/logs # sbatch benchmark/slurm/pgen_seeds_array.sbatch +# +# To repeat only some of them, override SUBSETS: +# sbatch --export=ALL,SUBSETS="1k 10k" benchmark/slurm/pgen_seeds_array.sbatch #SBATCH --job-name=irrm-pgen-seeds #SBATCH --partition=gpu @@ -19,7 +23,7 @@ #SBATCH --cpus-per-task=4 #SBATCH --mem=24G #SBATCH --time=01:00:00 -#SBATCH --array=0-27%2 +#SBATCH --array=0-55%2 #SBATCH --output=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.out #SBATCH --error=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%A_%a.err @@ -35,7 +39,9 @@ REPRESENTATIONS_DIR="${REPRESENTATIONS_DIR:-$SCRATCH/data/benchmark/trb/represen PRETRAINED_CHECKPOINT="${PRETRAINED_CHECKPOINT:-$SCRATCH/artifacts/benchmark/forward_encoder/best.pt}" OUTPUT_DIR="${OUTPUT_DIR:-$SCRATCH/artifacts/benchmark/pgen}" -TRAIN_SUBSET="${TRAIN_SUBSET:-all}" +# "all" is excluded by default because it was covered by an earlier submission of this +# same file; add it back through SUBSETS and widen --array to match if it is ever needed. +SUBSETS="${SUBSETS:-1k 10k}" EPOCHS="${EPOCHS:-60}" BATCH_SIZE="${BATCH_SIZE:-256}" PATIENCE="${PATIENCE:-8}" @@ -43,18 +49,22 @@ PATIENCE="${PATIENCE:-8}" # Seeds 42-44 already ran in the main array; these continue the sequence. CONFIGS=() for target in log10_pgen log10_pgen_1mm; do - for arm in irrm_scratch irrm_pretrained; do - for seed in 45 46 47 48 49 50 51; do - CONFIGS+=("$arm $target $seed") + for subset in $SUBSETS; do + for arm in irrm_scratch irrm_pretrained; do + for seed in 45 46 47 48 49 50 51; do + CONFIGS+=("$arm $target $subset $seed") + done done done done +# Exit cleanly rather than failing, so an array wider than the config list leaves no +# spurious FAILED tasks in the accounting record. if [ "${SLURM_ARRAY_TASK_ID:-0}" -ge "${#CONFIGS[@]}" ]; then - echo "task ${SLURM_ARRAY_TASK_ID} is past the end of the ${#CONFIGS[@]}-run list" >&2 - exit 1 + echo "task ${SLURM_ARRAY_TASK_ID} is past the end of the ${#CONFIGS[@]}-run list; nothing to do" + exit 0 fi -read -r ARM TARGET SEED <<< "${CONFIGS[${SLURM_ARRAY_TASK_ID:-0}]}" +read -r ARM TARGET TRAIN_SUBSET SEED <<< "${CONFIGS[${SLURM_ARRAY_TASK_ID:-0}]}" mkdir -p "$OUTPUT_DIR" From ddcb927f2b866a8e8850a2af9c1d5cede1f0cbd6 Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Sat, 8 Aug 2026 23:58:49 +0300 Subject: [PATCH 56/70] Add Pgen results and limitations to the report --- REPORT.md | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 182 insertions(+), 11 deletions(-) diff --git a/REPORT.md b/REPORT.md index 0ab2718..cbb63f2 100644 --- a/REPORT.md +++ b/REPORT.md @@ -13,7 +13,7 @@ task heads are trained. | --- | --- | --- | | 1 | train/validation/test splits | done | | 2 | sequence reconstruction | done | -| 3 | Pgen prediction | pending | +| 3 | Pgen prediction | done | ## 1. Dataset @@ -163,20 +163,191 @@ Reproduce with `benchmark/slurm/reconstruction_array.sbatch`, then ## 3. Pgen prediction -Pending. Both targets are cached and the splits are fixed, so the remaining work is the -model arms themselves. +Six arms, both targets, three training sizes. The three frozen-embedding arms share one +regression head (512 → 256 → 1) and one training configuration, so only the representation +differs between them. The two IRRM arms differ only in initialization. Ridge is +deterministic and selects its penalty on validation, which is that arm's equivalent of +early stopping. + +Targets are standardized on train statistics and mapped back before any metric, so a +freshly initialized network does not spend its first epochs locating an offset near −6.5 +that Ridge fits for free. Reported errors are in log10 units. + +Neural arms ran ten seeds each on every cell — three from the main sweep plus seven more, +added because the IRRM arms spread by 0.04–0.08 RMSE across seeds, which is larger than +the effect they are meant to measure. 180 runs in total. + +### Results on the full training split + +Mean ± standard deviation over seeds, on the held-out test split. + +**`log10_pgen_1mm`, train = 79,730** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | **0.2098** ± 0.0493 | 0.1262 | 0.9822 | 0.9928 | 0.9909 | +0.0606 | 232 | 1575 | +| irrm_scratch | 0.2653 ± 0.0376 | 0.1730 | 0.9724 | 0.9894 | 0.9923 | +0.0609 | 135 | 1574 | +| tcr_bert_mlp | 0.3115 ± 0.0073 | 0.2002 | 0.9627 | 0.9813 | 0.9852 | +0.0028 | 62 | 1671 | +| sceptr_mlp | 0.4560 ± 0.0080 | 0.2636 | 0.9200 | 0.9599 | 0.9754 | +0.0484 | 53 | 1197 | +| esm2_8m_mlp | 0.4794 ± 0.0092 | 0.2868 | 0.9116 | 0.9561 | 0.9721 | +0.0650 | 68 | 1301 | +| tfidf_ridge | 0.5542 | 0.3671 | 0.8819 | 0.9391 | 0.9566 | +0.0035 | 10 | 716 | + +**`log10_pgen`, train = 79,730** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | **0.2909** ± 0.0474 | 0.1846 | 0.9753 | 0.9904 | 0.9876 | +0.1154 | 205 | 1582 | +| irrm_scratch | 0.3358 ± 0.0713 | 0.2225 | 0.9666 | 0.9898 | 0.9904 | +0.0998 | 146 | 1569 | +| tcr_bert_mlp | 0.4104 ± 0.0065 | 0.2641 | 0.9520 | 0.9761 | 0.9794 | +0.0299 | 64 | 1669 | +| sceptr_mlp | 0.5833 ± 0.0035 | 0.3536 | 0.9031 | 0.9524 | 0.9649 | +0.0871 | 67 | 1200 | +| esm2_8m_mlp | 0.6031 ± 0.0126 | 0.3811 | 0.8964 | 0.9475 | 0.9599 | +0.0433 | 66 | 1300 | +| tfidf_ridge | 0.6210 | 0.4145 | 0.8901 | 0.9435 | 0.9563 | +0.0087 | 9 | 719 | + +The ordering is identical on both targets and at every training size: the two IRRM arms +lead, TCR-BERT is the best frozen representation, then SCEPTR and ESM-2, with Ridge last. +Per-size tables are in `results/pgen/pgen_summary.md`. + +For reference, the committed pgen notebook reports RMSE 0.5914, R² 0.9437 and Pearson +0.9874 on `log10_pgen_1mm`. The pretrained arm here reaches RMSE 0.2098, R² 0.9822 and +Pearson 0.9928 on a different split of the same data. + +### Does IRRM pretraining improve Pgen prediction? + +Welch's t-test on RMSE across ten seeds per arm. A positive delta means pretraining won. + +| target | train | irrm_scratch | irrm_pretrained | Δ RMSE | p | +| --- | --- | ---: | ---: | ---: | ---: | +| log10_pgen | 1k | 0.8379 | 0.8550 | −0.017 | 0.527 | +| log10_pgen | 10k | 0.5052 | 0.5422 | −0.037 | 0.157 | +| log10_pgen | all | 0.3358 | 0.2909 | +0.045 | 0.118 | +| log10_pgen_1mm | 1k | 0.6315 | 0.6569 | −0.025 | 0.307 | +| log10_pgen_1mm | 10k | 0.3957 | 0.4087 | −0.013 | 0.500 | +| **log10_pgen_1mm** | **all** | 0.2653 | **0.2098** | **+0.056** | **0.012** | + +**Yes, but narrowly: only on `log10_pgen_1mm` and only with the full training set**, where +pretraining cuts RMSE by 20.9%. Every other cell is indistinguishable from zero, and in +three of the four smaller-data cells the sign is negative. + +Two things support the one positive result beyond its p-value. It replicated: an earlier +independent run of the same configuration gave Δ = +0.049 at p = 0.017, and the arms were +retrained from scratch in between. And its direction is consistent with the mechanism — +TCRemP encodes similarity to a panel of reference receptors, and `Pgen_1mm` sums +probability over a sequence's single-mismatch neighbours. Both are neighbourhood +quantities, whereas exact `Pgen` is a property of one sequence alone, and that is the +target where transfer does nothing (p = 0.118). + +Against it: six comparisons were made. A Bonferroni correction over all six would require +p < 0.008, which this result does not meet. Restricting to the two full-data comparisons, +which are the primary ones, the threshold is p < 0.025 and it does. The finding should be +read as suggestive and mechanistically plausible rather than firmly established. + +### Is the advantage larger in the low-data regime? + +**No — the opposite.** The effect appears only at 79,730 training sequences and is absent +at 1k and 10k, where the sign is negative on three of four cells. This inverts the usual +expectation that pretraining pays off most when labelled data is scarce. + +The bias column shows the mechanism. At 1k the pretrained arm carries bias +0.31 and ++0.24 against +0.16 and +0.15 for the from-scratch arm. The transferred encoder was fitted +to predict 9000-dimensional TCRemP vectors, and its features push predictions in a +systematic direction that a small training set cannot correct. With enough data the head +overcomes it and the transferred features start to pay. + +### Quality against speed + +End-to-end inference: string in, log10 Pgen out, including tokenization or encoder passes, +measured on one device at a time over 5,000 test sequences. + +| arm | GPU (GTX 1080 Ti) | CPU (Xeon Gold, 8 threads) | RMSE (1mm, all) | +| --- | ---: | ---: | ---: | +| tfidf_ridge | 86,661 seq/s | 82,842 seq/s | 0.5542 | +| **irrm** | **64,814 seq/s** | **3,777 seq/s** | **0.2098** | +| esm2_8m_mlp | 9,393 seq/s | 813 seq/s | 0.4794 | +| tcr_bert_mlp | 4,039 seq/s | 216 seq/s | 0.3115 | +| sceptr_mlp | 2,495 seq/s | 1,265 seq/s | 0.4560 | + +**IRRM dominates all three pretrained encoders on both axes at once** — 4.6× to 17.5× +faster on CPU, 6.9× to 26× on GPU, and lower RMSE than any of them. There is no trade-off +to make against the large frozen encoders; they are simply worse in both respects, because +their per-sequence encoding cost dwarfs the regression head that follows it. + +The real trade-off is against Ridge, which is 1.3× faster on GPU and 22× on CPU while +carrying 2.6× the error. Ridge is the right choice when throughput matters more than +precision; IRRM when it does not. + +Caveat on the SCEPTR row: it is the slowest arm on GPU yet mid-pack on CPU, which suggests +its library evaluates on CPU unless `sceptr.enable_hardware_acceleration()` is called, +which this benchmark does not do. Its GPU figure should be read as a CPU computation plus +transfer overhead, not as a GPU measurement. + +### Against OLGA + +The practical argument for a neural Pgen predictor is speed against the exact calculation. +Measured on the same 8-core laptop CPU, so the two numbers are directly comparable: + +| | sequences/second | IRRM speedup | +| --- | ---: | ---: | +| IRRM | 1,969 | — | +| OLGA exact | 42.7 | **46×** | +| OLGA 1-mismatch | 2.7 | **729×** | + +On the cluster GPU IRRM reaches 64,814 sequences/second, but OLGA was not benchmarked on +that node, so the laptop comparison is the honest one to quote. -Measured reference point for the speed question: exact OLGA Pgen runs at **43 -sequences/second** per core (23.4 ms/sequence), and `Pgen_1mm` at **2.7/second** -(370 ms/sequence). The committed pgen notebook reports about 11,000 sequences/second for -the neural predictor on CPU, so the speed argument is roughly two orders of magnitude — -this benchmark will quantify it against the frozen-embedding baselines. +### Where IRRM-CODEC wins and loses + +**Wins: accuracy at every training size, on both targets.** IRRM leads all four baselines +in all six cells. On the full split it reaches R² 0.982 and Pearson 0.993 for +`log10_pgen_1mm`, against 0.963 for the best frozen representation. + +**Wins: the quality–speed trade-off against pretrained encoders.** Faster and more accurate +than frozen ESM-2, TCR-BERT and SCEPTR simultaneously. For this task the large pretrained +encoders contribute nothing. + +**Wins: two to three orders of magnitude over OLGA**, which is the argument the model exists +to make. + +**Partial: pretraining helps only in one corner.** The sequence-to-TCRemP initialization +pays off on `log10_pgen_1mm` at full data (−20.9% RMSE) and nowhere else. Anyone adopting +it should expect a modest, target-specific gain, not a general one. + +**Loses: seed stability.** The IRRM arms vary by 0.04–0.08 RMSE across seeds where the +frozen arms vary by 0.004–0.015 — roughly tenfold. Validation loss oscillates rather than +descending smoothly, so early stopping fires at inconsistent epochs. The learning rate is +constant at 1e-3 with no decay; a schedule would likely reduce this and is the clearest +next improvement. + +**Loses: throughput against a trivial baseline.** TF-IDF + Ridge is 22× faster on CPU. If +an application needs coarse Pgen estimates at maximum rate, k-mers remain the right tool. + +Reproduce with `benchmark/slurm/pgen_array.sbatch` and +`benchmark/slurm/pgen_seeds_array.sbatch`, then `python -m benchmark.collect_pgen` and +`python -m benchmark.benchmark_speed`. + +## Limitations + +- **Mean pooling** for ESM-2 and TCR-BERT discards positional information, which penalizes + them most on reconstruction. A CLS token or per-position features would likely score + higher. +- **Aligned one-hot is not a peer baseline** in section 2: it encodes the target + reversibly, so it bounds the task rather than competing in it. +- **GPU training is not bit-reproducible.** Re-running a configuration with the same seed + gives slightly different results, because cuDNN selects algorithms at runtime and some + backward kernels accumulate non-deterministically. Conclusions here rest on ten-seed + means rather than single runs. +- **One chain, one species.** Everything is human TRB. Nothing here shows the ordering + holds for TRA or for other loci. +- **One bottleneck width.** Reconstruction was compared at 64 dimensions. Projections at + 32 and 128 are cached in `data/benchmark/trb/bottleneck/` but were not trained. +- **Six statistical comparisons** were made for the pretraining question; only one is + significant, and it does not survive a Bonferroni correction over all six. ## Environment -Results in section 2 were produced on the ctlab Slurm cluster: GTX 1080 Ti, -torch 2.6.0+cu124, Python 3.11. Section 1 timings are from an 8-core CPU (Ryzen 7 8845HS). -Peak-memory figures for section 3 will be resident set size via `psutil`, not +Sections 2 and 3 were produced on the ctlab Slurm cluster: GTX 1080 Ti, torch 2.6.0+cu124, +Python 3.11. Section 1 timings and the OLGA comparison are from an 8-core CPU +(Ryzen 7 8845HS); the CPU speed column in section 3 is from a cluster Xeon Gold node. +Peak memory is peak resident set size via `getrusage`, not `torch.cuda.max_memory_allocated`, and the device is recorded with every measurement. Encoder checkpoints: `esm2_t6_8M_UR50D` (fair-esm), `wukevin/tcr-bert` (HuggingFace), From 54acc94e593e09d70fa8cd202c99961b83239ada Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Sun, 9 Aug 2026 00:06:14 +0300 Subject: [PATCH 57/70] Add cosine LR schedule and a dependency chain for the Pgen rerun --- benchmark/slurm/forward_encoder.sbatch | 42 ++++++++++++++++++++++ benchmark/slurm/pgen_array.sbatch | 3 +- benchmark/slurm/pgen_seeds_array.sbatch | 3 +- benchmark/slurm/submit_pgen_all.sh | 48 +++++++++++++++++++++++++ benchmark/train_forward_encoder.py | 4 +++ benchmark/train_pgen_arm.py | 10 +++++- 6 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 benchmark/slurm/forward_encoder.sbatch create mode 100644 benchmark/slurm/submit_pgen_all.sh diff --git a/benchmark/slurm/forward_encoder.sbatch b/benchmark/slurm/forward_encoder.sbatch new file mode 100644 index 0000000..570c931 --- /dev/null +++ b/benchmark/slurm/forward_encoder.sbatch @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Pretrain the sequence-to-TCRemP encoder that the irrm_pretrained Pgen arm starts from. +# +# Trained on the benchmark's own train split, so nothing the Pgen arms are evaluated on +# was seen during pretraining. Must finish before the Pgen arrays start. + +#SBATCH --job-name=irrm-fwd +#SBATCH --partition=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=48G +#SBATCH --time=02:00:00 +#SBATCH --output=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%j.out +#SBATCH --error=/mnt/tank/scratch/mpodsytnik/irrm-codec/logs/%x_%j.err + +set -euo pipefail + +SCRATCH="${SCRATCH:-/mnt/tank/scratch/mpodsytnik/irrm-codec}" +REPO="${REPO:-/nfs/home/mpodsytnik/irrm-codec}" +CONDA_ROOT="${CONDA_ROOT:-/mnt/tank/scratch/mpodsytnik/miniconda3}" +CONDA_ENV="${CONDA_ENV:-irrm-codec}" + +DATASET_DIR="${DATASET_DIR:-$SCRATCH/data/benchmark/trb}" +OUTPUT_DIR="${OUTPUT_DIR:-$SCRATCH/artifacts/benchmark/forward_encoder}" +EPOCHS="${EPOCHS:-40}" +PATIENCE="${PATIENCE:-12}" + +source "$CONDA_ROOT/bin/activate" +conda activate "$CONDA_ENV" + +echo "job=${SLURM_JOB_ID:-local} node=${SLURMD_NODENAME:-?}" +nvidia-smi --query-gpu=name,memory.total --format=csv,noheader || true + +cd "$REPO" +export PYTHONUNBUFFERED=1 +python -m benchmark.train_forward_encoder \ + --dataset-dir "$DATASET_DIR" \ + --output-dir "$OUTPUT_DIR" \ + --train-subset all \ + --epochs "$EPOCHS" \ + --patience "$PATIENCE" \ + --threads "${SLURM_CPUS_PER_TASK:-4}" diff --git a/benchmark/slurm/pgen_array.sbatch b/benchmark/slurm/pgen_array.sbatch index 8a7ba39..4f97f9d 100644 --- a/benchmark/slurm/pgen_array.sbatch +++ b/benchmark/slurm/pgen_array.sbatch @@ -38,7 +38,8 @@ OUTPUT_DIR="${OUTPUT_DIR:-$SCRATCH/artifacts/benchmark/pgen}" EPOCHS="${EPOCHS:-60}" BATCH_SIZE="${BATCH_SIZE:-256}" -PATIENCE="${PATIENCE:-8}" +# Left to the trainer's own default so the cosine schedule is not cut short. +PATIENCE="${PATIENCE:-12}" # Build the task list in a fixed order so a task id always maps to the same run. CONFIGS=() diff --git a/benchmark/slurm/pgen_seeds_array.sbatch b/benchmark/slurm/pgen_seeds_array.sbatch index 6d0b5e3..33d7972 100644 --- a/benchmark/slurm/pgen_seeds_array.sbatch +++ b/benchmark/slurm/pgen_seeds_array.sbatch @@ -44,7 +44,8 @@ OUTPUT_DIR="${OUTPUT_DIR:-$SCRATCH/artifacts/benchmark/pgen}" SUBSETS="${SUBSETS:-1k 10k}" EPOCHS="${EPOCHS:-60}" BATCH_SIZE="${BATCH_SIZE:-256}" -PATIENCE="${PATIENCE:-8}" +# Left to the trainer's own default so the cosine schedule is not cut short. +PATIENCE="${PATIENCE:-12}" # Seeds 42-44 already ran in the main array; these continue the sequence. CONFIGS=() diff --git a/benchmark/slurm/submit_pgen_all.sh b/benchmark/slurm/submit_pgen_all.sh new file mode 100644 index 0000000..dd8c214 --- /dev/null +++ b/benchmark/slurm/submit_pgen_all.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Submit the whole Pgen benchmark as one dependency chain, so it can be started and left. +# +# bash benchmark/slurm/submit_pgen_all.sh +# +# Stages, each waiting for the previous one to succeed: +# 1. pretrain the sequence-to-TCRemP encoder (~10 min) +# 2. main sweep: 6 arms x 2 targets x 3 sizes x 3 seeds (96 runs) +# 3. extra seeds for the two IRRM arms, 7 more each (84 runs) +# +# Existing results are archived rather than left in place: run names are identical +# between submissions, so mixing a finished constant-learning-rate sweep with a new +# cosine-schedule one would silently average two different configurations together. + +set -euo pipefail + +SCRATCH="${SCRATCH:-/mnt/tank/scratch/mpodsytnik/irrm-codec}" +REPO="${REPO:-/nfs/home/mpodsytnik/irrm-codec}" +PGEN_DIR="$SCRATCH/artifacts/benchmark/pgen" +FORWARD_DIR="$SCRATCH/artifacts/benchmark/forward_encoder" + +mkdir -p "$SCRATCH/logs" + +stamp="$(date +%Y%m%d_%H%M%S)" +for dir in "$PGEN_DIR" "$FORWARD_DIR"; do + if [ -d "$dir" ]; then + mv "$dir" "${dir}_constlr_${stamp}" + echo "archived $(basename "$dir") -> $(basename "${dir}")_constlr_${stamp}" + fi +done + +cd "$REPO" + +forward_id=$(sbatch --parsable benchmark/slurm/forward_encoder.sbatch) +echo "1/3 forward encoder : $forward_id" + +main_id=$(sbatch --parsable --dependency=afterok:"$forward_id" benchmark/slurm/pgen_array.sbatch) +echo "2/3 main sweep : $main_id (after $forward_id)" + +# The extra seeds only cover 1k and 10k here; the main sweep already supplies three seeds +# per cell, and SUBSETS controls which sizes get topped up to ten. +seeds_id=$(sbatch --parsable --dependency=afterok:"$main_id" \ + --export=ALL,SUBSETS="1k 10k all" --array=0-83%2 benchmark/slurm/pgen_seeds_array.sbatch) +echo "3/3 extra seeds : $seeds_id (after $main_id)" + +echo +echo "watch with: squeue -u \$USER" +echo "count with: ls $PGEN_DIR/*/metrics.json 2>/dev/null | wc -l # expect 180" diff --git a/benchmark/train_forward_encoder.py b/benchmark/train_forward_encoder.py index b3acd52..8589958 100644 --- a/benchmark/train_forward_encoder.py +++ b/benchmark/train_forward_encoder.py @@ -145,6 +145,9 @@ def main(): model = ForwardModel(output_dim=matrix.shape[1], max_len=args.max_len).to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + # A constant learning rate leaves the model bouncing around the minimum, which shows + # up as an oscillating validation loss and, downstream, as large seed-to-seed spread. + scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=args.epochs) log.info("model params=%.2fM output_dim=%d", sum(p.numel() for p in model.parameters()) / 1e6, matrix.shape[1]) best_val = float("inf") @@ -155,6 +158,7 @@ def main(): for epoch in range(1, args.epochs + 1): train_metrics = run_epoch(model, loaders["train"], device, optimizer) val_metrics = run_epoch(model, loaders["val"], device) + scheduler.step() history.append( { "epoch": epoch, diff --git a/benchmark/train_pgen_arm.py b/benchmark/train_pgen_arm.py index 12ce2aa..6a7bd25 100644 --- a/benchmark/train_pgen_arm.py +++ b/benchmark/train_pgen_arm.py @@ -56,7 +56,10 @@ def parse_args(): p.add_argument("--batch-size", type=int, default=256) p.add_argument("--lr", type=float, default=1e-3) p.add_argument("--weight-decay", type=float, default=1e-4) - p.add_argument("--patience", type=int, default=8) + # Wider than the reconstruction runs use: the cosine schedule only pays off if training + # reaches the low-learning-rate tail, and stopping at epoch 17 of 60 would decay the + # rate by under a fifth. + p.add_argument("--patience", type=int, default=12) p.add_argument("--max-len", type=int, default=40) p.add_argument("--threads", type=int, default=8) return p.parse_args() @@ -255,6 +258,10 @@ def fit_neural(args, features, targets, log): model = build_model(args, features["train"].shape[-1], log).to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + # A constant learning rate leaves the model bouncing around the minimum: validation + # loss oscillates, early stopping fires at an arbitrary epoch, and the IRRM arms end up + # spreading roughly tenfold wider across seeds than the frozen-embedding arms. + scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=args.epochs) log.info("device=%s params=%.2fM", device, sum(p.numel() for p in model.parameters()) / 1e6) best_val, best_epoch = float("inf"), 0 @@ -265,6 +272,7 @@ def fit_neural(args, features, targets, log): for epoch in range(1, args.epochs + 1): train_loss = run_epoch(model, loaders["train"], device, is_sequence, optimizer) val_loss = run_epoch(model, loaders["val"], device, is_sequence) + scheduler.step() history.append({"epoch": epoch, "train_loss": train_loss, "val_loss": val_loss}) if epoch % 5 == 0 or epoch == 1: log.info("epoch=%d train_loss=%.4f val_loss=%.4f", epoch, train_loss, val_loss) From d3c0b918dceb755e38cce6e59c17c920cec91b21 Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Sun, 9 Aug 2026 08:27:16 +0300 Subject: [PATCH 58/70] Update Pgen results after the cosine-schedule rerun --- REPORT.md | 168 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 66 deletions(-) diff --git a/REPORT.md b/REPORT.md index cbb63f2..a1e3e0f 100644 --- a/REPORT.md +++ b/REPORT.md @@ -173,9 +173,17 @@ Targets are standardized on train statistics and mapped back before any metric, freshly initialized network does not spend its first epochs locating an offset near −6.5 that Ridge fits for free. Reported errors are in log10 units. -Neural arms ran ten seeds each on every cell — three from the main sweep plus seven more, -added because the IRRM arms spread by 0.04–0.08 RMSE across seeds, which is larger than -the effect they are meant to measure. 180 runs in total. +Neural arms ran ten seeds on every cell: 180 runs. Ten rather than three because the two +IRRM arms spread widely across seeds, and the effect they exist to measure is small by +construction — the arms are the same architecture on the same data, differing only in +their starting weights. + +The whole sweep was then run **twice**, under two learning-rate configurations: a constant +1e-3, and a cosine schedule decaying to zero over the epoch budget (with early-stopping +patience widened from 8 to 12 so the schedule reaches its tail). The second configuration +was not a tuning pass but a robustness check, and it changed the headline conclusion. All +tables below report the cosine runs, which converge better and vary less; the constant-rate +numbers are kept in `results/pgen/` for comparison. ### Results on the full training split @@ -185,73 +193,91 @@ Mean ± standard deviation over seeds, on the held-out test split. | arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | peak RSS MB | | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | -| irrm_pretrained | **0.2098** ± 0.0493 | 0.1262 | 0.9822 | 0.9928 | 0.9909 | +0.0606 | 232 | 1575 | -| irrm_scratch | 0.2653 ± 0.0376 | 0.1730 | 0.9724 | 0.9894 | 0.9923 | +0.0609 | 135 | 1574 | -| tcr_bert_mlp | 0.3115 ± 0.0073 | 0.2002 | 0.9627 | 0.9813 | 0.9852 | +0.0028 | 62 | 1671 | -| sceptr_mlp | 0.4560 ± 0.0080 | 0.2636 | 0.9200 | 0.9599 | 0.9754 | +0.0484 | 53 | 1197 | -| esm2_8m_mlp | 0.4794 ± 0.0092 | 0.2868 | 0.9116 | 0.9561 | 0.9721 | +0.0650 | 68 | 1301 | -| tfidf_ridge | 0.5542 | 0.3671 | 0.8819 | 0.9391 | 0.9566 | +0.0035 | 10 | 716 | +| irrm_pretrained | **0.2181** ± 0.0322 | 0.1248 | 0.9813 | 0.9935 | 0.9921 | +0.0338 | 187 | 1584 | +| irrm_scratch | 0.2435 ± 0.0248 | 0.1583 | 0.9770 | 0.9916 | 0.9937 | +0.0466 | 105 | 1583 | +| tcr_bert_mlp | 0.2766 ± 0.0006 | 0.1671 | 0.9706 | 0.9854 | 0.9908 | +0.0175 | 71 | 1668 | +| sceptr_mlp | 0.4465 ± 0.0060 | 0.2510 | 0.9233 | 0.9621 | 0.9783 | +0.0642 | 58 | 1193 | +| esm2_8m_mlp | 0.4539 ± 0.0015 | 0.2655 | 0.9208 | 0.9607 | 0.9762 | +0.0549 | 68 | 1295 | +| tfidf_ridge | 0.5542 | 0.3671 | 0.8819 | 0.9391 | 0.9566 | +0.0035 | 9 | 717 | **`log10_pgen`, train = 79,730** | arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | peak RSS MB | | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | -| irrm_pretrained | **0.2909** ± 0.0474 | 0.1846 | 0.9753 | 0.9904 | 0.9876 | +0.1154 | 205 | 1582 | -| irrm_scratch | 0.3358 ± 0.0713 | 0.2225 | 0.9666 | 0.9898 | 0.9904 | +0.0998 | 146 | 1569 | -| tcr_bert_mlp | 0.4104 ± 0.0065 | 0.2641 | 0.9520 | 0.9761 | 0.9794 | +0.0299 | 64 | 1669 | -| sceptr_mlp | 0.5833 ± 0.0035 | 0.3536 | 0.9031 | 0.9524 | 0.9649 | +0.0871 | 67 | 1200 | -| esm2_8m_mlp | 0.6031 ± 0.0126 | 0.3811 | 0.8964 | 0.9475 | 0.9599 | +0.0433 | 66 | 1300 | -| tfidf_ridge | 0.6210 | 0.4145 | 0.8901 | 0.9435 | 0.9563 | +0.0087 | 9 | 719 | +| irrm_pretrained | **0.3102** ± 0.0388 | 0.1925 | 0.9722 | 0.9912 | 0.9883 | +0.1177 | 159 | 1593 | +| irrm_scratch | 0.3114 ± 0.0333 | 0.2027 | 0.9721 | 0.9921 | 0.9928 | +0.0987 | 131 | 1580 | +| tcr_bert_mlp | 0.3758 ± 0.0019 | 0.2333 | 0.9598 | 0.9800 | 0.9851 | +0.0238 | 74 | 1666 | +| esm2_8m_mlp | 0.5728 ± 0.0005 | 0.3494 | 0.9065 | 0.9535 | 0.9673 | +0.0746 | 63 | 1296 | +| sceptr_mlp | 0.5795 ± 0.0046 | 0.3442 | 0.9043 | 0.9532 | 0.9668 | +0.0976 | 61 | 1193 | +| tfidf_ridge | 0.6210 | 0.4145 | 0.8901 | 0.9435 | 0.9563 | +0.0087 | 8 | 714 | The ordering is identical on both targets and at every training size: the two IRRM arms lead, TCR-BERT is the best frozen representation, then SCEPTR and ESM-2, with Ridge last. -Per-size tables are in `results/pgen/pgen_summary.md`. +The gaps are large — IRRM halves the error of SCEPTR, ESM-2 and Ridge — and far exceed +seed spread. Per-size tables are in `results/pgen/pgen_summary.md`. For reference, the committed pgen notebook reports RMSE 0.5914, R² 0.9437 and Pearson -0.9874 on `log10_pgen_1mm`. The pretrained arm here reaches RMSE 0.2098, R² 0.9822 and -Pearson 0.9928 on a different split of the same data. +0.9874 on `log10_pgen_1mm`. The best arm here reaches RMSE 0.2181, R² 0.9813 and Pearson +0.9935 on a different split of the same data. ### Does IRRM pretraining improve Pgen prediction? -Welch's t-test on RMSE across ten seeds per arm. A positive delta means pretraining won. +**No — not consistently.** Welch's t-test on RMSE, ten seeds per arm, under both +learning-rate configurations. A positive delta means pretraining won. -| target | train | irrm_scratch | irrm_pretrained | Δ RMSE | p | +| target | train | Δ RMSE (constant lr) | p | Δ RMSE (cosine) | p | | --- | --- | ---: | ---: | ---: | ---: | -| log10_pgen | 1k | 0.8379 | 0.8550 | −0.017 | 0.527 | -| log10_pgen | 10k | 0.5052 | 0.5422 | −0.037 | 0.157 | -| log10_pgen | all | 0.3358 | 0.2909 | +0.045 | 0.118 | -| log10_pgen_1mm | 1k | 0.6315 | 0.6569 | −0.025 | 0.307 | -| log10_pgen_1mm | 10k | 0.3957 | 0.4087 | −0.013 | 0.500 | -| **log10_pgen_1mm** | **all** | 0.2653 | **0.2098** | **+0.056** | **0.012** | - -**Yes, but narrowly: only on `log10_pgen_1mm` and only with the full training set**, where -pretraining cuts RMSE by 20.9%. Every other cell is indistinguishable from zero, and in -three of the four smaller-data cells the sign is negative. - -Two things support the one positive result beyond its p-value. It replicated: an earlier -independent run of the same configuration gave Δ = +0.049 at p = 0.017, and the arms were -retrained from scratch in between. And its direction is consistent with the mechanism — -TCRemP encodes similarity to a panel of reference receptors, and `Pgen_1mm` sums -probability over a sequence's single-mismatch neighbours. Both are neighbourhood -quantities, whereas exact `Pgen` is a property of one sequence alone, and that is the -target where transfer does nothing (p = 0.118). - -Against it: six comparisons were made. A Bonferroni correction over all six would require -p < 0.008, which this result does not meet. Restricting to the two full-data comparisons, -which are the primary ones, the threshold is p < 0.025 and it does. The finding should be -read as suggestive and mechanistically plausible rather than firmly established. +| log10_pgen | 1k | −0.017 | 0.527 | +0.045 | 0.113 | +| log10_pgen | 10k | −0.037 | 0.157 | −0.030 | **0.006** | +| log10_pgen | all | +0.045 | 0.118 | +0.001 | 0.940 | +| log10_pgen_1mm | 1k | −0.025 | 0.307 | +0.068 | **0.044** | +| log10_pgen_1mm | 10k | −0.013 | 0.500 | −0.006 | 0.763 | +| log10_pgen_1mm | all | +0.056 | **0.012** | +0.025 | 0.065 | + +Under the constant rate, one cell was significant: pretraining cut RMSE by 20.9% on +`log10_pgen_1mm` at full data, p = 0.012, and it replicated across an accidental rerun. +That looked like a real, narrow effect. + +It did not survive the schedule change. The same cell falls to Δ = +0.025 at p = 0.065, +while two different cells become significant — with **opposite signs**: pretraining +"helps" at 1k on one target and "hurts" at 10k on the other. No cell is significant under +both configurations, and three cells flip sign between them. That is the signature of +noise being read as effect, not of a small effect being measured precisely. + +The mechanism is visible in the absolute numbers. Cosine scheduling improved almost every +arm, but not the pretrained one: + +| arm, `log10_pgen_1mm` all | constant lr | cosine | +| --- | ---: | ---: | +| irrm_scratch | 0.2653 | **0.2435** | +| irrm_pretrained | 0.2098 | 0.2181 | +| tcr_bert_mlp | 0.3115 | **0.2766** | + +The from-scratch arm gained what the pretrained arm did not. The transferred encoder was +supplying a good starting point that compensated for a poorly annealed learning rate; once +the optimizer no longer needed compensating, the advantage disappeared. Pretraining was +substituting for training quality rather than adding information. + +Seed spread also fell where the comparison lives — 0.071 → 0.033 and 0.055 → 0.017 on the +from-scratch arm at `all` and 10k — so the cosine numbers are the more trustworthy ones, +not merely the more recent. + +With six comparisons, a Bonferroni threshold is p < 0.008. Only the 10k "hurts" result +meets it, and it contradicts the 1k "helps" result on the other target. The honest +reading is that the sequence-to-TCRemP initialization has no reliable effect on Pgen +prediction at any training size. ### Is the advantage larger in the low-data regime? -**No — the opposite.** The effect appears only at 79,730 training sequences and is absent -at 1k and 10k, where the sign is negative on three of four cells. This inverts the usual -expectation that pretraining pays off most when labelled data is scarce. +The question presupposes an advantage that the data does not support. Across both +configurations and all six cells there is no consistent direction: the sign flips between +configurations at 1k on both targets, and the two nominally significant results point +opposite ways. -The bias column shows the mechanism. At 1k the pretrained arm carries bias +0.31 and -+0.24 against +0.16 and +0.15 for the from-scratch arm. The transferred encoder was fitted -to predict 9000-dimensional TCRemP vectors, and its features push predictions in a -systematic direction that a small training set cannot correct. With enough data the head -overcomes it and the transferred features start to pay. +One asymmetry does survive both runs. The pretrained arm carries a larger positive bias at +small data — +0.32 and +0.24 at 1k against +0.23 for the from-scratch arm — so the +transferred features do push predictions systematically, and a small training set corrects +that less well. But this shows up as bias rather than as a reliable RMSE penalty. ### Quality against speed @@ -297,25 +323,28 @@ that node, so the laptop comparison is the honest one to quote. ### Where IRRM-CODEC wins and loses **Wins: accuracy at every training size, on both targets.** IRRM leads all four baselines -in all six cells. On the full split it reaches R² 0.982 and Pearson 0.993 for -`log10_pgen_1mm`, against 0.963 for the best frozen representation. +in all six cells. On the full split it reaches R² 0.981 and Pearson 0.994 for +`log10_pgen_1mm`, and halves the error of SCEPTR, ESM-2 and Ridge. These margins are ten +times the seed spread, so they are not in question. **Wins: the quality–speed trade-off against pretrained encoders.** Faster and more accurate than frozen ESM-2, TCR-BERT and SCEPTR simultaneously. For this task the large pretrained -encoders contribute nothing. +encoders contribute nothing on either axis. -**Wins: two to three orders of magnitude over OLGA**, which is the argument the model exists -to make. +**Wins: 46× to 729× over OLGA** on identical hardware, which is the argument the model +exists to make. -**Partial: pretraining helps only in one corner.** The sequence-to-TCRemP initialization -pays off on `log10_pgen_1mm` at full data (−20.9% RMSE) and nowhere else. Anyone adopting -it should expect a modest, target-specific gain, not a general one. +**Loses: the pretraining step buys nothing.** The sequence-to-TCRemP initialization shows no +reliable effect once the learning rate is properly annealed, and what looked like a 20.9% +gain under a constant rate was the pretrained encoder compensating for an untuned +optimizer. The practical implication is direct: train the Pgen model from scratch and skip +the pretraining stage, which costs an extra training run for no measurable return. -**Loses: seed stability.** The IRRM arms vary by 0.04–0.08 RMSE across seeds where the -frozen arms vary by 0.004–0.015 — roughly tenfold. Validation loss oscillates rather than -descending smoothly, so early stopping fires at inconsistent epochs. The learning rate is -constant at 1e-3 with no decay; a schedule would likely reduce this and is the clearest -next improvement. +**Loses: seed stability.** Even with cosine scheduling the IRRM arms vary by 0.017–0.092 +RMSE across seeds where the frozen arms vary by 0.0005–0.006 — still an order of magnitude +wider, because these arms fit a full encoder rather than a head over fixed features. Any +comparison between IRRM variants needs many seeds; three is not enough, as the first sweep +demonstrated. **Loses: throughput against a trivial baseline.** TF-IDF + Ridge is 22× faster on CPU. If an application needs coarse Pgen estimates at maximum rate, k-mers remain the right tool. @@ -339,8 +368,15 @@ Reproduce with `benchmark/slurm/pgen_array.sbatch` and holds for TRA or for other loci. - **One bottleneck width.** Reconstruction was compared at 64 dimensions. Projections at 32 and 128 are cached in `data/benchmark/trb/bottleneck/` but were not trained. -- **Six statistical comparisons** were made for the pretraining question; only one is - significant, and it does not survive a Bonferroni correction over all six. +- **Six statistical comparisons** were made for the pretraining question, under each of two + learning-rate configurations. No cell is significant under both, and three flip sign + between them, which is why the conclusion is stated as absence of a reliable effect + rather than as a measured null. +- **Sections 2 and 3 used different learning-rate schedules** — constant for reconstruction, + cosine for Pgen. The issues require identical settings across the arms compared within + each experiment, which holds; they are not comparable across sections. Reconstruction was + not rerun because its seed spread (±0.0006 to ±0.008) leaves nothing for a schedule to + fix. ## Environment From d437f96ce93526d36ed2202e4e05f0c3ed400e9a Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Tue, 11 Aug 2026 09:56:10 +0300 Subject: [PATCH 59/70] Point the report at the archived constant-lr results --- REPORT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REPORT.md b/REPORT.md index a1e3e0f..05ad27b 100644 --- a/REPORT.md +++ b/REPORT.md @@ -183,7 +183,7 @@ The whole sweep was then run **twice**, under two learning-rate configurations: patience widened from 8 to 12 so the schedule reaches its tail). The second configuration was not a tuning pass but a robustness check, and it changed the headline conclusion. All tables below report the cosine runs, which converge better and vary less; the constant-rate -numbers are kept in `results/pgen/` for comparison. +numbers are kept in `results/pgen_constlr/` for comparison. ### Results on the full training split From 93b63b61eaae7b911782dbe1eef439d190e01b08 Mon Sep 17 00:00:00 2001 From: Petr Grigorev Date: Tue, 11 Aug 2026 13:43:59 +0300 Subject: [PATCH 60/70] Add benchmark result CSVs --- results/pgen/pgen_runs.csv | 181 ++++++++++++++++++ results/pgen/pgen_summary.csv | 37 ++++ results/pgen/pgen_summary.md | 70 +++++++ results/pgen/pretraining_delta.csv | 7 + results/pgen/speed_end_to_end_cpu.csv | 6 + results/pgen/speed_end_to_end_cuda.csv | 6 + results/pgen_constlr/pgen_runs.csv | 181 ++++++++++++++++++ results/pgen_constlr/pgen_summary.csv | 37 ++++ results/pgen_constlr/pgen_summary.md | 70 +++++++ results/pgen_constlr/pretraining_delta.csv | 7 + .../reconstruction/reconstruction_runs.csv | 16 ++ .../reconstruction/reconstruction_summary.csv | 6 + .../reconstruction/reconstruction_summary.md | 9 + 13 files changed, 633 insertions(+) create mode 100644 results/pgen/pgen_runs.csv create mode 100644 results/pgen/pgen_summary.csv create mode 100644 results/pgen/pgen_summary.md create mode 100644 results/pgen/pretraining_delta.csv create mode 100644 results/pgen/speed_end_to_end_cpu.csv create mode 100644 results/pgen/speed_end_to_end_cuda.csv create mode 100644 results/pgen_constlr/pgen_runs.csv create mode 100644 results/pgen_constlr/pgen_summary.csv create mode 100644 results/pgen_constlr/pgen_summary.md create mode 100644 results/pgen_constlr/pretraining_delta.csv create mode 100644 results/reconstruction/reconstruction_runs.csv create mode 100644 results/reconstruction/reconstruction_summary.csv create mode 100644 results/reconstruction/reconstruction_summary.md diff --git a/results/pgen/pgen_runs.csv b/results/pgen/pgen_runs.csv new file mode 100644 index 0000000..7fae920 --- /dev/null +++ b/results/pgen/pgen_runs.csv @@ -0,0 +1,181 @@ +arm,target,train_subset,train_size,seed,training_seconds,rmse,mae,r2,pearson_r,spearman_rho,bias,inference_seq_per_second,inference_ms_per_sequence,device,peak_rss_mb,peak_gpu_mb,epochs_ran +esm2_8m_mlp,log10_pgen,1k,1000,42,5.34,1.0771408535945268,0.7260378855007953,0.669508854815493,0.8216067160495758,0.8331470316606933,0.13865496676993277,705960.7233955928,0.0014165093989791824,cuda,1197.78125,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,1k,1000,43,5.1,1.0751237520233003,0.7263235609554174,0.6707454805022155,0.8223345359775261,0.8340828674416486,0.13843278495773942,747093.4212828245,0.00133852068765766,cuda,1194.6875,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,1k,1000,44,4.11,1.0695933554075805,0.7286857503677006,0.6741241143295938,0.8228841204325575,0.8323480349886503,0.10114906892531643,735015.6226967543,0.001360515299431357,cuda,1195.64453125,23.45751953125,46.0 +irrm_pretrained,log10_pgen,1k,1000,42,6.24,0.8649319159558528,0.573572627859008,0.7869023415752135,0.9225699791418592,0.9119520006525227,0.4028323986191931,80863.50773405924,0.0123665177039903,cuda,1552.5234375,255.98876953125,25.0 +irrm_pretrained,log10_pgen,1k,1000,43,5.9,0.8313225259801558,0.5495318621784235,0.8031416099725512,0.9236803569147729,0.9135004792110046,0.36259704153653866,78945.20760898925,0.012667013366446999,cuda,1550.91015625,255.98876953125,23.0 +irrm_pretrained,log10_pgen,1k,1000,44,6.16,0.8039642867965016,0.5216304005308618,0.8158853501548303,0.929212427359479,0.922879820889854,0.3472389288297001,80992.25445801619,0.012346859668147256,cuda,1545.44140625,255.98876953125,25.0 +irrm_pretrained,log10_pgen,1k,1000,45,6.53,0.8174569543838605,0.5322813395104757,0.8096536218416155,0.9271785368544058,0.9203442313044025,0.3599058488751396,80060.79152636931,0.012490508536511706,cuda,1544.26171875,255.98876953125,26.0 +irrm_pretrained,log10_pgen,1k,1000,46,7.85,0.8237597476667486,0.5406323265712351,0.8067070717851613,0.9297969710103117,0.9226493652846909,0.3918390707428683,79906.00704535747,0.012514703674685743,cuda,1563.98046875,255.98876953125,30.0 +irrm_pretrained,log10_pgen,1k,1000,47,6.61,0.795733847970004,0.5171656860759076,0.8196357352293764,0.9285150090131103,0.921082252441927,0.3313119003076507,77841.70608175163,0.012846583795963706,cuda,1548.0859375,255.98876953125,25.0 +irrm_pretrained,log10_pgen,1k,1000,48,5.72,0.8021244491460586,0.5302790450689656,0.816727062835779,0.9220099669223497,0.9179323947568008,0.31359157081286243,80136.58582260921,0.012478694840002361,cuda,1566.8984375,255.98876953125,22.0 +irrm_pretrained,log10_pgen,1k,1000,49,4.68,0.8318569691142761,0.5448034584308773,0.8028884147796086,0.907612296788354,0.9008832577185555,0.2114075241262159,80186.96882282455,0.012470854238293123,cuda,1556.875,255.98876953125,18.0 +irrm_pretrained,log10_pgen,1k,1000,50,5.84,0.7830557427649305,0.5141476876670233,0.8253372917973597,0.922166417284953,0.9141818947508201,0.24003536004227982,80261.9705837884,0.012459200698991854,cuda,1547.0625,255.98876953125,23.0 +irrm_pretrained,log10_pgen,1k,1000,51,4.96,0.7998190142313116,0.5398007120038264,0.8177790607593768,0.9173102792460404,0.9079210168206249,0.28461443290058946,79910.51413303308,0.012513997824306627,cuda,1562.07421875,255.98876953125,19.0 +irrm_scratch,log10_pgen,1k,1000,42,7.69,0.8441119514619323,0.5319142441170579,0.7970379080578323,0.9051526732558525,0.906339826203102,0.25311759515793814,78739.84026758223,0.01270005116344778,cuda,1565.42578125,255.98876953125,30.0 +irrm_scratch,log10_pgen,1k,1000,43,10.56,0.7437902178581257,0.4714709206837621,0.8424146805105919,0.9204954050970439,0.9219248220744659,0.1288298033379222,80851.88208602746,0.012368295878826752,cuda,1546.63671875,255.98876953125,44.0 +irrm_scratch,log10_pgen,1k,1000,44,6.41,0.9439559508218183,0.6187347933622375,0.7461844128303036,0.8696195540239993,0.8685103108517291,0.18257265629955535,78595.5292329371,0.012723370015567363,cuda,1561.90234375,255.98876953125,25.0 +irrm_scratch,log10_pgen,1k,1000,45,6.98,0.885964311952314,0.5553881292737052,0.7764126193240595,0.8968896378559235,0.8945789702406476,0.26261517141442153,80666.26935827773,0.012396755272746265,cuda,1546.95703125,255.98876953125,28.0 +irrm_scratch,log10_pgen,1k,1000,46,5.84,0.9763104933844673,0.6321716080463298,0.7284869263676981,0.870469034070754,0.861312281330798,0.31175582583126027,80848.42252814662,0.012368825126450171,cuda,1545.22265625,255.98876953125,23.0 +irrm_scratch,log10_pgen,1k,1000,47,8.73,0.8783602742491172,0.5487071160322827,0.780234152019625,0.9088537530042312,0.9072049580677213,0.3422900177627635,76363.0089395081,0.013095345690112373,cuda,1551.3046875,255.98876953125,34.0 +irrm_scratch,log10_pgen,1k,1000,48,10.64,0.919467769293943,0.58948479091107,0.7591826060141407,0.9116245478710833,0.9121262001095223,0.4535502971643727,79905.32213663701,0.012514810944507722,cuda,1558.87890625,255.98876953125,42.0 +irrm_scratch,log10_pgen,1k,1000,49,6.74,0.8736720995109767,0.5701165193450962,0.7825738551116111,0.8916065482310117,0.8876233950864687,0.20014242571748278,80802.20622960075,0.012375899702026502,cuda,1573.88671875,255.98876953125,27.0 +irrm_scratch,log10_pgen,1k,1000,50,10.54,0.7922520694606673,0.49711589769390385,0.8212106701729678,0.9145798789121482,0.9180335296945293,0.1337827529050968,80315.75408298723,0.012450857386792856,cuda,1540.3359375,255.98876953125,43.0 +irrm_scratch,log10_pgen,1k,1000,51,11.01,0.7476454702404467,0.48343691228369096,0.8407768378569647,0.9201273521939399,0.9226283285508657,0.0296063515905427,80351.0919746068,0.012445381580078938,cuda,1551.796875,255.98876953125,45.0 +sceptr_mlp,log10_pgen,1k,1000,42,4.74,1.0981920422083575,0.7610458447203725,0.6564646628435225,0.8121566102601996,0.8074398847933616,0.10412556109970554,1062266.7426666566,0.0009413831383722458,cuda,1172.00390625,21.20751953125,60.0 +sceptr_mlp,log10_pgen,1k,1000,43,3.42,1.0999811361432124,0.7624915073977926,0.655344425928786,0.8120102287560248,0.8046603984441668,0.11799728837458752,1061074.718902842,0.00094244069921297,cuda,1168.94140625,21.20751953125,43.0 +sceptr_mlp,log10_pgen,1k,1000,44,3.2,1.0940586433868646,0.758922927361791,0.6590458075780972,0.8133347744266023,0.8086149192965398,0.09307519652395542,1071874.0294636576,0.0009329454511556532,cuda,1174.91796875,21.20751953125,39.0 +tcr_bert_mlp,log10_pgen,1k,1000,42,4.65,0.8673881393172919,0.5780485788243145,0.7856903186825444,0.8898886415389792,0.8930102409604314,0.10531888878673068,476370.05146904866,0.002099208371550984,cuda,1242.5546875,28.14501953125,48.0 +tcr_bert_mlp,log10_pgen,1k,1000,43,5.87,0.858948772460653,0.5726932261716688,0.7898403393004456,0.892423247305388,0.8953746242397653,0.08094347219936113,483633.3470054774,0.002067682069881493,cuda,1246.63671875,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen,1k,1000,44,5.51,0.8662151855680355,0.5750684743816339,0.7862695412187646,0.8906440030475861,0.8943119327291345,0.10118385512174216,483340.43726194254,0.0020689351084814326,cuda,1247.06640625,28.14501953125,57.0 +tfidf_ridge,log10_pgen,1k,1000,42,0.18,1.2769573384805994,0.8800498060420275,0.5355193690361973,0.7459276280012653,0.7755959954308803,0.24748512995339594,82046.7449062024,0.012188173962821092,cpu,647.671875,0.0, +esm2_8m_mlp,log10_pgen,10k,10000,42,13.12,0.7892901399554304,0.5117788675519823,0.8225450219460526,0.9077396313574956,0.922136015327215,0.06535016127457582,751323.1196541691,0.0013309852629855125,cuda,1218.4375,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,10k,10000,43,11.67,0.7910012590527175,0.5090540726294859,0.821774770988962,0.908184530983501,0.9233618174289024,0.09305254228575181,707665.0616763182,0.0014130978822540683,cuda,1217.71484375,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,10k,10000,44,12.8,0.7937840810408098,0.5114952986728927,0.8205185365266188,0.9069227656983063,0.9224128719321808,0.07858451337605844,691845.9266758637,0.0014454085244163175,cuda,1217.4921875,23.45751953125,60.0 +irrm_pretrained,log10_pgen,10k,10000,42,22.1,0.49633429136522883,0.3364633920574051,0.929828074355773,0.9788465234302741,0.9769528791960383,0.2582476449257332,79422.11814450966,0.012590951026771734,cuda,1614.30859375,255.36376953125,31.0 +irrm_pretrained,log10_pgen,10k,10000,43,25.12,0.5193359156545152,0.36831604542598495,0.9231734116100119,0.978126930098433,0.9718469313258652,0.3012286896888966,78484.32285378146,0.012741398073383758,cuda,1594.49609375,255.36376953125,34.0 +irrm_pretrained,log10_pgen,10k,10000,44,32.11,0.5252833859981841,0.3584885153591458,0.9214036891479529,0.9735898112520421,0.9643449436380355,0.2684473076598781,78905.69137201828,0.012673357049560336,cuda,1570.359375,255.36376953125,45.0 +irrm_pretrained,log10_pgen,10k,10000,45,22.37,0.5275998646962152,0.39018114650797886,0.9207089474596369,0.9729629104504584,0.958600728526982,0.29486428735038855,78146.06342119222,0.01279654989925971,cuda,1576.4296875,255.36376953125,31.0 +irrm_pretrained,log10_pgen,10k,10000,46,31.75,0.5158049435613763,0.37157946936378206,0.9242145502587643,0.9783526876739728,0.9718356785668307,0.3058773639971277,78655.62426811836,0.012713649014992712,cuda,1608.67578125,255.36376953125,43.0 +irrm_pretrained,log10_pgen,10k,10000,47,18.23,0.5332813946641329,0.35700741491474547,0.9189920399063798,0.97604323639183,0.9748606762478106,0.2938373550204833,78264.75742759714,0.012777143031780323,cuda,1581.08203125,255.36376953125,25.0 +irrm_pretrained,log10_pgen,10k,10000,48,24.91,0.4579817124860741,0.3023822172194899,0.9402536876166383,0.9782543855947416,0.9757298823937622,0.20419803463546618,78031.82970995203,0.01281528324681155,cuda,1594.7578125,255.36376953125,34.0 +irrm_pretrained,log10_pgen,10k,10000,49,25.92,0.4976124581595938,0.3438377496106781,0.9294661936068322,0.9784862915435858,0.9759692349627562,0.27500778441402923,78638.12822918102,0.012716477649183417,cuda,1580.44921875,255.36376953125,35.0 +irrm_pretrained,log10_pgen,10k,10000,50,19.67,0.5425341893413741,0.39877899006847456,0.9161565664369719,0.9734359952461339,0.9633476928509621,0.321624207014219,77982.10842038045,0.01282345425452298,cuda,1586.1640625,255.36376953125,27.0 +irrm_pretrained,log10_pgen,10k,10000,51,13.38,0.5341332976578411,0.37650608358281984,0.9187330170116145,0.9667227466615107,0.9633437546517095,0.23337067889230595,78704.76482654782,0.012705711048166311,cuda,1613.80078125,255.36376953125,18.0 +irrm_scratch,log10_pgen,10k,10000,42,20.95,0.498671630386942,0.32079206399879684,0.9291656104710792,0.9657117315186489,0.9694134769384374,0.09424418102101653,78508.39615413654,0.012737491134536582,cuda,1583.9453125,255.36376953125,28.0 +irrm_scratch,log10_pgen,10k,10000,43,33.65,0.4706407993114887,0.29323152256924806,0.936905140469252,0.9740480810857403,0.9781106763867039,0.16780619885200848,79078.70122623147,0.0126456300431536,cuda,1602.7890625,255.36376953125,46.0 +irrm_scratch,log10_pgen,10k,10000,44,33.05,0.5079075377997477,0.32965094824733154,0.9265174619388699,0.9712447393219146,0.9755254688138308,0.22044626558539696,78956.04437864256,0.012665274810429812,cuda,1590.59765625,255.36376953125,45.0 +irrm_scratch,log10_pgen,10k,10000,45,27.82,0.47713739863574445,0.2912506286196337,0.9351512291587034,0.9718732546431008,0.9750787340415884,0.11394230996095928,79112.17619742312,0.012640279259977842,cuda,1582.5078125,255.36376953125,39.0 +irrm_scratch,log10_pgen,10k,10000,46,29.27,0.4579175921407287,0.29244273401005727,0.9402704161710751,0.9708733181295428,0.9743106241169605,-0.0422780559037735,78999.96939361731,0.012658232752186277,cuda,1574.63671875,255.36376953125,40.0 +irrm_scratch,log10_pgen,10k,10000,47,36.55,0.465288916422154,0.3107330220285725,0.9383319456243314,0.9721828697208292,0.9783745998124969,0.1545819731891662,78634.00965443617,0.012717143693862043,cuda,1587.2578125,255.36376953125,51.0 +irrm_scratch,log10_pgen,10k,10000,48,24.69,0.4868968973441002,0.32282410811390244,0.9324712289538608,0.9666661177257057,0.9732218700912197,0.08242033868522627,79166.7916318792,0.012631559008352135,cuda,1600.56640625,255.36376953125,34.0 +irrm_scratch,log10_pgen,10k,10000,49,30.38,0.49955472550048546,0.3238743178975122,0.9289145077923109,0.9669152473849376,0.9734628057385909,0.14312938242896417,78494.10538506562,0.012739810143632277,cuda,1578.953125,255.36376953125,41.0 +irrm_scratch,log10_pgen,10k,10000,50,23.59,0.5021787474881457,0.3100156924156718,0.9281657618398458,0.9687455318772152,0.9699728610796904,0.16583821028234638,78789.2636408248,0.012692084603794266,cuda,1612.04296875,255.36376953125,32.0 +irrm_scratch,log10_pgen,10k,10000,51,25.4,0.4806922198139846,0.28437546648930967,0.9341813427954785,0.971277292615862,0.9743939805805218,0.09846404782942433,78746.8403341449,0.012698922213979886,cuda,1590.25,255.36376953125,35.0 +sceptr_mlp,log10_pgen,10k,10000,42,10.85,0.8197409601112305,0.5322377064815003,0.8085884658779793,0.900190469155707,0.9106309096825668,0.07351937350297826,1045992.739596697,0.0009560295804592005,cuda,1184.78515625,21.20751953125,60.0 +sceptr_mlp,log10_pgen,10k,10000,43,10.9,0.8232791649384097,0.5329595503445926,0.8069325407912433,0.8993982334295626,0.910789330836775,0.07795665485235405,1002912.2882333912,0.0009970961685607412,cuda,1178.8515625,21.20751953125,60.0 +sceptr_mlp,log10_pgen,10k,10000,44,11.99,0.8213314982545481,0.5383096758524992,0.8078449561119915,0.8998291633130819,0.9092193480549974,0.06639299892483241,1015685.420632926,0.0009845568122626475,cuda,1184.00390625,21.20751953125,60.0 +tcr_bert_mlp,log10_pgen,10k,10000,42,13.04,0.5491397489252545,0.3589531191073769,0.9141024862729251,0.9565472815665261,0.9603263904726105,0.028682170324545696,483779.5195345584,0.002067057325953142,cuda,1284.14453125,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen,10k,10000,43,13.05,0.5525621465801277,0.360994787679031,0.9130284736191095,0.9561370066319027,0.9611197559421756,0.022896591890857958,485116.2109191465,0.0020613617469210244,cuda,1278.78515625,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen,10k,10000,44,12.88,0.5531349877060555,0.3610178326203211,0.9128480534001411,0.9561711841901395,0.9604234621650158,0.03684545612776406,471155.4772059833,0.0021224416320704525,cuda,1266.859375,28.14501953125,60.0 +tfidf_ridge,log10_pgen,10k,10000,42,0.58,0.7659173935252817,0.5084553048733631,0.8328991356685383,0.9129315175825418,0.9404240652599085,0.03423890204930655,79360.64652403284,0.01260070379715429,cpu,652.96484375,0.0, +esm2_8m_mlp,log10_pgen,all,79730,42,62.4,0.5731677057093365,0.3493723214550509,0.9064210307249039,0.9536062412202215,0.9675506650848761,0.07753757589264149,737700.7938537622,0.0013555631339041703,cuda,1292.87109375,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,all,79730,43,63.05,0.5722816128637928,0.3497724788661413,0.9067101452692726,0.9532051754785794,0.9667819816787405,0.06594397495518078,744636.9475580577,0.0013429363171937319,cuda,1295.58203125,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,all,79730,44,63.38,0.5729095378508662,0.34892790104491134,0.9065053119604066,0.9536574004133471,0.9674232426731361,0.08018154737074212,736760.647026297,0.0013572929065038773,cuda,1300.19921875,23.45751953125,60.0 +irrm_pretrained,log10_pgen,all,79730,42,123.85,0.3057602609523895,0.2083267044257563,0.9733696476549023,0.9917018462735949,0.9894025191718101,0.1588558915729577,77911.56266318262,0.012835065371786638,cuda,1596.3984375,254.86376953125,27.0 +irrm_pretrained,log10_pgen,all,79730,43,118.85,0.3227698346701869,0.19583600915331453,0.9703243178058237,0.9886645939613051,0.9832962906240956,0.11649408246044561,77761.84919341622,0.012859776489017266,cuda,1579.3515625,254.86376953125,26.0 +irrm_pretrained,log10_pgen,all,79730,44,211.48,0.28060503644475776,0.14739548233582567,0.9775712146156854,0.9929846069686562,0.9923312548184898,0.08320273340059216,76331.09878614836,0.013100820188657731,cuda,1584.953125,254.86376953125,47.0 +irrm_pretrained,log10_pgen,all,79730,45,215.6,0.2906337822506723,0.1697879711770245,0.9759393686285257,0.9930494157956323,0.9915791451404403,0.11848370121901147,76213.84869992676,0.013120974954791398,cuda,1603.67578125,254.86376953125,48.0 +irrm_pretrained,log10_pgen,all,79730,46,144.15,0.33693704512417527,0.2029260203209646,0.9676620595011232,0.989456937144701,0.985854278301268,0.07777895175197753,77506.95307456442,0.012902068270416523,cuda,1622.1328125,254.86376953125,32.0 +irrm_pretrained,log10_pgen,all,79730,47,198.11,0.28260784579697307,0.16704077865556358,0.977249902558756,0.9926284885670357,0.9930547129437717,0.12034238878009869,76224.02236325688,0.013119223690851051,cuda,1597.26171875,254.86376953125,44.0 +irrm_pretrained,log10_pgen,all,79730,48,157.15,0.2956240286589957,0.16988515750641128,0.9751060224184863,0.9918395106629686,0.9882366619574364,0.037514705427660146,77747.24938970283,0.012862191368180339,cuda,1585.90625,254.86376953125,35.0 +irrm_pretrained,log10_pgen,all,79730,49,202.71,0.2568489903064575,0.15425740537613158,0.9812081058492581,0.9950565011110328,0.9960072133460977,0.11595127294142848,76347.31414166577,0.013098037714129096,cuda,1580.203125,254.86376953125,45.0 +irrm_pretrained,log10_pgen,all,79730,50,99.96,0.39284684013561044,0.2914359988728974,0.9560396278441484,0.9858889109334719,0.9763490870794563,0.21786421304129522,77578.69993954332,0.012890136091211825,cuda,1600.61328125,254.86376953125,21.0 +irrm_pretrained,log10_pgen,all,79730,51,115.95,0.33713538320078806,0.21844640571312485,0.9676239768220666,0.9906641206786925,0.9865010824105642,0.13035446438857884,77558.41612855578,0.012893507241592779,cuda,1579.63671875,254.86376953125,25.0 +irrm_scratch,log10_pgen,all,79730,42,114.17,0.2719535505097029,0.16653379054223957,0.9789329222438513,0.9919265890391352,0.9926972842928662,0.09609930151292388,77975.04366490629,0.012824616095086117,cuda,1585.13671875,254.86376953125,26.0 +irrm_scratch,log10_pgen,all,79730,43,148.87,0.2806572979150532,0.1858581395148315,0.977562859309801,0.9949507777304938,0.995145779501445,0.05192284273870285,78143.844898836,0.012796913196357142,cuda,1572.2421875,254.86376953125,33.0 +irrm_scratch,log10_pgen,all,79730,44,182.86,0.2834810367182595,0.16944260740206932,0.9771091006088122,0.9950294500699801,0.9956005429373097,0.10711986412509826,76530.48611350135,0.013066688202096523,cuda,1584.03515625,254.86376953125,41.0 +irrm_scratch,log10_pgen,all,79730,45,93.79,0.3284325426622101,0.22519455615620482,0.9692739171693161,0.988786459724294,0.9899692333708238,0.13219256068879753,77059.23870669039,0.012977029319044889,cuda,1574.84765625,254.86376953125,21.0 +irrm_scratch,log10_pgen,all,79730,46,114.35,0.27585077654973195,0.18547613126024184,0.9783247930033384,0.9915338350103832,0.9910657074195383,0.025506009252100864,77201.34301823228,0.012953142534888735,cuda,1576.3515625,254.86376953125,25.0 +irrm_scratch,log10_pgen,all,79730,47,198.35,0.33604797728519187,0.21124316666040283,0.967832493067254,0.9958645289807903,0.9960726435747845,0.10184083611487582,76554.00202823328,0.013062674367189815,cuda,1596.35546875,254.86376953125,44.0 +irrm_scratch,log10_pgen,all,79730,48,95.99,0.32095970522074435,0.2228937454828952,0.9706562335892933,0.9904940076818866,0.9904438010414041,0.17860603614144913,77715.69472656505,0.012867413763955924,cuda,1575.47265625,254.86376953125,21.0 +irrm_scratch,log10_pgen,all,79730,49,142.4,0.324897288809792,0.19739056002251965,0.969931829346724,0.9933873020382896,0.9936995466077865,0.12007436457931936,77726.9541308783,0.012865549810638133,cuda,1571.75390625,254.86376953125,31.0 +irrm_scratch,log10_pgen,all,79730,50,89.87,0.3152489172546755,0.21929226072923863,0.9716911622598429,0.9860163867885153,0.9893431929980233,0.04317832128811549,76554.0589797288,0.01306266464936622,cuda,1584.25390625,254.86376953125,20.0 +irrm_scratch,log10_pgen,all,79730,51,131.13,0.3766005567885428,0.24336180453560238,0.9596004295556182,0.9933946378049742,0.9936023254985136,0.13065965375684127,77555.69803371314,0.012893959120389892,cuda,1576.484375,254.86376953125,29.0 +sceptr_mlp,log10_pgen,all,79730,42,57.69,0.5766064944696535,0.3428484145267614,0.905294785689099,0.9535790459641675,0.9663776368101202,0.08926576441701496,1035103.8993361475,0.0009660865934727316,cuda,1194.8359375,21.20751953125,60.0 +sceptr_mlp,log10_pgen,all,79730,43,64.55,0.584833564731118,0.3453063517799877,0.9025729817429096,0.95246948351646,0.9672135688288871,0.10801653991967043,1061797.5338926413,0.0009417991359745523,cuda,1194.54296875,21.20751953125,60.0 +sceptr_mlp,log10_pgen,all,79730,44,59.51,0.5770612206641812,0.3445521396506703,0.9051453530234606,0.9536648620712153,0.9669085617186784,0.09536860715000833,991191.4022597936,0.0010088868786796617,cuda,1190.8828125,21.20751953125,60.0 +tcr_bert_mlp,log10_pgen,all,79730,42,79.88,0.3777564977751135,0.23458992981807736,0.9593520433627332,0.979747865553209,0.9847126718927225,0.024266606714189013,478528.72105608066,0.0020897387262212123,cuda,1670.765625,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen,all,79730,43,70.85,0.375505857040682,0.23313485418218585,0.9598349545543144,0.9801372299422181,0.9855585447736372,0.024686716803757173,481572.8058755746,0.0020765292138575885,cuda,1662.76171875,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen,all,79730,44,71.6,0.3740375957016166,0.23232463675184953,0.9601484382877309,0.9802273073279212,0.9850856333747358,0.02237037464962718,486510.9071794783,0.0020554523757698425,cuda,1665.94921875,28.14501953125,60.0 +tfidf_ridge,log10_pgen,all,79730,42,8.4,0.6210225099572112,0.41454671189516185,0.8901425494415403,0.9434950444517985,0.9563135820470278,0.008684176700797186,68718.25314155618,0.014552174339182484,cpu,714.09765625,0.0, +esm2_8m_mlp,log10_pgen_1mm,1k,1000,42,5.11,0.8638028049753916,0.568791218194971,0.7131110578070958,0.8469102887490368,0.8667108625359236,0.10372949114561908,734687.1376026621,0.0013611235978120881,cuda,1199.7890625,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,1k,1000,43,5.23,0.8619774244542309,0.5692703601559694,0.7143222790817589,0.8478099524307426,0.8669547470373846,0.1071127415864139,727775.8588480044,0.0013740494244792606,cuda,1200.953125,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,1k,1000,44,5.08,0.8590033542150199,0.5676105701335532,0.7162902189773253,0.8479008164271059,0.8685698320651293,0.08222814137429608,745106.2393934651,0.00134209049277862,cuda,1192.59765625,23.45751953125,60.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,42,12.53,0.6529562585935635,0.40768538159968476,0.8360721408566971,0.9442740681192724,0.949476176152167,0.3004492179255113,80240.86719978109,0.012462477474355214,cuda,1550.8359375,255.98876953125,52.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,43,5.16,0.6400113298790213,0.40304623811145285,0.8425074866906714,0.9312456988056497,0.9373496156964188,0.2231928880169614,80682.86935446602,0.012394204717815323,cuda,1549.69921875,255.98876953125,20.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,44,6.26,0.6200875499689317,0.3844985011699642,0.8521604565547631,0.9459296723810654,0.9503241412598608,0.2694864386133546,80083.91447115551,0.012486902102671045,cuda,1553.51953125,255.98876953125,25.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,45,6.54,0.6310536518942342,0.3986318635819051,0.8468852047631974,0.9443783978709075,0.9489821784491898,0.2896516474185923,77981.26403690618,0.01282359310727164,cuda,1549.2734375,255.98876953125,26.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,46,6.59,0.6195555852385934,0.3962891510289275,0.8524140068427615,0.9443500979728823,0.9469694023446114,0.27819833731219673,78697.9342770863,0.012706813834262993,cuda,1562.43359375,255.98876953125,26.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,47,6.33,0.6266547317455818,0.3904620047620022,0.849012416025269,0.943407263239133,0.9469707393444504,0.263707425816376,78310.37693883583,0.012769699739551095,cuda,1565.94921875,255.98876953125,25.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,48,5.67,0.6236619614132954,0.39930113323908234,0.8504511417494165,0.9389343391116015,0.9458162046101952,0.25761830099041527,78693.53284131692,0.012707524543553905,cuda,1543.70703125,255.98876953125,22.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,49,4.71,0.6499044803178063,0.40785618003239943,0.8376008876652727,0.9264759291777597,0.9328795005102539,0.17716616132361881,78385.95400081249,0.012757387630820119,cuda,1555.32421875,255.98876953125,18.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,50,5.9,0.5994330346497347,0.380280920901402,0.8618452136538101,0.939269318647871,0.9421541893901585,0.18829553681659392,79014.97934627304,0.012655828151490463,cuda,1548.5,255.98876953125,23.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,51,4.96,0.5994008301275314,0.3870256531801975,0.8618600579787317,0.9348727785466787,0.9388998800257852,0.17224279149582014,78674.18185650515,0.012710650132007891,cuda,1560.15234375,255.98876953125,19.0 +irrm_scratch,log10_pgen_1mm,1k,1000,42,6.48,0.7756210635607437,0.488775886202463,0.768695661554632,0.9158074553176181,0.9222819561703773,0.3852233068305189,79599.61677741556,0.012562874552478065,cuda,1574.03125,255.98876953125,25.0 +irrm_scratch,log10_pgen_1mm,1k,1000,43,11.15,0.5616567093437265,0.34603153059101177,0.8787095823268849,0.9386583217064812,0.9474188542893907,0.07016255632983405,79666.25790176584,0.01255236566066742,cuda,1544.94921875,255.98876953125,44.0 +irrm_scratch,log10_pgen_1mm,1k,1000,44,6.88,0.7058828649367268,0.43409787223543767,0.8084201324866083,0.9140735719556143,0.9168842625543453,0.21586295803326302,79344.34843686518,0.012603292102092269,cuda,1563.3046875,255.98876953125,27.0 +irrm_scratch,log10_pgen_1mm,1k,1000,45,7.91,0.6740001737872768,0.4130208410802216,0.8253355155724036,0.9192456087003898,0.926908100052709,0.20133236035721191,77125.38840246688,0.012965899047167906,cuda,1583.46875,255.98876953125,31.0 +irrm_scratch,log10_pgen_1mm,1k,1000,46,7.63,0.682312413436616,0.42114535487571414,0.8210007817215697,0.9154231043861375,0.9224241754873767,0.19040918863685738,77714.31885101968,0.01286764157216671,cuda,1544.8125,255.98876953125,30.0 +irrm_scratch,log10_pgen_1mm,1k,1000,47,9.5,0.65108646567971,0.3912826224971895,0.8370096379269262,0.9316193931638769,0.9398473653548969,0.21678677651645972,78072.18619042147,0.012808658868101327,cuda,1571.74609375,255.98876953125,38.0 +irrm_scratch,log10_pgen_1mm,1k,1000,48,6.33,0.8344811555092708,0.5589508598595957,0.7322572888207102,0.9108633601503565,0.91322708473897,0.4732333279414907,78272.52281380334,0.012775875416444992,cuda,1548.8046875,255.98876953125,25.0 +irrm_scratch,log10_pgen_1mm,1k,1000,49,6.92,0.82629497434108,0.5637715445233729,0.7374845841235782,0.912489113508546,0.9179172506572928,0.48450341909887745,77540.4721325073,0.01289649098719854,cuda,1551.09375,255.98876953125,27.0 +irrm_scratch,log10_pgen_1mm,1k,1000,50,8.19,0.6103351399149818,0.3876196098409824,0.8567741727273026,0.9259979083199648,0.9311154743696028,0.019025652453153675,75476.72065839717,0.013249118288086949,cuda,1547.109375,255.98876953125,31.0 +irrm_scratch,log10_pgen_1mm,1k,1000,51,8.32,0.6251580173699457,0.3920347913893575,0.8497327980864278,0.9250595921373767,0.9335045905874384,0.0355205504947733,78642.68759238251,0.012715740402758845,cuda,1561.4453125,255.98876953125,33.0 +sceptr_mlp,log10_pgen_1mm,1k,1000,42,4.88,0.8729629962973278,0.585332278608628,0.7069941717233896,0.8422360133559548,0.855733573185971,0.07803339644954202,1052124.6577599368,0.0009504577167966822,cuda,1173.1171875,21.20751953125,60.0 +sceptr_mlp,log10_pgen_1mm,1k,1000,43,3.81,0.872707884195867,0.5878114142571446,0.7071654009980505,0.8424537096287541,0.8531245639028813,0.08160378789314612,1025225.5230945263,0.0009753951471883124,cuda,1171.46875,21.20751953125,43.0 +sceptr_mlp,log10_pgen_1mm,1k,1000,44,4.35,0.875039007473917,0.5886985468686378,0.7055989083216988,0.8411393439083864,0.8544929176996288,0.07046295775930289,1009110.5557346264,0.0009909716971219333,cuda,1169.109375,21.20751953125,50.0 +tcr_bert_mlp,log10_pgen_1mm,1k,1000,42,5.29,0.6852645656848846,0.43437482691831775,0.8194484836357487,0.9093048373927972,0.9256513310486022,0.08790968486708374,469312.9234898688,0.0021307744789209647,cuda,1243.875,28.14501953125,47.0 +tcr_bert_mlp,log10_pgen_1mm,1k,1000,43,4.25,0.6829331715832121,0.434071752462488,0.8206749316672025,0.9093094169413265,0.9264527464334696,0.0736007711157669,468664.7860406887,0.0021337212220445805,cuda,1238.6015625,28.14501953125,38.0 +tcr_bert_mlp,log10_pgen_1mm,1k,1000,44,5.38,0.6872351224425811,0.4356053796900238,0.8184085974905176,0.9083054888112506,0.9259385459713246,0.076839266100189,484858.9313030664,0.002062455562719003,cuda,1242.58203125,28.14501953125,57.0 +tfidf_ridge,log10_pgen_1mm,1k,1000,42,0.19,1.085296409794027,0.73535530121258,0.5471218978219647,0.750774560158103,0.795403603438914,0.18915308819686613,80950.28937014837,0.012353260350033597,cpu,643.671875,0.0, +esm2_8m_mlp,log10_pgen_1mm,10k,10000,42,13.41,0.6260295155704774,0.3933335705938847,0.8493135476799875,0.9221821094460882,0.9420381756814984,0.04854568221982546,739495.3955814017,0.0013522734637364253,cuda,1219.70703125,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,10k,10000,43,11.81,0.6223697320332455,0.3882320646994455,0.8510702310367887,0.9238662517056982,0.9434740284740887,0.0649370734917326,735547.6744995526,0.0013595311829112556,cuda,1225.6953125,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,10k,10000,44,13.37,0.6259706667490265,0.3916924130701659,0.8493418763868927,0.9223776550508551,0.9421140639783299,0.053312992388272695,731884.5499928056,0.0013663357151204106,cuda,1219.30859375,23.45751953125,60.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,42,23.04,0.3522035785638962,0.23605209785853865,0.9523050807498069,0.983930424800023,0.9843882615672284,0.18039631196874276,79187.71578948178,0.012628221309710091,cuda,1592.3515625,255.36376953125,32.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,43,29.11,0.38753899215660315,0.27109869129044467,0.9422548651039686,0.9811142357156362,0.9703975743994855,0.2089216769812675,79484.49264258641,0.012581070429632676,cuda,1595.453125,255.36376953125,39.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,44,32.26,0.3822850747742425,0.25218843297052235,0.9438099686538676,0.9813273427294593,0.9755213089198129,0.18395725029628748,78665.73866989763,0.012712014364935492,cuda,1596.4609375,255.36376953125,45.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,45,17.65,0.4041191447823732,0.27990819980915715,0.9372081267064315,0.979920025727262,0.9765428583968161,0.2257876246112694,78729.95469238408,0.012701645820923287,cuda,1589.9296875,255.36376953125,24.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,46,31.18,0.3911848445918753,0.26226686425507795,0.9411632560109777,0.9829105055368497,0.9776255144294108,0.20629808755274887,77487.35419934198,0.012905331590331831,cuda,1591.9296875,255.36376953125,43.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,47,23.39,0.38348089009514835,0.2531676301319391,0.9434578858919235,0.9826728115818364,0.9819501282337215,0.19949019843057192,78626.90485599045,0.012718292826502017,cuda,1600.2109375,255.36376953125,32.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,48,25.34,0.31816722084810306,0.20541534208333775,0.9610779722310352,0.9830906838143463,0.9823737812284563,0.10997886851599012,78570.88446529236,0.01272736086408365,cuda,1581.47265625,255.36376953125,34.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,49,29.76,0.3814527636735218,0.2392016173657349,0.9440543761849206,0.9826898812367412,0.9814819849844005,0.17505504218945128,77532.6625809653,0.012897789998579327,cuda,1575.05078125,255.36376953125,41.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,50,22.5,0.40909544792676755,0.261909274021916,0.9356521733237381,0.983110380156732,0.9833059108264491,0.22079621710108355,78582.57884899958,0.012725466822888961,cuda,1583.88671875,255.36376953125,30.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,51,13.44,0.4038788122079963,0.2812596679686494,0.9372827900596038,0.9746190105546972,0.9714999790318952,0.16937099385437487,77728.24803117815,0.012865335644756622,cuda,1569.32421875,255.36376953125,18.0 +irrm_scratch,log10_pgen_1mm,10k,10000,42,20.33,0.36921385599324186,0.23028669602259502,0.9475868125935152,0.9744331202623125,0.9801626054392585,0.03312593973357653,79122.29371026848,0.012638662924280468,cuda,1585.8984375,255.36376953125,28.0 +irrm_scratch,log10_pgen_1mm,10k,10000,43,21.57,0.36219569504086635,0.22513798777308272,0.9495604553291446,0.9756419521768758,0.9802466698170175,0.04881839728880603,76747.8627017076,0.013029678805345422,cuda,1586.53515625,255.36376953125,29.0 +irrm_scratch,log10_pgen_1mm,10k,10000,44,18.83,0.3831162822600322,0.23419808420311247,0.9435653535535624,0.9728618066319854,0.9764946080845648,0.07214146335570987,80006.72679311575,0.012498949026946643,cuda,1576.73046875,255.36376953125,25.0 +irrm_scratch,log10_pgen_1mm,10k,10000,45,28.99,0.35224366238484983,0.22376578294680224,0.9522942239413621,0.9760330880069608,0.9834552471268139,-0.012863246857717952,76926.3501805443,0.012999446843026143,cuda,1571.3359375,255.36376953125,39.0 +irrm_scratch,log10_pgen_1mm,10k,10000,46,39.09,0.33900270671157107,0.20915864891427285,0.9558133658824247,0.9800842419254892,0.9855767889778858,0.10221936446662258,78725.08869905554,0.012702430908940939,cuda,1602.68359375,255.36376953125,53.0 +irrm_scratch,log10_pgen_1mm,10k,10000,47,35.52,0.33813072800923394,0.21959607994470112,0.9560403861991751,0.9801886364299571,0.9853709016134247,0.10500751758902857,77535.64982109178,0.01289729308140748,cuda,1579.80859375,255.36376953125,49.0 +irrm_scratch,log10_pgen_1mm,10k,10000,48,32.9,0.3378822660799348,0.2061434139007981,0.9561049664141406,0.9787600364711352,0.9840258078648648,0.06777958021349939,78439.5066056244,0.012748677844542899,cuda,1582.52734375,255.36376953125,45.0 +irrm_scratch,log10_pgen_1mm,10k,10000,49,17.22,0.5211322195049435,0.34843281043792573,0.8955807814829972,0.9674054163214658,0.970678072425513,0.30572248198059976,77709.23790181913,0.012868482911432472,cuda,1572.69921875,255.36376953125,23.0 +irrm_scratch,log10_pgen_1mm,10k,10000,50,19.9,0.37348189977801466,0.23958918079854716,0.9463680351794995,0.9731939619808125,0.9802889403153295,0.04181760784932039,78409.30288658597,0.012753588709319811,cuda,1582.83203125,255.36376953125,27.0 +irrm_scratch,log10_pgen_1mm,10k,10000,51,25.7,0.37806560313552356,0.22143062541018307,0.9450435182028492,0.9757677766800191,0.9812830800850978,0.05084201869418621,77880.5342036482,0.012840179002690461,cuda,1570.671875,255.36376953125,35.0 +sceptr_mlp,log10_pgen_1mm,10k,10000,42,11.75,0.6371332141671232,0.39614468171809036,0.8439207819168444,0.9190377199718023,0.9394482016893153,0.04125073329136141,1057753.3728966473,0.0009453999633785235,cuda,1184.921875,21.20751953125,60.0 +sceptr_mlp,log10_pgen_1mm,10k,10000,43,10.84,0.6407606075461617,0.39765060478869485,0.842138509788058,0.9183379902101502,0.9390568683069896,0.04882956748748253,1009009.5155340733,0.0009910709310513245,cuda,1186.05078125,21.20751953125,60.0 +sceptr_mlp,log10_pgen_1mm,10k,10000,44,12.35,0.637657661090663,0.3986599607309693,0.8436637274958344,0.9191095715446563,0.9392093880388864,0.04484058808243563,1051063.8584379375,0.0009514169781141299,cuda,1186.1640625,21.20751953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,10k,10000,42,13.18,0.4111318934993246,0.25845667002793843,0.9350099417710966,0.967297966003536,0.9756017679174287,0.008384003869639601,479165.2697996234,0.0020869626056541587,cuda,1280.30859375,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,10k,10000,43,14.65,0.41350585090839187,0.2565953029194565,0.9342572438418231,0.966898297425101,0.97593350933347,0.01531694211326789,485958.66084314627,0.0020577882041756053,cuda,1279.98046875,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,10k,10000,44,13.26,0.41106930870267516,0.25502984257628103,0.9350297265655259,0.9675431906442596,0.97598224972199,0.026138567755919037,470986.4438187892,0.002123203359935233,cuda,1285.44921875,28.14501953125,60.0 +tfidf_ridge,log10_pgen_1mm,10k,10000,42,0.55,0.679848528075636,0.44560910401677106,0.8222912089245368,0.9069106930892485,0.9418412049600424,0.018927686789477982,79617.02327020983,0.012560127959144239,cpu,651.0703125,0.0, +esm2_8m_mlp,log10_pgen_1mm,all,79730,42,68.38,0.45471149866490485,0.2655386843892589,0.9205019524469311,0.9605820531819961,0.9763708989995882,0.05194563645716011,732619.9504161674,0.0013649641938251157,cuda,1291.36328125,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,all,79730,43,65.72,0.45216768528691753,0.26522786955099303,0.9213889435621597,0.9608687465987668,0.9762787240690396,0.05328308914404441,715461.1194133183,0.001397699990769596,cuda,1297.3359375,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,all,79730,44,69.37,0.4549245239649274,0.26568223603381097,0.9204274477889403,0.9606880913298007,0.9760459387204964,0.05959356687875681,732726.0886193139,0.0013647664734912253,cuda,1296.890625,23.45751953125,60.0 +irrm_pretrained,log10_pgen_1mm,all,79730,42,197.32,0.2010198735884292,0.11098549405704658,0.9844631640433253,0.9957314596428587,0.9967040399178354,0.061738928489644775,77704.89332565277,0.012869202404140863,cuda,1599.6015625,254.86376953125,43.0 +irrm_pretrained,log10_pgen_1mm,all,79730,43,201.51,0.19844419233978014,0.10745138967990057,0.9848587623496916,0.994074687121133,0.9932460677425246,0.00047019676069362895,76702.7717764188,0.013037338506030836,cuda,1580.54296875,254.86376953125,45.0 +irrm_pretrained,log10_pgen_1mm,all,79730,44,211.1,0.22832235688634206,0.12134789785717585,0.9799561350952133,0.9932992236706577,0.9903972598369296,0.008108554940664215,77555.84641114557,0.012893934452068462,cuda,1590.78515625,254.86376953125,45.0 +irrm_pretrained,log10_pgen_1mm,all,79730,45,218.6,0.214663543875197,0.10917544386411444,0.9822825515055111,0.9931988998785725,0.9902501268322028,0.01889345747215228,77644.95169252451,0.012879137383715803,cuda,1587.48828125,254.86376953125,49.0 +irrm_pretrained,log10_pgen_1mm,all,79730,46,202.2,0.19382356300065293,0.10396384714341159,0.9855556589259883,0.9949288895266005,0.996159075626305,0.03274914680978691,76330.32244284997,0.013100953434969701,cuda,1582.69140625,254.86376953125,45.0 +irrm_pretrained,log10_pgen_1mm,all,79730,47,264.54,0.20821800322930945,0.10973956171749896,0.9833305548661806,0.9948324953928825,0.9952488381802871,0.008130821087864773,77603.79416967419,0.01288596789241495,cuda,1589.7421875,254.86376953125,56.0 +irrm_pretrained,log10_pgen_1mm,all,79730,48,157.77,0.21873573252501982,0.12205762993538553,0.9816039721229748,0.9933163416010036,0.9946624243808212,0.010566345166154303,76365.73780152647,0.013094877739530084,cuda,1580.36328125,254.86376953125,35.0 +irrm_pretrained,log10_pgen_1mm,all,79730,49,140.76,0.21032706256829567,0.1248383391297992,0.9829911519147718,0.9953674218542565,0.995268712887437,0.06345402711592327,76480.93193590423,0.013075154482140229,cuda,1578.29296875,254.86376953125,31.0 +irrm_pretrained,log10_pgen_1mm,all,79730,50,98.67,0.3050127360048115,0.2223549543074473,0.9642298684623126,0.9866466817661931,0.9767291951976588,0.1524269310931368,77514.2341875952,0.012900856345685635,cuda,1577.84375,254.86376953125,21.0 +irrm_pretrained,log10_pgen_1mm,all,79730,51,174.39,0.2025477173651247,0.11567008877527189,0.9842260922848269,0.9934815527437457,0.9921715207108387,-0.018485427401458462,77031.87929353648,0.012981638370646724,cuda,1575.97265625,254.86376953125,39.0 +irrm_scratch,log10_pgen_1mm,all,79730,42,100.9,0.19633344317316612,0.12458027456075794,0.9851791485170951,0.9931292366678238,0.9947710352522292,0.050957250625054906,77995.24701890766,0.0128212940944668,cuda,1589.96484375,254.86376953125,23.0 +irrm_scratch,log10_pgen_1mm,all,79730,43,117.63,0.24310322146472474,0.15923510689506007,0.9772769817622599,0.9934988890065156,0.9949599529712726,0.05080266396051272,78482.72969605918,0.012741656716996334,cuda,1590.64453125,254.86376953125,25.0 +irrm_scratch,log10_pgen_1mm,all,79730,44,93.54,0.2137935159265193,0.13860440255569756,0.9824258775437755,0.9917096398136698,0.9936772681741826,-0.005426926835017065,77045.82669410027,0.012979288339268017,cuda,1585.46484375,254.86376953125,21.0 +irrm_scratch,log10_pgen_1mm,all,79730,45,88.95,0.24961439845675001,0.16239639861369026,0.976043473157776,0.9894739139539525,0.9908986908663686,0.050949834173454445,76718.78796334841,0.013034616767899663,cuda,1587.9609375,254.86376953125,19.0 +irrm_scratch,log10_pgen_1mm,all,79730,46,114.28,0.24344421065623903,0.1654815839553585,0.9772131920875918,0.9932718413750967,0.9946481437848445,0.000411995501209572,76869.21650122834,0.01300910878913434,cuda,1570.91796875,254.86376953125,25.0 +irrm_scratch,log10_pgen_1mm,all,79730,47,162.25,0.2623964374412026,0.15666522343761038,0.9735271646889943,0.9947957802738262,0.9963339789925373,0.07214033209339996,77821.99642085207,0.01284983739805542,cuda,1580.6953125,254.86376953125,36.0 +irrm_scratch,log10_pgen_1mm,all,79730,48,94.34,0.2756881202965431,0.1874225016620911,0.9707772761679718,0.9914597073267497,0.9936345681852634,0.13766648666405745,76817.75721149794,0.013017823434323356,cuda,1566.234375,254.86376953125,21.0 +irrm_scratch,log10_pgen_1mm,all,79730,49,94.61,0.25040927656190526,0.16263100405986253,0.9758906547425884,0.9906799443983614,0.9925507522500705,0.11173074335760001,76616.09987191304,0.013052086985265526,cuda,1590.24609375,254.86376953125,21.0 +irrm_scratch,log10_pgen_1mm,all,79730,50,101.62,0.22903029253875162,0.14824262140358074,0.979831646498065,0.9914505658360079,0.9938290217871487,0.042517517343130445,77764.52751135893,0.012859333580518852,cuda,1592.57421875,254.86376953125,22.0 +irrm_scratch,log10_pgen_1mm,all,79730,51,80.82,0.27079802850363044,0.17755006597799897,0.9718047736339673,0.9866817276800025,0.9915138366409755,-0.04579108726461479,76768.9593331389,0.013026098161113529,cuda,1578.109375,254.86376953125,18.0 +sceptr_mlp,log10_pgen_1mm,all,79730,42,58.13,0.4422856412715362,0.24850351471532656,0.9247874575108979,0.9628673381017279,0.9787701463480561,0.06165277549235565,1026396.787782811,0.0009742820826243693,cuda,1195.98828125,21.20751953125,60.0 +sceptr_mlp,log10_pgen_1mm,all,79730,43,58.16,0.4532838787285646,0.2528874805480784,0.9210003556570947,0.9610954079350825,0.9781999681797215,0.07523289538804193,1036979.2601728663,0.0009643394409192893,cuda,1188.16796875,21.20751953125,60.0 +sceptr_mlp,log10_pgen_1mm,all,79730,44,58.97,0.4438398228288394,0.251492624705254,0.9242579384996292,0.9624833450691401,0.9780063631797343,0.05573852857717545,1067511.1234785551,0.0009367583887476829,cuda,1195.93359375,21.20751953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,all,79730,42,70.1,0.27590123549840345,0.1670392069257,0.9707320786177651,0.9854458261580342,0.9908209029750301,0.015594443637952673,486114.4564435013,0.0020571287003397836,cuda,1669.57421875,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,all,79730,43,72.57,0.27667355629747115,0.1669020757783433,0.9705679919147793,0.985455078383879,0.9908143589668412,0.01800416090842117,481155.3265214974,0.002078330935728135,cuda,1670.77734375,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,all,79730,44,70.66,0.277176078142094,0.16742615472770725,0.9704609801791605,0.9854239740579062,0.9906712868241694,0.01896631708478492,471095.082362874,0.0021227137311310806,cuda,1664.90234375,28.14501953125,60.0 +tfidf_ridge,log10_pgen_1mm,all,79730,42,8.65,0.5542270263983469,0.36706299488768934,0.8818972557236601,0.9391297435576847,0.9565962719889497,0.0035393838152091624,67434.86203217156,0.01482912502323982,cpu,717.2109375,0.0, diff --git a/results/pgen/pgen_summary.csv b/results/pgen/pgen_summary.csv new file mode 100644 index 0000000..28f519b --- /dev/null +++ b/results/pgen/pgen_summary.csv @@ -0,0 +1,37 @@ +target,train_subset,arm,seeds,train_size,rmse_mean,rmse_std,mae_mean,mae_std,r2_mean,r2_std,pearson_r_mean,pearson_r_std,spearman_rho_mean,spearman_rho_std,bias_mean,bias_std,training_seconds_mean,inference_seq_per_second_mean,peak_rss_mb_mean,peak_gpu_mb_mean +log10_pgen,1k,irrm_pretrained,10,1000,0.81540254540097,0.023651584767435244,0.5363845145896604,0.01761324618463643,0.8104657560730872,0.011097509580039815,0.9230052240535637,0.006701123055612074,0.9153326713831202,0.007112225627182163,0.32453740767930384,0.06286931463118653,6.049,79910.55138167983,1553.811328125,255.98876953125 +log10_pgen,1k,irrm_scratch,10,1000,0.8605530608233808,0.07907712609580614,0.5498540931749136,0.05496680052186431,0.7874514668265794,0.038402525773423256,0.9009418384515987,0.01869080920210034,0.900028262220985,0.021674349507537095,0.22982628971813562,0.12186389434072437,8.514,79743.93268363111,1554.234765625,255.98876953125 +log10_pgen,1k,tcr_bert_mlp,3,1000,0.8641840324486602,0.004571642536440778,0.5752700931258724,0.0026833632063272307,0.7872667330672515,0.0022475456545458564,0.8909852972973177,0.0013013139211785886,0.8942322659764437,0.0011842031778845218,0.09581540536927798,0.013044363649120726,5.343333333333334,481114.6119121562,1245.4192708333333,28.14501953125 +log10_pgen,1k,esm2_8m_mlp,3,1000,1.0739526536751358,0.003907657319455539,0.7270157322746377,0.0014533144669035686,0.6714594832157674,0.0023890385099123545,0.8222751241532199,0.000640771264232261,0.8331926446969974,0.0008683152203000417,0.1260789402176629,0.021590187659655407,4.8500000000000005,729356.5891250572,1196.0377604166667,23.45751953125 +log10_pgen,1k,sceptr_mlp,3,1000,1.097410607246145,0.0030375912434647237,0.7608200931599853,0.0017949689951640149,0.6569516321168019,0.0018981335130340972,0.8125005378142754,0.000726167976573551,0.806905067511356,0.0020307833308386533,0.1050660153327495,0.012487634130457757,3.7866666666666666,1065071.8303443855,1171.9544270833333,21.20751953125 +log10_pgen,1k,tfidf_ridge,1,1000,1.2769573384805994,,0.8800498060420275,,0.5355193690361973,,0.7459276280012653,,0.7755959954308803,,0.24748512995339594,,0.18,82046.7449062024,647.671875,0.0 +log10_pgen,10k,irrm_scratch,10,10000,0.48468864648435217,0.017093841387999915,0.3079190504390036,0.01637888879825529,0.9330074645214808,0.004709659869646582,0.9699538184023497,0.0027724153081702158,0.9741865097600041,0.0029359356023705156,0.1198594851930735,0.0708025137861426,28.534999999999997,78848.62979964017,1590.3546875,255.36376953125 +log10_pgen,10k,irrm_pretrained,10,10000,0.5149901453584536,0.025042621888465344,0.3603541024110505,0.027959074461221787,0.9242930177410577,0.007147733530583638,0.9754821518342982,0.0038646581191170513,0.9696832402360751,0.0066390374950387595,0.27567033535985275,0.035946894046752415,23.556,78523.54086732784,1592.05234375,255.36376953125 +log10_pgen,10k,tcr_bert_mlp,3,10000,0.5516122944038125,0.0021603582102378664,0.3603219131355763,0.001185466400222133,0.9133263377640586,0.0006781907878428965,0.956285157462856,0.00022764843655370855,0.9606232028599339,0.00043275795888619406,0.02947473944772257,0.0070081258362111026,12.99,480017.0692198961,1276.5963541666667,28.14501953125 +log10_pgen,10k,tfidf_ridge,1,10000,0.7659173935252817,,0.5084553048733631,,0.8328991356685383,,0.9129315175825418,,0.9404240652599085,,0.03423890204930655,,0.58,79360.64652403284,652.96484375,0.0 +log10_pgen,10k,esm2_8m_mlp,3,10000,0.7913584933496525,0.0022681686173861636,0.5107760796181203,0.0014980266616373488,0.8216127764872111,0.0010229088193688608,0.9076156426797676,0.0006399553131931383,0.9226369015627661,0.0006428760803300136,0.07899573897879536,0.013855768051405546,12.530000000000001,716944.7026687836,1217.8815104166667,23.45751953125 +log10_pgen,10k,sceptr_mlp,3,10000,0.8214505411013961,0.0017721037636965911,0.534502310892864,0.0033169693385023216,0.8077886542604048,0.0008293970081266804,0.8998059552994505,0.0003966274326964802,0.9102131961914464,0.000864334949118416,0.07262300909338824,0.005833706923441675,11.246666666666668,1021530.1494876714,1182.546875,21.20751953125 +log10_pgen,all,irrm_pretrained,10,79730,0.31017690475410065,0.03876912606322715,0.1925337933537014,0.0421692419704994,0.9722094243698776,0.0071918253654449016,0.9911934932097092,0.002627633642411745,0.988261224579343,0.005649934632632095,0.11768424049840458,0.04843363342634476,158.781,77118.10143799629,1593.01328125,254.86376953125 +log10_pgen,all,irrm_scratch,10,79730,0.3114129649713904,0.03330243911503736,0.2026686762306246,0.025686145645484902,0.972091574015385,0.006053100947354877,0.9921383974868743,0.0030753230018360387,0.9927640057242495,0.0024501388116768847,0.09871997901982245,0.046786331452667265,131.178,77301.63643012849,1579.693359375,254.86376953125 +log10_pgen,all,tcr_bert_mlp,3,79730,0.37576665017247074,0.0018731171749935922,0.23334980691737092,0.001147842183293328,0.959778478734926,0.0004011899273065553,0.9800374676077827,0.0002548146313769847,0.9851189500136984,0.0004239194870380052,0.023774566055857788,0.0012340738433489955,74.11,482204.1447037112,1666.4921875,28.14501953125 +log10_pgen,all,esm2_8m_mlp,3,79730,0.5727862854746651,0.0004557230451824632,0.34935756712203453,0.0004224821792519374,0.906545495984861,0.00014868716086941896,0.9534896057040494,0.00024764840122839165,0.9672519631455843,0.0004119721497089627,0.0745543660728548,0.007573095317883042,62.94333333333333,739699.4628127055,1296.2174479166667,23.45751953125 +log10_pgen,all,sceptr_mlp,3,79730,0.5795004266216509,0.004624225940520761,0.3442356353191398,0.0012591644567361206,0.9043377068184898,0.0015301220456800072,0.9532377971839475,0.000666761216473622,0.9668332557858953,0.00042302343036070976,0.09755030382889791,0.009563877131517034,60.583333333333336,1029364.2784961942,1193.4205729166667,21.20751953125 +log10_pgen,all,tfidf_ridge,1,79730,0.6210225099572112,,0.41454671189516185,,0.8901425494415403,,0.9434950444517985,,0.9563135820470278,,0.008684176700797186,,8.4,68718.25314155618,714.09765625,0.0 +log10_pgen_1mm,1k,irrm_pretrained,10,1000,0.6262719413828294,0.01830265138298122,0.3955077027607018,0.00961961574615435,0.8490809012780591,0.00880504553440322,0.9393137563872822,0.006548271545908237,0.9439822027783091,0.00589778494371969,0.24200087457294406,0.04804549899851409,6.465000000000001,79076.58743231386,1553.939453125,255.98876953125 +log10_pgen_1mm,1k,tcr_bert_mlp,3,1000,0.685144286570226,0.002153496133772639,0.43468398635694316,0.0008122116639941274,0.8195106709311563,0.0011344461621800414,0.9089732477151248,0.0005783007075420176,0.9260142078177989,0.0004060297908214042,0.07944990736101322,0.007503188590872171,4.973333333333334,474278.88027787465,1241.6861979166667,28.14501953125 +log10_pgen_1mm,1k,irrm_scratch,10,1000,0.6946828977880078,0.09169235422773352,0.4396730913095346,0.07394649046737808,0.8115420155347044,0.05006709040749404,0.9209237429346361,0.009130494064272706,0.92715291142624,0.01084600102257937,0.229206009669244,0.16953090969254042,7.931,78145.45197570449,1559.0765625,255.98876953125 +log10_pgen_1mm,1k,esm2_8m_mlp,3,1000,0.8615945278815476,0.0024225274486241732,0.5685573828281646,0.0008542452596914314,0.7145745186220601,0.0016045201855514647,0.8475403525356285,0.0005475393573428439,0.8674118138794791,0.0010102596207092706,0.09769012470210969,0.013496899355350991,5.140000000000001,735856.4119480439,1197.7799479166667,23.45751953125 +log10_pgen_1mm,1k,sceptr_mlp,3,1000,0.873569962655704,0.001278608640091633,0.5872807465781368,0.0017447483024049287,0.7065861603477129,0.000859261187461126,0.8419430222976985,0.0007044658486279333,0.8544503515961605,0.001305025388521403,0.07670004736733034,0.005688838971975157,4.346666666666667,1028820.2455296965,1171.2317708333333,21.20751953125 +log10_pgen_1mm,1k,tfidf_ridge,1,1000,1.085296409794027,,0.73535530121258,,0.5471218978219647,,0.750774560158103,,0.795403603438914,,0.18915308819686613,,0.19,80950.28937014837,643.671875,0.0 +log10_pgen_1mm,10k,irrm_scratch,10,10000,0.37544649188982115,0.05393243068687214,0.23577393103520206,0.04089320136394839,0.9447957898778669,0.01791525764663305,0.9754370036887015,0.0038427589703087235,0.9807582721749771,0.00451351584966454,0.08146111243136314,0.08586850228496051,26.005000000000003,78150.25535034612,1581.172265625,255.36376953125 +log10_pgen_1mm,10k,irrm_pretrained,10,10000,0.38134067696205276,0.027442508022011,0.2542467817755318,0.02295537004741706,0.9438266494916274,0.0076933826463340274,0.9815385301853583,0.0027043074180465344,0.9785087302017675,0.004963049737352929,0.18800522715017878,0.03347324976757551,24.767,78459.65347761178,1587.60703125,255.36376953125 +log10_pgen_1mm,10k,tcr_bert_mlp,3,10000,0.41190235103679723,0.0013890241512824646,0.25669393850789196,0.0017155417017192197,0.9347656373928152,0.00044039284910229917,0.9672464846909655,0.00032551430104860114,0.9758391756576296,0.00020704041320170286,0.01661317124627551,0.00894797698767368,13.696666666666667,478703.45815385296,1281.9127604166667,28.14501953125 +log10_pgen_1mm,10k,esm2_8m_mlp,3,10000,0.6247899714509164,0.0020961953451629095,0.39108601612116534,0.002604252012107772,0.8499085517012229,0.0010061435225250147,0.9228086720675472,0.0009210947503702813,0.9425420893779722,0.0008079743916434745,0.05559858269994359,0.008431332591102741,12.863333333333335,735642.5400245866,1221.5703125,23.45751953125 +log10_pgen_1mm,10k,sceptr_mlp,3,10000,0.6385171609346493,0.0019604975562168936,0.39748508241258484,0.0012657825132708074,0.8432410064002456,0.0009634019559633482,0.9188284272422029,0.0004262476087169893,0.9392381526783972,0.00019724605799668942,0.044973629620426524,0.0037911682871111067,11.646666666666667,1039275.5822895527,1185.7122395833333,21.20751953125 +log10_pgen_1mm,10k,tfidf_ridge,1,10000,0.679848528075636,,0.44560910401677106,,0.8222912089245368,,0.9069106930892485,,0.9418412049600424,,0.018927686789477982,,0.55,79617.02327020983,651.0703125,0.0 +log10_pgen_1mm,all,irrm_pretrained,10,79730,0.21811147813829623,0.032210945564203126,0.12475846464670519,0.034986743339859155,0.9813497911570795,0.006241034205243758,0.9934877653197903,0.002576512029083435,0.992083726131284,0.005850870340073854,0.033805298153456245,0.049056661532578,186.68599999999998,77093.5363036828,1584.332421875,254.86376953125 +log10_pgen_1mm,all,irrm_scratch,10,79730,0.24346109450194323,0.024810691892533376,0.1582809183121708,0.018059866352145078,0.9769970188800086,0.004526437952595065,0.9916151246332007,0.002322840744846866,0.9936817248904892,0.001651159132919006,0.04659588096187876,0.05440170415855433,104.894,77290.11482224047,1583.28125,254.86376953125 +log10_pgen_1mm,all,tcr_bert_mlp,3,79730,0.2765836233126562,0.0006421618938097269,0.16712247914391684,0.000271781866644313,0.9705870169039016,0.00013654689125638776,0.9854416261999398,1.5971834883716513e-05,0.9907688495886803,8.455516409449843e-05,0.017521640543719588,0.001736951945831234,71.11,479454.95510929095,1668.41796875,28.14501953125 +log10_pgen_1mm,all,sceptr_mlp,3,79730,0.44646978094298007,0.005952127061135091,0.2509612066562197,0.00223977520363394,0.9233485838892074,0.002050787523950637,0.9621486970353169,0.0009321620614320843,0.9783254925691707,0.0003970622889583402,0.06420806648585768,0.00999523478389865,58.419999999999995,1043629.0571447442,1193.36328125,21.20751953125 +log10_pgen_1mm,all,esm2_8m_mlp,3,79730,0.45393456930558324,0.00153386906096142,0.2654829299913543,0.00023225770136071967,0.9207727812660104,0.0005349109434407152,0.9607129637035211,0.00014495604518536024,0.976231853929708,0.00016747358961218396,0.05494076415998711,0.0040845593124909495,67.82333333333334,726935.7194829332,1295.1966145833333,23.45751953125 +log10_pgen_1mm,all,tfidf_ridge,1,79730,0.5542270263983469,,0.36706299488768934,,0.8818972557236601,,0.9391297435576847,,0.9565962719889497,,0.0035393838152091624,,8.65,67434.86203217156,717.2109375,0.0 diff --git a/results/pgen/pgen_summary.md b/results/pgen/pgen_summary.md new file mode 100644 index 0000000..1730a22 --- /dev/null +++ b/results/pgen/pgen_summary.md @@ -0,0 +1,70 @@ +### log10_pgen + +**train = 1k (1,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | 0.8154 ± 0.0237 | 0.5364 | 0.8105 | 0.9230 | 0.9153 | +0.3245 | 6 | 79911 | 1554 | +| irrm_scratch | 0.8606 ± 0.0791 | 0.5499 | 0.7875 | 0.9009 | 0.9000 | +0.2298 | 9 | 79744 | 1554 | +| tcr_bert_mlp | 0.8642 ± 0.0046 | 0.5753 | 0.7873 | 0.8910 | 0.8942 | +0.0958 | 5 | 481115 | 1245 | +| esm2_8m_mlp | 1.0740 ± 0.0039 | 0.7270 | 0.6715 | 0.8223 | 0.8332 | +0.1261 | 5 | 729357 | 1196 | +| sceptr_mlp | 1.0974 ± 0.0030 | 0.7608 | 0.6570 | 0.8125 | 0.8069 | +0.1051 | 4 | 1065072 | 1172 | +| tfidf_ridge | 1.2770 | 0.8800 | 0.5355 | 0.7459 | 0.7756 | +0.2475 | 0 | 82047 | 648 | + +**train = 10k (10,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_scratch | 0.4847 ± 0.0171 | 0.3079 | 0.9330 | 0.9700 | 0.9742 | +0.1199 | 29 | 78849 | 1590 | +| irrm_pretrained | 0.5150 ± 0.0250 | 0.3604 | 0.9243 | 0.9755 | 0.9697 | +0.2757 | 24 | 78524 | 1592 | +| tcr_bert_mlp | 0.5516 ± 0.0022 | 0.3603 | 0.9133 | 0.9563 | 0.9606 | +0.0295 | 13 | 480017 | 1277 | +| tfidf_ridge | 0.7659 | 0.5085 | 0.8329 | 0.9129 | 0.9404 | +0.0342 | 1 | 79361 | 653 | +| esm2_8m_mlp | 0.7914 ± 0.0023 | 0.5108 | 0.8216 | 0.9076 | 0.9226 | +0.0790 | 13 | 716945 | 1218 | +| sceptr_mlp | 0.8215 ± 0.0018 | 0.5345 | 0.8078 | 0.8998 | 0.9102 | +0.0726 | 11 | 1021530 | 1183 | + +**train = all (79,730 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | 0.3102 ± 0.0388 | 0.1925 | 0.9722 | 0.9912 | 0.9883 | +0.1177 | 159 | 77118 | 1593 | +| irrm_scratch | 0.3114 ± 0.0333 | 0.2027 | 0.9721 | 0.9921 | 0.9928 | +0.0987 | 131 | 77302 | 1580 | +| tcr_bert_mlp | 0.3758 ± 0.0019 | 0.2333 | 0.9598 | 0.9800 | 0.9851 | +0.0238 | 74 | 482204 | 1666 | +| esm2_8m_mlp | 0.5728 ± 0.0005 | 0.3494 | 0.9065 | 0.9535 | 0.9673 | +0.0746 | 63 | 739699 | 1296 | +| sceptr_mlp | 0.5795 ± 0.0046 | 0.3442 | 0.9043 | 0.9532 | 0.9668 | +0.0976 | 61 | 1029364 | 1193 | +| tfidf_ridge | 0.6210 | 0.4145 | 0.8901 | 0.9435 | 0.9563 | +0.0087 | 8 | 68718 | 714 | + +### log10_pgen_1mm + +**train = 1k (1,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | 0.6263 ± 0.0183 | 0.3955 | 0.8491 | 0.9393 | 0.9440 | +0.2420 | 6 | 79077 | 1554 | +| tcr_bert_mlp | 0.6851 ± 0.0022 | 0.4347 | 0.8195 | 0.9090 | 0.9260 | +0.0794 | 5 | 474279 | 1242 | +| irrm_scratch | 0.6947 ± 0.0917 | 0.4397 | 0.8115 | 0.9209 | 0.9272 | +0.2292 | 8 | 78145 | 1559 | +| esm2_8m_mlp | 0.8616 ± 0.0024 | 0.5686 | 0.7146 | 0.8475 | 0.8674 | +0.0977 | 5 | 735856 | 1198 | +| sceptr_mlp | 0.8736 ± 0.0013 | 0.5873 | 0.7066 | 0.8419 | 0.8545 | +0.0767 | 4 | 1028820 | 1171 | +| tfidf_ridge | 1.0853 | 0.7354 | 0.5471 | 0.7508 | 0.7954 | +0.1892 | 0 | 80950 | 644 | + +**train = 10k (10,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_scratch | 0.3754 ± 0.0539 | 0.2358 | 0.9448 | 0.9754 | 0.9808 | +0.0815 | 26 | 78150 | 1581 | +| irrm_pretrained | 0.3813 ± 0.0274 | 0.2542 | 0.9438 | 0.9815 | 0.9785 | +0.1880 | 25 | 78460 | 1588 | +| tcr_bert_mlp | 0.4119 ± 0.0014 | 0.2567 | 0.9348 | 0.9672 | 0.9758 | +0.0166 | 14 | 478703 | 1282 | +| esm2_8m_mlp | 0.6248 ± 0.0021 | 0.3911 | 0.8499 | 0.9228 | 0.9425 | +0.0556 | 13 | 735643 | 1222 | +| sceptr_mlp | 0.6385 ± 0.0020 | 0.3975 | 0.8432 | 0.9188 | 0.9392 | +0.0450 | 12 | 1039276 | 1186 | +| tfidf_ridge | 0.6798 | 0.4456 | 0.8223 | 0.9069 | 0.9418 | +0.0189 | 1 | 79617 | 651 | + +**train = all (79,730 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | 0.2181 ± 0.0322 | 0.1248 | 0.9813 | 0.9935 | 0.9921 | +0.0338 | 187 | 77094 | 1584 | +| irrm_scratch | 0.2435 ± 0.0248 | 0.1583 | 0.9770 | 0.9916 | 0.9937 | +0.0466 | 105 | 77290 | 1583 | +| tcr_bert_mlp | 0.2766 ± 0.0006 | 0.1671 | 0.9706 | 0.9854 | 0.9908 | +0.0175 | 71 | 479455 | 1668 | +| sceptr_mlp | 0.4465 ± 0.0060 | 0.2510 | 0.9233 | 0.9621 | 0.9783 | +0.0642 | 58 | 1043629 | 1193 | +| esm2_8m_mlp | 0.4539 ± 0.0015 | 0.2655 | 0.9208 | 0.9607 | 0.9762 | +0.0549 | 68 | 726936 | 1295 | +| tfidf_ridge | 0.5542 | 0.3671 | 0.8819 | 0.9391 | 0.9566 | +0.0035 | 9 | 67435 | 717 | + diff --git a/results/pgen/pretraining_delta.csv b/results/pgen/pretraining_delta.csv new file mode 100644 index 0000000..9ca3d57 --- /dev/null +++ b/results/pgen/pretraining_delta.csv @@ -0,0 +1,7 @@ +target,train_subset,n_scratch,n_pretrained,irrm_scratch,irrm_pretrained,rmse_delta,relative_improvement,p_value,verdict +log10_pgen,1k,10,10,0.8605530608233808,0.81540254540097,0.045150515422410775,0.05246685820768631,0.11262996695012906,no detectable effect +log10_pgen,10k,10,10,0.48468864648435217,0.5149901453584536,-0.030301498874101385,-0.06251745134508664,0.006104018174065397,pretraining hurts +log10_pgen,all,10,10,0.31141296497139037,0.31017690475410065,0.001236060217289725,0.003969199604143913,0.9399003420219125,no detectable effect +log10_pgen_1mm,1k,10,10,0.6946828977880077,0.6262719413828294,0.06841095640517836,0.09847796256826079,0.04394678471543129,pretraining helps +log10_pgen_1mm,10k,10,10,0.37544649188982115,0.38134067696205276,-0.005894185072231606,-0.01569913476235468,0.7628154827592442,no detectable effect +log10_pgen_1mm,all,10,10,0.24346109450194325,0.21811147813829623,0.02534961636364702,0.10412183686065161,0.06525425563284348,no detectable effect diff --git a/results/pgen/speed_end_to_end_cpu.csv b/results/pgen/speed_end_to_end_cpu.csv new file mode 100644 index 0000000..cc1d905 --- /dev/null +++ b/results/pgen/speed_end_to_end_cpu.csv @@ -0,0 +1,6 @@ +arm,device,sequences_per_second,ms_per_sequence,seconds_total +tfidf_ridge,cpu,82842.20607184026,0.012071141600608825,0.06035570800304413 +irrm,cpu,3776.528412201475,0.26479345336556437,1.3239672668278217 +sceptr_mlp,cpu,1264.9458164759842,0.7905476953834295,3.9527384769171476 +esm2_8m_mlp,cpu,812.9761726854197,1.2300483502447606,6.150241751223803 +tcr_bert_mlp,cpu,215.6417930730961,4.637320000678301,23.186600003391504 diff --git a/results/pgen/speed_end_to_end_cuda.csv b/results/pgen/speed_end_to_end_cuda.csv new file mode 100644 index 0000000..5a644ee --- /dev/null +++ b/results/pgen/speed_end_to_end_cuda.csv @@ -0,0 +1,6 @@ +arm,device,sequences_per_second,ms_per_sequence,seconds_total +tfidf_ridge,cuda,86660.47446799547,0.011539286002516747,0.05769643001258373 +irrm,cuda,64813.57391703495,0.01542886681854725,0.07714433409273624 +esm2_8m_mlp,cuda,9392.62324529416,0.10646652951836587,0.5323326475918293 +tcr_bert_mlp,cuda,4038.584267802087,0.24761152267456055,1.2380576133728027 +sceptr_mlp,cuda,2495.308062377455,0.4007521215826273,2.0037606079131365 diff --git a/results/pgen_constlr/pgen_runs.csv b/results/pgen_constlr/pgen_runs.csv new file mode 100644 index 0000000..5eaca29 --- /dev/null +++ b/results/pgen_constlr/pgen_runs.csv @@ -0,0 +1,181 @@ +arm,target,train_subset,train_size,seed,training_seconds,rmse,mae,r2,pearson_r,spearman_rho,bias,inference_seq_per_second,inference_ms_per_sequence,device,peak_rss_mb,peak_gpu_mb,epochs_ran +esm2_8m_mlp,log10_pgen,1k,1000,42,3.94,1.0915541051919524,0.7402943732362133,0.660605057411438,0.8169628083446634,0.8234968097446708,0.15321451674286654,516076.35393841757,0.0019376977696585731,cuda,1199.19140625,23.45751953125,36.0 +esm2_8m_mlp,log10_pgen,1k,1000,43,3.62,1.0795015732119884,0.7359788250816464,0.6680586231435096,0.8196909145226835,0.825906573915183,0.11602056096385072,521901.14098656137,0.0019160716876565505,cuda,1202.671875,23.45751953125,33.0 +esm2_8m_mlp,log10_pgen,1k,1000,44,4.23,1.0792830312542607,0.7377109537684872,0.6681930106739722,0.8189650446270591,0.8286560440522147,0.09293785484005393,533565.0251171781,0.0018741858122735583,cuda,1198.1796875,23.45751953125,39.0 +irrm_pretrained,log10_pgen,1k,1000,42,9.58,0.8726550760693804,0.5738058147665613,0.783079762948996,0.9159395638398967,0.904600743389775,0.3580331865933481,51294.28117321873,0.01949535069266377,cuda,1545.14453125,255.98876953125,24.0 +irrm_pretrained,log10_pgen,1k,1000,43,9.41,0.8380269458087515,0.5430632993028036,0.799953573378763,0.9165763115138791,0.9104608804983463,0.29427279298237435,51134.894099149045,0.01955611755176474,cuda,1530.4296875,255.98876953125,24.0 +irrm_pretrained,log10_pgen,1k,1000,44,10.64,0.8284073138270375,0.5369289222086728,0.8045198421966144,0.9202394479936183,0.9145521115122686,0.31079326245117705,50260.79320984828,0.019896223997596132,cuda,1533.0625,255.98876953125,27.0 +irrm_pretrained,log10_pgen,1k,1000,45,6.98,0.8730714403127777,0.5729750874305046,0.7828727180827383,0.9150187388529426,0.9086835384224735,0.3783469468940029,80348.14928043708,0.012445837383381736,cuda,1551.4609375,255.98876953125,28.0 +irrm_pretrained,log10_pgen,1k,1000,46,10.14,0.8955693146946709,0.5783578312292941,0.7715383856109055,0.9135258281103794,0.9083706530804575,0.3708126548954926,50534.95524079303,0.019788283085146102,cuda,1527.92578125,255.98876953125,26.0 +irrm_pretrained,log10_pgen,1k,1000,47,5.36,0.8396945597007993,0.5545821248403418,0.7991566249701977,0.9113736381289581,0.9056997342503031,0.28816276817374503,80618.55931828934,0.012404091668915962,cuda,1551.01953125,255.98876953125,21.0 +irrm_pretrained,log10_pgen,1k,1000,48,7.28,0.8150718432048386,0.5475463423471961,0.8107627565877321,0.9143665674978133,0.905040473254371,0.1834927141464866,50143.35650795583,0.019942821335491138,cuda,1533.8359375,255.98876953125,18.0 +irrm_pretrained,log10_pgen,1k,1000,49,8.05,0.8704777136313411,0.5613098881755785,0.7841608882495538,0.9197475352791084,0.9121646002518446,0.3501417096914958,80054.3104401068,0.012491519750809137,cuda,1556.7109375,255.98876953125,32.0 +irrm_pretrained,log10_pgen,1k,1000,50,9.15,0.8728682173569736,0.5556686607249849,0.7829737868166594,0.9069782520813081,0.9077522395634259,0.26813947600043,49952.29768064458,0.020019099149216475,cuda,1524.78125,255.98876953125,23.0 +irrm_pretrained,log10_pgen,1k,1000,51,5.82,0.8444090542591324,0.550895488311041,0.7968950094359974,0.9150288894370522,0.9074025004235194,0.29766531813792796,80316.62807986789,0.01245072189790621,cuda,1566.3046875,255.98876953125,23.0 +irrm_scratch,log10_pgen,1k,1000,42,13.39,0.8273421285536087,0.5551784896127165,0.8050222248124117,0.909914579519032,0.9121780503326388,0.008624446700217612,50720.321822123,0.019715963228841813,cuda,1529.171875,255.98876953125,29.0 +irrm_scratch,log10_pgen,1k,1000,43,16.43,0.7659800942598978,0.4832207026282427,0.8328717756010071,0.9169360837216642,0.9190804948555896,0.13152816635376696,51292.88083902965,0.019495882930386756,cuda,1526.18359375,255.98876953125,37.0 +irrm_scratch,log10_pgen,1k,1000,44,14.37,0.7734791074501303,0.48697228424591754,0.8295833567191366,0.9177807024004445,0.9177315561830938,0.134461495555832,50365.65252164455,0.019854800840121183,cuda,1539.015625,255.98876953125,36.0 +irrm_scratch,log10_pgen,1k,1000,45,6.0,0.8539224789496141,0.5486367348054839,0.7922927172235745,0.8934616865743961,0.8922835537384012,0.14120462825912458,81472.33337984262,0.012274105312999588,cuda,1563.94921875,255.98876953125,24.0 +irrm_scratch,log10_pgen,1k,1000,46,10.49,0.821753873046916,0.5321979550634945,0.8076472714601192,0.9006659274404937,0.8979426733955749,0.10031384699661687,50611.856025323556,0.019758216325827915,cuda,1526.07421875,255.98876953125,27.0 +irrm_scratch,log10_pgen,1k,1000,47,7.49,0.8155386677194593,0.5207589655369478,0.8105459269103279,0.9062289998614832,0.9034322766161501,0.1744060220632375,81164.71916927739,0.012320624160780953,cuda,1555.8046875,255.98876953125,30.0 +irrm_scratch,log10_pgen,1k,1000,48,10.13,1.0387836221780697,0.6855247208672894,0.6926274929312484,0.894016387851271,0.8914120357400651,0.5572090034998788,50667.35209156709,0.019736575106446837,cuda,1527.1015625,255.98876953125,26.0 +irrm_scratch,log10_pgen,1k,1000,49,5.84,0.8624344844562729,0.5699924510092282,0.7881311746289452,0.8912662667482427,0.8891159235445192,0.07916370451294726,80878.741597902,0.01236418841642734,cuda,1541.0234375,255.98876953125,23.0 +irrm_scratch,log10_pgen,1k,1000,50,11.18,0.8471909549401387,0.5283402923875888,0.7955545485946303,0.9049882896587529,0.9049888220927975,0.2020672699252005,50459.30508681347,0.019817950292409597,cuda,1538.03125,255.98876953125,29.0 +irrm_scratch,log10_pgen,1k,1000,51,7.99,0.7730128518213162,0.5031581391390016,0.8297887501673299,0.9138801307741508,0.9151692724245305,0.02280371236558214,80576.88220665505,0.012410507488181363,cuda,1577.8984375,255.98876953125,32.0 +sceptr_mlp,log10_pgen,1k,1000,42,4.47,1.1015078458851626,0.7649751967259993,0.6543870382698407,0.8100436681628357,0.804978245151527,0.07793970883382847,778354.4681485145,0.0012847616875364225,cuda,1170.66796875,21.20751953125,43.0 +sceptr_mlp,log10_pgen,1k,1000,43,3.26,1.1016636574753431,0.7619187374556721,0.6542892553733989,0.811423946447547,0.8051246776840334,0.12022796173619192,882398.3426362096,0.0011332750206810786,cuda,1166.8515625,21.20751953125,32.0 +sceptr_mlp,log10_pgen,1k,1000,44,3.67,1.0896400265903015,0.761396253152809,0.6617942958022931,0.8142103565529715,0.8080201289452699,0.04627952788417081,908732.0562786325,0.0011004343833705182,cuda,1171.33203125,21.20751953125,35.0 +tcr_bert_mlp,log10_pgen,1k,1000,42,5.05,0.8760345003106056,0.5819093645526308,0.7813964290543859,0.8881443789227367,0.8913580831616918,0.12819454572911565,318430.06197725417,0.0031404070136802323,cuda,1246.765625,28.14501953125,40.0 +tcr_bert_mlp,log10_pgen,1k,1000,43,4.17,0.8632398237103549,0.5830586150560361,0.7877353046815565,0.8891474748834872,0.8893524914152939,0.055539820699031614,309981.80367169366,0.0032259958105770458,cuda,1244.59375,28.14501953125,35.0 +tcr_bert_mlp,log10_pgen,1k,1000,44,6.12,0.8580475606372164,0.579303658373242,0.7902811083390895,0.8897587965843224,0.8932709859909886,0.02707135115754949,291458.1496005449,0.003431024321572549,cuda,1249.66015625,28.14501953125,52.0 +tfidf_ridge,log10_pgen,1k,1000,42,0.44,1.276955755696797,0.8800488403651113,0.5355205204794624,0.7459285398734663,0.7755971181289645,0.24748485510618118,46905.79064077635,0.021319329369339647,cpu,655.55078125,0.0, +esm2_8m_mlp,log10_pgen,10k,10000,42,14.47,0.7966986650954415,0.5174849735727736,0.8191980913374267,0.9071021327654052,0.9216778640250258,0.11214545445353795,520928.62497661123,0.001919648781145206,cuda,1217.65234375,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,10k,10000,43,12.23,0.8015686329227331,0.5239774840812171,0.8169809655284199,0.904688112817364,0.9187355591684678,0.06898057147978498,543791.4727871665,0.0018389402005047405,cuda,1217.609375,23.45751953125,52.0 +esm2_8m_mlp,log10_pgen,10k,10000,44,11.7,0.8130470777845348,0.5269840306024154,0.8117017783783829,0.9031960836644991,0.9162947786091444,0.11342834681753776,519796.4815531242,0.001923829874746465,cuda,1216.08203125,23.45751953125,48.0 +irrm_pretrained,log10_pgen,10k,10000,42,38.49,0.5019841051682237,0.35627390506351453,0.9282214363308795,0.975111086691799,0.9682088622524755,0.2690681770530914,49387.35804129182,0.020248096672106232,cuda,1536.140625,255.36376953125,28.0 +irrm_pretrained,log10_pgen,10k,10000,43,29.14,0.6072004539701912,0.427645045166025,0.8949783089310082,0.9724442690808554,0.9664332662967745,0.36938994676744685,49579.00388832995,0.020169828386475165,cuda,1534.71484375,255.36376953125,21.0 +irrm_pretrained,log10_pgen,10k,10000,44,54.5,0.4370812238168363,0.29203450514300294,0.9455824314863231,0.9769737912781561,0.9738792892972243,0.16793524652596767,48117.34292600225,0.020782527446244488,cuda,1558.37890625,255.36376953125,39.0 +irrm_pretrained,log10_pgen,10k,10000,45,19.05,0.5500174080896365,0.36935044114925275,0.91382769653112,0.9726686230820053,0.9645339276878059,0.27234471256262516,78345.31960212644,0.0127640043474002,cuda,1600.17578125,255.36376953125,26.0 +irrm_pretrained,log10_pgen,10k,10000,46,13.76,0.5911542166154463,0.406977227846606,0.900455695805151,0.9714829073068255,0.9660735651292331,0.3354204946989577,78635.7118076855,0.012716868417820625,cuda,1586.33203125,255.36376953125,18.0 +irrm_pretrained,log10_pgen,10k,10000,47,15.36,0.4888588784078921,0.3293540748698081,0.9319259097726058,0.9732700643861482,0.9664655902116925,0.21819266897231107,78277.66738632193,0.012775035759110239,cuda,1579.4765625,255.36376953125,21.0 +irrm_pretrained,log10_pgen,10k,10000,48,16.01,0.5354970143071539,0.3902579098488256,0.9183175154346566,0.974014324072708,0.9671961798973695,0.31852752852926525,78617.67365585294,0.01271978619435468,cuda,1596.01171875,255.36376953125,21.0 +irrm_pretrained,log10_pgen,10k,10000,49,18.22,0.5581728783451227,0.40858714159675347,0.9112532837722653,0.9728205507714903,0.960817491415762,0.3282748804806309,77998.74070560814,0.012820719808468646,cuda,1599.359375,255.36376953125,25.0 +irrm_pretrained,log10_pgen,10k,10000,50,19.25,0.5270736550875357,0.38627417251271373,0.9208670328180113,0.9744715976870983,0.9647418996062248,0.3086164301141052,78419.26439319062,0.01275196863599798,cuda,1584.53515625,255.36376953125,26.0 +irrm_pretrained,log10_pgen,10k,10000,51,12.61,0.6251439984244976,0.45201107165020654,0.8886795471851842,0.9676513537306013,0.9604122315429587,0.3910038787630061,78106.44570462324,0.012803040657895516,cuda,1590.1171875,255.36376953125,17.0 +irrm_scratch,log10_pgen,10k,10000,42,19.37,0.5751521553443715,0.36240860395121677,0.9057719214879167,0.9520192928529396,0.9524838673585823,0.04430426241683526,50632.00661867529,0.019750352924609478,cuda,1542.84375,255.36376953125,14.0 +irrm_scratch,log10_pgen,10k,10000,43,31.69,0.5007316165717091,0.3300130508894094,0.928579175452831,0.9642083396331315,0.9665581193770536,-0.06257023294812729,49718.20607856898,0.020113356431640233,cuda,1534.55078125,255.36376953125,23.0 +irrm_scratch,log10_pgen,10k,10000,44,61.01,0.4469771841868142,0.27836988726873746,0.9430903987777541,0.9741013193473115,0.9754319376831495,0.13597858457402748,49778.46625232864,0.02008900786398215,cuda,1544.23046875,255.36376953125,45.0 +irrm_scratch,log10_pgen,10k,10000,45,38.13,0.4631258469189825,0.3008167975501209,0.938903986870447,0.9704180906902137,0.9711355946769996,0.08284721902999719,49424.02072992871,0.020233076654454583,cuda,1549.046875,255.36376953125,28.0 +irrm_scratch,log10_pgen,10k,10000,46,15.11,0.513747792852385,0.3283076451165438,0.9248178449988129,0.9619094348416142,0.9659900784041277,0.03270629272861952,79673.31215256036,0.012551254278034482,cuda,1578.6796875,255.36376953125,20.0 +irrm_scratch,log10_pgen,10k,10000,47,23.61,0.45577350966876207,0.29101608587140165,0.9408284438149535,0.9699673282824827,0.9704972919439828,0.005078207319413182,79138.31108404836,0.012636104894100608,cuda,1592.99609375,255.36376953125,32.0 +irrm_scratch,log10_pgen,10k,10000,48,41.17,0.4734539790509061,0.3158020615534417,0.9361486074139419,0.9680498037965779,0.9701016241272683,-0.05792117853843921,49208.22809005352,0.02032180468213466,cuda,1542.109375,255.36376953125,30.0 +irrm_scratch,log10_pgen,10k,10000,49,14.14,0.6207776331020315,0.42591710844635566,0.890229168663141,0.9608567893677247,0.9620175525332944,0.338611312952432,78777.80804498789,0.012693930242752208,cuda,1598.8828125,255.36376953125,19.0 +irrm_scratch,log10_pgen,10k,10000,50,20.27,0.5104941019143432,0.3157260706700292,0.92576712354424,0.966965276583171,0.9666370862800718,0.10494240099662171,78415.86048844548,0.012752522178180384,cuda,1574.81640625,255.36376953125,28.0 +irrm_scratch,log10_pgen,10k,10000,51,18.5,0.4912820150441888,0.3233667366122514,0.9312493888304615,0.9660599780498389,0.9695236673192581,-0.05855530574608454,78525.09469403228,0.012734782478091016,cuda,1578.3046875,255.36376953125,25.0 +sceptr_mlp,log10_pgen,10k,10000,42,12.43,0.8241140085650038,0.5328266240608573,0.8065407833721275,0.8997464229402171,0.9116146522108373,0.10096275534285942,933740.0276133372,0.0010709619063413453,cuda,1180.078125,21.20751953125,56.0 +sceptr_mlp,log10_pgen,10k,10000,43,8.72,0.8398266277213052,0.5446345861976845,0.7990934422983463,0.8950853150574498,0.9065704590796785,0.08551405539283576,928490.7344967334,0.0010770166710839895,cuda,1183.64453125,21.20751953125,39.0 +sceptr_mlp,log10_pgen,10k,10000,44,9.32,0.8345979343986126,0.543566797366414,0.8015873110179307,0.8967334069477051,0.9075547226147163,0.09449457219799369,897752.4414176691,0.0011138928215231234,cuda,1182.296875,21.20751953125,42.0 +tcr_bert_mlp,log10_pgen,10k,10000,42,14.7,0.5716066534740867,0.37969244209306996,0.906930071018644,0.952757972654319,0.9536264682586161,0.048066586677211275,317680.7349723767,0.003147814424714653,cuda,1273.0234375,28.14501953125,58.0 +tcr_bert_mlp,log10_pgen,10k,10000,43,15.03,0.5636854793599815,0.3738462210991635,0.9094916751782824,0.9538177223571953,0.9569626148875244,0.011505552497695236,310494.78990068275,0.0032206659580982593,cuda,1272.17578125,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen,10k,10000,44,11.24,0.5689464613822552,0.3818325411493399,0.9077943288924409,0.9531500150003065,0.9539839680301143,0.019939592151627557,319234.63163778995,0.003132492220125479,cuda,1271.4765625,28.14501953125,44.0 +tfidf_ridge,log10_pgen,10k,10000,42,0.8,0.76592457502429,0.5084579081617813,0.83289600206607,0.9129297738264299,0.9404228939259158,0.03423942511518709,59776.55467359597,0.016728966824207284,cpu,649.6875,0.0, +esm2_8m_mlp,log10_pgen,all,79730,42,74.59,0.5951112784062191,0.3778985089314805,0.8991185783382184,0.9484219706765102,0.961556478055205,0.008018448818370851,512009.60178724234,0.00195308837277535,cuda,1302.80859375,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen,all,79730,43,50.88,0.617624643001898,0.3918682055753462,0.8913414103811155,0.9452014036779254,0.9567233374476869,0.056252967770279834,537971.2513126577,0.0018588353886197177,cuda,1297.15625,23.45751953125,41.0 +esm2_8m_mlp,log10_pgen,all,79730,44,72.62,0.5966358832752859,0.37357570394098827,0.8986010236337659,0.9487803111146647,0.9612983902630552,0.06572506115436895,530540.8837711269,0.0018848688773840019,cuda,1300.69140625,23.45751953125,59.0 +irrm_pretrained,log10_pgen,all,79730,42,139.98,0.3713165663531919,0.2728079802272566,0.9607261494233188,0.988563084501092,0.9869164526749541,0.23043004494876027,44512.322638950456,0.022465689065727414,cuda,1571.984375,254.86376953125,14.0 +irrm_pretrained,log10_pgen,all,79730,43,347.53,0.2732877421635648,0.16781113564368397,0.9787257069575539,0.991832386281639,0.9888689143888211,0.11093694782506916,47394.69275674851,0.02109940885433022,cuda,1590.50390625,254.86376953125,35.0 +irrm_pretrained,log10_pgen,all,79730,44,205.57,0.3504203019450061,0.19649729263615834,0.9650221306775171,0.9851718707287127,0.978683330148102,0.1121013101544567,48625.990574486685,0.020565133752250688,cuda,1557.7890625,254.86376953125,22.0 +irrm_pretrained,log10_pgen,all,79730,45,442.88,0.22182566736977571,0.15680747819213534,0.9859835373059486,0.9942586166515042,0.9937141588261896,0.09475363882593475,47269.34832899524,0.02115535828926576,cuda,1563.43359375,254.86376953125,46.0 +irrm_pretrained,log10_pgen,all,79730,46,152.94,0.25087874409297584,0.17141298237291647,0.9820715573743454,0.9930255075484793,0.9897789108642574,0.11165818089101294,76249.21253309137,0.01311488954152819,cuda,1579.53125,254.86376953125,34.0 +irrm_pretrained,log10_pgen,all,79730,47,90.82,0.3081060827680913,0.18067044300141025,0.9729594589703192,0.98795043358461,0.982963120190587,0.08818773965778262,77044.89818934872,0.012979444758851634,cuda,1571.203125,254.86376953125,20.0 +irrm_pretrained,log10_pgen,all,79730,48,135.12,0.2986887215728427,0.18298794555902867,0.9745872022580503,0.9892383244365203,0.9876915622839695,0.10148357882720346,77142.23328055044,0.01296306779664008,cuda,1605.953125,254.86376953125,30.0 +irrm_pretrained,log10_pgen,all,79730,49,197.31,0.2363387040497491,0.14275755332583007,0.9840894742264049,0.9932642509249219,0.9919847270618742,0.077734183311473,76508.9197560553,0.01307037144411982,cuda,1597.3515625,254.86376953125,44.0 +irrm_pretrained,log10_pgen,all,79730,50,230.84,0.3051675125435428,0.204067754933738,0.9734727990480465,0.9907285747007517,0.9885527241317941,0.151946996887396,45097.88213776874,0.022173990276197833,cuda,1599.87109375,254.86376953125,24.0 +irrm_pretrained,log10_pgen,all,79730,51,103.4,0.29346090454675655,0.17002071923826675,0.9754689953051937,0.9899495870083614,0.9870642278998465,0.07495573131594488,76568.00698079141,0.013060285090754284,cuda,1580.66796875,254.86376953125,23.0 +irrm_scratch,log10_pgen,all,79730,42,180.5,0.279814286287663,0.1880315391386849,0.9776974459635999,0.9893302583812692,0.9909131558161663,0.014503944017790777,44026.03046998928,0.02271383518624643,cuda,1556.59765625,254.86376953125,19.0 +irrm_scratch,log10_pgen,all,79730,43,163.51,0.32091193596616924,0.20097612255800545,0.9706649675550438,0.9903812553054268,0.9903384271183792,0.10042179829816784,48413.8793434837,0.02065523386186973,cuda,1554.2265625,254.86376953125,18.0 +irrm_scratch,log10_pgen,all,79730,44,158.27,0.33497006170309135,0.22447315337168178,0.9680385246398328,0.9903139887992916,0.9907750466785762,0.15124634206940737,48154.72149260951,0.020766395672197457,cuda,1565.8125,254.86376953125,17.0 +irrm_scratch,log10_pgen,all,79730,45,69.33,0.38364183086153864,0.24361249078632374,0.9580756110250899,0.9868639987947267,0.9873375371802209,0.15954624188589653,78605.74365544904,0.012721716677387846,cuda,1566.375,254.86376953125,15.0 +irrm_scratch,log10_pgen,all,79730,46,256.28,0.2765557228636666,0.19643691692277543,0.9782138679476076,0.9945744989211008,0.9943793188551895,-0.03322250443971604,47319.816123156845,0.021132795558574266,cuda,1559.6171875,254.86376953125,28.0 +irrm_scratch,log10_pgen,all,79730,47,49.79,0.4767214417749651,0.3107282061051032,0.935264247058595,0.9741276964314304,0.9767865361194387,0.20746135859338838,78385.25126887314,0.01275750200212857,cuda,1592.8828125,254.86376953125,11.0 +irrm_scratch,log10_pgen,all,79730,48,138.08,0.28539163367483134,0.20092957071021314,0.976799502012103,0.9939909339821749,0.99446663064038,0.17717354120223236,77375.05021257492,0.012924062695309,cuda,1574.5078125,254.86376953125,31.0 +irrm_scratch,log10_pgen,all,79730,49,219.8,0.27950952345275093,0.17243624843163155,0.9777460016551317,0.9928358034944527,0.9934787961501889,0.10517735134727471,47216.97727532152,0.02117882290873925,cuda,1556.86328125,254.86376953125,23.0 +irrm_scratch,log10_pgen,all,79730,50,126.62,0.29019055088587026,0.2017640000268431,0.9760127000527028,0.9935500344917078,0.9938903933807892,-0.011590887368701517,76962.32866136862,0.012993369839417967,cuda,1586.01953125,254.86376953125,28.0 +irrm_scratch,log10_pgen,all,79730,51,94.65,0.4301566653976132,0.28585552544683723,0.9472930184547584,0.9920160751800176,0.9918333428144999,0.12769040293382197,76544.8788356785,0.013064231274658285,cuda,1580.16015625,254.86376953125,21.0 +sceptr_mlp,log10_pgen,all,79730,42,68.73,0.5795817078970179,0.35118457974334066,0.9043149314162111,0.9530617534275462,0.9646389496705083,0.08103153479383794,903096.3845214696,0.0011073015207893643,cuda,1205.3125,21.20751953125,60.0 +sceptr_mlp,log10_pgen,all,79730,43,63.41,0.5864017681293087,0.35538681299615843,0.9020497893897336,0.9512580809778278,0.9650385869823047,0.0895127140611525,932787.822787842,0.0010720551614956547,cuda,1197.5,21.20751953125,54.0 +sceptr_mlp,log10_pgen,all,79730,44,69.09,0.5839895730378692,0.35415758598602276,0.9028539788212233,0.9529103660424704,0.9650201847137837,0.09078357713498891,840967.2787517394,0.0011891069073273759,cuda,1197.9453125,21.20751953125,60.0 +tcr_bert_mlp,log10_pgen,all,79730,42,51.11,0.41770773759434954,0.2717698329057919,0.9502996013491293,0.9748411659041659,0.9781232625528591,0.005214108014531167,319254.11607227504,0.0031323010406343918,cuda,1670.78125,28.14501953125,39.0 +tcr_bert_mlp,log10_pgen,all,79730,43,79.57,0.4082671293067538,0.2585217788211574,0.9525207705490689,0.9769878226010591,0.980975805469901,0.061827468664735444,319375.7427781945,0.0031311081777882456,cuda,1669.08203125,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen,all,79730,44,62.81,0.4052985618099394,0.26193266943809845,0.953208716605654,0.9764250140488404,0.9789578701970347,0.02276455072057831,313163.7880490887,0.003193217217832508,cuda,1666.2890625,28.14501953125,47.0 +tfidf_ridge,log10_pgen,all,79730,42,9.48,0.6210237131878172,0.4145452767389449,0.8901421237436864,0.9434948178107029,0.9563123982662174,0.008686388197035454,46069.398916552265,0.02170638262095298,cpu,719.30078125,0.0, +esm2_8m_mlp,log10_pgen_1mm,1k,1000,42,3.72,0.8734384426546405,0.5811203823236456,0.7066749222466395,0.8428611811931889,0.8595136817400962,0.09854411271895464,531093.36010315,0.0018829081195927174,cuda,1199.21875,23.45751953125,34.0 +esm2_8m_mlp,log10_pgen_1mm,1k,1000,43,3.68,0.8676287772120702,0.5797603585575622,0.7105640414240096,0.8447384362193011,0.8588298556977834,0.08767572292374373,535898.101289993,0.0018660263911979516,cuda,1193.8125,23.45751953125,33.0 +esm2_8m_mlp,log10_pgen_1mm,1k,1000,44,4.15,0.8644075419017213,0.5799084298984422,0.7127092228837868,0.8447698749869166,0.8628554857306527,0.0476420760920801,537734.4054442797,0.0018596541152575005,cuda,1200.45703125,23.45751953125,39.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,42,9.55,0.6800570702951657,0.42365609350148575,0.8221821685480444,0.933677407276072,0.9388725488205081,0.2802916052170561,50542.42011624055,0.019785360449700248,cuda,1565.16015625,255.98876953125,24.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,43,10.39,0.6584753322447946,0.4057328196643852,0.8332892484227971,0.9367753943134008,0.945499893493824,0.2825335584781099,49021.009200498906,0.02039941682779192,cuda,1525.6953125,255.98876953125,26.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,44,10.59,0.6350050580507642,0.3884640395355252,0.8449617139927675,0.937801711477871,0.9459502912847946,0.22436193183759795,50416.68569021295,0.019834703259641744,cuda,1531.1953125,255.98876953125,27.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,45,7.0,0.6751810614818567,0.4172362618894598,0.8247229346342868,0.9339740537359036,0.9430059456408061,0.28812560326747977,78496.26553820826,0.012739459554458005,cuda,1545.91015625,255.98876953125,28.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,46,6.15,0.6685058569575997,0.40767457030235643,0.828171569821408,0.9354996251517697,0.94440611285962,0.25846381532024154,78715.08871845975,0.012704044628301188,cuda,1562.8828125,255.98876953125,24.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,47,5.45,0.642218084734104,0.4031555004716163,0.8414195480163037,0.9303131458716969,0.9390571523791333,0.2127156710366962,78601.48299372749,0.012722406269100565,cuda,1568.2421875,255.98876953125,21.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,48,9.68,0.6342088584075344,0.38472686559228664,0.8453502590541507,0.9380904108313092,0.9460257613442419,0.18461700954641433,78680.31644771349,0.012709659100882542,cuda,1557.07421875,255.98876953125,39.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,49,6.84,0.6778525531966003,0.4063589834535896,0.8233331515954379,0.9308549053584529,0.9425814646334755,0.2311877650974568,79128.20936664913,0.01263771805281719,cuda,1549.296875,255.98876953125,27.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,50,4.99,0.6604886606165908,0.40637006388958447,0.8322682333755885,0.9292828110884466,0.9392455130418712,0.21391503595003497,79443.85923264487,0.01258750531078282,cuda,1549.6328125,255.98876953125,19.0 +irrm_pretrained,log10_pgen_1mm,1k,1000,51,5.89,0.6372390774341838,0.39241801627750306,0.8438689107279675,0.9333474225263396,0.941621721540056,0.19241422764986238,78580.33201102511,0.012725830680630063,cuda,1567.53515625,255.98876953125,23.0 +irrm_scratch,log10_pgen_1mm,1k,1000,42,23.13,0.5675127906661855,0.35095961425392186,0.8761671416561154,0.937109291811129,0.9487226634897591,0.07096433712849722,49901.41476917611,0.020039511998319045,cuda,1547.078125,255.98876953125,60.0 +irrm_scratch,log10_pgen_1mm,1k,1000,43,15.61,0.5487943112163485,0.33568773672051616,0.8842012714556997,0.9412726757779909,0.949084309670342,0.06602086182336614,49383.01988887116,0.020249875407586358,cuda,1530.03125,255.98876953125,40.0 +irrm_scratch,log10_pgen_1mm,1k,1000,44,9.52,0.6648318977548506,0.42654361325296536,0.8300550415051868,0.9127595437394332,0.9188339077448422,0.0633631568418735,49671.77068032257,0.020132159299007017,cuda,1536.828125,255.98876953125,23.0 +irrm_scratch,log10_pgen_1mm,1k,1000,45,8.8,0.5754026215571453,0.3537011322377345,0.8727000416146815,0.9359365018938964,0.9437906456738564,0.08697872636101138,78318.26257008441,0.012768413996737137,cuda,1567.0390625,255.98876953125,35.0 +irrm_scratch,log10_pgen_1mm,1k,1000,46,10.78,0.5914339264050594,0.3559291734268365,0.8655078129659881,0.9347964630335666,0.9440643595280251,0.08504480157971957,78297.12279984003,0.012771861394657061,cuda,1540.38671875,255.98876953125,44.0 +irrm_scratch,log10_pgen_1mm,1k,1000,47,10.54,0.6312892435409316,0.37127948106885506,0.8467708585419784,0.938358781754315,0.947146302229228,0.20864989401004486,78701.99357101899,0.012706158441814075,cuda,1542.140625,255.98876953125,42.0 +irrm_scratch,log10_pgen_1mm,1k,1000,48,5.42,0.7789986520475849,0.4847890187497359,0.766676758356806,0.9101877824346927,0.9124383703561733,0.33916751335536144,78214.11359544039,0.012785416263520711,cuda,1536.45703125,255.98876953125,21.0 +irrm_scratch,log10_pgen_1mm,1k,1000,49,6.06,0.7225787829148815,0.4803692043319228,0.799250256201727,0.9158206089433159,0.9218188258377523,0.31839776090918176,77636.35061136573,0.012880564221853094,cuda,1561.94921875,255.98876953125,23.0 +irrm_scratch,log10_pgen_1mm,1k,1000,50,9.09,0.6073520635952829,0.3868976601348002,0.8581708134341803,0.9344983541620274,0.9446860349277294,0.19716863613669644,73919.43957497159,0.013528241092598736,cuda,1545.10546875,255.98876953125,35.0 +irrm_scratch,log10_pgen_1mm,1k,1000,51,8.61,0.6263301451334247,0.37914429651656706,0.8491687887564309,0.9280868284134893,0.9410847460057685,0.07778436074450072,79116.83397937867,0.01263953509894802,cuda,1553.6875,255.98876953125,34.0 +sceptr_mlp,log10_pgen_1mm,1k,1000,42,5.15,0.8810064957993323,0.5850634018423648,0.7015697722686547,0.8403622848328763,0.8545658323343029,0.10923790320890234,882821.5452160854,0.0011327317569659373,cuda,1177.9609375,21.20751953125,51.0 +sceptr_mlp,log10_pgen_1mm,1k,1000,43,3.26,0.8746353820476067,0.5889435925023606,0.7058704398980913,0.8414885522865576,0.8527221642098379,0.07441716460277809,914632.7917439189,0.0010933349525915341,cuda,1174.5703125,21.20751953125,32.0 +sceptr_mlp,log10_pgen_1mm,1k,1000,44,3.58,0.8782573629605056,0.5871160035537236,0.70342933697857,0.8410865411091808,0.8535996617833912,0.09703216727003491,890798.2918995839,0.001122588591708622,cuda,1170.9921875,21.20751953125,34.0 +tcr_bert_mlp,log10_pgen_1mm,1k,1000,42,6.18,0.6816212251140086,0.4366693685684581,0.82136325351949,0.9088467547401823,0.924966468087286,0.06101595375050499,314954.2306226356,0.0031750645102403986,cuda,1248.34765625,28.14501953125,52.0 +tcr_bert_mlp,log10_pgen_1mm,1k,1000,43,4.14,0.6793982191316419,0.4378072850036896,0.8225265476865682,0.9087161823299943,0.9238383313662871,0.053667050221566405,317582.12648712896,0.0031487918135107277,cuda,1246.90234375,28.14501953125,35.0 +tcr_bert_mlp,log10_pgen_1mm,1k,1000,44,4.65,0.6878677483806852,0.4429540581453104,0.8180741200953934,0.9072606006109809,0.9226372171396086,0.04333846563685214,309389.4351772415,0.003232172421877059,cuda,1249.19140625,28.14501953125,39.0 +tfidf_ridge,log10_pgen_1mm,1k,1000,42,0.32,1.0852944231152912,0.7353522020723512,0.5471235558436147,0.750775753234674,0.7954033678341129,0.18915192191042499,47177.071821432546,0.021196737342772085,cpu,654.21875,0.0, +esm2_8m_mlp,log10_pgen_1mm,10k,10000,42,11.56,0.6430747866190542,0.40745519085125576,0.8409961815941281,0.9185196137541594,0.9363519119678613,0.08332422824857887,538169.2784562818,0.0018581514033436883,cuda,1216.796875,23.45751953125,50.0 +esm2_8m_mlp,log10_pgen_1mm,10k,10000,43,13.99,0.6306860686151857,0.40229598440644404,0.8470635288924342,0.9211499809443683,0.939748810891317,0.038799049758178106,527803.3593734449,0.0018946450079194257,cuda,1215.671875,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,10k,10000,44,8.66,0.6611521713168533,0.42557124266900453,0.8319310656720827,0.9124578749759534,0.9301727900061972,0.039136087227110615,517421.681469499,0.0019326596387688251,cuda,1215.515625,23.45751953125,36.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,42,41.65,0.35014197467911184,0.24343691858470326,0.9528618056553566,0.9816822892074405,0.9790687929250388,0.1665855199568644,48129.36627137599,0.020777335698989468,cuda,1548.6015625,255.36376953125,30.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,43,29.39,0.4313657428770761,0.2741951117819419,0.9284555591077652,0.9790466822962967,0.9782558105357633,0.2068312263721413,48760.62302536395,0.020508351574585647,cuda,1543.375,255.36376953125,21.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,44,29.98,0.37998173937666613,0.23754270438177846,0.9444850386158077,0.9784090079761774,0.9786407582301763,0.15045958642347596,45442.359880088385,0.02200589939956382,cuda,1536.1328125,255.36376953125,21.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,45,19.5,0.38967208225694244,0.24806408147764908,0.9416174347071837,0.9797404689589103,0.9770233552637545,0.16339216413745158,78750.25101444994,0.012698372222540718,cuda,1575.671875,255.36376953125,26.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,46,13.32,0.45681643268603583,0.2994579549083242,0.9197642298987043,0.9786137525002476,0.9770029606653783,0.24480818914323121,78082.57722053208,0.01280695432446672,cuda,1598.0390625,255.36376953125,18.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,47,15.65,0.3302367401562472,0.2121627214782346,0.9580689858485731,0.9807385058013642,0.9785634446932512,0.08867936156471229,78239.31749460826,0.012781297588247921,cuda,1575.87890625,255.36376953125,21.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,48,9.01,0.4601046655746993,0.3112046844265132,0.918604974508381,0.9710594170731376,0.9674161539957851,0.23073410752599088,78125.415720281,0.012799931888751595,cuda,1584.9296875,255.36376953125,12.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,49,13.28,0.42220643993618356,0.2868667920655672,0.9314615472701736,0.9776291443929536,0.9737151019226785,0.22247335337541346,78233.47222931472,0.012782252551297241,cuda,1577.703125,255.36376953125,18.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,50,11.29,0.40000050278216176,0.2671247144719602,0.9384815104664057,0.9757313885303056,0.9723141763195362,0.166277798141714,78714.28512446466,0.012704174323869923,cuda,1581.85546875,255.36376953125,15.0 +irrm_pretrained,log10_pgen_1mm,10k,10000,51,13.43,0.46614344171337685,0.3209338557302386,0.916454368508382,0.9769192225657825,0.9705874373403192,0.26804017515069967,78940.1169968257,0.01266783022427255,cuda,1577.5625,255.36376953125,18.0 +irrm_scratch,log10_pgen_1mm,10k,10000,42,19.45,0.44597789242184976,0.27716016426362267,0.923526450047828,0.9619298081954418,0.9655188940132988,0.045043227895579865,49678.4435373698,0.0201294551277108,cuda,1547.33984375,255.36376953125,14.0 +irrm_scratch,log10_pgen_1mm,10k,10000,43,29.16,0.41747837743011523,0.2587127286235791,0.9329880025986563,0.9706742053550433,0.9756462190319197,0.058843259232818426,50159.388972695255,0.019936447003857237,cuda,1569.26171875,255.36376953125,21.0 +irrm_scratch,log10_pgen_1mm,10k,10000,44,44.48,0.3686214976297636,0.24951271291904806,0.9477548587464316,0.9758187390687287,0.9826749820055413,0.08981302069059369,49087.11666474849,0.02037194416672963,cuda,1539.15625,255.36376953125,32.0 +irrm_scratch,log10_pgen_1mm,10k,10000,45,21.04,0.37169950839382454,0.24491287615278978,0.9468787161492357,0.9752518625507858,0.9805370387548386,0.09421506924227235,76535.86619263089,0.01306576968088568,cuda,1584.4375,255.36376953125,28.0 +irrm_scratch,log10_pgen_1mm,10k,10000,46,14.89,0.38276351460773933,0.2471445237431523,0.9436692340359019,0.971782066968998,0.9755962370095889,0.01284569682245751,78559.09322070763,0.012729271163944735,cuda,1589.38671875,255.36376953125,20.0 +irrm_scratch,log10_pgen_1mm,10k,10000,47,11.18,0.45773894183737657,0.27476089458618436,0.9194398415263564,0.9648299509760926,0.9713430094180486,0.14051059713170738,78499.43459207573,0.012738945257332424,cuda,1589.20703125,255.36376953125,15.0 +irrm_scratch,log10_pgen_1mm,10k,10000,48,23.87,0.3456903560926719,0.20971918710266105,0.9540527929814415,0.9771313469305555,0.9817604989495604,0.04363672955178386,78526.85782180715,0.012734496549819887,cuda,1594.03515625,255.36376953125,32.0 +irrm_scratch,log10_pgen_1mm,10k,10000,49,14.1,0.4073696215734271,0.2520798791207299,0.9361939487404316,0.9702873629167561,0.9727032762915658,0.11533500071674543,78575.93218125278,0.012726543258733205,cuda,1607.69140625,255.36376953125,19.0 +irrm_scratch,log10_pgen_1mm,10k,10000,50,17.33,0.3638889125453413,0.22850331503421772,0.9490877564538704,0.9744755401401348,0.980159241404828,0.03594200359354233,78979.94634026023,0.012661441876546926,cuda,1608.0625,255.36376953125,23.0 +irrm_scratch,log10_pgen_1mm,10k,10000,51,21.79,0.3959283377167753,0.23382869758806193,0.939727700302192,0.9764227136087295,0.9823862851349912,0.13576840298631876,78324.60890559829,0.012767379422286838,cuda,1599.27734375,255.36376953125,30.0 +sceptr_mlp,log10_pgen_1mm,10k,10000,42,9.63,0.645827637038086,0.4068036199738689,0.8396319527003634,0.9164770048749564,0.9360747724957823,0.027719664424225597,916432.6280458241,0.0010911876873397367,cuda,1181.9296875,21.20751953125,42.0 +sceptr_mlp,log10_pgen_1mm,10k,10000,43,9.19,0.6532333481759839,0.409299590819611,0.8359329819489905,0.9145515186929961,0.9359316492492474,0.032295013070945074,887704.5331397445,0.001126500950111266,cuda,1179.8046875,21.20751953125,39.0 +sceptr_mlp,log10_pgen_1mm,10k,10000,44,9.67,0.6495695749089844,0.4056266461442478,0.8377682178782393,0.9160401203643372,0.9367067372055377,0.05914198352740034,915879.2358882766,0.0010918470042943357,cuda,1178.87890625,21.20751953125,42.0 +tcr_bert_mlp,log10_pgen_1mm,10k,10000,42,8.95,0.43260012130778047,0.27748984096282453,0.9280455160181926,0.9633803919392315,0.9706797264555369,0.01180787024418463,310603.97321174777,0.003219533831649574,cuda,1276.2109375,28.14501953125,34.0 +tcr_bert_mlp,log10_pgen_1mm,10k,10000,43,15.22,0.421858887434182,0.26746360618628684,0.9315743399900089,0.9652323883296584,0.9732567446625279,0.009886096964405733,317514.9456476062,0.0031494580450705757,cuda,1272.53515625,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,10k,10000,44,8.96,0.42981001830337606,0.27754906861007,0.9289706799220001,0.9639476620845376,0.9706564063195163,0.010106714404347067,317600.07131345535,0.003148613902586471,cuda,1274.28125,28.14501953125,35.0 +tfidf_ridge,log10_pgen_1mm,10k,10000,42,0.79,0.6798483740334681,0.4456090287409803,0.8222912894561352,0.9069107278125044,0.9418410114465724,0.018927879241947294,58098.109898958115,0.01721226390564443,cpu,648.9140625,0.0, +esm2_8m_mlp,log10_pgen_1mm,all,79730,42,74.3,0.46899616986313375,0.28366711611461526,0.9154286659694916,0.9569846240109816,0.9730241066544465,0.018638176980045787,547451.8876378721,0.0018266445373213852,cuda,1299.3828125,23.45751953125,60.0 +esm2_8m_mlp,log10_pgen_1mm,all,79730,43,59.95,0.4863207128254932,0.29147505686690234,0.9090651984987221,0.9550695754445274,0.9709942057450834,0.0882283553982555,529579.7460452183,0.0018882897381702637,cuda,1304.2421875,23.45751953125,49.0 +esm2_8m_mlp,log10_pgen_1mm,all,79730,44,71.01,0.48283508427727606,0.28513132216226056,0.91036404937305,0.9563536575939271,0.9721687047226008,0.08814281761993255,554802.0910919767,0.0018024445402355506,cuda,1299.171875,23.45751953125,59.0 +irrm_pretrained,log10_pgen_1mm,all,79730,42,140.33,0.29083007096135444,0.2098718946239174,0.9674790511927934,0.9907727648593888,0.9874548324427458,0.17782213587315893,44069.23582390069,0.022691566606599874,cuda,1558.08203125,254.86376953125,14.0 +irrm_pretrained,log10_pgen_1mm,all,79730,43,309.62,0.19178641612678832,0.11479367564442367,0.9858576924817093,0.994653716168127,0.9941628093444557,0.06551083671283722,47695.29669604378,0.020966427913697155,cuda,1578.21875,254.86376953125,33.0 +irrm_pretrained,log10_pgen_1mm,all,79730,44,220.33,0.23311122370676388,0.12960197515861094,0.9791065115378612,0.9896635201545613,0.9850500673303398,0.02886887512971913,43989.910272901674,0.02273248555853528,cuda,1558.9921875,254.86376953125,22.0 +irrm_pretrained,log10_pgen_1mm,all,79730,45,269.72,0.15868507534782078,0.08505078419565594,0.9903181855762656,0.9953405868926234,0.9970612987096276,-0.018548766321781516,76408.93078313439,0.013087475374288683,cuda,1586.76953125,254.86376953125,60.0 +irrm_pretrained,log10_pgen_1mm,all,79730,46,327.58,0.17893124003444805,0.11649784998203631,0.9876900317543066,0.9944873753403464,0.9934121864733891,0.05748933470935837,48046.353383919544,0.02081323408687008,cuda,1561.046875,254.86376953125,34.0 +irrm_pretrained,log10_pgen_1mm,all,79730,47,91.12,0.22684790947864455,0.12761343549003248,0.9802141755269492,0.9913132664242993,0.9879244544819463,0.0428836753199869,76291.03266716524,0.013107700407762183,cuda,1583.94921875,254.86376953125,20.0 +irrm_pretrained,log10_pgen_1mm,all,79730,48,91.39,0.2672039101747195,0.15850310311757398,0.9725482391013425,0.989855109751394,0.985813195353334,0.10367822122398167,76762.82293730929,0.013027139463287856,cuda,1583.31640625,254.86376953125,20.0 +irrm_pretrained,log10_pgen_1mm,all,79730,49,492.85,0.15331362972511323,0.09336122804377556,0.9909625455636024,0.9958130660577037,0.995566207785459,0.03562421480685179,47207.914573014874,0.021182888696625945,cuda,1568.7890625,254.86376953125,51.0 +irrm_pretrained,log10_pgen_1mm,all,79730,50,268.43,0.15444098240428322,0.09742089487884842,0.9908291476734726,0.9961100967107266,0.9968357584571697,0.056485239300779894,76450.86408964357,0.01308029689275239,cuda,1590.7421875,254.86376953125,60.0 +irrm_pretrained,log10_pgen_1mm,all,79730,51,104.31,0.24259668004354265,0.12878927401599008,0.9773715766288749,0.9901045476909557,0.9860099208508144,0.056035867666271395,76305.9339249849,0.013105140695651316,cuda,1581.4140625,254.86376953125,23.0 +irrm_scratch,log10_pgen_1mm,all,79730,42,182.2,0.24742771296521945,0.157050990621428,0.9764613651971807,0.9929284722679887,0.9944522727001026,0.09369640877203453,44012.93829160942,0.022720591689981286,cuda,1557.33984375,254.86376953125,19.0 +irrm_scratch,log10_pgen_1mm,all,79730,43,164.46,0.21579927855743838,0.14238205001424453,0.9820945777897901,0.9920916216231709,0.9937298104111683,-0.02161755598062506,48196.633862531206,0.0207483369658605,cuda,1573.13671875,254.86376953125,18.0 +irrm_scratch,log10_pgen_1mm,all,79730,44,121.45,0.32828928131963364,0.20981698564201592,0.9585620754190175,0.9815517547820619,0.9873401004095298,0.05558387703943304,47504.06554863723,0.021050829827946958,cuda,1552.19921875,254.86376953125,13.0 +irrm_scratch,log10_pgen_1mm,all,79730,45,211.91,0.2848072379190708,0.20553148194253587,0.9688120640790565,0.9922746098718975,0.9950765364472423,0.042364935671912546,47078.90490162043,0.021240935873289193,cuda,1564.90625,254.86376953125,22.0 +irrm_scratch,log10_pgen_1mm,all,79730,46,54.58,0.32282093426343655,0.1940359213846715,0.9599310493194535,0.9819233271806727,0.9836484176549345,0.09733460792348787,76869.10938834613,0.013009126916612967,cuda,1576.37109375,254.86376953125,12.0 +irrm_scratch,log10_pgen_1mm,all,79730,47,147.26,0.2559991761785086,0.15067211437522288,0.9748022522085213,0.9940023026524442,0.9961921259351151,0.11158205967586128,76798.71471554741,0.013021051246806303,cuda,1617.33984375,254.86376953125,32.0 +irrm_scratch,log10_pgen_1mm,all,79730,48,182.77,0.2335171541479004,0.15523083215682953,0.9790336820331119,0.9911588526121001,0.9941198058114114,0.07813050404736843,48080.641854246656,0.0207983912326178,cuda,1572.85546875,254.86376953125,19.0 +irrm_scratch,log10_pgen_1mm,all,79730,49,77.54,0.27385095790334146,0.19382559150444986,0.9711654539881946,0.9909897033406608,0.9936805074797037,0.16402027947482764,76598.80083274224,0.013055034662795256,cuda,1589.9375,254.86376953125,17.0 +irrm_scratch,log10_pgen_1mm,all,79730,50,71.91,0.23204268378956183,0.15422337004000328,0.9792976165218135,0.9896301157879785,0.9930708539631528,0.003519611339806289,76968.537959956,0.01299232162263839,cuda,1580.3046875,254.86376953125,16.0 +irrm_scratch,log10_pgen_1mm,all,79730,51,134.45,0.25863070214883893,0.16719389261637624,0.9742815526056321,0.9873098753313578,0.991357120638237,-0.015157397736740554,45549.57022164899,0.02195410396045221,cuda,1559.40625,254.86376953125,14.0 +sceptr_mlp,log10_pgen_1mm,all,79730,42,47.72,0.4590071571918785,0.26491759622764105,0.918992821822185,0.959962995648993,0.9752358006705864,0.066629467263402,908790.3950185104,0.0011003637422682397,cuda,1199.44140625,21.20751953125,40.0 +sceptr_mlp,log10_pgen_1mm,all,79730,43,54.04,0.46201987164360353,0.2647853562151094,0.9179259433906491,0.958619255812622,0.975345369198441,0.04454950212876287,920832.7705944345,0.0010859735143379616,cuda,1194.40234375,21.20751953125,47.0 +sceptr_mlp,log10_pgen_1mm,all,79730,44,57.35,0.4469669894594107,0.2609785939350046,0.9231868653260547,0.9610926944199375,0.975631702210054,0.033990439569041256,909364.3039765669,0.0010996692916437245,cuda,1198.41015625,21.20751953125,49.0 +tcr_bert_mlp,log10_pgen_1mm,all,79730,42,58.15,0.3098943987334235,0.19844359774924528,0.9630757194284447,0.9815324691892897,0.9850971523921663,0.013213505453879129,318647.4263871291,0.003138264794221455,cuda,1670.19921875,28.14501953125,44.0 +tcr_bert_mlp,log10_pgen_1mm,all,79730,43,79.21,0.30509861900551083,0.19526537661917165,0.9642097219020543,0.9820934038858983,0.9869364844825658,-0.0119739816780719,316693.254885937,0.0031576296134256747,cuda,1670.44921875,28.14501953125,60.0 +tcr_bert_mlp,log10_pgen_1mm,all,79730,44,48.95,0.3193936611517518,0.20682718145954618,0.960777328144496,0.9802463373113919,0.983617638847924,0.007206928689406769,320776.8613929061,0.00311743183612967,cuda,1673.2109375,28.14501953125,37.0 +tfidf_ridge,log10_pgen_1mm,all,79730,42,9.66,0.5542224821064449,0.3670566172834339,0.8818991924431581,0.9391308258396079,0.9565974661198886,0.0035328855355764607,44726.53155722081,0.022358094070421077,cpu,716.12109375,0.0, diff --git a/results/pgen_constlr/pgen_summary.csv b/results/pgen_constlr/pgen_summary.csv new file mode 100644 index 0000000..70f0a0d --- /dev/null +++ b/results/pgen_constlr/pgen_summary.csv @@ -0,0 +1,37 @@ +target,train_subset,arm,seeds,train_size,rmse_mean,rmse_std,mae_mean,mae_std,r2_mean,r2_std,pearson_r_mean,pearson_r_std,spearman_rho_mean,spearman_rho_std,bias_mean,bias_std,training_seconds_mean,inference_seq_per_second_mean,peak_rss_mb_mean,peak_gpu_mb_mean +log10_pgen,1k,irrm_scratch,10,1000,0.8379438263375423,0.07867249592710443,0.5413980735295911,0.0580446314810705,0.798406523904873,0.040498992051886576,0.9049139054549931,0.009840024528434311,0.904333465892336,0.011361519326849367,0.1551782296232404,0.15390117173821022,10.331,62821.00447401784,1542.425390625,255.98876953125 +log10_pgen,1k,irrm_pretrained,10,1000,0.8550251478865704,0.025339719180604656,0.5575133459336978,0.013908713333604477,0.7915913348278159,0.01233799418292649,0.9148794772734956,0.0038483435506742065,0.9084727474646785,0.0031749550782257897,0.30998608299664804,0.05861494528750305,8.241,62465.82250303106,1542.067578125,255.98876953125 +log10_pgen,1k,tcr_bert_mlp,3,1000,0.8657739615527257,0.009257369532250346,0.581423879327303,0.0019239794308733246,0.7864709473583439,0.004575295736734588,0.8890168834635155,0.0008150930534225373,0.8913271868559915,0.001959429986301301,0.07026857252856558,0.05214573058201129,5.113333333333333,306623.3384164976,1247.0065104166667,28.14501953125 +log10_pgen,1k,esm2_8m_mlp,3,1000,1.083446236552734,0.007022470402211829,0.7379947173621156,0.002171722887800877,0.6656188970763066,0.004342632397618175,0.8185395891648021,0.001412940229596168,0.8260198092373562,0.0025814804548312297,0.12072431084892372,0.030412381356488497,3.93,523847.50668071903,1200.0143229166667,23.45751953125 +log10_pgen,1k,sceptr_mlp,3,1000,1.0976038433169357,0.006897307587346891,0.7627633957781601,0.0019332084823762091,0.6568235298151776,0.0043050872520435145,0.8118926570544515,0.0021225197902238176,0.8060410172602768,0.0017155240942351325,0.0814823994847304,0.03710128987080741,3.7999999999999994,856494.9556877855,1169.6171875,21.20751953125 +log10_pgen,1k,tfidf_ridge,1,1000,1.276955755696797,,0.8800488403651113,,0.5355205204794624,,0.7459285398734663,,0.7755971181289645,,0.24748485510618118,,0.44,46905.79064077635,655.55078125,0.0 +log10_pgen,10k,irrm_scratch,10,10000,0.5051515834654494,0.054951652825074,0.3271744047929508,0.041713085823000436,0.9265386059854499,0.016676524110579356,0.9654555653445005,0.006190666031767679,0.9670376819703789,0.006265392894722844,0.05654215627852953,0.12147756529555402,28.3,64329.13142336295,1563.64609375,255.36376953125 +log10_pgen,10k,irrm_pretrained,10,10000,0.5422183832232536,0.057352525306723294,0.38187654948467087,0.04724556949707446,0.9154108858067206,0.017514758663127572,0.9730908568087688,0.0024674093272134758,0.9658762303337521,0.0038073550349844287,0.2978773964467407,0.06780555517243432,23.639,69548.45281110329,1576.52421875,255.36376953125 +log10_pgen,10k,tcr_bert_mlp,3,10000,0.5680795314054411,0.004031119636653914,0.37845706811385776,0.004133997900017408,0.9080720250297891,0.0013031846861411404,0.9532419033372737,0.0005358170938291702,0.9548576837254182,0.0018316667053695878,0.026503910442178022,0.01914405941888179,13.656666666666666,315803.3855036165,1272.2252604166667,28.14501953125 +log10_pgen,10k,tfidf_ridge,1,10000,0.76592457502429,,0.5084579081617813,,0.83289600206607,,0.9129297738264299,,0.9404228939259158,,0.03423942511518709,,0.8,59776.55467359597,649.6875,0.0 +log10_pgen,10k,esm2_8m_mlp,3,10000,0.8037714586009032,0.008393865622556233,0.5228154960854687,0.00485496479799742,0.8159602784147432,0.003850977620423332,0.9049954430824227,0.0019710768157375443,0.9189027339342127,0.0026954336757552023,0.09818479091695358,0.025299728810900795,12.799999999999999,528172.193105634,1217.1145833333333,23.45751953125 +log10_pgen,10k,sceptr_mlp,3,10000,0.8328461902283072,0.00800144086501869,0.5403426692083185,0.00653094512617079,0.8024071788961349,0.003790759788035956,0.8971883816484573,0.002363627118951327,0.9085799446350773,0.002673813985561092,0.09365712764456295,0.007758322471483018,10.156666666666666,919994.4011759133,1182.0065104166667,21.20751953125 +log10_pgen,all,irrm_pretrained,10,79730,0.29094909474054964,0.04741822316545527,0.18458412851304246,0.035762733378958134,0.9753107011546698,0.00800254329667357,0.9903982636366593,0.0027969455400128004,0.9876218128470395,0.00429003780174096,0.11541883526450339,0.04597981539220331,204.63899999999998,61641.35071767869,1581.82890625,254.86376953125 +log10_pgen,all,irrm_scratch,10,79730,0.33578636528681594,0.07126425216797283,0.22252437734980995,0.0446965625642714,0.9665805886364465,0.014984588581583783,0.9897984543781598,0.0059964201920581885,0.9904199184753828,0.0052830720928398155,0.09984075885395624,0.08298558555562141,145.683,62300.467733850506,1569.30625,254.86376953125 +log10_pgen,all,tcr_bert_mlp,3,79730,0.4104244762370142,0.006479777792889647,0.26407476038834926,0.006878891588527168,0.9520096961679507,0.001520406413171397,0.9760846675180218,0.0011130635940318988,0.9793523127399316,0.0014666079786796635,0.029935375799948306,0.028979884407407768,64.49666666666667,317264.54896651936,1668.7174479166667,28.14501953125 +log10_pgen,all,sceptr_mlp,3,79730,0.5833243496880652,0.0034583517709830796,0.3535763262418406,0.0021605759059627762,0.9030728998757227,0.0011483300575644375,0.9524100668159482,0.0010005163984225006,0.9648992404555322,0.0002256061400935981,0.08710927532999313,0.005301695083341565,67.07666666666667,892283.828687017,1200.2526041666667,21.20751953125 +log10_pgen,all,esm2_8m_mlp,3,79730,0.6031239348944677,0.012581097198351444,0.381114139482605,0.009560811361581226,0.8963536707843666,0.004348451618740226,0.9474678951563668,0.0019709996661059505,0.9598594019219823,0.0027189754719963667,0.04333215924767322,0.030947112086310898,66.03,526840.578957009,1300.21875,23.45751953125 +log10_pgen,all,tfidf_ridge,1,79730,0.6210237131878172,,0.4145452767389449,,0.8901421237436864,,0.9434948178107029,,0.9563123982662174,,0.008686388197035454,,9.48,46069.398916552265,719.30078125,0.0 +log10_pgen_1mm,1k,irrm_scratch,10,1000,0.6314524434831694,0.07261686713463565,0.3925300930693855,0.05359654264664398,0.8448668784488793,0.037029600737626185,0.9288826831963857,0.01158522271877412,0.9371670165463476,0.013830910702485056,0.1513540048890253,0.1074965335519036,10.756,69316.03220404696,1546.0703125,255.98876953125 +log10_pgen_1mm,1k,irrm_pretrained,10,1000,0.6569231613419195,0.018426714329123007,0.4035793214577793,0.012179916879442062,0.8339567738188751,0.009299913259190176,0.9339616887631262,0.0031160599077837098,0.942626640503833,0.002856669189694695,0.236862622340095,0.0381077679541767,7.6530000000000005,70162.56693153805,1552.2625,255.98876953125 +log10_pgen_1mm,1k,tcr_bert_mlp,3,1000,0.682962397542112,0.004391160329175946,0.43914357057248604,0.0033486676619782895,0.8206546404338172,0.0023092481985602415,0.9082745125603858,0.0008804972285221423,0.9238140055310605,0.0011648159957729678,0.052673823202974514,0.008880499503683912,4.989999999999999,313975.2640956687,1248.1471354166667,28.14501953125 +log10_pgen_1mm,1k,esm2_8m_mlp,3,1000,0.868491587256144,0.004576857325871695,0.58026305692655,0.0007461477118348201,0.7099827288514787,0.0030588624151971274,0.8441231641331356,0.0010930223257392714,0.8603996743895107,0.002154103414763927,0.0779539705782595,0.02680743711530656,3.85,534908.622279141,1197.8294270833333,23.45751953125 +log10_pgen_1mm,1k,sceptr_mlp,3,1000,0.8779664136024815,0.003195506416212866,0.5870409992994831,0.0019411824020671429,0.7036231830484386,0.0021568768483211037,0.840979126076205,0.0005707653513373905,0.8536292194425107,0.0009221893947024148,0.09356241169390511,0.01766777750843526,3.9966666666666666,896084.2096198626,1174.5078125,21.20751953125 +log10_pgen_1mm,1k,tfidf_ridge,1,1000,1.0852944231152912,,0.7353522020723512,,0.5471235558436147,,0.750775753234674,,0.7954033678341129,,0.18915192191042499,,0.32,47177.071821432546,654.21875,0.0 +log10_pgen_1mm,10k,irrm_scratch,10,10000,0.3957156960248885,0.036479454715929324,0.24763349791340467,0.020427223218532808,0.9393319301582345,0.011325238425838581,0.9718603596711267,0.005104883477754595,0.9768325682014181,0.005697693481619573,0.07719530078638195,0.044325297668403874,21.729,69692.66884291462,1582.785546875,255.36376953125 +log10_pgen_1mm,10k,irrm_pretrained,10,10000,0.4086669762038501,0.046905976308239894,0.2700989539306911,0.03504841161795715,0.9350255454586733,0.014519371549026574,0.9779569879302615,0.002987619383779735,0.9752587991891681,0.004033122939199344,0.19082814817916946,0.0534713821299041,19.65,69141.77849773047,1569.975,255.36376953125 +log10_pgen_1mm,10k,tcr_bert_mlp,3,10000,0.4280896756817795,0.005573437927670511,0.2741675052530605,0.00580582242250533,0.9295301786434006,0.0018297346174931833,0.9641868141178093,0.0009488771937410975,0.9715309591458604,0.001494619581813537,0.010600227204312479,0.0010516507488302893,11.043333333333335,315239.66339093645,1274.3424479166667,28.14501953125 +log10_pgen_1mm,10k,esm2_8m_mlp,3,10000,0.6449710088503644,0.015321311873335977,0.41177413930890144,0.012223927299852232,0.839996925386215,0.0076155594348420825,0.9173758232248271,0.004457507052465646,0.9354245042884585,0.0048549055347065495,0.053753121744622524,0.025609883901828074,11.403333333333334,527798.1064330753,1215.9947916666667,23.45751953125 +log10_pgen_1mm,10k,sceptr_mlp,3,10000,0.6495435200410181,0.0037029243182388977,0.4072432856459092,0.001875529278483193,0.8377777175091977,0.0018495036731835572,0.91568954797743,0.0010094800681917497,0.9362377196501891,0.000412436863463324,0.03971888700752367,0.016975746305393863,9.496666666666668,906672.1323579485,1180.2044270833333,21.20751953125 +log10_pgen_1mm,10k,tfidf_ridge,1,10000,0.6798483740334681,,0.4456090287409803,,0.8222912894561352,,0.9069107278125044,,0.9418410114465724,,0.018927879241947294,,0.79,58098.109898958115,648.9140625,0.0 +log10_pgen_1mm,all,irrm_pretrained,10,79730,0.20977471380034785,0.04934704474272933,0.1261504115150865,0.036345323942476096,0.9822377157037178,0.008214782973867617,0.9928114050050126,0.0026846786292086143,0.9909290731229282,0.004906346197013534,0.06058496344211638,0.05150767433523792,231.56800000000004,61322.829515201796,1575.13203125,254.86376953125 +log10_pgen_1mm,all,irrm_scratch,10,79730,0.265318511919295,0.03763402497421702,0.17299632302977777,0.025127194527394783,0.9724441689161771,0.007977149306655412,0.9893860635450332,0.0044306439958006795,0.9922667551450598,0.003882647933197412,0.060945733022736606,0.059777932774134894,134.853,58765.79175768857,1574.3796875,254.86376953125 +log10_pgen_1mm,all,tcr_bert_mlp,3,79730,0.31146222629689535,0.007275343286903232,0.20017871860932104,0.005973007290388119,0.9626875898249984,0.0017488039251256668,0.9812907367955267,0.0009469633811877807,0.9852170919075519,0.0016626705031840912,0.0028154841550713326,0.013155453843526574,62.10333333333333,318705.8475553241,1671.2864583333333,28.14501953125 +log10_pgen_1mm,all,sceptr_mlp,3,79730,0.45599800609829755,0.00796483259339435,0.2635605154592517,0.0022369870190182945,0.9200352101796296,0.0027810528614914155,0.9598916486271841,0.0012382618601008899,0.9754042906930271,0.00020442190227909016,0.048389802987068714,0.016654953173757057,53.03666666666667,912995.8231965039,1197.41796875,21.20751953125 +log10_pgen_1mm,all,esm2_8m_mlp,3,79730,0.4793839889886344,0.009163377719603393,0.28675783171459274,0.00415031742047246,0.9116193046137546,0.003362317482388092,0.9561359523498121,0.0009759095413796944,0.9720623390407103,0.0010191220089720955,0.06500311666607794,0.04015323839050756,68.42,543944.5749250223,1300.9322916666667,23.45751953125 +log10_pgen_1mm,all,tfidf_ridge,1,79730,0.5542224821064449,,0.3670566172834339,,0.8818991924431581,,0.9391308258396079,,0.9565974661198886,,0.0035328855355764607,,9.66,44726.53155722081,716.12109375,0.0 diff --git a/results/pgen_constlr/pgen_summary.md b/results/pgen_constlr/pgen_summary.md new file mode 100644 index 0000000..f5572ce --- /dev/null +++ b/results/pgen_constlr/pgen_summary.md @@ -0,0 +1,70 @@ +### log10_pgen + +**train = 1k (1,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_scratch | 0.8379 ± 0.0787 | 0.5414 | 0.7984 | 0.9049 | 0.9043 | +0.1552 | 10 | 62821 | 1542 | +| irrm_pretrained | 0.8550 ± 0.0253 | 0.5575 | 0.7916 | 0.9149 | 0.9085 | +0.3100 | 8 | 62466 | 1542 | +| tcr_bert_mlp | 0.8658 ± 0.0093 | 0.5814 | 0.7865 | 0.8890 | 0.8913 | +0.0703 | 5 | 306623 | 1247 | +| esm2_8m_mlp | 1.0834 ± 0.0070 | 0.7380 | 0.6656 | 0.8185 | 0.8260 | +0.1207 | 4 | 523848 | 1200 | +| sceptr_mlp | 1.0976 ± 0.0069 | 0.7628 | 0.6568 | 0.8119 | 0.8060 | +0.0815 | 4 | 856495 | 1170 | +| tfidf_ridge | 1.2770 | 0.8800 | 0.5355 | 0.7459 | 0.7756 | +0.2475 | 0 | 46906 | 656 | + +**train = 10k (10,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_scratch | 0.5052 ± 0.0550 | 0.3272 | 0.9265 | 0.9655 | 0.9670 | +0.0565 | 28 | 64329 | 1564 | +| irrm_pretrained | 0.5422 ± 0.0574 | 0.3819 | 0.9154 | 0.9731 | 0.9659 | +0.2979 | 24 | 69548 | 1577 | +| tcr_bert_mlp | 0.5681 ± 0.0040 | 0.3785 | 0.9081 | 0.9532 | 0.9549 | +0.0265 | 14 | 315803 | 1272 | +| tfidf_ridge | 0.7659 | 0.5085 | 0.8329 | 0.9129 | 0.9404 | +0.0342 | 1 | 59777 | 650 | +| esm2_8m_mlp | 0.8038 ± 0.0084 | 0.5228 | 0.8160 | 0.9050 | 0.9189 | +0.0982 | 13 | 528172 | 1217 | +| sceptr_mlp | 0.8328 ± 0.0080 | 0.5403 | 0.8024 | 0.8972 | 0.9086 | +0.0937 | 10 | 919994 | 1182 | + +**train = all (79,730 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | 0.2909 ± 0.0474 | 0.1846 | 0.9753 | 0.9904 | 0.9876 | +0.1154 | 205 | 61641 | 1582 | +| irrm_scratch | 0.3358 ± 0.0713 | 0.2225 | 0.9666 | 0.9898 | 0.9904 | +0.0998 | 146 | 62300 | 1569 | +| tcr_bert_mlp | 0.4104 ± 0.0065 | 0.2641 | 0.9520 | 0.9761 | 0.9794 | +0.0299 | 64 | 317265 | 1669 | +| sceptr_mlp | 0.5833 ± 0.0035 | 0.3536 | 0.9031 | 0.9524 | 0.9649 | +0.0871 | 67 | 892284 | 1200 | +| esm2_8m_mlp | 0.6031 ± 0.0126 | 0.3811 | 0.8964 | 0.9475 | 0.9599 | +0.0433 | 66 | 526841 | 1300 | +| tfidf_ridge | 0.6210 | 0.4145 | 0.8901 | 0.9435 | 0.9563 | +0.0087 | 9 | 46069 | 719 | + +### log10_pgen_1mm + +**train = 1k (1,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_scratch | 0.6315 ± 0.0726 | 0.3925 | 0.8449 | 0.9289 | 0.9372 | +0.1514 | 11 | 69316 | 1546 | +| irrm_pretrained | 0.6569 ± 0.0184 | 0.4036 | 0.8340 | 0.9340 | 0.9426 | +0.2369 | 8 | 70163 | 1552 | +| tcr_bert_mlp | 0.6830 ± 0.0044 | 0.4391 | 0.8207 | 0.9083 | 0.9238 | +0.0527 | 5 | 313975 | 1248 | +| esm2_8m_mlp | 0.8685 ± 0.0046 | 0.5803 | 0.7100 | 0.8441 | 0.8604 | +0.0780 | 4 | 534909 | 1198 | +| sceptr_mlp | 0.8780 ± 0.0032 | 0.5870 | 0.7036 | 0.8410 | 0.8536 | +0.0936 | 4 | 896084 | 1175 | +| tfidf_ridge | 1.0853 | 0.7354 | 0.5471 | 0.7508 | 0.7954 | +0.1892 | 0 | 47177 | 654 | + +**train = 10k (10,000 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_scratch | 0.3957 ± 0.0365 | 0.2476 | 0.9393 | 0.9719 | 0.9768 | +0.0772 | 22 | 69693 | 1583 | +| irrm_pretrained | 0.4087 ± 0.0469 | 0.2701 | 0.9350 | 0.9780 | 0.9753 | +0.1908 | 20 | 69142 | 1570 | +| tcr_bert_mlp | 0.4281 ± 0.0056 | 0.2742 | 0.9295 | 0.9642 | 0.9715 | +0.0106 | 11 | 315240 | 1274 | +| esm2_8m_mlp | 0.6450 ± 0.0153 | 0.4118 | 0.8400 | 0.9174 | 0.9354 | +0.0538 | 11 | 527798 | 1216 | +| sceptr_mlp | 0.6495 ± 0.0037 | 0.4072 | 0.8378 | 0.9157 | 0.9362 | +0.0397 | 9 | 906672 | 1180 | +| tfidf_ridge | 0.6798 | 0.4456 | 0.8223 | 0.9069 | 0.9418 | +0.0189 | 1 | 58098 | 649 | + +**train = all (79,730 sequences)** + +| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| irrm_pretrained | 0.2098 ± 0.0493 | 0.1262 | 0.9822 | 0.9928 | 0.9909 | +0.0606 | 232 | 61323 | 1575 | +| irrm_scratch | 0.2653 ± 0.0376 | 0.1730 | 0.9724 | 0.9894 | 0.9923 | +0.0609 | 135 | 58766 | 1574 | +| tcr_bert_mlp | 0.3115 ± 0.0073 | 0.2002 | 0.9627 | 0.9813 | 0.9852 | +0.0028 | 62 | 318706 | 1671 | +| sceptr_mlp | 0.4560 ± 0.0080 | 0.2636 | 0.9200 | 0.9599 | 0.9754 | +0.0484 | 53 | 912996 | 1197 | +| esm2_8m_mlp | 0.4794 ± 0.0092 | 0.2868 | 0.9116 | 0.9561 | 0.9721 | +0.0650 | 68 | 543945 | 1301 | +| tfidf_ridge | 0.5542 | 0.3671 | 0.8819 | 0.9391 | 0.9566 | +0.0035 | 10 | 44727 | 716 | + diff --git a/results/pgen_constlr/pretraining_delta.csv b/results/pgen_constlr/pretraining_delta.csv new file mode 100644 index 0000000..5584101 --- /dev/null +++ b/results/pgen_constlr/pretraining_delta.csv @@ -0,0 +1,7 @@ +target,train_subset,n_scratch,n_pretrained,irrm_scratch,irrm_pretrained,rmse_delta,relative_improvement,p_value,verdict +log10_pgen,1k,10,10,0.8379438263375423,0.8550251478865704,-0.017081321549028083,-0.020384805057501967,0.5270257428158892,no detectable effect +log10_pgen,10k,10,10,0.5051515834654494,0.5422183832232537,-0.03706679975780425,-0.0733775780796686,0.15732847985243456,no detectable effect +log10_pgen,all,10,10,0.335786365286816,0.29094909474054964,0.04483727054626635,0.13352915776662955,0.117526241878387,no detectable effect +log10_pgen_1mm,1k,10,10,0.6314524434831694,0.6569231613419194,-0.02547071785874999,-0.04033671596589345,0.3072070679790528,no detectable effect +log10_pgen_1mm,10k,10,10,0.3957156960248885,0.4086669762038501,-0.012951280178961633,-0.0327287502342264,0.49998985357929854,no detectable effect +log10_pgen_1mm,all,10,10,0.26531851191929495,0.2097747138003479,0.05554379811894705,0.20934761663310725,0.011632512578723934,pretraining helps diff --git a/results/reconstruction/reconstruction_runs.csv b/results/reconstruction/reconstruction_runs.csv new file mode 100644 index 0000000..61092dc --- /dev/null +++ b/results/reconstruction/reconstruction_runs.csv @@ -0,0 +1,16 @@ +representation,seed,bottleneck_dim,train_subset,train_size,epochs_ran,best_epoch,best_val_loss,training_seconds,test_loss,exact_match,token_accuracy,normalized_levenshtein,within_edit_distance_1,mean_edit_distance,inference_seq_per_second,inference_ms_per_sequence,device +esm2_8m,42,64,all,79730,36,28,0.0733299881984026,1449.82,0.072866829064412,0.6525534263068125,0.9325163975146336,0.0563025242603035,0.7704424601183907,0.855824219925755,6925.270491542189,0.14439869189532695,cuda +esm2_8m,43,64,all,79730,35,27,0.07321660067790593,1481.52,0.07167374705656981,0.6505468044547005,0.9328907864327216,0.05586594799605164,0.7669308718771948,0.845590448479984,6302.629250780989,0.15866394169958278,cuda +esm2_8m,44,64,all,79730,34,26,0.07201942428946495,1374.37,0.07244877650951728,0.6499448178990669,0.9323724017769074,0.05579528646580723,0.7703421290257851,0.8460921039430119,6931.001781474648,0.14427928768866063,cuda +onehot,42,64,all,79730,46,38,0.015626185442297123,1947.5,0.01686641280181133,0.9147185712852413,0.988012354834297,0.01044870014041422,0.9650847797732517,0.16925855322564462,6740.392889160309,0.14835930433790723,cuda +onehot,43,64,all,79730,44,36,0.015526399291001068,1773.28,0.0167713965026614,0.9147185712852413,0.9878251603752529,0.01055498694685954,0.9642821310324069,0.171666499448179,6959.059296335155,0.143697582879719,cuda +onehot,44,64,all,79730,39,31,0.01566104817753419,1654.49,0.016842290782966673,0.9137152603591853,0.9875299691129142,0.010679486103341483,0.9635798133841678,0.17397411457810777,6721.714112326583,0.14877157571550906,cuda +sceptr,42,64,all,79730,34,26,0.015631044331269387,1438.6,0.016878187322081663,0.9052874485803151,0.9872923761456661,0.010762903291556672,0.9606702116986054,0.1700612019664894,6681.0765368225,0.14967647720970384,cuda +sceptr,43,64,all,79730,25,17,0.015448446170641826,1005.99,0.01793186505062458,0.8911407645229257,0.9852404368830683,0.012352635473980028,0.9537473663088191,0.19353867763619945,6942.691494033216,0.1440363583574805,cuda +sceptr,44,64,all,79730,36,28,0.014794133317012053,1520.72,0.016622064921718378,0.9049864553024982,0.9872923761456661,0.01057906079226048,0.9614728604394502,0.16584729607705428,6718.565058588532,0.14884130633246928,cuda +tcr_bert,42,64,all,79730,29,21,0.04164245581397644,1170.33,0.040557941994988,0.7707434533962075,0.9647642429784078,0.02883887644221048,0.8893348048560249,0.4475770041135748,6948.343259792289,0.14391919952870805,cuda +tcr_bert,43,64,all,79730,26,18,0.041497998273907565,1101.03,0.04137205002972713,0.7640212701916324,0.9634538817650997,0.030204758605446042,0.8806059997993378,0.4672418982642721,6700.394915657967,0.14924493445350925,cuda +tcr_bert,44,64,all,79730,31,23,0.041648901043794095,1249.9,0.04166440746914118,0.7751580214708538,0.9649730367981108,0.028198279038403613,0.8936490418380656,0.4376442259456205,6943.732958313603,0.14401475488810647,cuda +tcremp,42,64,all,79730,39,31,0.0247877309910762,1566.19,0.025743332906411245,0.7975318551219023,0.9779254534065792,0.020130054818765956,0.9388983646031905,0.3027992374836962,7139.259510791705,0.14007054912185218,cuda +tcremp,43,64,all,79730,46,38,0.024846020345695507,1927.35,0.025916891745649852,0.8049563559747166,0.9786814310296416,0.01929511392118879,0.942008628473964,0.2894552021671516,6815.03971278562,0.14673428800772959,cuda +tcremp,44,64,all,79730,47,39,0.024844986697038014,1893.08,0.026344755951028604,0.8025484097521822,0.9785662344394606,0.019611650793997584,0.9408046553626969,0.29266579713053076,6948.998411166585,0.14390563083063387,cuda diff --git a/results/reconstruction/reconstruction_summary.csv b/results/reconstruction/reconstruction_summary.csv new file mode 100644 index 0000000..3e1d5dc --- /dev/null +++ b/results/reconstruction/reconstruction_summary.csv @@ -0,0 +1,6 @@ +representation,seeds,exact_match_mean,exact_match_std,token_accuracy_mean,token_accuracy_std,normalized_levenshtein_mean,normalized_levenshtein_std,within_edit_distance_1_mean,within_edit_distance_1_std,mean_edit_distance_mean,mean_edit_distance_std,training_seconds_mean,epochs_mean,inference_seq_per_second_mean,source_dim,explained_variance +onehot,3,0.9143841343098892,0.000579261833239334,0.9877891614408214,0.00024319938015680297,0.01056105773020508,0.00011551268752343819,0.9643155747299422,0.0007530403832110864,0.1716330557506438,0.002357958561529363,1791.756666666667,43.0,6807.05543260735,1000,0.379862 +sceptr,3,0.9004715561352463,0.008082103892102458,0.9866083963914668,0.0011846876856216142,0.011231533185932395,0.0009752447238186415,0.9586301461489583,0.004247612915008504,0.17648239189324774,0.014920687424517944,1321.77,31.666666666666668,6780.777696481416,64,1.0 +tcremp,3,0.8016788736162671,0.003787858636103861,0.9783910396252272,0.00040730266245565675,0.019678939844650776,0.00042151801606229864,0.9405705494799506,0.001568291908323191,0.29497341226045953,0.006964885880127865,1795.54,44.0,6967.76587824797,9000,0.949757 +tcr_bert,3,0.7699742483528978,0.005608080292114219,0.9643970538472061,0.0008234554615370438,0.02908063802868671,0.00102485441003165,0.8878632821644761,0.006644867995664911,0.45082104277448914,0.015063146809206184,1173.7533333333333,28.666666666666668,6864.157044587952,768,0.910277 +esm2_8m,3,0.6510150162201933,0.0013658792586644186,0.9325931952414209,0.0002675893887576123,0.05598791957405413,0.0002747368639656366,0.7692384870071235,0.00199908285794834,0.8491689241162503,0.005769110528054075,1435.2366666666667,35.0,6719.6338412659425,320,0.974346 diff --git a/results/reconstruction/reconstruction_summary.md b/results/reconstruction/reconstruction_summary.md new file mode 100644 index 0000000..c492a6e --- /dev/null +++ b/results/reconstruction/reconstruction_summary.md @@ -0,0 +1,9 @@ +### Reconstruction at a 64-dimensional bottleneck + +| representation | source dim | expl. var | exact match | token acc | norm. Levenshtein | within ED 1 | train s | seq/s | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| onehot | 1000 | 0.380 | 0.9144 ± 0.0006 | 0.9878 ± 0.0002 | 0.0106 ± 0.0001 | 0.9643 ± 0.0008 | 1792 | 6807 | +| sceptr | 64 | 1.000 | 0.9005 ± 0.0081 | 0.9866 ± 0.0012 | 0.0112 ± 0.0010 | 0.9586 ± 0.0042 | 1322 | 6781 | +| tcremp | 9000 | 0.950 | 0.8017 ± 0.0038 | 0.9784 ± 0.0004 | 0.0197 ± 0.0004 | 0.9406 ± 0.0016 | 1796 | 6968 | +| tcr_bert | 768 | 0.910 | 0.7700 ± 0.0056 | 0.9644 ± 0.0008 | 0.0291 ± 0.0010 | 0.8879 ± 0.0066 | 1174 | 6864 | +| esm2_8m | 320 | 0.974 | 0.6510 ± 0.0014 | 0.9326 ± 0.0003 | 0.0560 ± 0.0003 | 0.7692 ± 0.0020 | 1435 | 6720 | From e5fefbbd0e65ac25f12d338d2912a77fccda4951 Mon Sep 17 00:00:00 2001 From: maria Date: Tue, 11 Aug 2026 21:42:54 +0300 Subject: [PATCH 61/70] Add hidden_dim/num_conv_blocks awareness to both notebooks --- .../compare_forward_tokenizers_report.ipynb | 911 ++---------------- .../convergence_curves_by_epoch_report.ipynb | 298 ++---- 2 files changed, 166 insertions(+), 1043 deletions(-) diff --git a/notebooks/compare_forward_tokenizers_report.ipynb b/notebooks/compare_forward_tokenizers_report.ipynb index 34585ac..23db243 100644 --- a/notebooks/compare_forward_tokenizers_report.ipynb +++ b/notebooks/compare_forward_tokenizers_report.ipynb @@ -17,14 +17,14 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "25047bb7", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:07.657782Z", - "iopub.status.busy": "2026-08-07T10:53:07.657129Z", - "iopub.status.idle": "2026-08-07T10:53:07.661495Z", - "shell.execute_reply": "2026-08-07T10:53:07.660717Z" + "iopub.execute_input": "2026-08-11T18:27:04.187772Z", + "iopub.status.busy": "2026-08-11T18:27:04.187506Z", + "iopub.status.idle": "2026-08-11T18:27:04.192533Z", + "shell.execute_reply": "2026-08-11T18:27:04.191765Z" }, "tags": [ "parameters" @@ -33,192 +33,23 @@ "outputs": [], "source": [ "# parameters\n", - "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs\"\n", - "DOMAIN_TOKENIZATION_STATS_PATH = \"../artifacts/REPLACE_ME_domain_stats/tokenization_stats.json\"" + "RESULTS_DIR = \"../artifacts/REPLACE_ME\"\n", + "DOMAIN_TOKENIZATION_STATS_PATH = \"../artifacts/tokenizers_2026-08-01_fine_grid_on_background100k/tokenization_stats.json\"" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "b314dd93", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:07.663261Z", - "iopub.status.busy": "2026-08-07T10:53:07.662773Z", - "iopub.status.idle": "2026-08-07T10:53:08.202915Z", - "shell.execute_reply": "2026-08-07T10:53:08.202066Z" + "iopub.execute_input": "2026-08-11T18:27:04.194626Z", + "iopub.status.busy": "2026-08-11T18:27:04.194002Z", + "iopub.status.idle": "2026-08-11T18:27:04.876570Z", + "shell.execute_reply": "2026-08-11T18:27:04.875532Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loaded 15 individual runs across 15 tokenizer configs from ..\\artifacts\\compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizemax_token_lenpad_layoutmax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_path
0char25NaNend4010.1976780.8678360.192469331148.3492790.55189410850856NaN
1wordpiece10009.0anchored1110.2223790.8500600.21952925815.8021140.47294910913256artifacts/tokenizers_2026-08-01_fine_grid/word...
2wordpiece20009.0anchored1010.2357470.8407430.22957027800.5669070.49776610977256artifacts/tokenizers_2026-08-01_fine_grid/word...
3wordpiece29989.0anchored1010.2424570.8358470.24023038792.8189000.46958711041128artifacts/tokenizers_2026-08-01_fine_grid/word...
4wordpiece39869.0anchored1010.2504180.8304160.24791538793.6826300.47194111104360artifacts/tokenizers_2026-08-01_fine_grid/word...
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size max_token_len pad_layout max_len seed test_loss \\\n", - "0 char 25 NaN end 40 1 0.197678 \n", - "1 wordpiece 1000 9.0 anchored 11 1 0.222379 \n", - "2 wordpiece 2000 9.0 anchored 10 1 0.235747 \n", - "3 wordpiece 2998 9.0 anchored 10 1 0.242457 \n", - "4 wordpiece 3986 9.0 anchored 10 1 0.250418 \n", - "\n", - " test_cosine best_val_loss epochs_to_best_val train_time_sec \\\n", - "0 0.867836 0.192469 33 1148.349279 \n", - "1 0.850060 0.219529 25 815.802114 \n", - "2 0.840743 0.229570 27 800.566907 \n", - "3 0.835847 0.240230 38 792.818900 \n", - "4 0.830416 0.247915 38 793.682630 \n", - "\n", - " inference_time_sec num_parameters \\\n", - "0 0.551894 10850856 \n", - "1 0.472949 10913256 \n", - "2 0.497766 10977256 \n", - "3 0.469587 11041128 \n", - "4 0.471941 11104360 \n", - "\n", - " tokenizer_path \n", - "0 NaN \n", - "1 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", - "2 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", - "3 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", - "4 artifacts/tokenizers_2026-08-01_fine_grid/word... " - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import json\n", "from pathlib import Path\n", @@ -232,20 +63,28 @@ "with open(results_dir / \"summary.json\") as f:\n", " summary = json.load(f)\n", "\n", + "if \"pad_layout\" not in raw.columns:\n", + " raw[\"pad_layout\"] = \"end\" # older raw_results.csv, from before --pad-layout existed\n", + "if \"hidden_dim\" not in raw.columns:\n", + " raw[\"hidden_dim\"] = 192 # older raw_results.csv, from before --hidden-dim existed (ForwardModel default)\n", + "if \"num_conv_blocks\" not in raw.columns:\n", + " raw[\"num_conv_blocks\"] = 4 # older raw_results.csv, from before --num-conv-blocks existed (ForwardModel default)\n", + "\n", "wp = sorted((r for r in summary if r[\"tokenizer\"] == \"wordpiece\"), key=lambda r: r[\"vocab_size\"])\n", "char_row = next(r for r in summary if r[\"tokenizer\"] == \"char\")\n", "vocab_sizes = [r[\"vocab_size\"] for r in wp]\n", "\n", "# This notebook assumes one wordpiece config per vocab_size. If RESULTS_DIR mixes\n", - "# multiple --max-token-len/--pad-layout variants for the same vocab_size (e.g. after\n", - "# merging runs), that assumption breaks silently in the plots below - fail loudly instead.\n", + "# multiple --max-token-len/--pad-layout/--hidden-dim/--num-conv-blocks variants for the\n", + "# same vocab_size (e.g. after merging runs), that assumption breaks silently in the plots\n", + "# below - fail loudly instead.\n", "if len(vocab_sizes) != len(set(vocab_sizes)):\n", " dupes = sorted({vs for vs in vocab_sizes if vocab_sizes.count(vs) > 1})\n", " raise ValueError(\n", " f\"vocab_size {dupes} appears more than once in summary.json (different \"\n", - " \"max_token_len/pad_layout variants mixed in one RESULTS_DIR) - this notebook \"\n", - " \"isn't designed to compare those side by side; filter raw_results.csv/summary.json \"\n", - " \"to a single max_token_len+pad_layout combination first.\"\n", + " \"max_token_len/pad_layout/hidden_dim/num_conv_blocks variants mixed in one \"\n", + " \"RESULTS_DIR) - this notebook isn't designed to compare those side by side; \"\n", + " \"filter raw_results.csv/summary.json to a single combination first.\"\n", " )\n", "\n", "print(f\"Loaded {len(raw)} individual runs across {len(summary)} tokenizer configs from {results_dir}\")\n", @@ -262,259 +101,17 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "41f68c7f", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.204542Z", - "iopub.status.busy": "2026-08-07T10:53:08.204326Z", - "iopub.status.idle": "2026-08-07T10:53:08.213800Z", - "shell.execute_reply": "2026-08-07T10:53:08.213016Z" + "iopub.execute_input": "2026-08-11T18:27:04.878574Z", + "iopub.status.busy": "2026-08-11T18:27:04.878368Z", + "iopub.status.idle": "2026-08-11T18:27:04.891303Z", + "shell.execute_reply": "2026-08-11T18:27:04.890102Z" } }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizetest_losstest_cosinebest_val_lossepochs_to_best_valnum_parametersn_seeds
0char250.1977 ± 0.00000.8678 ± 0.00000.1925 ± 0.000033.0 ± 0.0108508561
1wordpiece10000.2224 ± 0.00000.8501 ± 0.00000.2195 ± 0.000025.0 ± 0.0109132561
2wordpiece20000.2357 ± 0.00000.8407 ± 0.00000.2296 ± 0.000027.0 ± 0.0109772561
3wordpiece29980.2425 ± 0.00000.8358 ± 0.00000.2402 ± 0.000038.0 ± 0.0110411281
4wordpiece39860.2504 ± 0.00000.8304 ± 0.00000.2479 ± 0.000038.0 ± 0.0111043601
5wordpiece49700.2559 ± 0.00000.8263 ± 0.00000.2540 ± 0.000036.0 ± 0.0111673361
6wordpiece59510.2608 ± 0.00000.8232 ± 0.00000.2581 ± 0.000037.0 ± 0.0112301201
7wordpiece69230.2668 ± 0.00000.8186 ± 0.00000.2650 ± 0.000037.0 ± 0.0112923281
8wordpiece78970.2746 ± 0.00000.8128 ± 0.00000.2728 ± 0.000038.0 ± 0.0113546641
9wordpiece88550.2818 ± 0.00000.8081 ± 0.00000.2801 ± 0.000036.0 ± 0.0114159761
10wordpiece98160.2848 ± 0.00000.8052 ± 0.00000.2824 ± 0.000040.0 ± 0.0114774801
11wordpiece117190.3012 ± 0.00000.7935 ± 0.00000.3033 ± 0.000040.0 ± 0.0115992721
12wordpiece145500.3142 ± 0.00000.7839 ± 0.00000.3140 ± 0.000040.0 ± 0.0117804561
13wordpiece164140.3258 ± 0.00000.7750 ± 0.00000.3248 ± 0.000040.0 ± 0.0118997521
14wordpiece191990.3343 ± 0.00000.7684 ± 0.00000.3346 ± 0.000039.0 ± 0.0120779921
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size test_loss test_cosine best_val_loss \\\n", - "0 char 25 0.1977 ± 0.0000 0.8678 ± 0.0000 0.1925 ± 0.0000 \n", - "1 wordpiece 1000 0.2224 ± 0.0000 0.8501 ± 0.0000 0.2195 ± 0.0000 \n", - "2 wordpiece 2000 0.2357 ± 0.0000 0.8407 ± 0.0000 0.2296 ± 0.0000 \n", - "3 wordpiece 2998 0.2425 ± 0.0000 0.8358 ± 0.0000 0.2402 ± 0.0000 \n", - "4 wordpiece 3986 0.2504 ± 0.0000 0.8304 ± 0.0000 0.2479 ± 0.0000 \n", - "5 wordpiece 4970 0.2559 ± 0.0000 0.8263 ± 0.0000 0.2540 ± 0.0000 \n", - "6 wordpiece 5951 0.2608 ± 0.0000 0.8232 ± 0.0000 0.2581 ± 0.0000 \n", - "7 wordpiece 6923 0.2668 ± 0.0000 0.8186 ± 0.0000 0.2650 ± 0.0000 \n", - "8 wordpiece 7897 0.2746 ± 0.0000 0.8128 ± 0.0000 0.2728 ± 0.0000 \n", - "9 wordpiece 8855 0.2818 ± 0.0000 0.8081 ± 0.0000 0.2801 ± 0.0000 \n", - "10 wordpiece 9816 0.2848 ± 0.0000 0.8052 ± 0.0000 0.2824 ± 0.0000 \n", - "11 wordpiece 11719 0.3012 ± 0.0000 0.7935 ± 0.0000 0.3033 ± 0.0000 \n", - "12 wordpiece 14550 0.3142 ± 0.0000 0.7839 ± 0.0000 0.3140 ± 0.0000 \n", - "13 wordpiece 16414 0.3258 ± 0.0000 0.7750 ± 0.0000 0.3248 ± 0.0000 \n", - "14 wordpiece 19199 0.3343 ± 0.0000 0.7684 ± 0.0000 0.3346 ± 0.0000 \n", - "\n", - " epochs_to_best_val num_parameters n_seeds \n", - "0 33.0 ± 0.0 10850856 1 \n", - "1 25.0 ± 0.0 10913256 1 \n", - "2 27.0 ± 0.0 10977256 1 \n", - "3 38.0 ± 0.0 11041128 1 \n", - "4 38.0 ± 0.0 11104360 1 \n", - "5 36.0 ± 0.0 11167336 1 \n", - "6 37.0 ± 0.0 11230120 1 \n", - "7 37.0 ± 0.0 11292328 1 \n", - "8 38.0 ± 0.0 11354664 1 \n", - "9 36.0 ± 0.0 11415976 1 \n", - "10 40.0 ± 0.0 11477480 1 \n", - "11 40.0 ± 0.0 11599272 1 \n", - "12 40.0 ± 0.0 11780456 1 \n", - "13 40.0 ± 0.0 11899752 1 \n", - "14 39.0 ± 0.0 12077992 1 " - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "def fmt(mean_std, precision=4):\n", " mean, std = mean_std\n", @@ -546,28 +143,17 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "e9fac0c5", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.215191Z", - "iopub.status.busy": "2026-08-07T10:53:08.215056Z", - "iopub.status.idle": "2026-08-07T10:53:08.330467Z", - "shell.execute_reply": "2026-08-07T10:53:08.329650Z" + "iopub.execute_input": "2026-08-11T18:27:04.893651Z", + "iopub.status.busy": "2026-08-11T18:27:04.893004Z", + "iopub.status.idle": "2026-08-11T18:27:05.058307Z", + "shell.execute_reply": "2026-08-11T18:27:05.057047Z" } }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "loss_means = [r[\"test_loss\"][0] for r in wp]\n", "loss_stds = [r[\"test_loss\"][1] for r in wp]\n", @@ -605,28 +191,17 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "f24dbe8c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.331897Z", - "iopub.status.busy": "2026-08-07T10:53:08.331762Z", - "iopub.status.idle": "2026-08-07T10:53:08.474145Z", - "shell.execute_reply": "2026-08-07T10:53:08.473326Z" + "iopub.execute_input": "2026-08-11T18:27:05.060170Z", + "iopub.status.busy": "2026-08-11T18:27:05.060001Z", + "iopub.status.idle": "2026-08-11T18:27:05.282895Z", + "shell.execute_reply": "2026-08-11T18:27:05.281679Z" } }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "cos_means = [r[\"test_cosine\"][0] for r in wp]\n", "cos_stds = [r[\"test_cosine\"][1] for r in wp]\n", @@ -662,28 +237,17 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "a718abe6", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.476008Z", - "iopub.status.busy": "2026-08-07T10:53:08.475469Z", - "iopub.status.idle": "2026-08-07T10:53:08.567552Z", - "shell.execute_reply": "2026-08-07T10:53:08.566804Z" + "iopub.execute_input": "2026-08-11T18:27:05.284803Z", + "iopub.status.busy": "2026-08-11T18:27:05.284577Z", + "iopub.status.idle": "2026-08-11T18:27:05.417128Z", + "shell.execute_reply": "2026-08-11T18:27:05.416067Z" } }, - "outputs": [ - { - "data": { - "image/png": "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v6e6sUm5JEmSJEll4BNuSZIkSWog8+bNq3GZlyfNCEePHl/jcrceMygM6du1nrZM5WDALUmSJEkNpJQ+1cMGdAi9ur0bB0gr1iCcXts9KtqHYQN6O0VYE2eTckmSJElqQhgIjam/UDgkWnrN587H3fQZcEuSJElSE8M82zccsXl8kp3Fa953Hu7mwSblkiRJktQEEVTv3L9HGDd5Zpg+d0Ho3rl9GNyni0+2mxEDbkmSJElqomg2PrSfA6M1VzYplyRJkiSpJT7hXrhwYfj73/8epk2bFjbeeOMwZMiQGr/z+eefh+eeey4OqT9gwICw+eabf2OZyZMnh5deeim0bds2rnOttdYqUwokSZIkSWpiT7inT58evvWtb4URI0aEp556Kuy2227huOOOq/Y7V1xxRdhqq63CXXfdFR577LEwfPjwsPfee4dFixbFz3O5XDjwwAPDd77znTBmzJhwxx13hA022CBcdtllDZQqSZIkSZIa+Qn3mWeeGVZYYYX4JHqllVYKr732Wthiiy3CPvvsE/baa6+i39l0003D22+/Hb+H999/P6y77rrhoYceCvvvv38MuA8++OBwzz33hFat/m/Q/D//+c/hiCOOCPvtt1/o169fg6ZRkiRJkrR8arQn3EuXLg333ntvOProo2Owjc022yxsvfXW4e67767yezvttFM+2EbXrl1DmzZt4vrQunXrcMABB+SDbfAUnED8P//5T1nTJEmSJElSoz/h/vDDD8PcuXPDRhttVOl9Xr/yyivVfnfKlCnhwQcfDHPmzAl//etfw/e+97349LoqLEtQztPx6vqS85ewbkmSJEmSmt0TboJtrLLKKpXeX3XVVWsMdufPnx/eeeed8MYbb4SpU6eGzp07559wF3rzzTfDGWecEX72s5+FXr16VbnOCy+8MFRUVOT/evfuXad0SZIkSZLUqE+4UzPyFHgnBNsdOnSo9rs8Bb/22mvzT7s32WST0Ldv33DKKadUWu69996Lg6cxqNoFF1xQ7TpHjhwZTj/99ErbYdAtSZIkSWp2ATfTdK244opx+q6sSZMmhfXWW69W66Hv9/jx4yu9z2BqO+ywQ/y79dZbY9/u6rRr1y7+SZIkSZLUrJuUM/AZ04AxgjgDmuGjjz4KY8eOjU+kk2eeeSbceeed8d+LFy8OH3zwQaX1zJw5M0ycODGOVJ4N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vVbfOf7448Nbb70Vmhu2m0pQqRYsWBC/8/7774fmhECS7Z4yZUrJ3yE45zu1uSHRFKTtnj59esnfIY18pzY3JJqCjz/+OG733LlzS/4OeZfvkJebk7TdX3/9dcnfoUziO83NxIkTww9+8INafeeVV14JJ598cmhuqLCdfvrptfrOc889F0aMGBGaG7Z75MiRtfrOE088Ec4999zQ3FAZ/9WvflWr7zz44IPhoosuCs0N233ppZfW6jv33HNPuPLKK0Nzc9ddd4Vrr722Vt/h5uFNN90Umps//OEP8a82brjhhmZ54/OGG24Id9xxR62+Q/4lHzcHbRt7A/R/uKN6++23xwr6VlttFS+InTt3zu8enh795je/iXet2rdvH0444YSwyy675D8/7bTT4p2hVq1ahdVXXz18+9vfjkFr27ZtKzVN33///WNwxx0zljnnnHNazCE49thjQ69evUJLt8IKK8S0du/ePbR0HTt2jGldZZVVQktHGkkraW7pyLuklbzc0lEmkdblQZ8+fcJRRx0VlgcbbrhhOOSQQ8LyYODAgeG73/1uWB5svvnmYaWVVgrLgyFDhoQ111wzLA+22267WrXCas6GDx8eOnXqFJYHu+66a7Op9xtwNwEXX3xx+OUvfxmD3y222CI+JfjJT34Sfv/73+eXOfvss8Mpp5wS78ITLO+xxx7xCfCAAQPi5yeeeGI4+OCDQy6Xi08QWd/bb78dbrzxxkpN02lyRCDO3erevXtX+1SG76eL7Lx58+JdRQrojTfeON+E6dNPPw277757fM0Trqeffjr+n4tW//79K62Tpl1UyFZdddV442C11VaLBQP4Lda39tprx9/Iotkpdyf32Wef2LSeJy89e/YMw4YNq7QcNyoqKioqvTdr1qwwduzY2Jx5s802C+uvv/430sq2PProo2HTTTeNhXK7du3CfffdF7bddttYqWIdN998c2weTGWSdfAezZPmz58fBg8e/I313nvvvTH9XLhp/sT27rDDDvlmbm+88Ubo27dv/G7WV199Fe/wsd85jhyHtdZaK2yzzTb5Zdq0aRPTmr0hgxkzZoRnn302Nndl//fr169okx3yzyabbBK23377sHTp0jBmzJiw4447xu1hHdxlZB1HHHFEXAfvsQ+5WA0dOjQewyyaYnLMWBdPilgPy6U88s4774R11103rLfe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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(10, 4.5))\n", "configs = sorted(raw[[\"tokenizer\", \"vocab_size\"]].drop_duplicates().itertuples(index=False),\n", @@ -723,28 +287,17 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "70921265", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.569035Z", - "iopub.status.busy": "2026-08-07T10:53:08.568901Z", - "iopub.status.idle": "2026-08-07T10:53:08.669496Z", - "shell.execute_reply": "2026-08-07T10:53:08.668734Z" + "iopub.execute_input": "2026-08-11T18:27:05.418890Z", + "iopub.status.busy": "2026-08-11T18:27:05.418673Z", + "iopub.status.idle": "2026-08-11T18:27:05.576025Z", + "shell.execute_reply": "2026-08-11T18:27:05.574364Z" } }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "val_means = [r[\"best_val_loss\"][0] for r in wp]\n", "\n", @@ -782,32 +335,21 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "11901b9c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.670964Z", - "iopub.status.busy": "2026-08-07T10:53:08.670831Z", - "iopub.status.idle": "2026-08-07T10:53:08.759832Z", - "shell.execute_reply": "2026-08-07T10:53:08.759105Z" + "iopub.execute_input": "2026-08-11T18:27:05.578335Z", + "iopub.status.busy": "2026-08-11T18:27:05.577785Z", + "iopub.status.idle": "2026-08-11T18:27:05.765648Z", + "shell.execute_reply": "2026-08-11T18:27:05.764167Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAgjhJREFUeJzt3QeYFEXisPEiCYgCihHFnA4D5nx6glnMmPOZE5gV9cSM4cx65jPncCaMeJ45YjjBnDFHgoHc3/PWfTX/3mHDzM7CBt7f8wzszPR0V1dXV1dVV1W3yrIsC5IkSZJUgdaV/FiSJEmSrFhIkiRJahDesZAkSZJUMSsWkiRJkipmxUKSJElSxaxYSJIkSaqYFQtJkiRJFbNiIUmSJKliViwkSZIkVcyKhSTVw0cffRRatWoVrrnmmhYXfy1538rx448/xni48MILw4weX3/88Uc48MADwzzzzBP3dc899wxffvll/PvSSy9t7OBJaiKsWEhSM9HSC3Itff+as/POOy/ceuut4amnngpZloXrr7++sYMkqQlq29gBkCRJTdvQoUPDyiuvHP70pz8VPpt//vljJUOSEu9YSJKkWn3//fehY8eOxpKkWlmxkNRkTZw4MQwePDj07NkzdOjQIcw+++xhhx12CJ999lm1/dtvuummsPjii8dlV1hhhTBkyJCp1jlq1KgwYMCAsMACC4SZZpop9OjRIxx66KHx8+Jtn3322WHZZZeNBSpaZ/fee+/w1VdfTbXOe+65J7bktm/fPiy33HLhsccem2qZiy66KK5rlllmCd27dw9bbbVVeOONN0qOi+eeey6GFYSXfeZ1yCGHlL1v5SglTks5TnXFQSn7V5vffvstdO7cOfb9LzZhwoQw55xzxjAlbdu2LWyDuFpkkUXC0UcfHddTidrii3V37do17LrrrlP9bty4cWGOOeYI22+/fa3rLyVdlpIO8udNben3oYceisu9++67cV9SnOVfxV3Xvv3227DzzjvHfeW1++67hzFjxsQ4Oeyww+odt5KagUySmqDJkydnm222WTbHHHNkt99+e/bLL79kH374YbbJJptk8847b/bdd9/F5fiMrGzLLbfMDjrooOzLL7/MRo4cme27775Z69ats0ceeaSwznHjxmUrrLBC/P1jjz2WjR49Ohs6dGg233zzZcstt1z2+++/x+UmTZqUbbTRRlnXrl2z66+/Pvv++++zr7/+OrvuuuuyQYMGVdnudtttl/Xv3z9uk2W22GKLrGPHjtm3335b2O4VV1yRtWvXLu7HmDFjsh9//DF78MEHs5133rmsOGEbbPOSSy6Z6rtS960U5cRpqceplDiobf9Ksc8++2Qzzzxz3Pe8u+66K66XeKkO4Xn44YdjePfYY4/C5z/88EP83QUXXNBg8TVgwICsffv2MU3lkc5Yx6OPPlrjdkpJl6Wmg3LSL5Zccsl4nPOqO16s/09/+lO26KKLZs8991zcPsd51113jfvN/ktquaxYSGqS7rjjjlhooVCYN2rUqFiwOvbYY6sUkJZffvkqy02ZMiXr2bNnLEwlV111VVz2gQceqLIsBb98Aenmm2+O72+99dYaw5e2u+qqq1b5/PPPP4+fn3feeYXPdtxxx1jYqlRtBe9S960U5cRpqceplDiotGLx0ksvxd9feeWVVT7feOONswUWWCBWgmpz6aWXxopAKnyXW7EoJb7ef//9rFWrVtlZZ51VZdnVVlst69GjR61hLCVdlpoOykm/5VQsLr/88vjZ008/XWXZa665Jn5uxUJq2ewKJalJevDBB2M3ji222KLK5126dImDSJ9++ukqn2+++eZV3tNFg9/+97//jdOG4sknn4zr3Gyzzaosu/HGG8fuOXyPhx9+OHaV2W677eoMZ/G66H4y66yzhk8++aTwWa9evWJXErqBDBs2LEyePDk0tFL3rRylxGmpx2l6xMFqq60WlllmmfDPf/6zykxTjz/+eNhrr71C69b/d8njsw033DB069Ytfp66XU2ZMqXKsWvo+FpiiSVCnz59wpVXXhm3BbqDvfzyy1OFsVgp6bLcdFBK+i0Hs0bRJW2dddap8nlx+pDUMlmxkNQk0U+bvvEzzzxzLEy1adOmUABkhpqffvqpyvJzzz33VOtIn6Vl+X+uueaqtvDGsqnwx0BV3rPdusw777xTfUbBKt+f/cgjjwwnn3xyuP/++2Nhm8Jsv379wuuvvx4aSqn7Vo5S4rTU4zQ94gCMN6CQPmLEiPieaVG5O0+hPXnmmWfCJptsEhZaaKHw0ksvxWc05KdQZRxDfZQSXzjooIPCp59+Gh599NH4/h//+EeMr3wYq1NKuiw3HZSSfsuRtl+M8SO1VZoktQye5ZKaJAoiFHAotE6aNCm2cNPC+/+7cIYPPvigyvLffffdVOtIn1GIBYOKKZxVN0Umy7JNMNCX92y3LhQI69KuXbswaNCgWJjkdcEFF4Thw4fHVl1a1BtCqftWjlLitNTjND3iALvttltsseeuRaosrL/++mHBBRcsLHPzzTfHgc9XXHFFHGjNoGUQrkqUEl+p9Z4B1VQoRo8eHZ8PwV0MKjq1KSVdlpsOSkm/5WA/2X4xKjTpDo2klsuKhaQmiW4lzCSTWnXrwuw1eRSs6KbDLDepMEXhjQIwXUry6Bbz66+/xu/Rt2/fWHi76667QkOj8EjL9N///vc4S1A5LfadOnWK/48fP36q70rdt3KUEqflHqfa4qC2/SunYMtsU8zOxL5//PHH8S5GMSof+UI1FSIK+JUoJb7AXZ399tsvPPLII/Euzu+//15tGIuVki6nRToox3rrrRfTA7N81RY3klqoxh7kIUnVYRBr3759sznnnDO74YYbsm+++SbO3jNs2LA4IPjcc8+tMgiV2WwOOeSQOCMPr/333z8OxB0yZEhhnX/88UfWq1evOEPOE088Edf373//Ow6aXWaZZbLffvutxtl32H51s0JdffXVU4Wd9e+yyy6F97vvvnt28cUXZ++9916cteezzz7Ltt1222yWWWbJvvrqq7ISQPfu3bNNN900Do7OK3XfSlFOnJZ6nEqNg5r2rxzMhkT42ffZZ589bi+PWYr4/oQTTojbYX+ZHalfv37x8zfeeKNeg7dLia+EWZdmmmmm+LvqwlidUtJlqemgnPRbn1mhFl988eyFF16I22f/d9ttN2eFkmYAViwkNVkUpC688MJsxRVXjNOIdunSJVt55ZVjYTUVPPMFpH/+85/ZIossEgtsFK7uv//+qdb5888/ZwcffHAsPLVt2zYWZA888MDsp59+qrLc+PHjszPOOCMWkljf/PPPn+29996FQnA5BbNPPvkkO/zww7Ollloq69ChQ9wmBdlUgC0H05FSQEyFUval3H2rS7lxWspxKjUOatu/UjEb00ILLRR/z1Sq1WHmqCWWWCKGhWN84403ZrfddltFFYtS4yvZaaed4u8OPfTQkvetrnRZajqYVhULMG0ts4B17tw5vphqljC1adMmO+aYY0reV0nNTyv+aey7JpJUXzzoi37yV199ddhnn32MSDUbBxxwQJwd6s0334yzZrVkPMCPh/mdf/754fDDD2/s4EiaRhxjIUnSdMZYCZ54vcoqq7T4SgXYV6y77rqNHRRJ01DdcylKkqQGrVScd955caaka665psXF7Kmnnhqf18FAbgaqM5D8b3/7W9hyyy3Diiuu2NjBkzQNecdCkhrZYostFmcoqulVyvM0mtJ2GlpzDXd1br/99jj1LjNiUQCnsN3SMOUvs0CtuuqqYb755gunnHJKOPjgg+O+S2rZHGMhSZIkqWLesZAkSZJUMSsWkiRJkirWfDqmVmDKlCnh66+/DrPOOmuVJ61KkiRJqhlPphg7dmzo3r17aN269nsSM0TFgkpFjx49GjsYkiRJUrM0cuTI+DyaMKNXLLhTkSKkc+fOjR0cSZIkqVkYM2ZMbKBP5ekwo1csUvcnKhVWLCRJkqTylDKcwMHbkiRJkipmxUKSJElSxaxYSJIkSaqYFQtJkiRJFbNiIUmSJKliViwkSZIkVcyKhSRJkqSKWbGQJEmSVLEm84C8jz/+ODzyyCNh+eWXD2uvvXaV78aPHx8ef/zx8N1334Vll102rLbaao0WTkmSJElNtGJBxWHbbbcNH374Ydh3332rVCy+//778Je//CX+3atXr3DMMceEbbbZJlxzzTWNGGJJkiRJTa5iccQRR4Q111yz2u+OO+640K5du/DSSy+Fjh07hjfffDOstNJKYcsttwybb775dA+rJEmSpCZYsfjXv/4V/v3vf4dhw4ZNVbmYMmVKuPvuu8Mpp5wSKxWgqxTL3XHHHWVXLCZMmBBfxVq3bh3atv2/qKhumaRVq1axolOfZSdOnBiyLJuuy2KmmWaq17KTJk2Kx6AhliW8hHtaLjt58uT4aohlSQ+ki6ayLHFAXNSkTZs28dVUliWNkdYaYtn8+Tmtlq3rXDaP+D/mEf9jHjH1uWweYTnCPKJl5hG1XR+n2mZoRCNHjgwHHnhgePjhh8PMM89c7fdjx44Nf/rTn6p8zvvXXnut1q5VvJIxY8bE/88777zQoUOHqZZffPHFw84771x4//e//73GAsmCCy4Y9txzz8L7iy66KPz+++/VLtu9e/fYtSu57LLLwujRo6tdds455wwHHXRQ4f3VV18dfvjhh2qX7dKlSzjssMMK76+//vrw9ddfV7ss8Xr00UcX3t9yyy3h888/r7Hgffzxxxfe33nnnbF7Wk0GDRpUpYL4zjvv1LjswIEDCwWShx56KLz11ls1LnvUUUeFTp06xb8fe+yxWo/1gAEDQteuXePfTz75ZHjxxRdrXJa0Ntdcc8W/n3322fD000/XuOw+++wT5ptvvvg3d8uGDh1a47J77LFHWGihheLfVJAZK1STnXbaKSyxxBLx77fffjvcf//9NS7br1+/sPTSS8e/33333VjJrgl38Kh046OPPgq33XZbjctusskmYdVVV41/f/HFF+GGG26ocdn1118/rLXWWvHvb775ptYuiOuuu26h2yJp9/LLL69x2TXWWCNsuOGG8W/OCc6jmqy88sphs802i39zrnF+1oTukltttVX8m3N48ODBNS7bs2fPsN122xXe17asecT/mEf8H/OIaZtHkK/PMccchXO5putWU8kjuNZyzc+PG62pEa8plCMocKbrVipv5ctNTbEcscgiixQKyYy5pXxYE8sRDVuOGDduXGjyFQtqWBTmDz/88LDiiitWu0xKNKngmMw222yFykJ1OPm5yyFJkpqGC4d+EPZ89Lf4d9dWf4Stp27nKxgyZEh44okn/rds165VGtOK3fTS5+HgZ4fEv9uHiWHn/3VwqNiQt78JRw/733qxVy3rpZs2Y0ATCtf5u3t5L33yUzj5uP9b704dJoQO/7uZXpEPvhsbFsqtd6v2Y8NsNcz9+eOPP4YTTzyx8J7KS2pMK/bzbxOqrHfjmX4K8/6vYbti+fX+ZaZvwsK1rHfvvfcuNPpSOUyF4OqseNoTYXz4X8+O1dt9Hv7U6P1zZhytstr6xUxDN954Y+jfv3849dRTCzXQs846K7YMMpD74IMPDp988klYbLHF4oxQG2ywQZWW5+effz7897//LfmORY8ePWLNvXPnzlMtbzeH/2M3h5Z3C7MxlrUrlN0lYXfJGTOP6HnSo9UuOyW0ClMKs9xnoW2o2s11/PefhYk/ffG/ZbP/vQr72jqEdt0WCO3nWqjs9b5z6sZ1dpesLsxZaBUm52blbxsm1xheSlKTSwxvXevNh7emrs/VhzeEyeH/SuZtwuRQXF/Jh3lSLpratGJbNYd5UpX1EuNZteGt6byvKU3Utt7awtu61f9eNYeX+P3f3reOqaPqevNhtkt13ec95WjuiHG3rLpydF6j1eG4BbfrrruGDz74oPAZlYFffvklvPfee/HEWWCBBWIC/fTTT6v8lgoHFZCatG/fPr6K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V7j//vtDq1atwl577RUWXnjhcPPNN4c999yzEUMvSZIkqUncschXKsCdiilTpoS55porvp84cWJ49NFHw0477RQrFejevXtYb731wgMPPNAoYZYkSZLUBMdYvPPOO+Hiiy8OY8aMieMtzjvvvLDBBhvE7z7//PMwYcKEeIcij/fPP/98jescP358fCWsW5IkSVILnhVq1llnDcsvv3zo2bNnHJBNN6hUEfjjjz8Ky+R17tw5/P777zWuc/DgwaFLly6FV48ePabxXkiSJEkztkavWFDoZ2zFiSeeGF5++eUwYsSIcMEFFxQqEMgP5sYvv/xS+K46AwcODKNHjy68Ro4cOY33QpIkSZqxNXrFIo87E0sssUT46KOPCpUOPqO7VB7vmZq2Ju3bt48Vj/xLkiRJUgusWDB24sknn6zy2QcffBCGDRsWVllllfi+devW8bkW1113XaHrE9+/8MILYccdd2yUcEuSJEmqYPD2l19+WeqiYf75569zGWZ5uvDCC+N0soyvoLsTFY1tt902do3Kj5dgFqgVVlghTjv7xBNPhH333TdsttlmJYdHkiRJUhOpWJQzADrLsjqXadeuXXjwwQdjt6Y33ngjdOrUKVx00UVTzQDFcy1ef/31MHTo0PjkbSoiK620UslhkSRJktSEKhbvvvvuNAkAdyt41YbZojbddNNpsn1JkiRJ07FisdRSSzXA5iRJkiS1RE1qVihJkiRJM9CTtxlDcf3114e77rorfPHFF2HSpElVvn/vvfcaKnySJEmSWuodi3POOSc+0G7NNdeMD7TbZ599wnLLLReni91www0bPpSSJEmSWl7F4pprrol3K6hc4Kijjgp33nlnuOSSS8KHH37Y0GGUJEmS1BIrFp9++mnhIXYdOnQIY8eOjX/vtttu4bnnnmvYEEqSJElqmRWLyZMnx+dQYMEFFwwvv/xy/Puzzz4rfC5JkiRpxlGvwdt5jK/YYYcd4tOxuVux3XbbNUzIJEmSJLXsisUvv/xS+JvxFfPOO2948cUX45iL/fffvyHDJ0mSJKmlVix4Cvcaa6xReL/LLrvElyRJkqQZU73GWKy11lphscUWC4MGDXIWKEmSJEn1nxVq7733Dvfcc09YYoklwmqrrRanmv3hhx+MUkmSJGkGVK+KBTNBDRw4MAwfPjy8+eabYd11140PzevevXvYbLPNGj6UkiRJklr2rFC9evWKT93u27dv6N+/f3j44YcbJmSSJEmSWvYdi2TEiBHh+OOPDwsvvHDo3bt3mGuuucINN9zQcKGTJEmS1HLvWJx77rnhlltuCW+99VZYaaWVwoABA8JOO+0U5plnnoYPoSRJkqSWWbG44oorws477xzuuOOOsOSSSzZ8qKTpiHFC3H2rydJLLx2WX355j4kkSVJDVyw+/vjjkpbr169fuPvuu+uzCalsCx03pF6x9u2tx4XxI4fX+H37HsuEeXY+q+z1fnaWExlIkqQZR8WDt2vDdLRSUzdbn/3CxB8/r/H7dnMsOF3DI0mS1BxN04qF1By0n3uR+JIkSVIjzQolSZIkSVYsJEmSJDUI71hIkiRJqpgVC0mSJEmNU7HYaqutSvpu7733rl+oJEmSJLX8isX9999f7edTpkwJDz74YOH9NddcU/+QSZIkSWqZ081+++231f6dKhXPP/98mHfeeRsudJIkSZJaXsUiX2morgLRtm3bcP755zdMyCRJkiS1zIrF22+/Hf9fdtllC38n7dq1C/PNN1+YZZZZSl7fuHHjwi233BJeeOGFWClZe+21w8477xzatGlTWOaKK64Ijz76aJXfLbjgguGiiy4qJ+iSJEmSmkrFYplllon/f/PNN2Geeeap8t2PP/4YOnToUPK66DrVs2fP0KdPn7DWWmuF33//PZxwwgnhzjvvDA888EBo1apVXO7NN98M33//fTjmmGMKv+3cuXM5wZYkSZLUlCoWyQ8//BDOPffccN5558X3BxxwQLjyyitDt27d4t2FlVdeuc51UHHgTkW+gsLv1lhjjfDaa6+FVVZZpfB59+7da52JSpIkSVIznBXqyCOPDH379o1/v/vuu7E709ChQ8O+++4bjj322JLWQcWi+K4HXakwevToKp//97//jV2kDjzwwHDrrbeGLMvqE2xJkiRJTemOxUsvvRRWW221+Pfjjz8e7ybQpYm7DAsssEC9A3PhhReG2WabLay66qr/F8C2bcOf//znsO6664avvvoqHHbYYeH222+PU96m7lLFxo8fH1/JmDFj6h0mlY/uayNGjKjx+6WXXjosv/zyRq0kSdKMXrGYeeaZYyF/8cUXD0OGDAk77bRT/JxxEh07dqxXQG677bZYsWCMRX4MxRlnnBG6dOlSeL/pppuGFVZYIVYsauoeNXjw4HDKKafUKxz6PwsdN6Re0fHtrceF8SOH1/h9+x7LhHl2PqusdX521mYeGkmSpJZWsdhyyy3ji1bnl19+OXZPwhNPPBE23HDDstd37733hj333DOO09h2222rfJevVKBXr15hoYUWiuMwaqpYDBw4MBxxxBFV7lj06NGj7HCpfmbrs1+Y+OPnNX7fbo4FjVpJkqQWpl4VC6Z6ZeD2559/Hh555JEwxxxzxM8p7A8aNKisdd13333xjscll1wS9tlnnzqXZ3wFYzDoIlWT9u3bx5caR/u5F4kvSZIkzTjqVbFgWlmmhi1W7rMlmFZ2xx13jJWK/fbbb6rvJ06cGO+G7L777oXxFGeffXb45ZdfwhZbbFGfoEuSJElqKhULMDj6ueeeC5988kmcDQqMu0gzO9WF7knbbbdd7Or08MMPx1dyyCGHhPXXXz8+KI9tnHTSSWGJJZYII0eODD/99FO44YYbwoorrljfoEuSJElqChWLTz/9NGyyySbh66+/DmPHji1ULA4//PDYrWnrrbcu6a7HHXfcUe13DApH69atw9VXXx0fkMeTvpkxaqmlloqDxyVJkiQ184oFFYgNNtggzuKUH+vA8y0GDBhQUsVipplmKvmhd3PNNVeczlaSJElSC6pYPPvss+HDDz+MXZWKn0/AMwwkSZIkzVjq9eTtCRMmhClTpsS/8w+pYwzELLPM0nChkyRJktRyKxa9e/eOMznlKxYMxubZEXSRkiRJkjRjqVdXKJ5hsc4668SnbvNcic033zy8+OKLcUD2888/3/ChlCRJktTyKhaLLbZYGD58eLj22mvDoosuGrtFMXCbZ1F069at4UMpSZIkqWU+x2L22WcPRx99dMOGRpIkSdKMVbFgTAUPqnv33Xfj+549e8YnZHfu3LkhwydJkiSppQ7eZjzFwgsvHM4888z4sDxeZ5xxRlhkkUXCK6+80vChlCRJktTy7lgcdNBBYeeddw7nn39+aNeuXfxs4sSJcVaoAw44ILz++usNHU5JkiRJLa1i8d5774WhQ4cWKhXg75NPPjn06NGjIcMnSZIkqaV2hWJWqC+//HKqz3lAHt9JkiRJmrGUXLEYNWpU4dW/f/+w3XbbhXvvvTdWJr744ov49/bbbx8GDBgwbUMsSZIkqfl2hZptttmm+mzbbbed6rN99tkn7L333pWHTJIkSVLLq1i8+uqr0zYkkiRJklp+xWLllVcue+X9+vULd999d9m/kyRJkjQDDN4u1T333DMtVy9JkiRpRqhYSJIkSZoxWLGQJEmSVDErFpIkSZIqZsVCkiRJUsWsWEiSJElq2hULH5QnSZIkzRhKfo5Fdb7++uvw/vvvhyzLwlJLLRW6d+9e5ftrrrmm0vBJkiRJaql3LH799dewxx57hPnnnz/07t079OnTJ/7NZ7/99lvDh1KSJElSy6tYHHnkkeGVV14JDz/8cBg1alR88Tef8Z0kSZKkGUvb+j5R+6mnngrLLrts4bONN944doXiDsYVV1zRkGGUJEmS1FK7QhWPpwCf8Z0kSZKkGUu9KharrLJKOP3008PkyZMLn/H3aaedFlZdddWGDJ8kSZKkltoV6vzzzw8bbrhhuPfee8NKK60UPxs2bFgYO3ZseOyxx0pez08//RS7Tb3wwguhbdu2Ye211w4HH3xwmHnmmass98wzz4TLLrssfPfdd7H71fHHHx/mnXfe+gRdkiRJUlO6Y/HRRx+FAw88MHTq1CnMMsss8W8+47tScIdj5ZVXDuPGjYuVid122y1cf/31YaONNgqTJk0qLMdYDmadWnzxxcPRRx8dPvzww7DWWmvFSowkSZKkZnzHYquttgr33XdfOO6442r8ri5t2rQJw4cPjxWTZIkllgi9evWKs0utueaa8bMTTzwxbLvttrHrFdZbb714t+Kqq65yBipJkiSpOd+xuP/++6v9fMqUKeHBBx8seT35SgW484EJEybE/3///ffw0ksvhc0337ywDN2k1l9//TB06ND6BF2SJElSY9+x+Pbbb6v9O1Uqnn/++YrGPpxxxhnx92kA+MiRI+N6i2eg4v2TTz5Z43rGjx8fX8mYMWPqHSZJkiRJDVyxyFcaqqtAMACbgd31cfHFF4ebbropPPLII4XB2xMnToz/t2/fvsqyHTt2LHxXncGDB4dTTjmlXuGQJEmSNI0rFm+//Xb8n5mZ0t9Ju3btwnzzzVfozlQOxkswMPvOO++MA7WT2WefPf7/888/TzWbVLdu3Wpc38CBA8MRRxxR5Y5Fjx49yg6XJEmSpGlQsVhmmWXi/998802YZ5556ly+X79+4e677651mWuuuSYceuih4bbbbosDv4u7PLGdV199NfTt27fw+csvvxz+/Oc/17hO7nAU3+WQJEmS1MQGb5dSqcA999xT6/f//Oc/41SzVCq22Wabapf561//GisfX331VWGd77zzTvxckiRJUjOebrYhjBo1Kuy7776hS5cu4ZxzzomvhAfgbbHFFvHvk046KT67YrHFFovdmb788stw6aWXlvy8DEmSJEktuGLBWAxmkarOoosuWvibLk2Mvfj666/jk7epYMw666zTMaSSJEmSmmzFghmkVl999ZKXZ7xF8bSzkiRJkprxGAtJkiRJyrNiIUmSJKnpVCx+/PHHMGnSpCqf7b333g21ekmSJEktrWLBw/GOPPLIwvsDDjggzDnnnHEa2tdee63wOdPESpIkSWr56lWxoFKRHlj37rvvhltuuSUMHTo0Th977LHHNnQYJUmSJLXEWaFeeumlsNpqq8W/H3/88fjE7D59+sRnSyywwAINHUZJkiRJLfGOxcwzz1x4EvaQIUNC796949+///576NixY8OGUJIkSVLLvGOx5ZZbxtfyyy8fXn755XDrrbfGz5944omw4YYbNnQYJUmSJLXEOxYXXXRR2GWXXeLTsx955JEwxxxzxM8ZuD1o0KCGDqMkSZKklnjHokOHDuGEE06otsIhSZIkacZTr4oFJk6cGD799NPw888/T/Xd6quvXmm4JEmSJLX0isUzzzwTdtppp/D1119X+32WZZWGS5IkSVJLH2NxyCGHhG222SZ88cUXYezYsVO9JEmSJM1Y6nXH4uOPPw4vvPBCHLwtSZIkSfW6Y7H44ovX2A1KkiRJ0oyn5DsWo0aNKvx92GGHhb322itceOGFYbHFFgutWrWqsmzXrl0bNpSSJEmSWkbFYrbZZpvqs1VXXbXaZR28LUmSJM1YSq5YvPrqq9M2JJIkSZJafsVi5ZVXnrYhkSRJkjRjDd7+7bffwn333TfV53zGd5IkSZJmLPWqWBx77LHhq6++murzL7/8MgwcOLAhwiVJkiSppVcs7rjjjrDjjjtO9Tmf3XnnnQ0RLkmSJEktvWIxceLEMGbMmKk+57M//vijIcIlSZIkqaVXLNZbb71w/PHHh/Hjxxc+GzduXDjuuOPid5IkSZJmLCXPCpV3zjnnhD//+c9h4YUXjs+y4LkVTEc7ZcqU8OyzzzZ8KCVJkiS1vDsWiy++eHj77bfDoYceGtq1axfat28f/x4+fHj8TpIkSdKMpV53LDDnnHM6A5QkSZKkyioW+Prrr8P7778fu0IttdRSoXv37pWsTpIkSdKM1BXq119/DXvssUeYf/75Q+/evUOfPn3i33xWzgPyGJPx0EMPhb59+4bFFlssvPzyy1Mtc9JJJ8Xv8q9NN920PsGWJEmS1JTuWBx55JHhlVdeCQ8//HBYY4014mcvvvhiOPzww+N3V1xxRckP2nvnnXfCVlttFYYMGVLtVLXff/99HLdxySWXFD5jTIckSZKkZl6xuOeee8JTTz0Vll122cJnG2+8cewKxR2MUisWZ5xxRphpppniE7tr06lTp3inQpIkSVIL6wpV3XgKPuO7UlGpKMVzzz0XlltuuTjFLc/PGDt2bFnhlSRJktQEKxarrLJKOP3008PkyZMLn/H3aaedFp9r0ZBmn3322GXq+uuvD8ccc0zsMrXWWmuFCRMm1PgbHtzHU8DzL0mSJElNrCvU+eefHzbccMNw7733hpVWWil+NmzYsHgn4bHHHmvQAFJZadOmTfx7xRVXDCussEJ8MN/tt98edt9992p/M3jw4HDKKac0aDgkSZIkTYM7Fh999FE48MAD4/iHWWaZJf7NZ3zXkFKlImH2qYUWWiiMGDGixt8MHDgwjB49uvAaOXJkg4ZJkiRJUgM9x6Jbt27huOOOC9Mb3Zy+/fbb0LVr1xqXYdYoZ46SJEmSmkHFgnELN9xwQ3j33Xfj+549e8auSZ07d26wwDGO4oQTTogVGCoyv//+ezj00EPjeI4ddtihwbYjSZIkqRG6QvHMCsY5nHnmmeHTTz+NL6aOXWSRReLzLUrFGA2mkWW2J+yyyy7x/cUXXxzft2vXLnZ9YkaoeeedNw7kHj58eHjyySfjtiRJkiQ14zsWBx10UNh5553jIG4K/5g4cWI44ogjwgEHHBBef/31ktazwQYbhEcffXSqz6lAoFWrVmHAgAHx9d1334UuXbqEDh061CfIkiRJkppaxeK9994LQ4cOLVQqwN8nn3xy6NGjR8nrmXXWWeOrFHPPPXd9gipJkiSpqXaFortSdU/LZvYln5AtSZIkzXjqVbHo379/2G677eIYCSoTX3zxRfx7++23j92WRo0aVXhJkiRJavnq1RVqv/32i/9vu+22U323zz77xFeSZVkl4ZMkSZLUUisWr776asOHRJIkSdKMVbFYeeWVGz4kkiRJkmasMRbpCdg8T+Lqq68ufPbVV181VLgkSZIktfSKBQ/E69WrV9h6660L4y1w+OGHh3/9618NGT5JkiRJLbViQQWCh9v98ssvVT4/8sgjw9lnn91QYZMkSZLUksdYPPvss+HDDz8Mbdq0qfL50ksvHd58882GCpskSZKklnzHYsKECWHKlCnx71atWhU+55kWs8wyS8OFTpIkSVLLrVj07t07XHLJJVUqFmPGjAlHHHFE7CIlSZIkacZSr65Q5513XlhnnXXCkCFD4gPwNt988/Diiy+GDh06hOeff77hQylJkiSp5VUsFltssTB8+PBw7bXXhkUXXTR2i2LgNjNEdevWreFDKUmSJKnlVSww++yzh6OPPrphQyNJkiRpxnpAniRJkiQlViwkSZIkVcyKhSRJkqSKWbGQJEmSVDErFpIkSZIqZsVCkiRJUsWsWEiSJEmqmBULSZIkSRWzYiFJkiSpYlYsJEmSJFXMioUkSZKkilmxkCRJklQxKxaSJEmSKmbFQpIkSVLzrlj89ttv4Zprrgkrr7xymGWWWcKzzz5b7XJXXXVVWHrppcMcc8wR1ltvvTBs2LDpHlZJkiRJTbRicdppp4UXX3wxnHjiibGSMXny5KmWueWWW0L//v3D3/72t1ihoILRp0+f8PXXXzdKmCVJkiQ1sYrFWWedFa699tp4x6ImgwcPDnvttVfYcccdw4ILLhguvvji0LFjx3D55ZdP17BKkiRJaqZjLEaNGhVGjBgR71AkrVu3Dr179w7PPfdco4ZNkiRJ0v9pG5qw1N1prrnmqvI572sbZzF+/Pj4SsaMGTMNQylJkiSpSd+xyN+lKH6fZVmt3ae6dOlSePXo0WM6hFKSJEmacTXpikW6U/HDDz9U+Zz3xXcx8gYOHBhGjx5deI0cOXKah1WSJEmakTXpigXTyy622GLhmWeeqfL5008/HVZfffUaf9e+ffvQuXPnKi9JkiRJM2jFAocddlicOYrKxLhx4+IUtd9//3044IADGjtokiRJkppCxYJnVPBgvCWXXDK+32STTeL7M888s7DMwQcfHI466qiw9dZbh06dOsXfPPDAA2HRRRdtxJBLkiRJajKzQu2www5hyy23nOrzmWaaqcr7k046Kb4mTpwY2rVrNx1DKEmSJKnJVyzatm0b71CUykqFJEmS1DQ1+TEWkiRJkpo+KxaSJEmSKmbFQpIkSVLFrFhIkiRJqpgVC0mSJEkVs2IhSZIkqWJWLCRJkiRVzIqFJEmSpIpZsZAkSZJUMSsWkiRJkipmxUKSJElSxaxYSJIkSaqYFQtJkiRJFbNiIUmSJKliViwkSZIkVcyKhSRJkqSKWbGQJEmSZMVCkiRJUuPzjoUkSZKkilmxkCRJklQxKxaSJEmSKmbFQpIkSVLFrFhIkiRJqpgVC0mSJEkVs2IhSZIkqWJWLCRJkiRVzIqFJEmSpIq1DU3cpEmT4iuvdevWYaaZZmq0MEmSJElqZncsDjnkkNCpU6fQtWvXwmuNNdZo7GBJkiRJak4VC2y99dZh3LhxhdewYcMaO0iSJEmSmlvFAlOmTGnsIEiSJElqzhWLhx9+OLRv3z7MPvvsYYsttggffvhhYwdJkiRJUnOqWCy11FLh/vvvD7/++mvsApVlWVh33XXDL7/8UuNvxo8fH8aMGVPlJUmSJGkGrlgcdthhYYMNNoh3LBZeeOFwyy23hFGjRoU77rijxt8MHjw4dOnSpfDq0aPHdA2zJEmSNKNp8hWLYp07dw7zzz9/+Pjjj2tcZuDAgWH06NGF18iRI6drGCVJkqQZTZN/jkWxn3/+OXzxxRexclET7m7wkiRJkjR9NOk7FoyV2HTTTcMzzzwTfvrpp/DGG2+Efv36hdlmmy3suuuujR08SZIkSc2hYsFdh6OOOiqcfvrpcRD3DjvsEMdZvPrqq6Fbt26NHTxJkiRJzaUrVO/eveNLkiRJUtPVpO9YSJIkSWoerFhIkiRJqpgVC0mSJEkVs2IhSZIkqWJWLCRJkiRVzIqFJEmSpIpZsZAkSZJUMSsWkiRJkipmxUKSJElSxaxYSJIkSaqYFQtJkiRJFbNiIUmSJKliViwkSZIkVcyKhSRJkqSKWbGQJEmSVDErFpIkSZIqZsVCkiRJUsWsWEiSJEmqmBULSZIkSRWzYiFJkiSpYlYsJEmSJFXMioUkSZKkilmxkCRJklQxKxaSJEmSKmbFQpIkSVLFrFhIkiRJqpgVC0mSJEkVs2IhSZIkacapWIwbNy58++23YcqUKY0dFEmSJEnNrWJBRWLAgAGha9euYckllwzdu3cPd999d2MHS5IkSVJzqlice+654ZZbbgmvvfZaGDVqVDjppJPCTjvtFEaMGNHYQZMkSZLUXCoW//jHP8I+++wTlllmmdCqVatw0EEHhYUWWihcffXVjR00SZIkSc2hYvH999+HL774Iqy55ppVPl9rrbXCq6++2mjhkiRJklRV29CE/fDDD/H/bt26Vfl8jjnmCC+88EKNvxs/fnx8JaNHj47/jxkzJjSWKeN/D01JKXHRlMLc3MLbHMNseI3j5p4mSglzcwtvUwtzcwtvcwyz4TWOizVm+TW//SzL6l44a8Leeecd9iD7z3/+U+Xz/v37Z0sttVSNvxs0aFD8nS/jwDRgGjANmAZMA6YB04BpwDQQKo6DkSNH1ll2b9J3LOaff/74P9PM5vF+vvnmq/F3AwcODEcccUSVmaV+/vnneOeDcRrNFTXGHj16hJEjR4bOnTuH5qC5hdnwGsemCc+7lpZPNMcwG17j2DTRdHCnYuzYsXFm1ro06YrFrLPOGlZcccXw2GOPhR122CF+NnHixPDkk0/GKWhr0r59+/jKY7raloKLQnO4MDTnMBte49g04XnX0vKJ5hhmw2scmyaahi5dupS0XJOuWIDpZfv16xdWWmmlsMYaa4TzzjsvtGnTJhx44IGNHTRJkiRJzWFWKGy55Zbh9ttvD3fccUd8fgWDsp955pk4gFuSJElS09Dk71hg2223ja8ZHd27Bg0aNFU3r6asuYXZ8BrHpgnPu5aWTzTHMBte49g00Ty1YgR3YwdCkiRJUvPW5LtCSZIkSWr6rFhIkiRJqpgViybolltuCaeeempjB0OSJElqWYO3ZzRvv/12eO211xo7GJIkSVLJrFioVpMnTw4PP/xwuOGGG8KkSZPCfffdV+1yN910U7j//vvj8ptuumnYe++9Q+vWrafJMrX5/fffw3XXXReee+65+H7NNdcM++67b+jQoUOV5f773/+GSy+9NHz99dfhT3/6UzjqqKPC3HPPPU2WqQsPfLz33nvDV199FRZddNFw0EEHxf/zPvjgg/CPf/wjfPLJJ2GeeeYJBxxwQHx4ZLnLvP/+++Gqq64KH330UZhlllnCX/7yl7DHHnuEmWaaqeTw/vbbb+Haa6+NccwzZVZbbbWwzz77xPUl48aNi2F56aWX4rHcbLPNwp577lnlWHKsrrnmmvDCCy/E5Yk/nk+zwAILVNneTz/9FOP49ddfD/PNN1844ogjwmKLLRbqg3Ucc8wxMV7OOeecKt898cQT4c477wzffPNN6NmzZ9wO8Zj0798/vPPOO1Otc+mllw4XXXRR4f1nn30Wzj///PDxxx+HhRdeOBx22GFlhZe46Nu371SfE+4NN9yw8J40d8kll4R33303PriI49i7d++y18MU3nfddVec0pu4v+yyy0J9kC6uvPLKmC5mm222eCxXXnnlwvekA87Np556Kvz6668x7R188MFV0t7PP/8c08Qrr7wSZp555rg/u+22W0xnCQ9JJZ/gvJkwYUJYfvnlw/7771/WFORnnHFGDEexbt26xXhIaOAhzF988UXcJ9Lx9ttvH1q1alVlmX/+859xGY43D2/NH+9St1UXzoMrrrgivPHGG/E9+00cs55yltlqq61i/OfttddeYZdddilrmVKwf1w/fvnll7DKKqvEc4EH3ybMHXPPPfeEBx98MB57ngxOPrHqqqtWWQ/nHfvF/2eddVaVdJVPFxyHoUOHxhml/vrXv1Y5H6pDOiM/5JzlOLP9cpap6RwD6ZZzstRtcX0l/P/5z39i3rjeeuvFY5c/P77//vu4zL///e/40GCujzVhO5wX5Jn8JiG/5flgxZjWP51DpSyTwvP3v/89Hpd55503ns+kufw5z7HlfOUcJn+tzueffx7znffeey8sueSS4eijjw5zzTVXtcumfJi8j2tGuduqaz2lpLW60nVDrqeUZZocZoXS9PfDDz9kgwcPznbdddfs+OOPz7788svCd8cee2zWp0+f7KWXXsqOOuqo7K9//Wt2yy23VPn90KFDs2233Ta+9thjj+zcc8/Nfv311yrL3Hzzzdkpp5ySPf/889mBBx4Yt1WulVdeOdtss82yXXbZJevSpUu1y5xwwglZ165ds3/84x/Z1Vdfnc0555zZIYccMk2Wqcviiy8ef3PbbbdlN954Y/anP/0pW3PNNbMJEyYUlnn99dezjh07ZgcccEB2xx13ZBtssEG20EILZb/88kuDL1MXjv3666+fXXbZZdl9992X7bnnnlmHDh2y1157rbDMK6+8ks0000xxOyzDMZ1lllmyZ555pqxl3nvvvfgZx/L+++/PrrrqqmzeeefNdtttt7LieKWVVsqOPvro7J577smuv/76bJlllslWWWWVbNKkSfF74nq11VbLevXqld16663xOCy55JIxDeYRXxyvG264IfvXv/6VbbLJJtlcc82VffPNN4VlPv7442y++eaL3919991xeyuuuGL2+++/Z+UaO3ZsDAfb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dZZ8kHOCtMjxppJDvJO2uXbly3LkIRxT0ktqaEljH6e7TC3CL7/8Qkkie/XVV2td7oorrsiWWmqpKp/xu8MOO6zw/tdff81mnnnm7IEHHojvP/zww6x169bZnXfeWeV3X331VcnreP/997M2bdpkjz32WGGZ1VdfPf7u7bffrrKeffbZp/D+p59+ytq2bZstvPDC2fjx4+Nnu+yySzbXXHPF9X3//ffxsxVWWCHr2LFj9scff8T3a665Zta9e/e4vvRZCu/BBx+czT///PGVvsPOO++cbb/99oX3a6yxRrbbbrsV3t92220xHo4//vjCZ4RljjnmyMaOHVv4rG/fvnG5l156Kb5/4oknYjh69OiRXXLJJfGzm2++OX72r3/9K76/6qqrsvbt28fPrr766vjZhAkTsh9++CF78cUX4+e8HnroocJ2Hn/88fjZb7/9Ft9feeWVWZcuXbKff/65sEy7du1i+CZOnFglLLfffnthGdZJHO+///6Fz+abb75smWWWyVZaaaX4fvLkyVmHDh0K79lGp06d4vbWWmutqdLEkksumXXt2jXr169f4TvWQRz84x//iO9//PHHbJZZZsmuvfbaKseA8LFv+bBsvPHGhffjxo3LZp999rjt0aNHx89OOOGEmN6I95Settpqq/ieOEzrJt2wftI0SD/EzeDBg7N55pkn7tN3331X2BbHetVVVy2832mnnbJ11103mzJlSnz/yiuvxPXl95OwzDTTTNnnn39e+Ozwww+Pn6V4Z/v8jnPxyCOPjJ+99dZb8bOTTjqpcHxbtWoVP2OdYLvffPNNfKU0cemllxa288EHH8TP3nnnnfie843zhM8TzgvCwrmVD8tZZ51VWGb48OFx27179y58xnFeZJFFsm7duhU+m3vuubN55503hmvSpEnx+BLHHLPiNLHRRhvFba+yyiqF+Evn6jHHHBP/5liwjr/97W+F708++eR4HDlH8mHp2bNnTFMpXpZeeum4r1988UX8jPOI/SKdPPjgg/Gz4447Ln42YsSIwvHlez7j3ADn8pgxY+L5TnrgO+IjIRzsYzJw4MBs0UUXjecr0rHp1atXYZkUlpQn4MILL4znVIp38iKWWX755bNtt902fjZq1Kj4WcqXCDfHheNH3lMcx3zO8uxnwjrIB9I5xfnBOp5++unCMpzXfJbSSQrLIYccUliG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CAqWqQtWqagApL7JFAymx9O3KaBTaKEilp+hqhRUJimAgYrE9Hj6NgW61GefBo26BksXo4BLQReEd1oP+qQgne4UUokq9ynnFM7SjFBUVKbH07cp8KduusWVylJQUaNQS6Vqejx9mwJl6npLg1eapahUqdANrpXT+unbqXIGKib5Br7pcX2vD9Jw6jZZ3MDXFFE5S3fZqfAXzy7XUKxYSJIkSaqYg7clSZIkVcyKhSRJkqSKWbGQJEmSVDErFpIkSZIqZsVCkiRJUsWsWEiSJEmqmBULSZIkSRWzYiFJ0xkPVeLBerfffnvhydfpAWWV4MmrPPCPhyI2JTxNlicJTwvEIw/ha4mmZbyBB5LxtGpJaihWLCRpOnrttdfiU3CvuOKKcN9998WKxR577FF4unQlLrvssvjUaJ603pTsu+++8enQ08Khhx4a/v3vf4eWaFrGG3hS8RlnnDHN1i9pxtO2sQMgSTMSCv7rr79+vEuR9OvXL8w///wVrff3338Pp556anjooYfCjGTzzTcPiy66aGMHo1k67rjjwvLLLx8OP/zwMOecczZ2cCS1AFYsJOn/owvRK6+8En755ZewyiqrhLnnnrtK3IwdOza2II8fPz6sttpqU31P15WVVloptG/fPrz55pthlllmCauvvnpo06ZNoYWYOxYdOnSI3aCSjTfeOMw777xTdZd6+eWXQ/fu3UOvXr1iqzwF6MUXX7za43XrrbeGOeaYI6yxxhrx/TPPPBO3s+qqq1ZZ7umnn46fE/5S9qmueBk6dGj48ccfQ6tWreI+rLDCCmHWWWetNoxff/11eOutt0Lnzp3DmmuuGX9Tqtdffz18+eWXcf//9Kc/FT7fcMMNw4ILLhj//vDDD8OwYcOm+i13iAgXJkyYEF566aUwevTo0LNnz3pVSkpNB+wf4V5ggQUK2y83zeG7776rNj2VGv81hYd4WW655cK1114bKxmSVLFMkpS9/vrr2UILLZQtssgi2aabbhr/vummmwoxM3To0Kxr167ZSiutlK277rpZx44ds8svv7xKzHXr1i3baKON4jr69u2bzTvvvNmf//znbNKkSfH7AQMGZAsssED8focddii82rZtm/3rX/8qrOfee+/NOnTokK2++urx9yussELWvXv37JJLLqnxSG255ZbZAQccUHh/1llnZYsuumiVZcaPH5/N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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "inferred_total_epochs = int(raw[\"epochs_to_best_val\"].max())\n", "\n", - "group_cols = [\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"]\n", + "group_cols = [\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\", \"hidden_dim\", \"num_conv_blocks\"]\n", "conv = (\n", " raw.groupby(group_cols, dropna=False)[\"epochs_to_best_val\"]\n", " .agg([\"mean\", \"std\"])\n", @@ -815,8 +357,8 @@ " .sort_values(group_cols)\n", ")\n", "conv_labels = [\n", - " \"char\" if t == \"char\" else f\"{int(v)}\" + (\"\" if pl == \"end\" else f\"\\n[{pl}]\")\n", - " for t, v, pl in zip(conv[\"tokenizer\"], conv[\"vocab_size\"], conv[\"pad_layout\"])\n", + " \"char\" if t == \"char\" else f\"{int(v)}\" + (\"\" if pl == \"end\" else f\"\\n[{pl}]\") + (\"\" if (h == 192 and d == 4) else f\"\\nh{int(h)}d{int(d)}\")\n", + " for t, v, pl, h, d in zip(conv[\"tokenizer\"], conv[\"vocab_size\"], conv[\"pad_layout\"], conv[\"hidden_dim\"], conv[\"num_conv_blocks\"])\n", "]\n", "\n", "fig, ax = plt.subplots(figsize=(8, 4.5))\n", @@ -842,250 +384,24 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "305a88cc", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.761641Z", - "iopub.status.busy": "2026-08-07T10:53:08.761063Z", - "iopub.status.idle": "2026-08-07T10:53:08.775646Z", - "shell.execute_reply": "2026-08-07T10:53:08.774743Z" + "iopub.execute_input": "2026-08-11T18:27:05.768257Z", + "iopub.status.busy": "2026-08-11T18:27:05.768082Z", + "iopub.status.idle": "2026-08-11T18:27:05.793311Z", + "shell.execute_reply": "2026-08-11T18:27:05.791452Z" } }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizemax_token_lenpad_layoutseeds_hitting_ceilingn_seedsfraction_hitting_ceiling
12wordpiece145509.0anchored111.0
13wordpiece164149.0anchored111.0
10wordpiece98169.0anchored111.0
11wordpiece117199.0anchored111.0
0char25NaNend010.0
1wordpiece10009.0anchored010.0
2wordpiece20009.0anchored010.0
6wordpiece59519.0anchored010.0
5wordpiece49709.0anchored010.0
4wordpiece39869.0anchored010.0
3wordpiece29989.0anchored010.0
9wordpiece88559.0anchored010.0
8wordpiece78979.0anchored010.0
7wordpiece69239.0anchored010.0
14wordpiece191999.0anchored010.0
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size max_token_len pad_layout seeds_hitting_ceiling \\\n", - "12 wordpiece 14550 9.0 anchored 1 \n", - "13 wordpiece 16414 9.0 anchored 1 \n", - "10 wordpiece 9816 9.0 anchored 1 \n", - "11 wordpiece 11719 9.0 anchored 1 \n", - "0 char 25 NaN end 0 \n", - "1 wordpiece 1000 9.0 anchored 0 \n", - "2 wordpiece 2000 9.0 anchored 0 \n", - "6 wordpiece 5951 9.0 anchored 0 \n", - "5 wordpiece 4970 9.0 anchored 0 \n", - "4 wordpiece 3986 9.0 anchored 0 \n", - "3 wordpiece 2998 9.0 anchored 0 \n", - "9 wordpiece 8855 9.0 anchored 0 \n", - "8 wordpiece 7897 9.0 anchored 0 \n", - "7 wordpiece 6923 9.0 anchored 0 \n", - "14 wordpiece 19199 9.0 anchored 0 \n", - "\n", - " n_seeds fraction_hitting_ceiling \n", - "12 1 1.0 \n", - "13 1 1.0 \n", - "10 1 1.0 \n", - "11 1 1.0 \n", - "0 1 0.0 \n", - "1 1 0.0 \n", - "2 1 0.0 \n", - "6 1 0.0 \n", - "5 1 0.0 \n", - "4 1 0.0 \n", - "3 1 0.0 \n", - "9 1 0.0 \n", - "8 1 0.0 \n", - "7 1 0.0 \n", - "14 1 0.0 " - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "def summarize_convergence(group):\n", " hit_ceiling = int((group[\"epochs_to_best_val\"] == inferred_total_epochs).sum())\n", " return pd.Series({\"seeds_hitting_ceiling\": hit_ceiling, \"n_seeds\": len(group)})\n", "\n", "ceiling_df = (\n", - " raw.groupby([\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"], dropna=False)\n", + " raw.groupby([\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\", \"hidden_dim\", \"num_conv_blocks\"], dropna=False)\n", " .apply(summarize_convergence, include_groups=False)\n", " .reset_index()\n", ")\n", @@ -1103,28 +419,17 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "95004f13", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.776991Z", - "iopub.status.busy": "2026-08-07T10:53:08.776861Z", - "iopub.status.idle": "2026-08-07T10:53:08.877121Z", - "shell.execute_reply": "2026-08-07T10:53:08.876437Z" + "iopub.execute_input": "2026-08-11T18:27:05.795385Z", + "iopub.status.busy": "2026-08-11T18:27:05.795179Z", + "iopub.status.idle": "2026-08-11T18:27:05.943468Z", + "shell.execute_reply": "2026-08-11T18:27:05.942230Z" } }, - "outputs": [ - { - "data": { - "image/png": "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E5R+9dVXZoatN954w0xUYAWuVsBZtWpV873G2T169DDfnz592uVYGrS6uw0AAADsyaOZ16yMzCsAAEDKePUkBQAAAEBKEbwCAADANgheAQAAYBsErwAAALANglcAAADYBsErAAAAbIPgFQAAALZB8AoAAADbIHgFAACAbRC8AgAAwDYIXgEAAGAbBK8AAACwDYJXAAAA2AbBKwAAAGyD4BUAAAC2QfAKAAAA2yB4BQAAgG0QvAIAAMA2CF4BAABgGwSvAAAAsA2CVwAAANgGwSsAAABsg+AVAAAAtkHwCgAAANsgeAUAAIBtELwCAADANgheAQAAYBsErwAAALANglcAAADYBsErAAAAbIPgFQAAALZB8AoAAADbIHgFAACAbRC8AgAAwDYIXgEAAGAbBK8AAACwDYJXAAAA2AbBq42tXbtWNm7c6OmHAQAAkGkIXm1s8eLF8vPPP3v6YQAAAGQaglcAAADYRqCnHwDcc+bMGVm5cqWcPHlSChYsKL1793au09KBbdu2SdOmTaVSpUpm2ZYtW2T16tUSEBAgZcuWlfbt20tgYKCz3CBHjhwSExNjths8eDC/BgAAYAsErzbw559/SocOHUxwWrp0aYmMjHSumz17tqxatUqKFi0qw4cPlw0bNpgA9tKlS3Lo0CEToC5atEjef/99WbFihfj5+ZlyA72VLFlSbr/9do8+NwAAAFsFr5cvX5aFCxfKqVOnpEaNGtKuXbtk99Es4++//24yiXfddVeCAVhqjptVvfDCC/Lyyy/L0KFD463T5z5nzhzz/RNPPCE//PCDCV6bN28uOXPmNOfqtttuk3HjxsmRI0ekTJkyZtvKlSvLt99+m+nPBQAAwLY1r8eOHTOB5UcffSQHDhyQhx9+WO6//35xOBwJbq/L27RpI/3795cdO3aYy9933HGHvPTSS2k6bla3Z88eadWqVYLrateu7fy+WLFicuHCBfP9K6+8Ij169JA//vjDZGA143r27FnntvXq1cuERw4AAOBFmdfnnntOChcubILQbNmyyTPPPGMyifPnz5f77rsv3vYafOo+d999t3NZly5d5N5775WePXtKlSpVUnXcrE6zpVqbWrVqVbf3+eabb0xmVYPba9euyaxZs1yCd62FBQAAsBuPZV6jo6PNZf2+ffuaANO6lK11nfPmzUtwH39/f5fAVWnZgDp48GCqj5vVvfjii/LUU0+ZmtYJEyaYQDQ5NWvWNNtruUDbtm1N7SsAAIDdeSzzqvWXmhG0Rsdb9L5e6nbX3LlzTZBat27dNB03KirK3Cw64Cmr0OBTOwd89913cvjwYefjbNKkialrtTRs2NAE7+rTTz+Vzz77zNT+vvvuu7Ju3TozqCuh/QAAAOzCY8HrlStXzNeQkBCX5fny5XOuS462iNISgTFjxjgDs9QeVzOUY8eOlaxKyx7iDkzr2LGjy32tB7bkyZNHhg0b5hLYJrYfAACAXXisbCB37twJZjgjIiKc65KiA7bCwsLMYCwdjZ/W444ePdpsY92OHj2a4ucEAAAALw1etV+pXrrev3+/y/J9+/aZGtWk7Ny504y+1w4CEydOTJfjatP+vHnzutwyg9aiajcADcatvqwAAADIYmUD2qO1U6dO8sUXX8ijjz5q7mtbq19//dUssyxdulSOHz9utlF//fWXCVy1a8DHH39sWkCl5rhZwe7du2XZsmUuWWINmjWjnJLOAgAAAL7Cz+HB5qeaaWzcuLFpoq/9WrUbQK1atczAJO0soAYOHCjr16832VYdiKXb6kPWhvyxA1et47R6nrpz3ORoQKl1s1pCkBFZWA1cdbBZYh544AECWAAAYCuXMjh+8nif17Jly5qgVHuS6kxYH374oXTu3NklwNSgVANPiwazKnZnAGWNsnf3uJ6kpQGacU2Krtcyh6zymAEAAMTXM6+++slBM8MzZsxIdrt+/fqZQBwAAMAOLmVC5pW0ngdo79X03A4AAMBXELx6QHBwcLpuBwAA4CsIXj1A23kll0rX9bodAAAA/ofg1QN0EJa2w0qKrmewFgAAgCuCVw/RPq7aDituBlbv0yYLAAAgC7bK8nUawGo7rCNHjpjBWVrjqqUCZFwBAAASRvDqYRqo0g4LAADAPZQNAAAAwDYIXgEAAGAbBK8AAACwDYJXAAAA2AbBKwAAAGyD4BUAAAC2QfAKAAAA2yB4BQAAgG0QvAIAAMA2CF4BAABgG0wPmwiHw2G+Xrp0KTN/HwAAALZ16f/jJiuOyggEr4m4fPmy+VqqVKkMO/kAAADeGkeFhIRkyLH9HBkZGttYTEyMnDhxQoKDg8XPz898ktBA9ujRo5I3b15PPzyvw/nl/NoVf7ucXzvj75fzm940rNTAtXjx4uLvnzHVqWReE6EnvGTJkvGWa+BK8JpxOL8Zi/PLubUr/nY5v3bma3+/IRmUcbUwYAsAAAC2QfAKAAAA2yB4dVOOHDlkzJgx5ivSH+c3Y3F+Obd2xd8u59fO+PvNGAzYAgAAgG2QeQUAAIBtELwCAADANgheAQAAYBv+vjoBwffffy/33nuv3HnnnRIREeHWfnPnzpXOnTtLq1atzOCtq1evuqy/cuWKvPnmm9KpUydp3bq1PP7447J7927xNXoeJk+ebM5T3759022fqKgoGT9+vNx9991yzz33yPTp08UXHTlyRF588UW566675OOPP06XfW7duiUzZsyQHj16SNu2bWXYsGFmH1/0xx9/yMMPP2xeG/78889032fOnDlmu3fffVd8jf6dffvtt9KxY0dzDtJzH/171b9bfQ3R38WePXvE11y4cEEmTJggzZo1M+civfbZtWuXeT/T9zV9f3vrrbfivf/5gn379smIESOkUaNG8uWXXya7vb5nffrpp3LfffdJWFiYjBo1Sk6ePBlvu/3798vAgQOlefPm5v1v69atGfQMvIdPBq/6h/TRRx9J+fLlzZvOzZs3k91n0qRJ0q9fP/PG/uSTT8qCBQvMi2nsCco0GNaASrd7/vnnzYuCvtgeOnRIfEV0dLRUqlTJvIFrQ+bt27en2z49e/aUqVOnymOPPSbdunWTp556Sl577TXxJatXrzYvcNmzZ5fw8HC3Akx39tFzq9t17drVvDjrTHK1a9eWf/75R3yJfijV/9/VqlUzrw3ufLBNyT765vfss8+a2fsOHjwovkY/eH7xxRdSpkwZc67Sa59t27aZv9czZ87I6NGjpX379tKrVy/xJadPn5bq1aubv6vAwEC3Eifu7HPgwAHzPqYJBn1f69Onj3z22Wdy//33iy/RD1CaNClSpIjs3bvX/B9OjsYI+repSYFnnnnGBKX16tWTU6dOObc5duyYOb/Xr183wW3u3LmlSZMm8tdff2XwM7I5hw+6ePGi+frDDz9o5Ok4c+ZMktvfvHnTUbBgQcerr77qXLZ7926z77Jly8z9K1eumPtz5sxx2S8wMNAxdepUhy+JiIgwX4cPH+6oVatWuuzz559/mvO7bt0657KPPvrIkTNnTselS5ccvuLy5cuOW7dume9vv/12x3PPPZcu++g2sen2JUuWdPz73/92+OJrQ3h4uPl7W758ebrt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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(7, 5))\n", "for row in summary:\n", @@ -1161,14 +466,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "46065c2c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.878575Z", - "iopub.status.busy": "2026-08-07T10:53:08.878437Z", - "iopub.status.idle": "2026-08-07T10:53:08.884134Z", - "shell.execute_reply": "2026-08-07T10:53:08.883386Z" + "iopub.execute_input": "2026-08-11T18:27:05.945296Z", + "iopub.status.busy": "2026-08-11T18:27:05.945126Z", + "iopub.status.idle": "2026-08-11T18:27:05.953653Z", + "shell.execute_reply": "2026-08-11T18:27:05.952785Z" } }, "outputs": [], @@ -1186,30 +491,19 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "dfe53dfa", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.885992Z", - "iopub.status.busy": "2026-08-07T10:53:08.885393Z", - "iopub.status.idle": "2026-08-07T10:53:08.966904Z", - "shell.execute_reply": "2026-08-07T10:53:08.966129Z" + "iopub.execute_input": "2026-08-11T18:27:05.955500Z", + "iopub.status.busy": "2026-08-11T18:27:05.955334Z", + "iopub.status.idle": "2026-08-11T18:27:06.078304Z", + "shell.execute_reply": "2026-08-11T18:27:06.077094Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAG4CAYAAADYN3EQAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAf4pJREFUeJzt3QWUFMfCuP0igRAhClFCjDjE3YW4End39xuI5yY37rlx4u7uLiTEc+NuxIgCUQihv/PU/635eobZ3d6dXWB3n985AzszPd3V1dXVVdVV1R2yLMuCJEmSJNVgglp+LEmSJElWLCRJkiQ1C+9YSJIkSaqZFQtJkiRJNbNiIUmSJKlmViwkSZIk1cyKhSRJkqSaWbGQJEmSVDMrFpIkSZJqZsVCaiOWXnrpsNpqq7Xb7bcW8847b+jbt29oywYMGBDmmmuuMOGEE4Zu3brFzxZeeOGw1lprtcj2SHe77LJLGJeqpf/2ck40Nf6XXXbZsO+++4bx1VVXXRU6dOgQPv7442Zd72OPPRbXy/8tuc6rr746TDvttGHo0KHNth2pIVYspLGkJQtWY0tb2Ae1rNdffz3svvvuoX///mHEiBHhxx9/bNHt3XPPPeGZZ54JRx99dGhppv/mjf8TTjghXHLJJeHdd99tluOjcttuu23o2rVrjGdpbOk41rYkqUUNGjSoXW9f44fHH388ZFkWttpqq9Cx4/9/iXnjjTdaZHsnnXRSWH/99cNss80Wxjft4ZyoJf779OkT5pxzznD66aeHK6+8skXC155xx3DPPfcMRxxxRDjqqKPC1FNPPa6DpHbAOxaSpGbz/fffx/8nmWSSFo9VKisvvvhi2G677Vp8W2qZ+N9mm23CzTffHH755RejuAVQwefO4TXXXGP8aqywYiGNBVNNNVX43//+Fx5++OHYD5ZXvoUv9bt/++23Y3/lySabLLY0gc/Tb2iBmm666cKmm24aPvjggwb7c6f1sizfTTrppKF79+7x1jitys25D/Vt/6233gorrrhi3K9evXqFRx99tFQwWXnllWO4WNcNN9xQddv33ntvWGmllcLkk08eC6zLLbdceOSRR0JjPfnkk2HVVVeN/f6nnHLKsMwyy4Qbb7xxjLgour377rsvro+44bX66quHgQMHFgoLcbnCCivEfZ9lllnCv//97zB69OjS9xtttFGYfvrpw8iRI8f47RZbbBGmmWaaWGCoT5HwXXTRRWHBBRcME088cWzR3GCDDWLYmpKOSBO0Pqe/K1+V3ej++eefcPzxx8f9J56XX3752JWK9E1LdkM4TqyXNFRNkX3r0qVL1X7+7C/7XTT9V1PXGIsi6au+PKGa+pYvuo+NzTPqi/+i5xrL/Pnnn4XHGzQUd8ccc0yYYIIJwv3331/2u8MOOyzmn/ntfP3112GPPfaI6Y80Mv/884fTTjut3vPq0EMPLbsTlzz00EMxLp566qmyz59//vkYRsLao0ePcMYZZ9S5bsKz2267xfieaKKJYvribkNleBqzTvIQ8ly6rEljRSZprFhooYWyNddcs+p388wzT7b88stna621Vvbaa69l3333XXbLLbeMsdyIESOyN954I+vTp08222yzZcOHDy99t9RSS8XPK9e7wgorZBtttFH83bBhw7IzzzyTK3t24403Nus+1LV99ovtv/POO9lPP/2U7bHHHtkkk0ySPf/889k666yTvfXWW9nPP/+c7b333tkEE0yQffjhh2XrOP/887MOHTpkRx99dDZ48ODshx9+yE444YRswgknzO67777CYf/444+ziSeeODvggAOyb7/9Nvv999+zl156Kdt6662zTz75pNHbO/vss+NyBx98cFw3cfv4449nm266ab3hIE6WW265eKw5Jr/88ks2YMCArHPnztn+++9fWu7RRx+Nx+n6668v+z1h79SpU7bvvvvWu50i4TvssMPifp111lnZjz/+mL3//vvZ6quvnk066aTZ66+/3qR0dMghh8TPi6SdffbZJ+735ZdfHuPhzTffzNZdd924rZ49e2YNWWONNbK55pqr6ndF922yySaL4ai04YYbxv1uaB/qS//VPiuavormCUWWb8w+NuZY1xX/Rc81/PXXX3HfG0rPRePun3/+yVZbbbVs6qmnzj777LP42Z133hnDz7LJ559/nk0//fTxmD799NMxL33vvfeyfv36ZQ8++GBc5sorr4y/++ijj8rSN9urxG9Y9sknnyx9xnEgHjbYYIMYJ99//3123HHHZX379o3Lco4nX375ZTbjjDNmSy65ZPbiiy9mv/76a1zXLLPMEo9TU9aZ7LLLLjHP/fvvvxuMY6lWViyk8aRiwcWq8qJbFy6KXERuu+22Bgv2E000UbwI5y2wwALZKqus0qz7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FYtddtmlJVcvSZIkqbVXLEaMGBEef/zxcNlll5U++/rrr8uWGTBgQG2hkyRJktR2KxafffZZWGihhcJGG20Udt9999LnBx10ULjzzjubM3ySJEmS2mrFggrE6quvHn755Zeyzw855JBw6qmnNlfYJEmSJLUSHZvyo2effTZ89NFHYcIJJyz7vFevXuGNN95orrBJkiRJast3LEaOHBlGjx4d/+7QoUPp88GDB4cuXbo0X+gkSZIktd2KxaqrrhrOP//8sorF8OHDw8EHHxy7SEmSJElqX5rUFerMM88MK664Yrj//vtDlmVh/fXXDy+88EKYeOKJw8CBA5s/lJIkSZLaXsVizjnnDG+//Xa4/PLLQ8+ePWO3KAZuM0NU165dmz+UkiRJktpexQLTTDNNOOyww5o3NJIkSZJapRZ98rYkSZKk9qFJFYvPP/88Phxv2mmnDR07dhzjJUmSJKl9aVItYIcddgidOnWKM0NNNdVUzR8qSZIkSW2/YvHSSy+Fr776yoHakiRJkpreFWrmmWeOz62QJEmSpCZXLI488siw2267xSln//zzz/DXX3+VvSRJkiS1L03qCjXvvPOGV199NSywwAJVv+eheZIkSZLajybdseBuxfLLLx/uvffe8Oyzz47xam5ffPFF2H777WMXrLnnnjucccYZ8aF8eZdeemno1atX6NatW1hllVVixadSkWUkSZIkjaU7Fh9//HF45plnwtRTTx1aGoPEl1pqqbDqqquGJ598Mkw66aThv//9b3j++edj5QbXX3992H///cNVV10VlllmmXD66aeHPn36hHfffTfMNNNMhZeRJEmSNBbvWPTs2TP89NNPYWxgPAcVmGuvvTbMNddcoXv37uHkk08uVSrA+5122ilsueWWYdZZZw3nnXdemGSSScJFF13UqGUkSZIkjcWKxa677hp23HHH8PLLL4dffvklDB06tOzVXOjudNddd4Wtt946TDjhhFWXYXvvvPNOvPuQTDDBBPEOx3PPPVd4GUmSJEljuSvUQQcdFP9fcsklW3Tw9g8//BCntZ1iiinCWmutFcdE0G2JB/QdeOCBsXLwzTffxGWnm266st/yPo2hKLJMNSNGjIivxCl2JUmSpGasWHCnYmz4559/4v9HH310HBtB96cXX3wx3sGgwN+/f//SslQy8nhfWcEpskwe3aeOP/74ZtobSZIkqe1qUsVi8cUXD2MDszd17NgxbLXVVmHjjTeOn62//vph5513DjfeeGOsWKS7ENzdyON9+q7IMtWw/oMPPrjsjkWPHj2acQ8lSZKkdjbGgtmZeOX/ruvVXCaaaKKw2GKLhU6dOpV9zvt0N4PKx5xzzhlnqcp7+umnw9JLL114mWo6d+4cu2HlX5IkSZJqqFjQUp9a69Pfdb2a06GHHhqnin3hhRdityW6YdEtarPNNistw3iLyy+/PFYUePL3CSecEL7//vuw5557NmoZSZIkSS3cFeq9996r+ndL23TTTWOXJf4fMmRI7Lq09957h6OOOqq0zD777BOnv91oo43CsGHD4rS099xzT5wWtzHLSJIkSWrhisW8885b+rtfv35xGthq+vbtW+d3TbXXXnvF16hRo+KYi2qOOeaY+Pr777/H6DrVmGUkSZIkjaXnWNx99911Pnfi3nvvDS2lrkpFXpEKg5UKSZIkaRzOCvXdd99V/TtVKgYOHBhmnHHG5gudJEmSpLZXschXGqpVILijcNZZZzVPyCRJkiS1zYrFW2+9Ff9fYIEFSn/nuxd17949dOnSpXlDKEmSJKltVSx69+4d///222/DDDPM0ODyzOR02223NT10kiRJktru4O0ilQrcfvvtTVm9JEmSpPZQsZAkSZKkPCsWkiRJkmpmxUKSJElSzaxYSJIkSaqZFQtJkiRJ43fFYpdddmnJ1UuSJElqjc+xyPv777/DZ599Fn7++ecxvlt66aXj/wMGDKgtdJIkSZLabsXimWeeCVtttVX45ptvqn6fZVmt4ZIkSZLU1rtC7bvvvmHjjTcOX375Zfj111/HeEmSJElqX5p0x+KTTz4Jzz//fOjSpUvzh0iSJElS+7hjMddcc9XZDUqSJElS+9OkisWBBx4Ydtppp/Dyyy+HX375JQwdOrTsJUmSJKl9aVJXKCoVWHLJJat+7+BtSZIkqX1pUsWCOxWSJEmSVFPFYvHFF2/KzyRJkiS194rFV199Ff+feeaZS3/XhWUkSZIktR+FKxY9evQojZ9If9fFMRaSJElS+1K4YvHee+9V/VuSJEmSClcs5p133qp/S5IkSVKTnmMhSZIkSTXPCsUYiquuuirceuut4csvvwyjRo0q+/79999vymolSZIktac7Fqeddlo46qijwrLLLhveeeedsOuuu4YFF1wwfPjhh2GNNdZo/lBKkiRJansViwEDBsS7FVQucOihh4ZbbrklnH/++eGjjz5q7jBKkiRJaosVi88++ywsscQS8e+JJ544/Prrr/Hv7bbbLjz33HPNG0JJkiRJbbNi8c8//4ROnTrFv2edddbw4osvxr8///zz0ueSJEmS2o8mDd7OY3zFFltsEVZZZZV4t2KzzTZrnpBJkiRJatsVi19++aX0N+MrZpxxxvDCCy/EMRd77LFHc4ZPkiRJUlutWAwaNCistdZapffbbLNNfEmSJElqn5o0xmK99daLz7KQJEmSpCZXLOaYY47w3nvvGYOSJEmSml6x6NevX9h+++3DU089Fb7//vswdOjQspckSZKk9qVJYyx22WWX+D8zQVVjNylJkiSpfWlSxeLll19u/pBIkiRJal8VixNPPDHcddddVb/r27dvnd9JkiRJapuaNMbi7rvvrvr56NGjw7333ltrmCRJkiS15TsW3333XdW/U6Vi4MCB8WF5kiRJktqXRlUs8pWGahWIjh07hrPOOqt5QiZJkiSpbVYs3nrrrfj/AgssUPo76dSpU+jevXvo0qVL84ZQkiRJUtuqWPTu3Tv+/+2334YZZpghjG3ffPNNeOaZZ8I888wTFllkkTG6Yr344othyJAhMZxzzjnnGL8vsowkSZKksTR4e1xUKkaNGhU23XTTsMMOO4Srr7667Lthw4aF5ZZbLn5/wQUXhIUWWig+xK+xy0iSJEkai9PNjgvHHHNMmGOOOcIff/wxxndHHnlk+Pnnn8O7774bppxyyvDcc8+FFVZYIay++uqhT58+hZeRJEmSNBbvWIxtjz/+eLjpppvinYZqT/m+/vrr49PAqTBg+eWXD0suuWS47rrrCi8jSZIkqQ3fsfj+++9j96cbb7yxVCnI++qrr8LQoUNL4z8SBpi/8cYbhZepZsSIEfGVDB8+vBn2SJIkSWp7xus7FtxpoFLBi25L1TB2AtNMM03Z5127do2ViaLLVHPyySfHykx69ejRo+Z9kiRJktqi8bpicfPNN4cXXnghzDvvvLErFC8qAh9++GH8m4pH586d47K//fZb2W95P/HEE8e/iyxTTf/+/WOlJL0GDx7cAnspSZIktX7jdVco7jCstdZa4f777y99RgH/k08+CXfddVfYfPPNwyyzzBIfzPfll1+W/faLL76Ig71R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xx13XDj++OPHYkglSZKk8c/gwYPDzDPPXO8y7eKORYoEppnN43337t3r/F3//v3DwQcfXDaz1M8//xzvfDBOozWi1tmjR4+YOKaYYoowPjOsxq3pwHPM/MA04HXB621rTQOtMbzVcA/i119/jTOqNqRdVCwmn3zysOiii4aHH344bLHFFvGzv//+Ozz++OPxrkVdOnfuHF95TFfbFpC4W0sCN6zGrenAc8z8wDTgdcHrbWtNA60xvJWmnHLKQsu1i4oFmF520003DYsttlhYZpllwplnnhkmnHDCsNdee43roEmSJEmtXruYFQobbrhhuOmmm8LNN98cn1/BoOxnnnkmDuCWJEmSVJt2c8cCm2yySXy1Z3TtOvbYY8fo4jU+MqzGrenAc8z8wDTgdcHrbWtNA60xvLVqF7NCSZIkSWpZ7aYrlCRJkqSWY8VCkiRJUs2sWLRRhx9+eLjrrrvGdTAkSZLUTrSrwdvtCc/omHrqqcd1MCRJktROWLFQi/rpp5/ClVdeGR555JGw0UYbVX1uCMucccYZ4a233grTTz99XGbxxRdvkWXq88Ybb4Rrr702fPzxx/Fp7TvttNMYv//nn3/CJZdcEvdnookmirOMpYcuNvcy9eGp8QMGDAivvfZafODO2muvHTbffPOyJ8KPHDkybmPgwIHx7zXWWCPstttu8fktjVnmr7/+CldccUV49tlnwx9//BHmnnvuGLdzzDFH4fDee++94e677w4//vhj/P3uu+8e5pxzzjGWufPOO8MPP/wQFlpoofjU+2mmmaZsmfvvvz/cfvvt4fvvv49PAN1mm23CSiutVLbM6NGjw3XXXRceeOCBGB9bb711WH/99UNjkZ522GGH0LFjxzHu/r3zzjsx3j777LPQvXv3sM8++4QFFlig9P1///vfqncMO3XqFB588MGyJ7LyTJ1XX301Tn296667huWXX75wGPv27Rt+++23ss9It8RL8ssvv4Tzzjsv/O9//4uzkpDO+F1j10Oa5RhxjpA+brnlltBYv//+e4y35557LjZ8VJ6jbIP84sknn4zhWXnllWPcco4kP//8c0z7L730Uph00knDqquuGrbbbruyNMsDUAknDSyk64UXXjjssccehacXP+igg2I+UmneeeeNxzYhnDfccEM8H6ebbrr4rCTOxTzCwFTn3377bZhvvvliup5x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cGsIU2lef/31Max1Pe26OZAGSAsJ09wydSdxW23K4LqmDmWfmdZ56aWXbrGwcm5xjiVMM5ryrsbELU8jHjp0aPwtT29vCeRZxAnnBpj+le2R/9LQURTplWmT+W21KZebC9cEwpYst9xycdpZKrhFMdUt+8xvizzxu6m41nLNTSik0zBGmuW8Keraa6+N1y6mbm4p5P2333576T3Tc3Ms+XxQI65hYwMNQxy/1EDEFMCE9ddff22xRmQrFiq7sKdW7tZgiy22CGusscZY2x4tk5tvvnmTfkvhriXvWFSiEMH2mlIopIWI39b1TITmxnM82B7PAWgsnp/Abynsjy3rrbfeGM9hKWrDDTcMG2ywQRhbiJftttuuSb+lFZa4bezzH5qK5xmwvaYUCplbn98yV/3Ywp2gup6jUh+eV0NYef7H2EIrdZ8+fZr027XXXjtsuummYWyh8Er8NOXZM7TE89tqz8lpCTwTo6nboxLMb1uygllpyy23bNTznfLIR1qycawSFfem5pWk9a233jqMLTQYcSyrPaNmfENlmLDSMNtSOrbYmtXq0WL0n//8p1TL5eTZeeedy1qyaaW54447woEHHhi7JPCQLVpkuejmTzJaeG666abYVYEHgaXuGXncVq5vHXQnufzyy0utGrRY5x+uRPcUHibEw9VoDWU7LE94aWm8+OKL490DMisuCHxGa9xee+0VH1pD2GjhoWDDb9kODzDiVnXlQ/LoJsCtWu705NeRjB49Om7r2WefjS0DlQ/s4bb9FVdcES+EtIJReDvyyCNjKwvbpNWF9c8333zxrgytRixD5s5ndAe75JJLYpxQAaB1MrVMsExlBkcLNGHJryOPFmKOI3FAAZ/9S5USuskdcsghsWWN9RI+Kljsc2opPO+88+LDe9Zaa63YTYBw8TcvPiesdHVhHam176qrrgrHHnvsGHdG2BfuROTXkUcLHL/lYU/E7Q8//FB64BPxwsWTbbCtn376Kcw777yxixdotT/nnHNiqxJdF3jwEA9rozJN1xbunhBX7DMX/skmmyymywcffDCss846YzzAjrsspBke6JRfR8IdDY4zrergoWCkz2TbbbeNt/nJ5AkHlXu6f5Cm2C/SL11miAP2h/1jX/fcc8/4Py2fpBUKq4SXOGE9HBPCW9kCTVj4TX4dCXHBvj/++ONxHZVplmNI10P2k5Z6tkkXRsJGeuH8/u9//xsL+VS8iPvUAED3JlrKSdPEGWk23fVjveQrlZVguhvykLH8OirTCXc6CW+6K5QqJZy7++yzT4xPPuM4UEBO3Rc4p0kHxDH5AemF8FFwossQrbrEFQ+wJN4JG+c0dxs4fpUPdSMfoAWT9aV15BGfrI87ghwHjiPHGKTzjTbaKLa2UzFiHWyT+AStoJxf3IWgsERYyLsoINJljHOa9Hr33XfHfI18iIeEsj7iqLLSzbE7++yzY0twfh0J5+s111xT6lbGvuVbf+liwvbIo8lnKVSTLjjP2BfSK8d0xRVXjPvDMhwHuqiwz5wDxAVxTF7DceYcI/+pjDfSJOmb/civI4+0zjrYH+KN36RKCdeT4447Lhbeybf4jnxrk002icfhtttui2mWOCO8xBlpge9pSGJ/OB85Xqw7tZyTn9CtqLISzPlH3OTXkcc5RZgIL3feybPTQ++4i8D+ca0lPBwnwpS6q5BHk2bJ/0gvhJ9ziQoqXXRJn8QVeRvnF8eU9dMljkaCyp4IqacAaTOtI4/zgfwn3T1kuxxjcL6vu+668bpEGiIc5CWcH2yXZek2RT5OdybyUeKQ9EC+w3vOBcLGwwy5BnCuse/cyamsdHNun3/++THt5NeREB62TZolXfEwVhqAkn79+sVjTR7C+UWDFPHKe/IGrieUD+iRQFohzXJcdtppp3jXlwcDXnbZZTEcnPtcS1kPeT/Xm8pK8M033xyPQ34deeRZ9913XzzXuBPEOvIPyKX7NHkex4i8jGW4VqQ8mvyLBjnSR2Xli/0hnyXMHJvKBy6OFeP60d8aP5x99tlZr169yj4bMmRIduWVV8bXhRdemK2//vrZTDPNFB9Vn/DdJJNMks0777zZiSeemJ122mnxkfOHHHJIaZnffvstW2KJJbK55porO+mkk7ITTjghW2ihhbJPP/208DqGDRuWzTHHHNkyyyyTHX744TwtPuvcuXP23HPPlZbZbbfdsk6dOmXTTjttttRSS8XvH3jggeyVV17JunXrlm211Vbxd126dInf9e/fP4ZrkUUWict17Ngx23PPPbPll18+m2CCCbJJJ500W3jhhbNVV101u/766+M2Bg8eHNfBNvbff//s/PPPL63jn3/+KYVlyy23jHF1yimnZJNNNlkM16mnnlr6/sYbb4zrmXrqqbMll1wym2KKKeL62E/iZvXVV49xQFj57dZbbx1fhOnll1/Opp9++rjMTjvtFMM68cQTx+923HHHbNdddy1th9/zed++fbP//ve/pXV88cUXpWUuu+yybKKJJorxzX7wG9advPPOO9kMM8wQwzjffPNlPXr0yBZccMFs9OjRcVscV44LvyMcrOOII46Iccx+9unTJy7Tr1+/GBdsi30nrOxrssIKK2QTTjhhtuiii2ZnnXVW2TqSN998M5t88smzTTbZJO4L388444zZt99+G7//5Zdf4vEiLMQ/6+fvr7/+Oh7DaaaZJttoo41inBEW3pMmZ5555myXXXbJTj755Pg5aWP22WeP4WEba6+9dgwX2wfHnX3o2bNndtxxx8XwpnUkf/75Z9a7d+8YHyzD8qSxhx56qLTMoYceGsNCelp66aVj/F1zzTXZu+++G+N8m222KaXZdIxWXnnleC488cQT8TPica211so6dOgQjy3n0brrrpudd955pXCktLb77rvHdJDW8ddff5XCsu+++8b44Pwk7RGWww47rPT9Y489Ftcz5ZRTZosttlhclmPAOjhnlltuuRhnHB/CteGGG5bOyRdeeCGbbbbZ4jJ77bVXKV5Z3x577BGPZ0LaZtukQeI5rSPFPW6//fb42T777BPTDfHDefj333/H7z/55JNszjnnjGmW/zlOhG3kyJExHZKGV1lllRhf5D1zzz13PEash21uscUW8XgeeeSR2VRTTRW3RVg5HhzT33//PW6HcBPvfHb66adnxx9/fGkdyWeffRbzH9IQ+8Lx5lh89NFH8fs//vgjxhVhYd+JW/b//fffz+6///647GabbRa3T9yyfvJJzil+l85f0hJ5OHHLPnGMyQeffvrpuJ177703rmPWWWeN59a5555bWkdCHsYxIg1xLrA868ufg5wvfM4+kWbZ1jnnnJN9+eWX2SyzzBLDSjpPedfee+8d0yfpedCgQfH82nzzzeN5mNIsx2PjjTfO/v3vf5e2w3ccvx122CGm2bSO4cOHl5Y56qijYpwce+yxcb8IC3GcvPjiizEsrIe8nHS9zjrrZKNGjYrrI67nn3/+UpolzXEe8Jsnn3wyfrf44otnBxxwQNyXlGY5j9Zcc83SdjiX+P2KK64Yz7u0joEDB5aWeeSRR+Iy5Jn8lnhg/Rz/dG0hXyWsnCvzzDNPzNtIa1xH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oEGDwrBhw8L888/fpEpJ0XTA/hHuWWaZpbT9xqY5DBkypGp6Khr/dYWHeFlwwQXD5ZdfHisZklSvTJJUyGuvvZbNNtts2RxzzJGts8468e9rr7229P1jjz2WTTXVVNliiy2WrbTSStkkk0ySXXTRRWXr6Nq1a7bmmmvGday33nrZjDPOmK2wwgrZqFGj4vcHHHBANssss8Tvt9hii9KrY8eO2Z133llazx133JFNPPHE2dJLLx1/v8gii2QzzTRTdv7559cZ/g033DDbc889S+9POeWUrGfPnmXLjBgxIpt66qmzyy+/vPA+NRQvRx11VNyHzTffPFt88cWz6aabLnv22WfHiJfVV1896969e7b22mtn3bp1y/r06ZP99ddfDR4XlllllVWyHj16xH3s3bt3ttFGG2WjR4+O388666zZZZddFv9++OGHy+J10003zSaccMLs4IMPjt+//vrrcXnik+NDOPbYY4+sMYqmgzXWWCNuq2/fvtnVV19ddV0NxW1D6akx8V9XePr165ctt9xyjYoDSe2TFQtJKoDCKwXXHXfcsVRo+/PPP7OHHnqo9DffH3rooaXfXHXVVVnnzp2zTz/9tKwAt+SSS2a///57fD9kyJBssskmixWFhELgLrvsUrZ9lkkViz/++CObYYYZsmOPPbb0/dlnn53RVlRfxYLwnXfeeaX3X375ZdahQ4ds0KBBpc/YBhWWYcOGFdqnhuKlmv/85z+x8J9HvFCo/eGHH+L7b7/9Nu7jWWedlTXkvvvui5Wh3377rfTZXXfdlf3zzz9jVCwqHXLIIdm0006bff7559nIkSNjwZ24TL7//vtYWL/xxhuzIhqTDoiD4cOH17muInFbJD0Vjf+6wnP99dfH8EtSQxy8LUkF0M1o8ODB4ZRTTil1M6G70Jprrhn/HjhwYPy+f//+pd9sv/32YbrppovdTPIYiD3ppJPGv/mebjsffPBB4ePw3HPPxa4vhxxySOmzvffeu7TOutAdZuqppy6979GjR1hxxRXD9ddfX/qMvxmTQFekIvvUULwkzFz08MMPh5tvvjkOHH/77bfjmI+8nXbaKXbVwgwzzBC3xQxWDZlkkklil6N8HG644YZhggnqv8Rdd9114bzzzoszH9FV6sknnwxffPFF3D8+u/XWW+NndIXi/yIakw7Y37q6hDUmboukp6LxXy08pBnil+5dklQfx1hIUgEUzChsV+vfDgqkU001VZhmmmlKn9FffY455ojf5eWXAeMt/vrrr8LHgcJm165dywqBE000URxrUR/631dOHbrNNtuEo446Kpx11lmxoMnAbgqfRfepoXhJszJdeeWVcXwAFYc///wzfv7DDz+Uxj5gttlmK/vd7LPPHq699toG42PVVVcN+++/f/yfcPTp0yfsvvvucdBxXRjHwoxKVCyoXOHzzz+P8XjPPfeULdu9e/cw99xzhyIakw4qx8xUKhK3RdJT0fivKzykGSppDVVcJcmKhSQVQGHxt99+iy23FNwqUWCjRZfnRHTs+P9nrT///HOpFb65UJAcPnx4GD16dFmrPIN760Ph+LPPPiv7bLPNNosFTwb4fvvtt2GyySYLa6+9duF9aiheGAjMFLcMmk6DoBkYzSB1uuPmVYaf90Xj7uSTT44zXjEwm0HqDEh//fXXQ69evcZYlkHvffv2jS30e+65Z+lzCvEM3B4wYECshDVFY9JBQwPTG4rbIhoT/3WFhzQz55xzlg0Il6Rq7AolSQWstNJKsaCY7zaUWn1BazDf33333aXv3n///fDOO++E5ZdfvlnjmG1RKHzooYfKuuD89NNP9f6OlnyWqyy8rrPOOnG/eG2++ealZ1wU2aeG4oVCPF2V8i3jdDOqhmd2JOwfXYeWW265BuODbfzzzz8x3MyIxF0I7uZUm/2JisPGG28cC8rnnntu2Xcrr7xyvGNx6aWXln3Ouul6ljD7UuVdjaQ500FDcVtEY+K/LqQZpj+WpIZ4x0KSCqDP/+mnnx722muv8NZbb8VpSJlOlFZoPqcbyRFHHBFbwSlIUrA988wzY8v4Kqus0qxxTNccuv5st9124fDDD4+FTwrTtLLX1wq+8847x5Z9utgwnWiy7bbbxnXRfYZW/6TIPjUUL0xtS7iosKy33npxelzGLlRD4ZvndTA9LF2yPv7440KFYAq+hJvfsl+MhyAe6BpVifEKPGjw7LPPLntOSJpu9pxzzol3cNhfpoll+lqWO+mkk2L4cfXVV8eKxQYbbDDG+pszHTQUt0U0Jv6rYcpdxma05EP4JLUd3rGQpIIozKdBvDxXgILiaaedVvr+mGOOia3LjIGgVfvYY48tjVdIaC3Ptx6D1uDevXuX3vP8hspnS1Q+II/tUmB977334qBsCroUIOsbDMx2qUScf/75ZZ+vu+66YaONNooVD7adV2Sf6osXBv7S9YY7BE899VQs+PP8jC222CJ2u8rHyx133BErFdxpoNsWFYB8Bagum2yySbjxxhvj8x54BgfbIqwpvvIPyGPAOsszAJ47JOlFwR10jWIf6G5GOEFBPFUqwP6wz3VpajpoSpprKD01Jv6rheeyyy6LFbS6nrEhSXkdmBqq7BNJ0niPPvv5QbsUYCn8UUDOV1Iq0aWHGYsuueSSUpcnFUflZZ999onjFtpD/O27777hgAMOqPOhi5KUZ8VCklqhiy++OE5HSus0dyzoCkXLMgOX2xq6I3GHoRoK99yBkCSNe1YsJKmVYnDz448/HmfrYZAz/ejbIsYFMCaiGp7rcNVVV431MEmSxmTFQpIkSVLNHLwtSZIkqWZWLCRJkiTVzIqFJEmSpJpZsZAkSZJUMysWkiRJkmpmxUKSJElSzaxYSJIkSaqZFQtJkiRJNbNiIUmSJCnU6v8DB6BB7RuUl0EAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "group_cols = [\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"]\n", + "group_cols = [\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\", \"hidden_dim\", \"num_conv_blocks\"]\n", "time_stats = (\n", " clean.groupby(group_cols, dropna=False)[\"train_time_sec\"]\n", " .agg([\"mean\", \"std\"])\n", @@ -1217,8 +511,8 @@ " .sort_values(group_cols)\n", ")\n", "time_labels = [\n", - " \"char\" if t == \"char\" else f\"{int(v)}\" + (\"\" if pl == \"end\" else f\"\\n[{pl}]\")\n", - " for t, v, pl in zip(time_stats[\"tokenizer\"], time_stats[\"vocab_size\"], time_stats[\"pad_layout\"])\n", + " \"char\" if t == \"char\" else f\"{int(v)}\" + (\"\" if pl == \"end\" else f\"\\n[{pl}]\") + (\"\" if (h == 192 and d == 4) else f\"\\nh{int(h)}d{int(d)}\")\n", + " for t, v, pl, h, d in zip(time_stats[\"tokenizer\"], time_stats[\"vocab_size\"], time_stats[\"pad_layout\"], time_stats[\"hidden_dim\"], time_stats[\"num_conv_blocks\"])\n", "]\n", "\n", "fig, ax = plt.subplots(figsize=(8, 4.5))\n", @@ -1240,26 +534,17 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "b82b3da1", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:53:08.968253Z", - "iopub.status.busy": "2026-08-07T10:53:08.968122Z", - "iopub.status.idle": "2026-08-07T10:53:08.974932Z", - "shell.execute_reply": "2026-08-07T10:53:08.974113Z" + "iopub.execute_input": "2026-08-11T18:27:06.080774Z", + "iopub.status.busy": "2026-08-11T18:27:06.080111Z", + "iopub.status.idle": "2026-08-11T18:27:06.087986Z", + "shell.execute_reply": "2026-08-11T18:27:06.087106Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Not found: ..\\artifacts\\REPLACE_ME_domain_stats\\tokenization_stats.json\n", - "Run scripts/calc_tokenization_stats.py on the same AIRR file used for the results above (pointed at the same --tokenizers-dir) to produce this file, then re-run this cell.\n" - ] - } - ], + "outputs": [], "source": [ "domain_stats_path = Path(DOMAIN_TOKENIZATION_STATS_PATH)\n", "\n", diff --git a/notebooks/convergence_curves_by_epoch_report.ipynb b/notebooks/convergence_curves_by_epoch_report.ipynb index d70187b..a6a4c26 100644 --- a/notebooks/convergence_curves_by_epoch_report.ipynb +++ b/notebooks/convergence_curves_by_epoch_report.ipynb @@ -16,14 +16,14 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "11f2b459", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:45:11.022647Z", - "iopub.status.busy": "2026-08-07T10:45:11.022478Z", - "iopub.status.idle": "2026-08-07T10:45:11.026871Z", - "shell.execute_reply": "2026-08-07T10:45:11.025929Z" + "iopub.execute_input": "2026-08-11T18:24:43.101800Z", + "iopub.status.busy": "2026-08-11T18:24:43.100792Z", + "iopub.status.idle": "2026-08-11T18:24:43.106325Z", + "shell.execute_reply": "2026-08-11T18:24:43.105288Z" }, "tags": [ "parameters" @@ -32,191 +32,22 @@ "outputs": [], "source": [ "# parameters\n", - "RESULTS_DIR = \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs\"" + "RESULTS_DIR = \"../artifacts/REPLACE_ME\"" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "379bff96", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:45:11.028653Z", - "iopub.status.busy": "2026-08-07T10:45:11.028088Z", - "iopub.status.idle": "2026-08-07T10:45:11.689406Z", - "shell.execute_reply": "2026-08-07T10:45:11.688584Z" + "iopub.execute_input": "2026-08-11T18:24:43.109060Z", + "iopub.status.busy": "2026-08-11T18:24:43.107988Z", + "iopub.status.idle": "2026-08-11T18:24:43.964580Z", + "shell.execute_reply": "2026-08-11T18:24:43.963535Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "15 runs across 15 configs\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
tokenizervocab_sizemax_token_lenpad_layoutmax_lenseedtest_losstest_cosinebest_val_lossepochs_to_best_valtrain_time_secinference_time_secnum_parameterstokenizer_path
0char25NaNend4010.1976780.8678360.192469331148.3492790.55189410850856NaN
1wordpiece10009.0anchored1110.2223790.8500600.21952925815.8021140.47294910913256artifacts/tokenizers_2026-08-01_fine_grid/word...
2wordpiece20009.0anchored1010.2357470.8407430.22957027800.5669070.49776610977256artifacts/tokenizers_2026-08-01_fine_grid/word...
3wordpiece29989.0anchored1010.2424570.8358470.24023038792.8189000.46958711041128artifacts/tokenizers_2026-08-01_fine_grid/word...
4wordpiece39869.0anchored1010.2504180.8304160.24791538793.6826300.47194111104360artifacts/tokenizers_2026-08-01_fine_grid/word...
\n", - "
" - ], - "text/plain": [ - " tokenizer vocab_size max_token_len pad_layout max_len seed test_loss \\\n", - "0 char 25 NaN end 40 1 0.197678 \n", - "1 wordpiece 1000 9.0 anchored 11 1 0.222379 \n", - "2 wordpiece 2000 9.0 anchored 10 1 0.235747 \n", - "3 wordpiece 2998 9.0 anchored 10 1 0.242457 \n", - "4 wordpiece 3986 9.0 anchored 10 1 0.250418 \n", - "\n", - " test_cosine best_val_loss epochs_to_best_val train_time_sec \\\n", - "0 0.867836 0.192469 33 1148.349279 \n", - "1 0.850060 0.219529 25 815.802114 \n", - "2 0.840743 0.229570 27 800.566907 \n", - "3 0.835847 0.240230 38 792.818900 \n", - "4 0.830416 0.247915 38 793.682630 \n", - "\n", - " inference_time_sec num_parameters \\\n", - "0 0.551894 10850856 \n", - "1 0.472949 10913256 \n", - "2 0.497766 10977256 \n", - "3 0.469587 11041128 \n", - "4 0.471941 11104360 \n", - "\n", - " tokenizer_path \n", - "0 NaN \n", - "1 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", - "2 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", - "3 artifacts/tokenizers_2026-08-01_fine_grid/word... \n", - "4 artifacts/tokenizers_2026-08-01_fine_grid/word... " - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import json\n", "from pathlib import Path\n", @@ -231,6 +62,10 @@ " raw[\"max_token_len\"] = None # older raw_results.csv, from before --max-token-len existed\n", "if \"pad_layout\" not in raw.columns:\n", " raw[\"pad_layout\"] = \"end\" # older raw_results.csv, from before --pad-layout existed\n", + "if \"hidden_dim\" not in raw.columns:\n", + " raw[\"hidden_dim\"] = 192 # older raw_results.csv, from before --hidden-dim existed (ForwardModel default)\n", + "if \"num_conv_blocks\" not in raw.columns:\n", + " raw[\"num_conv_blocks\"] = 4 # older raw_results.csv, from before --num-conv-blocks existed (ForwardModel default)\n", "\n", "print(f\"{len(raw)} runs across {raw[['tokenizer','vocab_size','max_token_len']].drop_duplicates().shape[0]} configs\")\n", "raw.head()" @@ -246,26 +81,22 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "7b0dc511", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:45:11.691106Z", - "iopub.status.busy": "2026-08-07T10:45:11.690952Z", - "iopub.status.idle": "2026-08-07T10:45:11.699331Z", - "shell.execute_reply": "2026-08-07T10:45:11.698549Z" + "iopub.execute_input": "2026-08-11T18:24:43.966560Z", + "iopub.status.busy": "2026-08-11T18:24:43.966338Z", + "iopub.status.idle": "2026-08-11T18:24:43.978558Z", + "shell.execute_reply": "2026-08-11T18:24:43.977583Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loaded 1200 (config, seed, epoch, split) rows from history/\n" - ] - } - ], + "outputs": [], "source": [ + "DEFAULT_HIDDEN_DIM = 192\n", + "DEFAULT_NUM_CONV_BLOCKS = 4\n", + "\n", + "\n", "def history_filename(row):\n", " \"\"\"Mirrors compare_forward_tokenizers.py's run_one() naming exactly, so this stays in\n", " sync with whatever that script actually wrote - no separate parsing of filenames.\"\"\"\n", @@ -274,7 +105,14 @@ " filter_suffix = f\"_n{int(max_token_len)}\" if pd.notna(max_token_len) else \"\"\n", " pad_layout = row.get(\"pad_layout\", \"end\")\n", " layout_suffix = f\"_{pad_layout}\" if pad_layout != \"end\" else \"\"\n", - " return f\"{label}{filter_suffix}{layout_suffix}_seed{int(row['seed'])}.json\"\n", + " hidden_dim = row.get(\"hidden_dim\", DEFAULT_HIDDEN_DIM)\n", + " num_conv_blocks = row.get(\"num_conv_blocks\", DEFAULT_NUM_CONV_BLOCKS)\n", + " arch_suffix = (\n", + " f\"_h{int(hidden_dim)}_d{int(num_conv_blocks)}\"\n", + " if (hidden_dim != DEFAULT_HIDDEN_DIM or num_conv_blocks != DEFAULT_NUM_CONV_BLOCKS)\n", + " else \"\"\n", + " )\n", + " return f\"{label}{filter_suffix}{layout_suffix}{arch_suffix}_seed{int(row['seed'])}.json\"\n", "\n", "\n", "records = []\n", @@ -293,6 +131,8 @@ " \"vocab_size\": row[\"vocab_size\"],\n", " \"max_token_len\": row[\"max_token_len\"],\n", " \"pad_layout\": row.get(\"pad_layout\", \"end\"),\n", + " \"hidden_dim\": row.get(\"hidden_dim\", DEFAULT_HIDDEN_DIM),\n", + " \"num_conv_blocks\": row.get(\"num_conv_blocks\", DEFAULT_NUM_CONV_BLOCKS),\n", " \"seed\": row[\"seed\"],\n", " \"epoch\": entry[\"epoch\"],\n", " \"split\": split,\n", @@ -316,44 +156,37 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "a04f58e1", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:45:11.700786Z", - "iopub.status.busy": "2026-08-07T10:45:11.700646Z", - "iopub.status.idle": "2026-08-07T10:45:12.009374Z", - "shell.execute_reply": "2026-08-07T10:45:12.008530Z" + "iopub.execute_input": "2026-08-11T18:24:43.980275Z", + "iopub.status.busy": "2026-08-11T18:24:43.980122Z", + "iopub.status.idle": "2026-08-11T18:24:44.402199Z", + "shell.execute_reply": "2026-08-11T18:24:44.400985Z" } }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABjUAAASlCAYAAADgeltjAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Qd4FGXXBuAnvfcQCCH03nvvXVQQFAtiwYYF62eBz/4rYm+fKKIUFRXBriBI7733HhJCCOm9Z//rvLO77Ca7IUCS3WSf+7qG7ZvJbJh3Z857znHS6XQ6EBERERERERERERER2TlnW68AERERERERERERERFReTCoQURERERERERERERE1QKDGkREREREREREREREVC0wqEFERERERERERERERNUCgxpERERERERERERERFQtMKhBRERERERERERERETVAoMaRERERERERERERERULTCoQURERERERERERERE1QKDGkR25LXXXsMtt9xi69Ugompu6tSpmDhxoq1Xo9oaPXo0Fi5ciJpi7dq1CA0NtcnPljFNxjZ79NBDD+Hjjz+GPbnhhhvw9ttv23QdVq5ciTp16th0HajycZy4NhwnKg7HiSvDcYKqCseJa8NxouJwnLgyNzjQ8QSDGkRERA5s69at8PX1tfVq2NX2OHz4MG699VZbrwpVwcH69OnTkZWVZfU5ffv2hZOTk82CQvZADkhkG/Ts2dPWq0I2wnGi9PbgOOEYOE6UD8cJ4jhhjuOE4+A4YdtxgkENIiIiByZfLDIzM23yswsLC9WXG8Py7LPPlnrOwYMH0a9fP3h6eqJBgwaYOXNmhT5e0ueff44777wTzs72+RVp48aNCAwMtPVqVAtpaWkqGyM8PBw+Pj646aabEBcXZ3y8cePGaNGiBRYtWlTm+3z11VdITEyEo7pw4YLaBuS4bDlOSNBxxowZaNmypQrAd+7cGb/++qvZczhOmOM4UX4cJyoGxwmy93Hit99+Q4cOHeDl5YVmzZrhhx9+uKLH//jjD3Ts2BHe3t6IiIjA008/jfz8fKvrxOOJmoPjhH2PE/Z5xE5EREQ1nqurK3Q6nVqGDBlS6vGcnByMGjVKHUScP38es2fPxgsvvKAOLCri8ZKKi4vx559/YuTIkZX8m1NVkIDG/v37sXnzZpw9exYeHh4qsGFqxIgRpQ58ich+LF68WJ2wkv22HBDL/+vbbrsNO3fuVI9znKBrwXGCqOaPE5I1IRnYMqNeJqlI6dH7778f69atK9fjUVFRGD9+PCZPnqwe/+eff9R3x3feecfi+vB4ombhOGHfGNQgsoF58+ahffv28PPzw4ABA3DkyBHjY9nZ2Xj44YdVelZYWBhefvll42Nff/21cUazlMKQwffixYvGx6VuuZzAe/DBB1G3bl3ccccdVf67EZG55557Dvfcc4/x9rBhw9T/bzmRLz755BOzE/oHDhxQtwMCAtCoUSO8+uqrKqNB5Obmqv//n376qZpNJCdp5Yv2jz/+qGYVBQUFYezYsWb7BUM/hXfffVe9X0hIiPqibii5YyldfMuWLejfv79aB5nN/t577xnXV8hJYtl3ScaAzIqSQEB5X3sllixZgpSUFLXuwcHB6gS0ZFHMmjWrQh4vSfbFMhtHtm3J7ff666+r30dm/N977704c+YMrr/+ejVjq2nTpli1apXxNSdPnjTuq+X5UsJo165dxsfff/999Rr5WSI6Olp9Lr/88kuZ20MO1CTrRF5neH9D74+//voLnTp1Up9lmzZtsGDBAqvvs2HDBjVGGF4rM83k70zWyd/fH4MGDVIzn03rsj7++OOqNrB85g0bNiw1g628qupnyf+Z33//HS+++KL6u5fPULb79u3bsWPHDuPzZDaf/B+4EjJGG7Z/vXr18MwzzyAvL6/cv4M8V7aB/J+V/ydy4J2UlGR8PDY21uprMzIy8Mgjj6hZgvI3M27cOJw7d87sZ0+ZMkX9bcr+QH5nCejJ9wHD94r77rvP+LcnJPDTu3dv9Xl0794d27Ztu8KtTdeK44T1cUL2t2+++abKqpL9m/z/k/93Mg4JjhPmOE6UH8cJjhPVCceJqx8nJAAh33Pku5B8L5fvSPI9S7IpyvP40aNH1aW8r3zvl/M41113Hfbt22dxfXg8weOJ8uDxRAXREVGVmjt3ri4kJES3ZMkSXXp6um7dunW6119/XT326quv6pycnHRz5szRZWZm6jZv3qzz9PTUbdq0qdT7xMXF6e644w7d+PHjjffJ6+W/9cyZM9Xricj2li1bpqtbt666npubq/P399c1aNBAt2/fPnXfDTfcoHvrrbfU9dTUVF1YWJju+eef16WkpOh27dqla9iwoe7//u//1OM5OTnq/3iPHj10J06cUPft2LFD5+Hhofvll1/UPuX777/XOTs76+688071+Jo1a9Rrbr75Zl18fLx6XefOnXWPPPKIenzLli06Hx8f4/oeP35c3ZZ9VUZGhm7//v26pk2bqtviyJEjar/08ccf65KTk3VHjx7VPfTQQ+V6bVmGDBmi+89//mN230svvaR+V1OzZ8/WhYeHV8jjJS1fvtxsW5huv8cee0z9vocOHdIFBQWpz3TFihVqX/v222/rIiIiLL6nfCYffPCBLjIyUn3+BqNHj9aNGzdOl5eXp9bxiSee0JXHhg0bdAEBAWb3yd+Jm5ubbsGCBern/fHHH+oz+vfff42/g4w7Qv4+5Pdfv3698fWPP/64Wgf53eRze//999X6ZmVlqcevv/56XWBgoG7VqlXqPvk8vby81N/o5cjfnYxNFfWzXnzxRfV5WFvuuece9byCggK1Tf766y/jz46OjlbP+fLLL433bd++Xd0nn4Mlffr00X311VcWHysuLlZ//926ddO98847xvsv9zs8+uijurZt2+p27typS0tL0/3000+6efPmleu1EyZMUNvv5MmT6v/zrbfequvUqZOuqKjI+Hr5G/7nn390+fn5apGfJf/f5fmy3HTTTep9hPwM+dt94YUX1M+Q7VGvXj1d7dq1zX5X2QYl/y9RxeE4Ub5xQpw5c0aNcfL9WXCcKI3jBMcJjhM1D8eJqx8nnn32Wd2AAQPMniPfn5o1a1aux+X7kXzvnzVrli47O1t38OBBdXz2448/Wvz5PJ7g8URJPJ6ovOMJBjWIqpicfHjvvfcsPiYnfvr162d2X//+/XWfffaZxeefPXtWnbiSEyuG13ft2rUS1pqIrpZ8+ZWgg5zEXblypa5v377qBLmczJUTr35+fupEouGEs3xpLiwsNBv869evbxbUkPcxmDJligpwmpJAScmghpzMND0w8vb2VvuOkkENCSyYBksN6zB48GB1/emnn1YnTi253GuvNKghJ/qHDx9udt+iRYuM63utj5f3IEROjpue9B4zZowxkCMSEhLUNr5w4YLV369Ro0ZqWxvIAZIcEHXs2FHXvXt3qyfVy3OySgIFsk6m7r//fnVAZhrUePPNN3VNmjRRJ+IN5KS3/H7btm0ze32LFi10S5cuVdfl85bP3ZRsp61bt15RUKOyf1ZJEjjq1auXOrhNTExU/09k4oDpGGwIasi6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kpKizuvWrVvqCiQistfvSD8/P9gzxgkiotK/IxknuD1BRMQ4we0JIqLK2J5w0PFw22Ll5+cjMjISPj4+cHBwKJIxkmTHxYsX4evre1VvjD3h+uL64mes+vyflJAhgSU0NBSOjvbdwZBxouIwTnB9VTZ+xqpufTFOXME4UXH4f5jrq7LxM1Z164tx4grGiYrD/8NcX5WNnzHrixOs1CiBrLQ6deqUupLlTWFSw3xcX+XD9VV+XGdVs77s/chbPcaJisf/w1xflY2fsapZX4wTGsaJisf/w1xflY2fsapZX4wTGsaJisf/w1xflY2fMeuJE/Z9mC0REREREREREREREdkMJjWIiIiIiIiIiIiIiMgmMKlxFdzc3PDiiy+qc+L6qmj8fHGdVTZ+xiof1zHXFz9f1oX/J7m+rA0/k1xf/HxZF/6f5PqyNvxMcn3x82Vd+H/S+tYXB4UTEREREREREREREZFNYKUGERERERERERERERHZBCY1iIiIiIiIiIiIiIjIJjCpQURERERERERERERENoFJjXI4deoUhg0bBl9fX4SFheG5555Dbm5u5b07NiQvLw/Lli3DDTfcAFdXV8ycObPYx23cuBHdunWDt7c3mjZtii+//BL2KCMjA5988gm6dOkCPz8/tGrVCu+++65aj8aio6MxceJE+Pv7IygoCPfddx9SU1Nhj44dO4bJkyer/3uyLq677jps3rzZ5DE6nQ6vv/466tevDx8fHwwcOBAHDhyAvVu1ahVcXFzQo0ePIvetW7cOnTt3hpeXF1q0aIEffvjBIstYXTBOlIxxonwYJ8qPceLqMU5UHcaJkjFOlA/jRPkxTlw9xomqwzhRMsaJ8mGcKD/GCRuLEzoyS3p6uq5Bgwa6W265RRceHq7bsmWLLjg4WPfss89yDep0utWrV+tGjhypW7Vqla5ly5bFrpdTp07pPD09dTNnztRFR0frFi5cqHN1ddUtWLDA7tbhN998o3vkkUd0u3fv1iUlJenWrl2r8/f3182aNcvwmPz8fF2PHj10ffv21Z0+fVp34MABXbNmzXQTJkzQ2aM777xTt2jRIvXZiYyM1D322GM6Dw8P3fnz5w2Peeedd3R+fn66devWqcfcfffduqCgIF18fLzOXkVEROjq1q2rGzhwoK5z584m9x08eFD9H3zttdd0MTExuh9++EHn7Oys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dWuVXJBqiQkTJqh5Gps3b8acOXNMHicVF1OnTsWjjz6qHicVGvPmzTPc3759e6xZswbr16/HkCFD8Pnnn+OLL77AbbfdZniMJEC2bt2KiIgIjB49Go8//jhGjhyJRo0aqfu9vLxM5nYINzc3Nd+DiIgsg3GCiIgYJ4iIiNsTRFfPQaalX8PziegqfPbZZ+p07Ngxrj8iImKcICIibk8QEVGF4X4nqu5YqUFERERERERERERERDaBSQ0iCyiuLRQRERHjBBERcXuCiIi434modGw/RURERERERERERERENoGVGkREREREREREREREZBOY1CAiIiIiIiIiIiIiIpvApAYREREREREREREREdkEJjWIiIiIiIiIiIiIiMgmMKlBREREREREREREREQ2gUkNIiIiIiIiIiIiIiKyCUxqEBERERERERERERGRTWBSg4iIiIiIiIiIiIiIbAKTGkREREREREREREREZBOY1CAiIiIiIiIiIiIiIpvApAYREREREREREREREdkEJjWIiIiIiIiIiIiIiMgmMKlBREREREREREREREQ2gUkNIiIiIiIiIiIiIiKyCUxq2KA5c+bg9ddft/Ri2Ky33noLy5cvR3Wxb98+jB492iKv/eKLL+L777+HNXr55ZexZs0aWJPnnnsO8+fPt+gy7N69G2PHjrXoMlDlY5y4NowTFYdxonwYJ6iqME5cG8aJisM4UT6ME1RVGCeuDeNExWGcKJ/n7Gi/E5MaNujMmTM4evSoWY89cuQIhg0bVunLZCvOnz+Pjz76CAMHDkR1kZiYiC1btljktQ8fPoxz587BGg0aNAhPPvkk8vPzS3zMww8/jAEDBlRZUujgwYO4cOECLCkhIQFbt241XJdAI+vgwQcftOhyUcVinLh6jBMVi3GifBgnqKowTlw9xomKxThRPowTVFUYJ64e40TFYpwon4N2tN+JSY1qrk6dOpgxY4ZFA6HsWB4xYgTuu+8+7Nmzp8iX/aOPPorhw4fjnnvuKZKsOXv2LB577DF1/6RJk7Bs2bIir/HXX39h8uTJGDVqFH744YdSl2f27NkYM2YMfHx8YI3ky+fGG2+09GLYDMk+33rrrerzJcmq3Nxcw319+/ZFTk4O/vzzzxKfv3fvXnTt2hXPPPMM7NVTTz2l1kHh/5tkPywdJ/SioqIwZMgQ9Z1vbpyQaiz5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RERERC6BSQ0iIiIiIiIiIiIiInIJTGoQEREREREREREREZFLYFKDiIiIiIiIiIiIiIhcApMaRERERERERERERETkEpjUIGrEvvnmG1x22WWO3gwiInJSjBNERMQ4QUREPJ8gV8OkBlEjlpWVhSNHjjh6M4iIyEkxThAREeMEERHxfIJcDZMaRERERERERERERETkEpjUILKBw4cP484770Tv3r0xcuRIzJgxA5WVlTXKffz000+44oor1OumTp2KgoICk6+zceNGXHfddejRowcuueQS/Pbbb2Y/66677kKfPn0wevRozJ8/v8Zr/vjjD1x11VXo378/pkyZgpycHH7fiYgciHGCiIgYJ4iIiOcTRGdJR0QN6vDhw7qoqCjd008/rduwYYNu/vz5ui5duuj+85//GF4zY8YMnZeXl65Hjx66xYsX6xYtWqTr1KmT7sYbbzS8Zu/evTo/Pz/d1KlTdevXr9e9/fbbOl9fX90vv/xieM2BAwd04eHhurFjx+qWL1+uW7hwoe6yyy7THT161PA53t7euuHDh+uWLVumLrItEyZM4HediMhBGCeIiIhxgoiIeD5BdPaY1CBqYBMnTtTdeuutJo+tXr1aJTGKi4sNyQbJKe7evdvwmo0bN6rH9uzZo+7fcsstuhEjRph8nQcffFDXrVs3w335nAEDBtTYhvLycsPnSCIkIyPD8NysWbN0MTExDfb/JSKi+mGcICIixgkiIjpbPJ8g0um8z3aFBxGZt3LlSuTn56Nbt26SNFSXsrIyVFRUqKbdnTt3Vq9r0qQJunTpYnhfv379EBwcjG3btqnXbN26FePGjTP52hdffDHef/99lJaWwtfXF6tXr8bEiRNrbIOXl5fhdkJCAiIjIw334+LikJqaym8fEZGDME4QERHjBBER8XyC6OwxqUHUwIqKinDrrbdi0qRJNZ5r3bq14ba/v3+N5wMCAtT7ta8j96s/L705iouLVVKjpKQEgYGBtW6Ptzd/zYmInAnjBBERMU4QERHPJ4jOHkc7iRpYx44dcfDgQXTq1KnW1yUnJyMrKwsRERHqfkpKCtLS0tCuXTt1X6537txp8p4dO3YgJiYGoaGh6r58xpYtW/g9JCJyIYwTRETEOEFERDyfIDp7nufwXiIyY+rUqfjzzz/x6aefqtJT4ujRo5g2bZrJ68rLy/H444+rlRdy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siQy60J+t+WPtvr8H+R3VdsH8rPRvXt3k8+Qr2/pvUePHlVLf+XnQH7fjX/Gtc/29fVVP+/9+/dXM0d2796NlStXqlkl8nna779G/hDbtWsXOnXqZPK7TPbBOGE5TtQVB+p63vh4IINYltT1vIZxgnHCGowT1NAYJyzHibrOB+qKE56enoa/q82VXigoKFB/i8ms3ClTphgSJTLRyBzGCcYJazBO0LliXLAcF+o6rtf1fF3jSHW9v664VB3jBuOGNRg3zg5XapwjSRoYl7Z4/PHHVcZJli6LL774Qg1gaiRJIX84y8zyn3/+GV27dlXL34xnlF500UXquZKSEpUFloHZd955R/1xLf0gjPtpyKC8HHDPP/989Qe9XPr06aMGRc311JBBz6uvvhr3338/Tp48id9//13NdpftEXJAloFwGeSXwVV5Xsue1fXeunz88ccq4SKD7SI0NLTGa2QgWXtcmjxLcNCW8Xl5eanSUfPnz7fq61cnSSIJUMalp7T9J7P8JdG0ceNGtf/kpEa+jzJA//LLL2PChAlmv6YksO666y71fdVIgJSyR7KEXUgC5K233jIJnPUhPwdSHkkCpATPN998UyULcnJyzJ6YyeoEGcQeMWKEemz16tUqMSLbc+rUKZUAM+41IQPlEsDl/yvPy/bKz6BOp6v3tp7rZ0nCTL4fli7aMlH5vUhMTFQzIjSSrJJEgCTkNG3btq115U5t5OddZunJz+DWrVut/j9IckGSB99//73axokTJ6o/SjWzZs2y+F55nfxOSeJTtlsSQm+//bbJZ8vSPNmncvIu5GdLfn4lgSqJC9kP8rupkQSrbIMcP+QEXwZ3yb4YJyzHibriQF3Pa7755hs1w0r+GJQ4Vl1dz2sYJxgn6oNxghoK44TlOFHX+YC1ccISiQvyt7ac48iAlJxPyPfDUiKccYJxoj4YJ+hsMS5YP850ruoaR6quvuNUjBuMG/XBuFFPOjonBw4c0Hl7e+vy8vJ0R48e1cXFxelGjx6t++WXX9TzXbp00X3//ffq9rp163Q+Pj66gwcPGt4/adIk3YgRI9TtoqIiGdnUvfnmm4bn3333XV3nzp11paWlhte0atVKd8stt6j7y5YtU+/5888/De956aWXdN26dVO3165dqwsKCjI89/nnn+vat2+vKywsNDx2//336+644w51+5NPPtE1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wIEDUVlZiSuvvBKLFi3C0KFDUVRUZPE9xcXFGDFihBrUuuCCC9Tlsccew5YtW2BvzcL94eEBFJdVIqOg1O6fT0TU2D333HPYvXu3WqmxdetW/Pzzz3j00UexZs0ai+9ZunSpSnq/99576r0bN27Ea6+9hoyMDNibj5cnmoWx/xIRkS3NmzcPl1xyCXr16oXx48fjyJEjdb4nKysLTz75JAYNGqTOLb7//nuHfJM8PDzYV4OIyMZOnDiBl156CQ888AA++eQTlJRYN9lo/vz5+L//+z88++yz6nzE0VVCWNKWiNyF0yc1nnjiCYwaNQofffSRmkkrAePYsWP44osvLL7nlVdewd69e7FixQpMnjwZt9xyC5YtW4b27dvD3vy8vRAb4q9un2QTWCKiBjdr1ixMmjQJMTEx6r6s2pBBq6+++srie1588UVceumlGDdunOGxwYMHo3Pnzo5tFp5pOWFPRERnR84frrnmGlx88cX44IMP1OSoYcOGqaSFJZmZmWpilaz2fvXVV9VFEiOrV692yLchIbIqTvB8goiowUkp2p49e6qJsLLqWyY+STK7rKys1uog1157raoMEhYWpi5jxozBrl27HNtXI5N9NYjIPXjDicmKi3///dckgREeHo6LLroICxcuVBl0c2bOnKlmYEVHRxse8/T0REhICByheUQATucWq3rpPRPCHbINRESN0cmTJ5GWloY+ffqYPC73t23bZvY9MutKBqXeffddNWglSXApQ9W6detaP0veZzxjKzc3t0FPQtYfzeRycSIiG3j++edVEltm0or+/fujadOm+Pjjj9UEKnNkxq30Xfrrr78QEKBPKEiSQwaxHDoDl4NVREQN7vHHH1fnD7/88otaHXfbbbepc4PZs2fjjjvuMPued955B0uWLFGrviURIqRsekFBgUP7L3GSFBG5C09nX/5XUVGB+Ph4k8clYBw9etTse2SAKikpSc3SlVIiN954Ix566CHVCLY2MlAlA1TGl4aegXsymxlzIqKGpM2yjYyMNHk8KirK4gxcaSQug1ISF7p166ZKVfXt21eVKqytp4bM0tVmYclFO3lpCAmG5eJcqUFE1JDy8/PV8V5W52l8fX0xcuRItZLbEik1JWUKtYSGxtvb26EzcBOzeD5BRNSQJIEtZc5llYUkNESzZs0wfPhw/PnnnxbfJ4lxmUxr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LrvsMtWA3DSxsXPnTmRkZPDnSkRkpxgniIiIcYKIiHg8QXT6uFODqIHdfffd2L17NwYNGoSzzz5b9dfYsmULJk6ciClTppiVknrnnXfw22+/qaTH8uXL8emnn8Lf31/df8cdd+D3339H7969MWrUKPU1pD/HK6+8Yvwa99xzj7pdHiPfSxIlUtZk6dKl/LkSEdkpxgkiImKcICIiHk8QnT6ddAs/g+cTUS0OHDiAjRs3wsvLCwMGDEBMTIzZrgw5bd68GWvXrsXx48dVz40OHTqYfQ359Vy9ejXi4uLQokULlbgwbRxusH37dmzbtk2VNJEEiOExklzZtWsXLr30UuNjk5KSVJPaU5XHIiKixsU4QUREjBNERMTjCaL6Y1KDyAYMSY19+/Zx/ImIiHGCiIh4PEFERJx3IrISe2oQEREREREREREREZFDYE8NIhsYM2aM6qlBRETEOEFERDyeICIizjsRWY/lp4iIiIiIiIiIiIiIyCGw/BQRERERERERERERETkEJjWIiIiIiIiIiIiIiMghMKlBREREREREREREREQOgUkNIiIiIiIiIiIiIiJyCExqEBERERERERERERGRQ2BSg4iIiIiIiIiIiIiIHAKTGkRERERERERERERE5BCY1CAiIiIiIiIiIiIiIofApAYRERERERERERERETkEJjWIiIiIiIiIiIiIiMghMKlBREREREREREREREQOgUkNIiIiIiIiIiIiIiJyCExqEBERERERERERERGRQ2BSwwEcPnwYe/futfXLaLaOHj2qxri5yM7Oxpo1a2zyvXfv3o34+HjYoy1btiAnJwf2ZOfOnUhISLDpa8jKysLatWtt+hrozDFONC7GiYbDOFE/jBPUUBgnGhfjRMNhnKgfxgkiInJWTGo4gI8//hgvvPCCVY/Nzc3F6tWrG/01NReVlZWYPHkyUlJS0Fxs27YNU6ZMscn3njVrFj7//HPYoyVLluCJJ56o8zFbt27FqlWrmiwp9Oijj2L+/Pmwpc2bN2PatGnG65LgkDGQJBA5DsaJxsM40bAYJ+qHcYIaCuNE42GcaFiME/XDOEFERM7KzdYvgBrWsWPH8OKLL6oJ3Kam1+vx999/G69HR0ejffv2tT7+33//hZ+fH3r37m08IPjnn39qPG706NFW3W+a2NmzZw8iIiLQrl27Ol/zggUL1GsY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NWqUiitNhXGCiIiIiKhubrBzzzzzDHbv3q1W0bZv3x579+7Fq6++imHDhhkfs2fPHqxfv97seX///TcOHTpk1aqqhhTqq21jP5pR0KTfl4jIWfXt21ftxJCEhnz2T58+HbfffrtZWZH+/fvXWDG7a9cuXHTRRZg2bZpN4kRChnkpFCIiahzS62LEiBEqiT1kyBB89NFH6rjCNPn93nvvqeMJiQ2mpWyXLFmCL774okl/NDyeICIiIiJy8KSG7LKQ3RkHDhxQW7+7du2KsLAws8fcf//9xiaABjExMfjrr7/Qp0+fJn29sWHarpB4TlYRETWZLl26qF17tbnllltq3HbOOeeoU1OLCdXixNFMJr+JiJqCJLY3bdqkkhmyQ++CCy7AXXfdpXZxGMgxg6+vr9nzduzYgalTp6pkuU3iBI8niIiIiIgcM6lhIFu+a9v2LYmO6qRGrjV1chtaTKh2MMSdGkREZEl0iDZZxZ0aRERNp3v37pg9e3at98sOv+qknKGcmhqTGkREREREDt5Tw9HEVq2sSsktQVFpha1fDhER2RnDZFVybjFKyhkniIjI8iKpE7nFKC5jnCAiIiIiqo5JjQYW5OOBAC9tA0xCJuulExGRuVBfD/h6uEKvB45lFXF4iIjITLCPO/yrjicSeTxBRERERFQDkxqNIDZMW10Vz2bhRERUjU6nYwkqIiKqM04YdvWxTx8RERERUU1MajQC9tUgIqK640RVXw2uwCUiIh5PEBERERHVC5MajdhX42gGy08REVFdyW/GCSIishAnQng8QURERERUGyY1GkEbHoQQEVEdoqviREJmAceJiIhq3dF3lDv6iIiIiIhqYFKjEbCnBhERWbMCl+WniIio7h19TH4TEREREVXHpEYjrqw6nl2E0vLKxvgWRETUDHb0SVJDr9fb+uUQEZGdHk8kZRWhvILHE0REREREppjUaAThfp7w8XBFpR44lsV66UREZC4q2BuuLjoUl1UiNa+Ew0NERGYi/b3g6eaC8ko9jmcXc3SIiIiIiEwwqdEIdDod+2oQEVGt3F1d0CrIS11mCSoiIqrOxeXk8UQ8S1AREREREZlhUqORxFbVweVBCBERWWKYrDqawR19RERUR18NNgsnIiIiIjLDpEYjiQnjZBUREdWuTYg2WZXAFbhERFRHX42j6WwWTkRERERkikmNRhJTNVl1lJNVRERUx2QVy08REVFdcYI7NYiIiIiIzDGp0UhiDQchLCtCRER1lZ9iWREiIqqr/BQXSRERERERmWFSo5HEhGkHIYlZhaio1DfWtyEiIgdPaiQw+U1ERBbEGOJEZiH0eh5PEBEREREZMKnRSFoGeMHDzQVlFXoczy5qrG9DREQOqk3Vjr6MglLkl5Tb+uUQEZGdiQr2hquLDsVllUjNK7H1yyEiIiIishtMajTWwLroEB3srS6zBBUREVUX4OWOYB93dZm7NYiIqDp3VxdEBWnHE/FsFk5EREREZMSkRiOKraqDG886uEREZEGbqjjBZuFERGQJm4UTEREREdXEpEYjYnM/IiKyrl56AQeKiIgsHE9ocYLNwomIiIiITmJSo0kOQgob89sQEZGDNwtnnCAiIktiQrQdfYwTREREREQnManRiJjUICIia5qFs/wUERHxeIKIiIiIyDpMajRBT42jmQWorNQ35rciIiIH3qnBpAYREdVVzlZ69On1PJ4gIiIiIhJMajSiqGBvuLroUFxWidS8Er7jiIjI4o6+pKwilFdUcnSIiMhi8juvuBzZhWUcHSIiIiIiJjUal7urC6KCvNVlNvcjIqLqIv294OHmgvJKPZJzijlARERkxtvDFZEBntrxRCb79BERERERCe7UaGTsq0FERLVxcdEhOtiQ/OZkFRER1dUsvIDDQ0RERETEpEbT9dWQOrhERES11UuX/ktEREQ144RWgorJbyIiIiIiDXdqNNVBCLeLExGRBWwWTkREVh1PcEcfEREREZHCpEZTrcDlTg0iIqorqcHJKiIi4vEEEREREdEpManRyGINK6vSC6HX6xv72xERkYPhClwiIrIqTnDnNxERERGRwqRGI4sO8YFOB+SVlCOzoLSxvx0RETnoZFViJpPfRERUe6PwtLwSFJSUc4iIiIiIyOkxqdHIvNxd0TLAS13m6ioiIqqudbCW1JDkd1ZhGQeIiIjMBPq4I8jHXV1O4G4NIiIiIiLHSGosX74cU6ZMweDBg3HjjTciMTHxlM/Jzc3Fs88+i9GjR2PSpElYuHAhbKWNsblfgc1eAxFRc5eamopdu3ahsLDQ6udIWcC4uDgcP34ctkx+tzAkvxkniIjIgpiq/ktsFk5ERERE5ABJjWXLluHcc8/FgAED8MILLyAlJQXDhg1DTk5Orc/Jzs7GkCFD1HMffvhhdfr666+xbt062EJsVbPw+HTrJ9qIiMg6paWlmDFjBtq0aYMLLrgAERER+N///nfK5y1evBixsbEYNWqUOp1//vnIzMy0afKbK3CJiBpHRkYG5syZg6effhoLFixAZWWlVc/bsGEDXn75ZcyePRvJyck2+/HEVB1PMPlNREREROQASY2nnnoKl156KZ544gmMGzcO33//PfLy8vDRRx/V+hw5WJGdGn/88YdKiMhk1Q8//IB+/frBFngQQkTUeJ5//nn89ddfOHjwII4cOYJPPvkEN998MzZv3lzrc9auXYupU6eqpHdSUpJ67p133qku20KbqhW4CRlMfhMRNTSJDT179sR3332HgoIC3H///SoJXldiQ3byyQ5xOZaQZIaczjnnHOzfv98mPyA2CyciIiIicpCkRn5+vlodJeWjDLy8vFRyY8WKFbU+b/78+bjqqqvg66utaDLw8PCALfAghIio8cydOxczZ85EdHS0ui6J8K5du6rkRm1mzZqlEt633Xab8TaZrJJJL5uWFWGtdCKiBicJbNmZJ8cPr732GlauXImlS5eqJEdtZFeHYaf3O++8g5deegn//PMPAgMDbfIT4iIpIiIiIiIHSWrIillZJdWyZUuz21u1alVrX4309HSkpaWhffv2uOOOO1QZqunTp+PXX3+t83uVlJSo3R2mpwZPanAFLhFRgzKsnpUShaYGDRqELVu21FquSiamJk+ejKKiIuzevRtZWVk2/cmw/BQRUeMoLy/HokWLcOWVV8LV1VXd1q5dO5XY/umnn2p93rvvvosrrrgCnTt3Nt4WFBSEFi1a2ORHxeMJIiIiIiIHSWqUlZWpc09PT7Pb5brhPkvJCfHAAw+o+upvvPEGhg8fjosuugifffZZrd9LVl/JyivDybDityFXVmUWlCKnyPLrJiKi06uRLkJDQ81uDwsLM95nKfktiY0DBw6oBPjFF1+MqKgoleSQnky2SH6z/BQRUeNISEhAcXExOnToYHa7XJc4YImUut23bx9GjhyJ3377Dc8884zq1SQLp2y9SOp4dhFKy63rB0JERERE1FzZdVLDMElVfWJKrlefwDIICQmBTqfDeeedh4ceeghDhw7Fvffei6uvvhrvv/9+rd/r0UcfVc3HDafadoKcDj9PN4T5aYkZ1ksnImo47u7uZgltA9mBYbiv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Y+PPF8estfFnrPVxjDle/PkyL/yd5HiZG/5Mcrz482Ve+DvJ8SIiIsvCRuFERERERERERERERGQRuFODiIiIiIiIiIiIiIgsApMaRERERERERERERERkEZjUICIiIiIiIiIiIiIii8CkRguVlpZi+/btOHToUOv8j1i4kpISbNy4EYmJiQZfk5ubi23btuHkyZOwdfn5+YiPj0d6errB11RWVmLnzp3Yu3cvdDodbJn8++V3T8ZCftYMOXbsGP755x8UFRW16fszV9XV1diwYYP6OWpMdnY2/v77b6Smprb5e7NGjBNNY5xoGcaJlmGcODeME22LcaJpjBMtwzjRMowT54ZxgoiIzI6Omm3hwoU6Pz8/XUxMjM7X11c3ZMgQXVpaGkdQp1PjMH36dF1oaKjO1dVV98QTTzQ6Lm+++ab6eNeuXXVubm66SZMm6crKymxuDA8dOqS75ppr1M9R3759dZ6enrpLL71Ul5WV1eB1Gzdu1LVv314XERGhCw4O1sXFxekOHDigs0Xz58/XdejQQf3sdO7cWeft7a2bNWtWg9fk5eXpxo4dq8ZTXiO3X375pc7WvfLKKzp7e3td//79z/jYiy++qHNxcdF169ZN3d5xxx26yspKk7xPa8A4YRjjRMswTrQc48S5Y5xoO4wThjFOtAzjRMsxTpw7xgkiIjI3TGo0U0pKis7d3V33xhtvqMdFRUW6fv36qYlp0um2bt2qJphlUr579+6NJjVWr16ts7Oz0y1btkw9TkxMVBP1Mqlqa5YuXar7+eefddXV1epxZmammlSePHly7WuKi4t1YWFhugceeEA9lolmSXzIz50tmjNnji41NbX28XfffSfbVnTbt2+vfe7uu+/WdenSRZedna0ez5s3T+fo6GiziSB9Yiw6Olp30003nZHU+P3339X4rF27Vj0+ePCgSrSdniyi5mGcaBrjRMswTrQc48S5YZxoO4wTTWOcaBnGiZZjnDg3jBNERGSOmNRoprfeekutDK+/q0BWejg4OKgJaapjKKlx2223qd0t9T366KO6qKgoDp9Op3vhhRfUjgw9SXpIEkgugPXWr1+vJvLj4+NtfszS09PVWMjEvCgtLVWJx7lz59aOjSSNJDH09NNP2+R45eTkqN0tK1eu1D344INnJDUmTpyodrbUd99996nfYWo5xonmY5w4N4wTLcM4cXaME22LcaL5GCfODeNEyzBOnB3jBBERmSv21Ggm6XvQs2dPODs71z43aNAgVFVVYdeuXa1VHczqxrB///4NnpMxlP4bOTk5sHXS0yAmJqbBeIWFhSE0NLTBeOk/ZosyMjKwfv16/Pbbb7j11ltx4YUXYty4cepjBw4cQHFxcYOfMTs7OwwYMMBmx+vuu+/Gddddh9GjR7fodzIhIQFlZWVt9C6tB+OEccaQccIwxomzY5xoGcaJtsU4YZwxZJwwjHHi7BgnWoZxgoiIzJWjqd+ApZBGugEBAQ2e0z+Wj9H5j6Gfn5/NDuP8+fOxZMkSLF++vMnxcnJygpeXl83+zMmF7EsvvYS0tDQUFBRg7ty5tYlG/Zg09jMmk/S25v3338fRo0exYMGCFv9OSiPA3NxctGvXrg3eqfVgnGj9MWScYJw4G8aJ5mOcaHuME60/howTjBNnwzjRfIwTRERkzrhTo5lkMrm0tLTBcyUlJeq2/u4N4hi2lCQz7rrrLsyePRtjxoxp8mdOyHO2+jM3fvx4tVPj0KFD+PDDDzFp0iT89ddfteMlGvs9tbXxSk5OxowZM3D//fdj69atasxSU1NRWFio7ufl5anX8bxmXBxPjmFrYZxoPsaJ5mGcMA3GCY5ha2GcaD7GieZhnCAiInPHpEYzRUVFqcBen/5xZGSk8f9nbGgM5QIvJCQEtmjp0qWYOHEiXnvtNUydOvWM8Tp16pRaNa+Xnp6OiooK/swBuOqqq9C5c2c1hvrxEo39jNna76gkcvr164cvvvgCTz75pDo2bdqkxkLuyw6Opn4nZTeQLa90PFeME603howTjBPngnHCMMYJ02CcaL0xZJxgnDgXjBOGMU4QEZG5Y1KjmaRu/969e3HkyJHa5xYuXKgm46XXBjVvDKW8Uv1a/TKG0hdBv8relshYXHPNNXjllVfw73//u9Hxys/Px+rVqxuMl+w6GDVqFGxJeXm5SubUV1RUpJI++pID4eHhiIuLw6JFixokgWQyX993w1ZIbxbZkVH/kORZly5d1P2+ffuq18m4yMq+ysrKBj9jY8eONeG7t1yME8YZQ8aJOowTzcc40TKME6bBOGGcMWScqMM40XyMEy3DOEFEROaOPTWa6dJLL8UFF1yAa6+9Fs8++6xqbv3mm2/igw8+gL09c0My4bxlyxY1VtKs+eTJk2ry1NvbG7169VLPP/DAA/joo4/U5Op9992nJuuldNCaNWtgazZs2ICrr74aV155pWrMLGOlb2w9fPhwdb979+6qGfadd96JV199VY3rY489plba29oq+qysLPU7KGW6ZGJeGvxJPw3ZUSDN6/RknKQxtjRY79GjB9544w01jpMnTzbp+zdX06dPx+eff67KeN1xxx0qwSENJiURRC3HONE0xomWYZxoGcaJ1sE4YVyME01jnGgZxomWYZxoHYwTRERkKnY6nU5nsu9uYWRluCQy5A9ImUy97bbb1MQ0aY35ZIL+dDKhLL0P6m8Pf/3119Wul9DQUFVyafDgwTY3hF9++aVK8JzO0dGxwc4MubiTyftly5apj0lSTSafJflha44dO4b33nsPu3fvhq+vLwYOHIh7771XJc7q+/PPPzFv3jz1MzlgwAA88cQTNpcEaszbb7+tfu8+/vjjBs9LglZ+Jw8cOKB2u8iFiX4nB7Uc44RhjBMtwzjRcowT54dxom0wThjGONEyjBMtxzhxfhgniIjInDCpQUREREREREREREREFoF1k4iIiIiIiIiIiIiIyCIwqUFERERERERERERERBaBSQ0iIiIiIiIiIiIiIrIITGoQEREREREREREREZFFYFKDiIiIiIiIiIiIiIgsApMaRERERERERERERERkEZjUICIiIiIiIiIiIiIii8CkBpEVO3ToEP744w9Tvw0iIjJTjBNERMQ4QURERJaGSQ0iK7Zs2TI88sgjpn4bRERkphgniIiIcYKIiIgsDZMaRERERERERERERERkERxN/QaIrFViYiJ27NiBgIAA9OvXD+7u7g3Kfcgxbtw47Ny5E8nJyRg8eDBCQkLO+Dq7du3C4cOHERoaql5jb39mLjIpKQnx8fFo164dBgwYAAcHhwYfr6ysVF8nNTUVffr0Qfv27VvpX01ERM3FOEFERIwTRERERC3HpAaRkel0OkyfPh3z58/HkCFDkJmZqZIJP/30EwYOHFhb7uPll19WyQU3NzdUV1erBMi3336LK6+8sjYRccMNN2D16tXq60hSQpIeS5YsQVBQUO33evjhh/Hxxx+rhEdpaSkcHR2xePFieHt7q9fk5eVh5MiRcHFxUY+3bNmC7777rvb7EBFR22KcICIixgkiIiKi86AjIqP66KOPdJ06ddJlZmbWPvfyyy/r4uLiah/PmTNHJ79+b775Zu1zzz//vC4kJERXXFysHs+dO1fn7++vS0xMVI/z8/N1vXr10t1zzz21n/Pee+/p3N3ddTt37qx9buPGjbr09PQG3+fHH3+s/fijjz6qvg4REZkG4wQRETFOEBEREZ079tQgMrLPPvsMvXr1wqpVq/DDDz/g+++/h6enJ/bv3692bOjJzompU6fWPn700UeRnp6OtWvXqseya+OWW25BZGSkeuzl5YVp06apXRZ6X3zxBW677Tb1/fSGDh1au5NDyP1rr7229vGFF16IAwcO8P+diMhEGCeIiIhxgoiIiOjcsfwUkZEdP34c5eXl+PHHHxs8P2nSJPW8nvTI0JeEEpL4kASE1FgXcnvdddc1+BqdOnVCfn4+cnJy4OfnhxMnTuDGG29s8v34+/s3eCzfs6ys7Lz+jUREdO4YJ4iIiHGCiIiI6NwxqUFkZNLL4qKLLsIbb7zR5Otyc3PPqLEuzwUGBqrHcpudnd3gNfLYycmptl+Gr68vsrKy+H9IRGRBGCeIiIhxgoiIiOjcsfwUkZFNmDABX3/9NQoKCho8n5yc3OCxJDCkCbjeH3/8oRqG65uJjxgxAr/++qt6Tk/KWUl5KQcHB/V4/PjxqhxV/R0gRUVFKC4u5v8rEZGZYpwgIiLGCSIiIqJzx50aREb23HPPYcWKFSo5cc8998Dd3R1btmzB0aNHa/tlCA8PD9UPQ/pkSOLitddeU/cjIiLUx5955hmVxLj00ksxceJEbNq0CQsXLmyQCHn22WexdOlSlei4/fbbUVpaim+++UYlSOT7EhGR+WGcICIixgkiIiKic8edGkRGJj0stm7dihkzZiAhIQF79+7F2LFjsXLlygavCw8Px+LFi1V/DHndW2+9hTfffLP248HBwdixYweGDRuG9evXq34b27dvx6BBg2pfIyWqtm3bppIj8fHxyMvLU708pF+H6Ny5My677LIG3zckJET19yAiItNgnCAiIsYJIiIionNnp5NC/kTUpubOnauO/fv3c+SJiIhxgoiIeD1BRERE1EzcqUFERERERERERERERBaBSQ0iE2isLBQRERHjBBER8XqCiIiIqGksP0VERERERERERERERBaBOzWIiIiIiIiIiIiIiMgiMKlBREREREREREREREQWgUkNIiIiIiIiIiIiIiKyCExqEBERERERERERERGRRWBSg4iIiIiIiIiIiIiILAKTGkREREREREREREREZBGY1CAiIiIiIiIiIiIiIovApAYREREREREREREREVkEJjWIiIiIiIiIiIiIiAiW4P8Bp12Z9iRZi1kAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "def config_label(tokenizer, vocab_size, max_token_len, pad_layout=\"end\"):\n", + "def config_label(tokenizer, vocab_size, max_token_len, pad_layout=\"end\", hidden_dim=DEFAULT_HIDDEN_DIM, num_conv_blocks=DEFAULT_NUM_CONV_BLOCKS):\n", " if tokenizer == \"char\":\n", - " return \"char\"\n", - " label = f\"wordpiece {int(vocab_size)}\"\n", - " if pd.notna(max_token_len):\n", - " label += f\" (max_token_len={int(max_token_len)})\"\n", - " if pad_layout != \"end\":\n", - " label += f\" [{pad_layout}]\"\n", + " label = \"char\"\n", + " else:\n", + " label = f\"wordpiece {int(vocab_size)}\"\n", + " if pd.notna(max_token_len):\n", + " label += f\" (max_token_len={int(max_token_len)})\"\n", + " if pad_layout != \"end\":\n", + " label += f\" [{pad_layout}]\"\n", + " if hidden_dim != DEFAULT_HIDDEN_DIM or num_conv_blocks != DEFAULT_NUM_CONV_BLOCKS:\n", + " label += f\" h{int(hidden_dim)}d{int(num_conv_blocks)}\"\n", " return label\n", "\n", "\n", + "group_cols = [\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\", \"hidden_dim\", \"num_conv_blocks\"]\n", "configs = (\n", - " history_df[[\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"]]\n", + " history_df[group_cols]\n", " .drop_duplicates()\n", - " .sort_values([\"tokenizer\", \"vocab_size\", \"max_token_len\", \"pad_layout\"], na_position=\"first\")\n", + " .sort_values(group_cols, na_position=\"first\")\n", " .to_records(index=False)\n", ")\n", "\n", @@ -362,12 +195,14 @@ "nrows = int(np.ceil(n / ncols))\n", "fig, axes = plt.subplots(nrows, ncols, figsize=(4 * ncols, 3 * nrows), squeeze=False)\n", "\n", - "for ax, (tokenizer, vocab_size, max_token_len, pad_layout) in zip(axes.flat, configs):\n", + "for ax, (tokenizer, vocab_size, max_token_len, pad_layout, hidden_dim, num_conv_blocks) in zip(axes.flat, configs):\n", " subset = history_df[\n", " (history_df[\"tokenizer\"] == tokenizer)\n", " & (history_df[\"vocab_size\"] == vocab_size)\n", " & (history_df[\"max_token_len\"].isna() if pd.isna(max_token_len) else history_df[\"max_token_len\"] == max_token_len)\n", " & (history_df[\"pad_layout\"] == pad_layout)\n", + " & (history_df[\"hidden_dim\"] == hidden_dim)\n", + " & (history_df[\"num_conv_blocks\"] == num_conv_blocks)\n", " ]\n", " for split, color in [(\"train\", \"tab:blue\"), (\"val\", \"tab:orange\")]:\n", " split_data = subset[subset[\"split\"] == split]\n", @@ -376,7 +211,7 @@ " if per_epoch[\"std\"].notna().any():\n", " ax.fill_between(per_epoch.index, per_epoch[\"mean\"] - per_epoch[\"std\"].fillna(0),\n", " per_epoch[\"mean\"] + per_epoch[\"std\"].fillna(0), color=color, alpha=0.15)\n", - " ax.set_title(config_label(tokenizer, vocab_size, max_token_len, pad_layout), fontsize=9)\n", + " ax.set_title(config_label(tokenizer, vocab_size, max_token_len, pad_layout, hidden_dim, num_conv_blocks), fontsize=9)\n", " ax.set_xlabel(\"epoch\")\n", " ax.set_ylabel(\"loss\")\n", "\n", @@ -413,10 +248,10 @@ "id": "7a5eab55", "metadata": { "execution": { - "iopub.execute_input": "2026-08-07T10:45:12.010969Z", - "iopub.status.busy": "2026-08-07T10:45:12.010821Z", - "iopub.status.idle": "2026-08-07T10:45:12.129188Z", - "shell.execute_reply": "2026-08-07T10:45:12.128159Z" + "iopub.execute_input": "2026-08-11T18:24:44.404091Z", + "iopub.status.busy": "2026-08-11T18:24:44.403912Z", + "iopub.status.idle": "2026-08-11T18:24:44.560243Z", + "shell.execute_reply": "2026-08-11T18:24:44.559041Z" } }, "outputs": [], @@ -424,17 +259,20 @@ "fig, ax = plt.subplots(figsize=(8, 5))\n", "val_data = history_df[history_df[\"split\"] == \"val\"]\n", "\n", - "for tokenizer, vocab_size, max_token_len, pad_layout in configs:\n", + "for tokenizer, vocab_size, max_token_len, pad_layout, hidden_dim, num_conv_blocks in configs:\n", " subset = val_data[\n", " (val_data[\"tokenizer\"] == tokenizer)\n", " & (val_data[\"vocab_size\"] == vocab_size)\n", " & (val_data[\"max_token_len\"].isna() if pd.isna(max_token_len) else val_data[\"max_token_len\"] == max_token_len)\n", " & (val_data[\"pad_layout\"] == pad_layout)\n", + " & (val_data[\"hidden_dim\"] == hidden_dim)\n", + " & (val_data[\"num_conv_blocks\"] == num_conv_blocks)\n", " ]\n", " per_epoch = subset.groupby(\"epoch\")[\"loss\"].mean()\n", " style = \"--\" if tokenizer == \"char\" else \"-\"\n", " ax.plot(per_epoch.index, per_epoch.values, style,\n", - " label=config_label(tokenizer, vocab_size, max_token_len, pad_layout), linewidth=1.5 if tokenizer == \"char\" else 1)\n", + " label=config_label(tokenizer, vocab_size, max_token_len, pad_layout, hidden_dim, num_conv_blocks),\n", + " linewidth=1.5 if tokenizer == \"char\" else 1)\n", "\n", "ax.set_xlabel(\"epoch\")\n", "ax.set_ylabel(\"val_loss\")\n", From 7b0e7f1b82c64490528163210d154fddcb97a290 Mon Sep 17 00:00:00 2001 From: maria Date: Wed, 12 Aug 2026 01:03:29 +0300 Subject: [PATCH 62/70] Add a unified notebook comparing all 5 architecture runs --- .../architecture_comparison_report.ipynb | 461 ++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 notebooks/architecture_comparison_report.ipynb diff --git a/notebooks/architecture_comparison_report.ipynb b/notebooks/architecture_comparison_report.ipynb new file mode 100644 index 0000000..d06d9e4 --- /dev/null +++ b/notebooks/architecture_comparison_report.ipynb @@ -0,0 +1,461 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "891153ed", + "metadata": {}, + "source": [ + "# Architecture comparison \u2014 run5 (hidden_dim / num_conv_blocks) vs run4a baseline\n", + "\n", + "Compares 5 runs on one set of clean, headline charts (one line per run - not overloaded)\n", + "plus a per-vocab_size convergence grid (split out for readability, since 5 architectures x\n", + "15 configs would be unreadable in one chart).\n", + "\n", + "All 5 runs share the same tokenizer grid, `--max-token-len 9`, `--pad-layout anchored`,\n", + "individual per-vocab_size `max_len` - only the architecture (`hidden_dim`/`num_conv_blocks`)\n", + "differs between them." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2f20528", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:45.270207Z", + "iopub.status.busy": "2026-08-11T18:57:45.270039Z", + "iopub.status.idle": "2026-08-11T18:57:45.276187Z", + "shell.execute_reply": "2026-08-11T18:57:45.275111Z" + }, + "tags": [ + "parameters" + ] + }, + "outputs": [], + "source": [ + "# parameters\n", + "RUNS = {\n", + " \"baseline (h192 d4)\": \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_40epochs\",\n", + " \"h128 d4\": \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d4_40epochs\",\n", + " \"h192 d3\": \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h192_d3_40epochs\",\n", + " \"h128 d3\": \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h128_d3_40epochs\",\n", + " \"h96 d3\": \"../artifacts/compare_forward_tokenizers_2026-08-01_fine_grid_individual_maxlen_maxtokenlen9_anchored_h96_d3_40epochs\",\n", + "}\n", + "RUN_COLORS = {\n", + " \"baseline (h192 d4)\": \"black\",\n", + " \"h128 d4\": \"tab:blue\",\n", + " \"h192 d3\": \"tab:orange\",\n", + " \"h128 d3\": \"tab:green\",\n", + " \"h96 d3\": \"tab:red\",\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d7c0d62", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:45.278766Z", + "iopub.status.busy": "2026-08-11T18:57:45.278019Z", + "iopub.status.idle": "2026-08-11T18:57:46.104771Z", + "shell.execute_reply": "2026-08-11T18:57:46.103627Z" + } + }, + "outputs": [], + "source": [ + "import json\n", + "from pathlib import Path\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "DEFAULT_HIDDEN_DIM = 192\n", + "DEFAULT_NUM_CONV_BLOCKS = 4\n", + "\n", + "\n", + "def load_run(run_label, output_root):\n", + " results_dir = Path(output_root)\n", + " raw = pd.read_csv(results_dir / \"raw_results.csv\")\n", + " for col, default in [(\"max_token_len\", None), (\"pad_layout\", \"end\"),\n", + " (\"hidden_dim\", DEFAULT_HIDDEN_DIM), (\"num_conv_blocks\", DEFAULT_NUM_CONV_BLOCKS)]:\n", + " if col not in raw.columns:\n", + " raw[col] = default\n", + " raw[\"run_label\"] = run_label\n", + " with open(results_dir / \"summary.json\") as f:\n", + " summary = json.load(f)\n", + " for row in summary:\n", + " row[\"run_label\"] = run_label\n", + " return raw, summary, results_dir\n", + "\n", + "\n", + "all_raw, all_summary, run_dirs = [], [], {}\n", + "for run_label, output_root in RUNS.items():\n", + " raw, summary, results_dir = load_run(run_label, output_root)\n", + " all_raw.append(raw)\n", + " all_summary.extend(summary)\n", + " run_dirs[run_label] = results_dir\n", + "\n", + "raw = pd.concat(all_raw, ignore_index=True)\n", + "print(f\"Loaded {len(raw)} runs total across {len(RUNS)} architecture variants\")\n", + "raw.groupby(\"run_label\")[\"vocab_size\"].count().rename(\"rows\")" + ] + }, + { + "cell_type": "markdown", + "id": "7cc80613", + "metadata": {}, + "source": [ + "## Summary table: main metrics per (run, tokenizer, vocab_size)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b38038c7", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:46.106694Z", + "iopub.status.busy": "2026-08-11T18:57:46.106483Z", + "iopub.status.idle": "2026-08-11T18:57:46.128212Z", + "shell.execute_reply": "2026-08-11T18:57:46.127038Z" + } + }, + "outputs": [], + "source": [ + "def fmt(mean_std, precision=4):\n", + " mean, std = mean_std\n", + " return f\"{mean:.{precision}f} \\u00b1 {std:.{precision}f}\"\n", + "\n", + "summary_df = pd.DataFrame([\n", + " {\n", + " \"run\": row[\"run_label\"],\n", + " \"tokenizer\": row[\"tokenizer\"],\n", + " \"vocab_size\": row[\"vocab_size\"],\n", + " \"test_loss\": fmt(row[\"test_loss\"]),\n", + " \"test_cosine\": fmt(row[\"test_cosine\"]),\n", + " \"best_val_loss\": fmt(row[\"best_val_loss\"]),\n", + " \"epochs_to_best_val\": fmt(row[\"epochs_to_best_val\"], precision=1),\n", + " \"num_parameters\": row[\"num_parameters\"],\n", + " \"n_seeds\": row[\"n_seeds\"],\n", + " }\n", + " for row in all_summary\n", + "])\n", + "summary_df.sort_values([\"tokenizer\", \"vocab_size\", \"run\"])" + ] + }, + { + "cell_type": "markdown", + "id": "b786aeac", + "metadata": {}, + "source": [ + "## test_loss vs vocab_size, one line per architecture" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ee15756", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:46.130386Z", + "iopub.status.busy": "2026-08-11T18:57:46.130117Z", + "iopub.status.idle": "2026-08-11T18:57:46.417646Z", + "shell.execute_reply": "2026-08-11T18:57:46.416288Z" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(7.5, 5))\n", + "for run_label in RUNS:\n", + " wp = sorted((r for r in all_summary if r[\"run_label\"] == run_label and r[\"tokenizer\"] == \"wordpiece\"),\n", + " key=lambda r: r[\"vocab_size\"])\n", + " vocab_sizes = [r[\"vocab_size\"] for r in wp]\n", + " means = [r[\"test_loss\"][0] for r in wp]\n", + " stds = [r[\"test_loss\"][1] for r in wp]\n", + " ax.errorbar(vocab_sizes, means, yerr=stds, marker=\"o\", capsize=3, label=run_label, color=RUN_COLORS[run_label])\n", + "\n", + "ax.set_xlabel(\"vocab_size\")\n", + "ax.set_ylabel(\"test_loss\")\n", + "ax.set_title(\"test_loss vs vocab_size, by architecture\")\n", + "ax.legend(fontsize=8)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "52e925bf", + "metadata": {}, + "source": [ + "## test_cosine vs vocab_size, one line per architecture" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "01a16c18", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:46.419782Z", + "iopub.status.busy": "2026-08-11T18:57:46.419569Z", + "iopub.status.idle": "2026-08-11T18:57:46.790114Z", + "shell.execute_reply": "2026-08-11T18:57:46.788763Z" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(7.5, 5))\n", + "for run_label in RUNS:\n", + " wp = sorted((r for r in all_summary if r[\"run_label\"] == run_label and r[\"tokenizer\"] == \"wordpiece\"),\n", + " key=lambda r: r[\"vocab_size\"])\n", + " vocab_sizes = [r[\"vocab_size\"] for r in wp]\n", + " means = [r[\"test_cosine\"][0] for r in wp]\n", + " stds = [r[\"test_cosine\"][1] for r in wp]\n", + " ax.errorbar(vocab_sizes, means, yerr=stds, marker=\"o\", capsize=3, label=run_label, color=RUN_COLORS[run_label])\n", + "\n", + "ax.set_xlabel(\"vocab_size\")\n", + "ax.set_ylabel(\"test_cosine\")\n", + "ax.set_title(\"test_cosine vs vocab_size, by architecture\")\n", + "ax.legend(fontsize=8)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "06111d2e", + "metadata": {}, + "source": [ + "*Notes: `char`'s single point per architecture isn't on this vocab_size axis - see the\n", + "dedicated char comparison below.*" + ] + }, + { + "cell_type": "markdown", + "id": "62207304", + "metadata": {}, + "source": [ + "## char: test_loss / test_cosine across architectures" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ba724a9e", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:46.793204Z", + "iopub.status.busy": "2026-08-11T18:57:46.792245Z", + "iopub.status.idle": "2026-08-11T18:57:47.095549Z", + "shell.execute_reply": "2026-08-11T18:57:47.093942Z" + } + }, + "outputs": [], + "source": [ + "char_rows = [r for r in all_summary if r[\"tokenizer\"] == \"char\"]\n", + "char_rows.sort(key=lambda r: list(RUNS.keys()).index(r[\"run_label\"]))\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(10, 4))\n", + "labels = [r[\"run_label\"] for r in char_rows]\n", + "colors = [RUN_COLORS[l] for l in labels]\n", + "\n", + "axes[0].bar(labels, [r[\"test_loss\"][0] for r in char_rows],\n", + " yerr=[r[\"test_loss\"][1] for r in char_rows], capsize=3, color=colors)\n", + "axes[0].set_ylabel(\"test_loss\")\n", + "axes[0].set_title(\"char test_loss\")\n", + "axes[0].tick_params(axis=\"x\", rotation=30)\n", + "\n", + "axes[1].bar(labels, [r[\"test_cosine\"][0] for r in char_rows],\n", + " yerr=[r[\"test_cosine\"][1] for r in char_rows], capsize=3, color=colors)\n", + "axes[1].set_ylabel(\"test_cosine\")\n", + "axes[1].set_title(\"char test_cosine\")\n", + "axes[1].tick_params(axis=\"x\", rotation=30)\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "1095af89", + "metadata": {}, + "source": [ + "## num_parameters vs vocab_size, one line per architecture" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f574fcd", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:47.097855Z", + "iopub.status.busy": "2026-08-11T18:57:47.097632Z", + "iopub.status.idle": "2026-08-11T18:57:47.335303Z", + "shell.execute_reply": "2026-08-11T18:57:47.333850Z" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(7.5, 5))\n", + "for run_label in RUNS:\n", + " wp = sorted((r for r in all_summary if r[\"run_label\"] == run_label and r[\"tokenizer\"] == \"wordpiece\"),\n", + " key=lambda r: r[\"vocab_size\"])\n", + " vocab_sizes = [r[\"vocab_size\"] for r in wp]\n", + " params = [r[\"num_parameters\"] for r in wp]\n", + " ax.plot(vocab_sizes, params, marker=\"o\", label=run_label, color=RUN_COLORS[run_label])\n", + "\n", + "ax.set_xlabel(\"vocab_size\")\n", + "ax.set_ylabel(\"num_parameters\")\n", + "ax.set_title(\"num_parameters vs vocab_size, by architecture\")\n", + "ax.legend(fontsize=8)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "1c889a45", + "metadata": {}, + "source": [ + "## Convergence (val_loss by epoch), split one panel per vocab_size\n", + "\n", + "Split out on purpose - all 5 architectures x 15 configs in one chart would be unreadable.\n", + "Each panel below has (up to) 5 lines, one per architecture, for that single vocab_size." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c4d56d5", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:47.337885Z", + "iopub.status.busy": "2026-08-11T18:57:47.337636Z", + "iopub.status.idle": "2026-08-11T18:57:47.356748Z", + "shell.execute_reply": "2026-08-11T18:57:47.355452Z" + } + }, + "outputs": [], + "source": [ + "def history_filename(row):\n", + " label = \"char\" if row[\"tokenizer\"] == \"char\" else f\"wordpiece_{int(row['vocab_size'])}\"\n", + " max_token_len = row[\"max_token_len\"]\n", + " filter_suffix = f\"_n{int(max_token_len)}\" if pd.notna(max_token_len) else \"\"\n", + " pad_layout = row.get(\"pad_layout\", \"end\")\n", + " layout_suffix = f\"_{pad_layout}\" if pad_layout != \"end\" else \"\"\n", + " hidden_dim = row.get(\"hidden_dim\", DEFAULT_HIDDEN_DIM)\n", + " num_conv_blocks = row.get(\"num_conv_blocks\", DEFAULT_NUM_CONV_BLOCKS)\n", + " arch_suffix = (\n", + " f\"_h{int(hidden_dim)}_d{int(num_conv_blocks)}\"\n", + " if (hidden_dim != DEFAULT_HIDDEN_DIM or num_conv_blocks != DEFAULT_NUM_CONV_BLOCKS)\n", + " else \"\"\n", + " )\n", + " return f\"{label}{filter_suffix}{layout_suffix}{arch_suffix}_seed{int(row['seed'])}.json\"\n", + "\n", + "\n", + "records = []\n", + "missing = []\n", + "for _, row in raw.iterrows():\n", + " history_path = run_dirs[row[\"run_label\"]] / \"history\" / history_filename(row)\n", + " if not history_path.exists():\n", + " missing.append((row[\"run_label\"], history_path.name))\n", + " continue\n", + " with open(history_path) as f:\n", + " history = json.load(f)\n", + " for entry in history:\n", + " records.append({\n", + " \"run_label\": row[\"run_label\"],\n", + " \"tokenizer\": row[\"tokenizer\"],\n", + " \"vocab_size\": row[\"vocab_size\"],\n", + " \"epoch\": entry[\"epoch\"],\n", + " \"val_loss\": entry[\"val\"][\"loss\"],\n", + " })\n", + "\n", + "history_df = pd.DataFrame.from_records(records)\n", + "if missing:\n", + " print(f\"Missing {len(missing)} history file(s), e.g. {missing[:5]}\")\n", + "print(f\"Loaded {len(history_df)} (run, config, epoch) rows\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "edf30456", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-11T18:57:47.358819Z", + "iopub.status.busy": "2026-08-11T18:57:47.358618Z", + "iopub.status.idle": "2026-08-11T18:57:47.907033Z", + "shell.execute_reply": "2026-08-11T18:57:47.905460Z" + } + }, + "outputs": [], + "source": [ + "panel_keys = (\n", + " history_df[[\"tokenizer\", \"vocab_size\"]]\n", + " .drop_duplicates()\n", + " .sort_values([\"tokenizer\", \"vocab_size\"], na_position=\"first\")\n", + " .to_records(index=False)\n", + ")\n", + "\n", + "n = len(panel_keys)\n", + "ncols = min(4, n)\n", + "nrows = int(np.ceil(n / ncols))\n", + "fig, axes = plt.subplots(nrows, ncols, figsize=(4 * ncols, 3 * nrows), squeeze=False)\n", + "\n", + "for ax, (tokenizer, vocab_size) in zip(axes.flat, panel_keys):\n", + " subset = history_df[(history_df[\"tokenizer\"] == tokenizer) & (history_df[\"vocab_size\"] == vocab_size)]\n", + " for run_label in RUNS:\n", + " run_data = subset[subset[\"run_label\"] == run_label].sort_values(\"epoch\")\n", + " if run_data.empty:\n", + " continue\n", + " ax.plot(run_data[\"epoch\"], run_data[\"val_loss\"], label=run_label, color=RUN_COLORS[run_label], linewidth=1.2)\n", + " title = \"char\" if tokenizer == \"char\" else f\"wordpiece {int(vocab_size)}\"\n", + " ax.set_title(title, fontsize=9)\n", + " ax.set_xlabel(\"epoch\")\n", + " ax.set_ylabel(\"val_loss\")\n", + "\n", + "for ax in axes.flat[n:]:\n", + " ax.axis(\"off\")\n", + "\n", + "axes.flat[0].legend(fontsize=6)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8ffa303c", + "metadata": {}, + "source": [ + "*Notes: legend is only drawn once (top-left panel) to keep every other panel\n", + "uncluttered - the color mapping is the same across all panels (see the parameters\n", + "cell: `RUN_COLORS`).*" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file From 603ea761f7439a2faffe314525c5ac67def28357 Mon Sep 17 00:00:00 2001 From: Consoooomer Date: Thu, 13 Aug 2026 19:55:39 +0300 Subject: [PATCH 63/70] Add reconstruction result CSVs --- results/reconstruction/reconstruction_runs.csv | 16 ++++++++++++++++ .../reconstruction/reconstruction_summary.csv | 6 ++++++ results/reconstruction/reconstruction_summary.md | 9 +++++++++ 3 files changed, 31 insertions(+) create mode 100644 results/reconstruction/reconstruction_runs.csv create mode 100644 results/reconstruction/reconstruction_summary.csv create mode 100644 results/reconstruction/reconstruction_summary.md diff --git a/results/reconstruction/reconstruction_runs.csv b/results/reconstruction/reconstruction_runs.csv new file mode 100644 index 0000000..61092dc --- /dev/null +++ b/results/reconstruction/reconstruction_runs.csv @@ -0,0 +1,16 @@ +representation,seed,bottleneck_dim,train_subset,train_size,epochs_ran,best_epoch,best_val_loss,training_seconds,test_loss,exact_match,token_accuracy,normalized_levenshtein,within_edit_distance_1,mean_edit_distance,inference_seq_per_second,inference_ms_per_sequence,device +esm2_8m,42,64,all,79730,36,28,0.0733299881984026,1449.82,0.072866829064412,0.6525534263068125,0.9325163975146336,0.0563025242603035,0.7704424601183907,0.855824219925755,6925.270491542189,0.14439869189532695,cuda +esm2_8m,43,64,all,79730,35,27,0.07321660067790593,1481.52,0.07167374705656981,0.6505468044547005,0.9328907864327216,0.05586594799605164,0.7669308718771948,0.845590448479984,6302.629250780989,0.15866394169958278,cuda +esm2_8m,44,64,all,79730,34,26,0.07201942428946495,1374.37,0.07244877650951728,0.6499448178990669,0.9323724017769074,0.05579528646580723,0.7703421290257851,0.8460921039430119,6931.001781474648,0.14427928768866063,cuda +onehot,42,64,all,79730,46,38,0.015626185442297123,1947.5,0.01686641280181133,0.9147185712852413,0.988012354834297,0.01044870014041422,0.9650847797732517,0.16925855322564462,6740.392889160309,0.14835930433790723,cuda +onehot,43,64,all,79730,44,36,0.015526399291001068,1773.28,0.0167713965026614,0.9147185712852413,0.9878251603752529,0.01055498694685954,0.9642821310324069,0.171666499448179,6959.059296335155,0.143697582879719,cuda +onehot,44,64,all,79730,39,31,0.01566104817753419,1654.49,0.016842290782966673,0.9137152603591853,0.9875299691129142,0.010679486103341483,0.9635798133841678,0.17397411457810777,6721.714112326583,0.14877157571550906,cuda +sceptr,42,64,all,79730,34,26,0.015631044331269387,1438.6,0.016878187322081663,0.9052874485803151,0.9872923761456661,0.010762903291556672,0.9606702116986054,0.1700612019664894,6681.0765368225,0.14967647720970384,cuda +sceptr,43,64,all,79730,25,17,0.015448446170641826,1005.99,0.01793186505062458,0.8911407645229257,0.9852404368830683,0.012352635473980028,0.9537473663088191,0.19353867763619945,6942.691494033216,0.1440363583574805,cuda +sceptr,44,64,all,79730,36,28,0.014794133317012053,1520.72,0.016622064921718378,0.9049864553024982,0.9872923761456661,0.01057906079226048,0.9614728604394502,0.16584729607705428,6718.565058588532,0.14884130633246928,cuda +tcr_bert,42,64,all,79730,29,21,0.04164245581397644,1170.33,0.040557941994988,0.7707434533962075,0.9647642429784078,0.02883887644221048,0.8893348048560249,0.4475770041135748,6948.343259792289,0.14391919952870805,cuda +tcr_bert,43,64,all,79730,26,18,0.041497998273907565,1101.03,0.04137205002972713,0.7640212701916324,0.9634538817650997,0.030204758605446042,0.8806059997993378,0.4672418982642721,6700.394915657967,0.14924493445350925,cuda +tcr_bert,44,64,all,79730,31,23,0.041648901043794095,1249.9,0.04166440746914118,0.7751580214708538,0.9649730367981108,0.028198279038403613,0.8936490418380656,0.4376442259456205,6943.732958313603,0.14401475488810647,cuda +tcremp,42,64,all,79730,39,31,0.0247877309910762,1566.19,0.025743332906411245,0.7975318551219023,0.9779254534065792,0.020130054818765956,0.9388983646031905,0.3027992374836962,7139.259510791705,0.14007054912185218,cuda +tcremp,43,64,all,79730,46,38,0.024846020345695507,1927.35,0.025916891745649852,0.8049563559747166,0.9786814310296416,0.01929511392118879,0.942008628473964,0.2894552021671516,6815.03971278562,0.14673428800772959,cuda +tcremp,44,64,all,79730,47,39,0.024844986697038014,1893.08,0.026344755951028604,0.8025484097521822,0.9785662344394606,0.019611650793997584,0.9408046553626969,0.29266579713053076,6948.998411166585,0.14390563083063387,cuda diff --git a/results/reconstruction/reconstruction_summary.csv b/results/reconstruction/reconstruction_summary.csv new file mode 100644 index 0000000..3e1d5dc --- /dev/null +++ b/results/reconstruction/reconstruction_summary.csv @@ -0,0 +1,6 @@ +representation,seeds,exact_match_mean,exact_match_std,token_accuracy_mean,token_accuracy_std,normalized_levenshtein_mean,normalized_levenshtein_std,within_edit_distance_1_mean,within_edit_distance_1_std,mean_edit_distance_mean,mean_edit_distance_std,training_seconds_mean,epochs_mean,inference_seq_per_second_mean,source_dim,explained_variance +onehot,3,0.9143841343098892,0.000579261833239334,0.9877891614408214,0.00024319938015680297,0.01056105773020508,0.00011551268752343819,0.9643155747299422,0.0007530403832110864,0.1716330557506438,0.002357958561529363,1791.756666666667,43.0,6807.05543260735,1000,0.379862 +sceptr,3,0.9004715561352463,0.008082103892102458,0.9866083963914668,0.0011846876856216142,0.011231533185932395,0.0009752447238186415,0.9586301461489583,0.004247612915008504,0.17648239189324774,0.014920687424517944,1321.77,31.666666666666668,6780.777696481416,64,1.0 +tcremp,3,0.8016788736162671,0.003787858636103861,0.9783910396252272,0.00040730266245565675,0.019678939844650776,0.00042151801606229864,0.9405705494799506,0.001568291908323191,0.29497341226045953,0.006964885880127865,1795.54,44.0,6967.76587824797,9000,0.949757 +tcr_bert,3,0.7699742483528978,0.005608080292114219,0.9643970538472061,0.0008234554615370438,0.02908063802868671,0.00102485441003165,0.8878632821644761,0.006644867995664911,0.45082104277448914,0.015063146809206184,1173.7533333333333,28.666666666666668,6864.157044587952,768,0.910277 +esm2_8m,3,0.6510150162201933,0.0013658792586644186,0.9325931952414209,0.0002675893887576123,0.05598791957405413,0.0002747368639656366,0.7692384870071235,0.00199908285794834,0.8491689241162503,0.005769110528054075,1435.2366666666667,35.0,6719.6338412659425,320,0.974346 diff --git a/results/reconstruction/reconstruction_summary.md b/results/reconstruction/reconstruction_summary.md new file mode 100644 index 0000000..c492a6e --- /dev/null +++ b/results/reconstruction/reconstruction_summary.md @@ -0,0 +1,9 @@ +### Reconstruction at a 64-dimensional bottleneck + +| representation | source dim | expl. var | exact match | token acc | norm. Levenshtein | within ED 1 | train s | seq/s | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| onehot | 1000 | 0.380 | 0.9144 ± 0.0006 | 0.9878 ± 0.0002 | 0.0106 ± 0.0001 | 0.9643 ± 0.0008 | 1792 | 6807 | +| sceptr | 64 | 1.000 | 0.9005 ± 0.0081 | 0.9866 ± 0.0012 | 0.0112 ± 0.0010 | 0.9586 ± 0.0042 | 1322 | 6781 | +| tcremp | 9000 | 0.950 | 0.8017 ± 0.0038 | 0.9784 ± 0.0004 | 0.0197 ± 0.0004 | 0.9406 ± 0.0016 | 1796 | 6968 | +| tcr_bert | 768 | 0.910 | 0.7700 ± 0.0056 | 0.9644 ± 0.0008 | 0.0291 ± 0.0010 | 0.8879 ± 0.0066 | 1174 | 6864 | +| esm2_8m | 320 | 0.974 | 0.6510 ± 0.0014 | 0.9326 ± 0.0003 | 0.0560 ± 0.0003 | 0.7692 ± 0.0020 | 1435 | 6720 | From 9abb43c99de96108e178b8bbb5a0ed5d5cf414c6 Mon Sep 17 00:00:00 2001 From: Elizaveta Vlasova Date: Fri, 14 Aug 2026 22:56:19 +0300 Subject: [PATCH 64/70] Add multitask tokenizer and evaluation pipeline --- benchmark/__init__.py | 1 + benchmark/evaluate_vdjdb_frozen.py | 490 +++++++++++++ benchmark/evaluate_vdjdb_ylq_frozen.py | 310 ++++++++ benchmark/evaluate_vdjdb_ylq_motif_pooled.py | 388 ++++++++++ benchmark/prepare_trb_joint.py | 648 +++++++++++++++++ benchmark/prepare_vdjdb_epitope_cohort.py | 420 +++++++++++ benchmark/prepare_vdjdb_ylq.py | 216 ++++++ benchmark/prepare_vdjdb_ylq_motif_pooled.py | 458 ++++++++++++ docs/anchored_tokenizer_study.md | 70 ++ docs/vdjdb_epitope_validation.md | 59 ++ irrm_codec/anchored_tokenization.py | 186 +++++ irrm_codec/multitask_data.py | 368 ++++++++++ irrm_codec/multitask_losses.py | 101 +++ irrm_codec/multitask_metrics.py | 230 ++++++ irrm_codec/multitask_transformer.py | 318 ++++++++ irrm_codec/tokenization.py | 22 +- irrm_codec/train_multitask.py | 685 ++++++++++++++++++ irrm_codec/wordpiece_tokenization.py | 69 ++ requirements.txt | 1 + scripts/preflight_anchored_tokenizers.py | 203 ++++++ scripts/preflight_data_anchor_objectives.py | 221 ++++++ scripts/preflight_phase1_rq1.py | 132 ++++ scripts/preflight_rq5_depths.py | 164 +++++ scripts/preflight_rq5_widths.py | 140 ++++ scripts/preflight_vdjdb_evaluation.py | 80 ++ scripts/preflight_wordpiece_rq4.py | 140 ++++ scripts/preflight_wordpiece_sweep.py | 189 +++++ scripts/prepare_anchored_tokenizers.py | 553 ++++++++++++++ scripts/prepare_wordpiece_rq4.py | 177 +++++ scripts/prepare_wordpiece_sweep.py | 354 +++++++++ slurm/evaluate_vdjdb_frozen.sbatch | 34 + slurm/evaluate_vdjdb_ylq_frozen.sbatch | 25 + slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch | 25 + slurm/install_wordpiece_dependency.sbatch | 14 + slurm/preflight_data_anchor_objectives.sbatch | 30 + slurm/preflight_phase1_rq1.sbatch | 19 + slurm/preflight_rq5_depths.sbatch | 21 + slurm/preflight_rq5_widths.sbatch | 19 + slurm/preflight_vdjdb_epitope.sbatch | 38 + slurm/preflight_vdjdb_evaluation.sbatch | 25 + slurm/prepare_anchored_tokenizers.sbatch | 35 + slurm/prepare_trb_joint.sbatch | 29 + slurm/prepare_vdjdb_ylq.sbatch | 20 + slurm/prepare_vdjdb_ylq_motif_pooled.sbatch | 24 + slurm/prepare_wordpiece_rq4.sbatch | 29 + slurm/prepare_wordpiece_sweep.sbatch | 30 + slurm/train_anchored_tokenizer.sbatch | 56 ++ slurm/train_data_anchor_objective.sbatch | 57 ++ slurm/train_phase1_rq1_char.sbatch | 82 +++ slurm/train_phase2_rq23_char.sbatch | 82 +++ slurm/train_rq4_wordpiece.sbatch | 84 +++ slurm/train_rq5_depth.sbatch | 46 ++ slurm/train_rq5_width.sbatch | 46 ++ slurm/train_wordpiece_sweep.sbatch | 52 ++ tests/test_anchored_tokenization.py | 90 +++ tests/test_multitask_baselines.py | 191 +++++ tests/test_prepare_trb_joint.py | 104 +++ tests/test_vdjdb_cohort.py | 54 ++ tests/test_vdjdb_ylq.py | 45 ++ tests/test_vdjdb_ylq_motif_pooled.py | 129 ++++ tests/test_wordpiece_sweep.py | 71 ++ 61 files changed, 8998 insertions(+), 1 deletion(-) create mode 100644 benchmark/__init__.py create mode 100644 benchmark/evaluate_vdjdb_frozen.py create mode 100644 benchmark/evaluate_vdjdb_ylq_frozen.py create mode 100644 benchmark/evaluate_vdjdb_ylq_motif_pooled.py create mode 100644 benchmark/prepare_trb_joint.py create mode 100644 benchmark/prepare_vdjdb_epitope_cohort.py create mode 100644 benchmark/prepare_vdjdb_ylq.py create mode 100644 benchmark/prepare_vdjdb_ylq_motif_pooled.py create mode 100644 docs/anchored_tokenizer_study.md create mode 100644 docs/vdjdb_epitope_validation.md create mode 100644 irrm_codec/anchored_tokenization.py create mode 100644 irrm_codec/multitask_data.py create mode 100644 irrm_codec/multitask_losses.py create mode 100644 irrm_codec/multitask_metrics.py create mode 100644 irrm_codec/multitask_transformer.py create mode 100644 irrm_codec/train_multitask.py create mode 100644 irrm_codec/wordpiece_tokenization.py create mode 100644 scripts/preflight_anchored_tokenizers.py create mode 100644 scripts/preflight_data_anchor_objectives.py create mode 100644 scripts/preflight_phase1_rq1.py create mode 100644 scripts/preflight_rq5_depths.py create mode 100644 scripts/preflight_rq5_widths.py create mode 100644 scripts/preflight_vdjdb_evaluation.py create mode 100644 scripts/preflight_wordpiece_rq4.py create mode 100644 scripts/preflight_wordpiece_sweep.py create mode 100644 scripts/prepare_anchored_tokenizers.py create mode 100644 scripts/prepare_wordpiece_rq4.py create mode 100644 scripts/prepare_wordpiece_sweep.py create mode 100644 slurm/evaluate_vdjdb_frozen.sbatch create mode 100644 slurm/evaluate_vdjdb_ylq_frozen.sbatch create mode 100644 slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch create mode 100644 slurm/install_wordpiece_dependency.sbatch create mode 100644 slurm/preflight_data_anchor_objectives.sbatch create mode 100644 slurm/preflight_phase1_rq1.sbatch create mode 100644 slurm/preflight_rq5_depths.sbatch create mode 100644 slurm/preflight_rq5_widths.sbatch create mode 100644 slurm/preflight_vdjdb_epitope.sbatch create mode 100644 slurm/preflight_vdjdb_evaluation.sbatch create mode 100644 slurm/prepare_anchored_tokenizers.sbatch create mode 100644 slurm/prepare_trb_joint.sbatch create mode 100644 slurm/prepare_vdjdb_ylq.sbatch create mode 100644 slurm/prepare_vdjdb_ylq_motif_pooled.sbatch create mode 100644 slurm/prepare_wordpiece_rq4.sbatch create mode 100644 slurm/prepare_wordpiece_sweep.sbatch create mode 100644 slurm/train_anchored_tokenizer.sbatch create mode 100644 slurm/train_data_anchor_objective.sbatch create mode 100644 slurm/train_phase1_rq1_char.sbatch create mode 100644 slurm/train_phase2_rq23_char.sbatch create mode 100644 slurm/train_rq4_wordpiece.sbatch create mode 100644 slurm/train_rq5_depth.sbatch create mode 100644 slurm/train_rq5_width.sbatch create mode 100644 slurm/train_wordpiece_sweep.sbatch create mode 100644 tests/test_anchored_tokenization.py create mode 100644 tests/test_multitask_baselines.py create mode 100644 tests/test_prepare_trb_joint.py create mode 100644 tests/test_vdjdb_cohort.py create mode 100644 tests/test_vdjdb_ylq.py create mode 100644 tests/test_vdjdb_ylq_motif_pooled.py create mode 100644 tests/test_wordpiece_sweep.py diff --git a/benchmark/__init__.py b/benchmark/__init__.py new file mode 100644 index 0000000..69b6918 --- /dev/null +++ b/benchmark/__init__.py @@ -0,0 +1 @@ +"""Dataset preparation utilities for reproducible IRRM-CODEC benchmarks.""" diff --git a/benchmark/evaluate_vdjdb_frozen.py b/benchmark/evaluate_vdjdb_frozen.py new file mode 100644 index 0000000..fe2cbd0 --- /dev/null +++ b/benchmark/evaluate_vdjdb_frozen.py @@ -0,0 +1,490 @@ +"""Evaluate matched frozen IRRM-CODEC encoders on a locked VDJdb cohort.""" + +from __future__ import annotations + +import argparse +import csv +import hashlib +import json +import math +import os +from collections import defaultdict +from dataclasses import asdict +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +from sklearn.metrics import average_precision_score, roc_auc_score + +from irrm_codec.multitask_data import resolve_encoder_tokenizer +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import PAD_ID + + +AA = "ACDEFGHIKLMNPQRSTVWY" + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--cohort-preflight", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True, + help="NAME:CHECKPOINT:RUN_CONFIG; repeat for r,p,rp,rtp") + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--max-pairs-per-label", type=int, default=2000) + parser.add_argument("--bootstrap", type=int, default=2000) + parser.add_argument("--permutations", type=int, default=1000) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def stable_json(path: Path, value: object) -> None: + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def parse_models(values: list[str]) -> dict[str, tuple[Path, Path]]: + result = {} + for value in values: + fields = value.split(":", 2) + if len(fields) != 3: + raise ValueError(f"Invalid --model value: {value!r}") + name, checkpoint, config = fields + if name in result: + raise ValueError(f"Duplicate model name: {name}") + result[name] = (Path(checkpoint), Path(config)) + if set(result) != {"r", "p", "rp", "rtp"}: + raise ValueError("Exact required model names are r, p, rp, and rtp.") + return result + + +def validate_run_configs(models: dict[str, tuple[Path, Path]]) -> tuple[IRRMCodecConfig, dict]: + expected_weights = { + "r": (1.0, 0.0, 0.0), + "p": (0.0, 0.0, 1.0), + "rp": (1.0, 0.0, 1.0), + "rtp": (1.0, 1.0, 1.0), + } + configs = {name: json.loads(path.read_text(encoding="utf-8")) for name, (_, path) in models.items()} + reference = configs["rtp"] + ignored = {"output_dir", "reconstruction_loss_weight", "tcremp_loss_weight", "pgen_loss_weight"} + ref_training = {key: value for key, value in reference["training"].items() if key not in ignored} + report = {} + for name, payload in configs.items(): + if payload["model"] != reference["model"]: + raise ValueError(f"{name} architecture differs from full DATA-ANCHOR reference.") + comparable = {key: value for key, value in payload["training"].items() if key not in ignored} + if comparable != ref_training: + differing = sorted(key for key in set(comparable) | set(ref_training) + if comparable.get(key) != ref_training.get(key)) + raise ValueError(f"{name} has non-weight training differences: {differing}") + weights = ( + float(payload["training"]["reconstruction_loss_weight"]), + float(payload["training"]["tcremp_loss_weight"]), + float(payload["training"]["pgen_loss_weight"]), + ) + if weights != expected_weights[name]: + raise ValueError(f"{name} has weights {weights}, expected {expected_weights[name]}") + report[name] = { + "checkpoint": str(models[name][0]), + "checkpoint_sha256": sha256(models[name][0]), + "run_config": str(models[name][1]), + "run_config_sha256": sha256(models[name][1]), + "loss_weights_reconstruction_tcremp_pgen": list(weights), + "parameter_count": payload["parameter_count"], + } + return IRRMCodecConfig(**reference["model"]), report + + +def extract_embeddings( + cohort: pd.DataFrame, + models: dict[str, tuple[Path, Path]], + model_config: IRRMCodecConfig, + tokenizer_path: Path, + batch_size: int, + output: Path, +) -> tuple[dict[str, np.ndarray], dict]: + tokenizer = resolve_encoder_tokenizer("data_anchor", str(tokenizer_path)) + if tokenizer.vocab_size != model_config.input_vocab_size: + raise ValueError("Tokenizer vocabulary differs from matched checkpoint architecture.") + encoded = [tokenizer.encode(sequence, model_config.max_sequence_len) + for sequence in cohort["cdr3"].astype(str)] + results = {} + metadata = {} + for name, (checkpoint_path, _) in models.items(): + checkpoint = torch.load(checkpoint_path, map_location="cpu", weights_only=False) + if checkpoint["model_config"] != asdict(model_config): + raise ValueError(f"{name} checkpoint model_config differs from run_config.") + model = IRRMCodecTransformer(model_config) + model.load_state_dict(checkpoint["model_state"], strict=True) + model.eval() + batches = [] + with torch.no_grad(): + for start in range(0, len(encoded), batch_size): + rows = encoded[start:start + batch_size] + width = max(map(len, rows)) + tokens = torch.full((len(rows), width), PAD_ID, dtype=torch.long) + for index, ids in enumerate(rows): + tokens[index, :len(ids)] = torch.tensor(ids, dtype=torch.long) + batches.append(model.encode(tokens, tokens.ne(PAD_ID)).numpy().astype(np.float32)) + array = np.concatenate(batches) + if array.shape != (len(cohort), model_config.latent_dim) or not np.isfinite(array).all(): + raise ValueError(f"{name} emitted invalid latent array {array.shape}.") + path = output / f"embeddings_{name}.npy" + np.save(path, array, allow_pickle=False) + results[name] = array + metadata[name] = { + "best_epoch_one_based": int(checkpoint["epoch"]), + "best_validation_loss": float(checkpoint["best_val_loss"]), + "shape": list(array.shape), + "finite": True, + "sha256": sha256(path), + } + del checkpoint, model + return results, metadata + + +def distance_matrix(array: np.ndarray, metric: str) -> np.ndarray: + x = array.astype(np.float64) + if metric == "cosine": + norms = np.linalg.norm(x, axis=1, keepdims=True) + if np.any(norms == 0): + raise ValueError("Zero-norm latent prevents cosine distance.") + unit = x / norms + return np.maximum(0.0, 1.0 - unit @ unit.T) + squared = np.sum(x * x, axis=1, keepdims=True) + return np.sqrt(np.maximum(0.0, squared + squared.T - 2.0 * (x @ x.T))) + + +def build_pair_manifest(cohort: pd.DataFrame, limit: int, seed: int) -> pd.DataFrame: + labels = cohort["label"].astype(str).to_numpy() + donors = cohort["donor_key"].astype(str).to_numpy() + lengths = cohort["length"].to_numpy(dtype=int) + by_label = {label: np.flatnonzero(labels == label) for label in sorted(set(labels))} + by_length = {length: np.flatnonzero(lengths == length) for length in sorted(set(lengths))} + rows = [] + for label_index, (label, indices) in enumerate(by_label.items()): + positives = [(int(indices[i]), int(indices[j])) for i in range(len(indices)) + for j in range(i + 1, len(indices)) if donors[indices[i]] != donors[indices[j]]] + rng = np.random.default_rng(seed + label_index) + if len(positives) > limit: + chosen = rng.choice(len(positives), size=limit, replace=False) + positives = [positives[index] for index in sorted(chosen)] + for pair_index, (query, positive) in enumerate(positives): + if rng.integers(2): + query, positive = positive, query + candidates = by_length.get(int(lengths[positive]), np.empty(0, dtype=int)) + candidates = candidates[(labels[candidates] != label) & (donors[candidates] != donors[query])] + match_type = "exact_length" + if len(candidates) == 0: + allowed = np.flatnonzero((labels != label) & (donors != donors[query])) + difference = np.abs(lengths[allowed] - lengths[positive]) + candidates = allowed[difference == difference.min()] + match_type = "nearest_length" + negative = int(candidates[rng.integers(len(candidates))]) + rows.append({ + "label": label, "query_index": query, "positive_index": positive, + "negative_index": negative, "query_donor": donors[query], + "positive_donor": donors[positive], "negative_donor": donors[negative], + "query_length": int(lengths[query]), "positive_length": int(lengths[positive]), + "negative_length": int(lengths[negative]), "match_type": match_type, + "pair_index_within_label": pair_index, + }) + result = pd.DataFrame(rows) + if result.empty or (result["query_donor"] == result["positive_donor"]).any(): + raise ValueError("Could not construct donor-disjoint positive pairs.") + return result + + +def pair_metrics(matrix: np.ndarray, pairs: pd.DataFrame) -> tuple[dict, pd.DataFrame]: + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + within = matrix[q, p] + between = matrix[q, n] + truth = np.concatenate((np.ones(len(within), dtype=int), np.zeros(len(between), dtype=int))) + score = -np.concatenate((within, between)) + per_label = [] + label_values = pairs["label"].astype(str).to_numpy() + for label in sorted(set(label_values)): + mask = label_values == label + pooled = math.sqrt((float(within[mask].var()) + float(between[mask].var())) / 2.0) + per_label.append({ + "label": label, + "pairs": int(mask.sum()), + "within_mean": float(within[mask].mean()), + "between_mean": float(between[mask].mean()), + "within_between_ratio": float(within[mask].mean() / between[mask].mean()), + "standardized_separation": float((between[mask].mean() - within[mask].mean()) / pooled) + if pooled > 0 else float("nan"), + }) + table = pd.DataFrame(per_label) + return { + "pairs_per_class": len(within), + "same_label_auroc": float(roc_auc_score(truth, score)), + "same_label_auprc_balanced": float(average_precision_score(truth, score)), + "macro_within_between_ratio": float(table["within_between_ratio"].mean()), + "macro_standardized_separation": float(table["standardized_separation"].mean()), + "within_expected_lower_fraction": float((table["within_mean"] < table["between_mean"]).mean()), + }, table + + +def retrieval_metrics(matrix: np.ndarray, cohort: pd.DataFrame) -> tuple[dict, pd.DataFrame]: + labels = cohort["label"].astype(str).to_numpy() + donors = cohort["donor_key"].astype(str).to_numpy() + rows = [] + for query in range(len(cohort)): + allowed = np.flatnonzero((donors != donors[query]) & (np.arange(len(cohort)) != query)) + relevant = labels[allowed] == labels[query] + total_relevant = int(relevant.sum()) + if total_relevant == 0: + continue + order = np.argsort(matrix[query, allowed], kind="mergesort") + ranked = relevant[order] + values = {"query_index": query, "label": labels[query], "query_donor": donors[query], + "relevant_donor_excluded": total_relevant} + for k in (1, 5, 10): + values[f"precision_at_{k}"] = float(ranked[:k].sum() / k) + r = total_relevant + hits = ranked[:r].astype(float) + precision = np.cumsum(hits) / np.arange(1, r + 1) + values["ap_at_r"] = float((precision * hits).sum() / r) + rows.append(values) + table = pd.DataFrame(rows) + return { + "eligible_queries": len(table), + "precision_at_1": float(table["precision_at_1"].mean()), + "precision_at_5": float(table["precision_at_5"].mean()), + "precision_at_10": float(table["precision_at_10"].mean()), + "map_at_r": float(table["ap_at_r"].mean()), + }, table + + +def bootstrap_primary( + matrices: dict[str, np.ndarray], pairs: pd.DataFrame, + retrieval: dict[str, pd.DataFrame], replicates: int, seed: int, +) -> dict: + donors = sorted( + set(pairs["query_donor"].astype(str)).union( + *(set(table["query_donor"].astype(str)) for table in retrieval.values()) + ) + ) + donor_index = {donor: index for index, donor in enumerate(donors)} + pair_donor = pairs["query_donor"].map(donor_index).to_numpy(int) + labels = sorted(set(pairs["label"].astype(str))) + label_index = {label: index for index, label in enumerate(labels)} + pair_label = pairs["label"].map(label_index).to_numpy(int) + rng = np.random.default_rng(seed) + weights = rng.multinomial(len(donors), np.full(len(donors), 1 / len(donors)), size=replicates) + model_boot = {} + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + for name, matrix in matrices.items(): + within = matrix[q, p] + between = matrix[q, n] + donor_label_within = np.zeros((len(donors), len(labels))) + donor_label_between = np.zeros_like(donor_label_within) + donor_label_count = np.zeros_like(donor_label_within) + np.add.at(donor_label_within, (pair_donor, pair_label), within) + np.add.at(donor_label_between, (pair_donor, pair_label), between) + np.add.at(donor_label_count, (pair_donor, pair_label), 1) + summed_within = weights @ donor_label_within + summed_between = weights @ donor_label_between + counts = weights @ donor_label_count + mean_within = np.full_like(summed_within, np.nan) + mean_between = np.full_like(summed_between, np.nan) + np.divide(summed_within, counts, out=mean_within, where=counts > 0) + np.divide(summed_between, counts, out=mean_between, where=counts > 0) + ratios = np.full_like(mean_within, np.nan) + np.divide(mean_within, mean_between, out=ratios, where=mean_between > 0) + macro_ratio = np.nanmean(ratios, axis=1) + + query_table = retrieval[name] + query_donor_index = query_table["query_donor"].map(donor_index).to_numpy(int) + donor_ap_sum = np.zeros(len(donors)) + donor_query_count = np.zeros(len(donors)) + np.add.at(donor_ap_sum, query_donor_index, query_table["ap_at_r"].to_numpy(float)) + np.add.at(donor_query_count, query_donor_index, 1) + boot_map = (weights @ donor_ap_sum) / np.maximum(weights @ donor_query_count, 1) + model_boot[name] = {"macro_ratio": macro_ratio, "map_at_r": boot_map} + + def summarize(values: np.ndarray) -> dict: + return {"ci95": [float(np.nanpercentile(values, 2.5)), float(np.nanpercentile(values, 97.5))]} + + report = {"replicates": replicates, "cluster": "query donor", "models": {}} + for name, values in model_boot.items(): + report["models"][name] = { + "macro_within_between_ratio": summarize(values["macro_ratio"]), + "map_at_r": summarize(values["map_at_r"]), + } + report["paired_differences_rtp_minus_other"] = {} + for other in ("r", "p", "rp"): + report["paired_differences_rtp_minus_other"][other] = { + "macro_ratio_lower_is_better": summarize( + model_boot["rtp"]["macro_ratio"] - model_boot[other]["macro_ratio"] + ), + "map_at_r_higher_is_better": summarize( + model_boot["rtp"]["map_at_r"] - model_boot[other]["map_at_r"] + ), + } + return report + + +def assert_finite_tree(value: object, path: str = "root") -> None: + if isinstance(value, dict): + for key, child in value.items(): + assert_finite_tree(child, f"{path}.{key}") + elif isinstance(value, list): + for index, child in enumerate(value): + assert_finite_tree(child, f"{path}[{index}]") + elif isinstance(value, (float, np.floating)) and not math.isfinite(float(value)): + raise FloatingPointError(f"Non-finite result at {path}: {value}") + + +def controls( + cohort: pd.DataFrame, pairs: pd.DataFrame, matrices: dict[str, np.ndarray], + permutations: int, seed: int, +) -> dict: + lengths = cohort["length"].to_numpy(float) + length_matrix = np.abs(lengths[:, None] - lengths[None, :]) + length_metrics, _ = pair_metrics(length_matrix, pairs) + composition = np.zeros((len(cohort), len(AA)), dtype=float) + for index, sequence in enumerate(cohort["cdr3"].astype(str)): + for aa_index, aa in enumerate(AA): + composition[index, aa_index] = sequence.count(aa) / len(sequence) + composition_metrics = {} + for metric in ("cosine", "euclidean"): + value, _ = pair_metrics(distance_matrix(composition, metric), pairs) + composition_metrics[metric] = value + + rng = np.random.default_rng(seed + 10000) + all_i, all_j = np.triu_indices(len(cohort), k=1) + donor = cohort["donor_key"].astype(str).to_numpy() + same_length = lengths[all_i] == lengths[all_j] + donor_disjoint = donor[all_i] != donor[all_j] + eligible = np.flatnonzero(same_length & donor_disjoint) + if len(eligible) > 100000: + eligible = rng.choice(eligible, size=100000, replace=False) + pair_i, pair_j = all_i[eligible], all_j[eligible] + labels = cohort["label"].astype(str).to_numpy() + actual_same = labels[pair_i] == labels[pair_j] + model_distance = {name: matrix[pair_i, pair_j] for name, matrix in matrices.items()} + actual = { + name: float(distance[~actual_same].mean() - distance[actual_same].mean()) + for name, distance in model_distance.items() + } + null = {name: np.empty(permutations, dtype=float) for name in matrices} + groups = [np.flatnonzero(lengths == value) for value in sorted(set(lengths))] + for replicate in range(permutations): + shuffled = labels.copy() + for group in groups: + shuffled[group] = rng.permutation(shuffled[group]) + same = shuffled[pair_i] == shuffled[pair_j] + for name, distance in model_distance.items(): + null[name][replicate] = float(distance[~same].mean() - distance[same].mean()) + return { + "length_only_on_primary_pairs": length_metrics, + "amino_acid_composition": composition_metrics, + "shuffled_label_null": { + "pairs": len(pair_i), "permutations": permutations, + "permutation_strata": "exact CDR3 length", + "models": { + name: { + "observed_between_minus_within": actual[name], + "null_ci95": [float(np.percentile(null[name], 2.5)), float(np.percentile(null[name], 97.5))], + "one_sided_p": float((1 + np.sum(null[name] >= actual[name])) / (permutations + 1)), + } for name in matrices + }, + }, + } + + +def main() -> None: + args = parse_args() + models = parse_models(args.model) + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + preflight = json.loads(args.cohort_preflight.read_text(encoding="utf-8")) + if preflight["status"] != "ready_for_cohort_review_not_embedding_extraction": + raise ValueError("Cohort preflight status is not accepting.") + if sha256(args.cohort) != preflight["cohort"]["cohort_sha256"]: + raise ValueError("Cohort hash differs from accepted CPU preflight.") + cohort = pd.read_csv(args.cohort, sep="\t") + if cohort["cdr3"].duplicated().any() or len(cohort) != preflight["cohort"]["unique_cdr3"]: + raise ValueError("Cohort is not the expected unique-clonotype table.") + + config, model_report = validate_run_configs(models) + embeddings, extraction = extract_embeddings( + cohort, models, config, args.tokenizer, args.batch_size, args.output_dir + ) + pairs = build_pair_manifest(cohort, args.max_pairs_per_label, args.seed) + pairs.to_csv(args.output_dir / "pair_manifest.tsv", sep="\t", index=False) + matrices_by_metric = {} + metrics = {} + retrieval_tables = {} + per_label_tables = [] + for metric in ("cosine", "euclidean"): + matrices = {name: distance_matrix(array, metric) for name, array in embeddings.items()} + matrices_by_metric[metric] = matrices + metrics[metric] = {} + retrieval_tables[metric] = {} + for name, matrix in matrices.items(): + pair_value, per_label = pair_metrics(matrix, pairs) + retrieval_value, per_query = retrieval_metrics(matrix, cohort) + metrics[metric][name] = {"pairwise_and_contrast": pair_value, "retrieval": retrieval_value} + retrieval_tables[metric][name] = per_query + per_label.insert(0, "model", name) + per_label.insert(0, "distance", metric) + per_label_tables.append(per_label) + per_query.to_csv(args.output_dir / f"retrieval_queries_{metric}_{name}.tsv", sep="\t", index=False) + stable_json( + args.output_dir / f"bootstrap_{metric}.json", + bootstrap_primary(matrices, pairs, retrieval_tables[metric], args.bootstrap, args.seed), + ) + pd.concat(per_label_tables, ignore_index=True).to_csv( + args.output_dir / "per_label_metrics.tsv", sep="\t", index=False + ) + control_report = controls( + cohort, pairs, matrices_by_metric["cosine"], args.permutations, args.seed + ) + assert_finite_tree(metrics, "metrics") + assert_finite_tree(control_report, "controls") + stable_json(args.output_dir / "metrics.json", metrics) + stable_json(args.output_dir / "controls.json", control_report) + + artifact_hashes = { + path.name: sha256(path) for path in sorted(args.output_dir.iterdir()) if path.is_file() + } + manifest = { + "status": "complete", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "study": "matched DATA-ANCHOR frozen-encoder VDJdb epitope separation", + "cohort": {"path": str(args.cohort), "sha256": sha256(args.cohort), "rows": len(cohort), + "labels": int(cohort["label"].nunique()), "donors": int(cohort["donor_key"].nunique())}, + "models": model_report, + "extraction": extraction, + "pairs": {"rows": len(pairs), "sha256": sha256(args.output_dir / "pair_manifest.tsv"), + "nearest_length_fallbacks": int((pairs["match_type"] != "exact_length").sum())}, + "selection_statement": "No checkpoint or model was selected using VDJdb outcomes; all are reported.", + "inactive_head_statement": "Only frozen encoder latents are evaluated; inactive-head predictions are ignored.", + "artifact_sha256": artifact_hashes, + "nonfinite_scan": "passed", + } + stable_json(args.output_dir / "RESULTS.json", manifest) + print(json.dumps(manifest, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_ylq_frozen.py b/benchmark/evaluate_vdjdb_ylq_frozen.py new file mode 100644 index 0000000..c89026c --- /dev/null +++ b/benchmark/evaluate_vdjdb_ylq_frozen.py @@ -0,0 +1,310 @@ +"""Frozen-encoder evaluation for exact YLQPRTFLL in one dominant MHC context.""" + +from __future__ import annotations + +import argparse +import json +import os +from pathlib import Path + +import numpy as np +import pandas as pd +from sklearn.metrics import average_precision_score, roc_auc_score + +from benchmark.evaluate_vdjdb_frozen import ( + AA, + assert_finite_tree, + distance_matrix, + extract_embeddings, + pair_metrics, + parse_models, + sha256, + stable_json, + validate_run_configs, +) + + +def binary_retrieval(matrix: np.ndarray, candidates: pd.DataFrame) -> tuple[dict, pd.DataFrame]: + positive = candidates["is_ylq"].to_numpy(int).astype(bool) + donors = candidates["donor_key"].astype(str).to_numpy() + rows = [] + for query in np.flatnonzero(positive): + allowed = np.flatnonzero((donors != donors[query]) & (np.arange(len(candidates)) != query)) + relevant = positive[allowed] + r = int(relevant.sum()) + if r == 0: + continue + ranked = relevant[np.argsort(matrix[query, allowed], kind="mergesort")] + hits = ranked[:r].astype(float) + precision = np.cumsum(hits) / np.arange(1, r + 1) + rows.append({ + "query_index": int(query), "label": "YLQPRTFLL", "query_donor": donors[query], + "relevant_donor_excluded": r, + "precision_at_1": float(ranked[:1].sum()), + "precision_at_5": float(ranked[:5].sum() / 5), + "precision_at_10": float(ranked[:10].sum() / 10), + "ap_at_r": float((precision * hits).sum() / r), + }) + table = pd.DataFrame(rows) + return { + "eligible_positive_queries": len(table), + "precision_at_1": float(table["precision_at_1"].mean()), + "precision_at_5": float(table["precision_at_5"].mean()), + "precision_at_10": float(table["precision_at_10"].mean()), + "map_at_r": float(table["ap_at_r"].mean()), + }, table + + +def composition_matrix(candidates: pd.DataFrame) -> np.ndarray: + result = np.zeros((len(candidates), len(AA)), dtype=float) + for row, sequence in enumerate(candidates["cdr3"].astype(str)): + for column, aa in enumerate(AA): + result[row, column] = sequence.count(aa) / len(sequence) + return result + + +def vj_distance(candidates: pd.DataFrame) -> np.ndarray: + v = candidates["v_call"].fillna("").astype(str).to_numpy() + j = candidates["j_call"].fillna("").astype(str).to_numpy() + v_comparable = (v[:, None] != "") & (v[None, :] != "") + j_comparable = (j[:, None] != "") & (j[None, :] != "") + v_mismatch = (~v_comparable | (v[:, None] != v[None, :])).astype(float) + j_mismatch = (~j_comparable | (j[:, None] != j[None, :])).astype(float) + return (v_mismatch + j_mismatch) / 2.0 + + +def bootstrap_ylq( + matrices: dict[str, np.ndarray], pairs: pd.DataFrame, + retrieval: dict[str, pd.DataFrame], replicates: int, seed: int, +) -> dict: + """Paired query-donor bootstrap for all prespecified primary metrics.""" + donors = sorted(set(pairs["query_donor"].astype(str)).union( + *(set(table["query_donor"].astype(str)) for table in retrieval.values()))) + donor_index = {donor: index for index, donor in enumerate(donors)} + pair_donor = pairs["query_donor"].map(donor_index).to_numpy(int) + rng = np.random.default_rng(seed) + weights = rng.multinomial( + len(donors), np.full(len(donors), 1 / len(donors)), size=replicates + ) + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + metric_values: dict[str, dict[str, np.ndarray]] = {} + for name, matrix in matrices.items(): + within = matrix[q, p] + between = matrix[q, n] + result = {key: np.empty(replicates) for key in ( + "within_between_ratio", "between_minus_within", "auroc", "auprc", + "precision_at_1", "map_at_r", + )} + query_table = retrieval[name] + query_donor = query_table["query_donor"].map(donor_index).to_numpy(int) + query_p1 = query_table["precision_at_1"].to_numpy(float) + query_ap = query_table["ap_at_r"].to_numpy(float) + for replicate, donor_weight in enumerate(weights): + pair_weight = donor_weight[pair_donor].astype(float) + within_mean = float(np.average(within, weights=pair_weight)) + between_mean = float(np.average(between, weights=pair_weight)) + result["within_between_ratio"][replicate] = within_mean / between_mean + result["between_minus_within"][replicate] = between_mean - within_mean + truth = np.concatenate((np.ones(len(within), dtype=int), np.zeros(len(between), dtype=int))) + score = -np.concatenate((within, between)) + sample_weight = np.concatenate((pair_weight, pair_weight)) + result["auroc"][replicate] = roc_auc_score( + truth, score, sample_weight=sample_weight + ) + result["auprc"][replicate] = average_precision_score( + truth, score, sample_weight=sample_weight + ) + query_weight = donor_weight[query_donor].astype(float) + result["precision_at_1"][replicate] = np.average(query_p1, weights=query_weight) + result["map_at_r"][replicate] = np.average(query_ap, weights=query_weight) + metric_values[name] = result + + def interval(values: np.ndarray) -> list[float]: + return [float(np.percentile(values, 2.5)), float(np.percentile(values, 97.5))] + + report = { + "replicates": replicates, + "cluster": "query donor", + "paired_across_frozen_models": True, + "models": { + name: {metric: {"ci95": interval(values)} for metric, values in result.items()} + for name, result in metric_values.items() + }, + "paired_differences_rtp_minus_other": {}, + } + for other in ("r", "p", "rp"): + report["paired_differences_rtp_minus_other"][other] = { + metric: { + "ci95": interval(metric_values["rtp"][metric] - metric_values[other][metric]), + "direction": "negative_favors_rtp" if metric == "within_between_ratio" + else "positive_favors_rtp", + } + for metric in metric_values["rtp"] + } + return report + + +def shuffle_null( + matrices: dict[str, np.ndarray], candidates: pd.DataFrame, + permutations: int, seed: int, +) -> dict: + rng = np.random.default_rng(seed + 20000) + labels = candidates["is_ylq"].to_numpy(int).astype(bool) + lengths = candidates["length"].to_numpy(int) + donors = candidates["donor_key"].astype(str).to_numpy() + left, right = np.triu_indices(len(candidates), k=1) + eligible = (lengths[left] == lengths[right]) & (donors[left] != donors[right]) + left, right = left[eligible], right[eligible] + if len(left) > 100000: + selected = rng.choice(len(left), size=100000, replace=False) + left, right = left[selected], right[selected] + + def contrast(distance: np.ndarray, value: np.ndarray) -> float: + positive_pair = value[left] & value[right] + negative_pair = value[left] ^ value[right] + if not positive_pair.any() or not negative_pair.any(): + return float("nan") + return float(distance[left[negative_pair], right[negative_pair]].mean() - + distance[left[positive_pair], right[positive_pair]].mean()) + + observed = {name: contrast(matrix, labels) for name, matrix in matrices.items()} + null = {name: np.empty(permutations) for name in matrices} + groups = [np.flatnonzero(lengths == length) for length in sorted(set(lengths))] + for replicate in range(permutations): + shuffled = labels.copy() + for group in groups: + shuffled[group] = rng.permutation(shuffled[group]) + for name, matrix in matrices.items(): + null[name][replicate] = contrast(matrix, shuffled) + return { + "pairs": len(left), "permutations": permutations, + "strata": "exact CDR3 length", "models": { + name: { + "observed_between_minus_within": observed[name], + "null_ci95": [float(np.nanpercentile(null[name], 2.5)), + float(np.nanpercentile(null[name], 97.5))], + "one_sided_p": float((1 + np.nansum(null[name] >= observed[name])) / + (1 + np.isfinite(null[name]).sum())), + } for name in matrices + }, + } + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--preflight-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--bootstrap", type=int, default=2000) + parser.add_argument("--permutations", type=int, default=1000) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + preflight = json.loads((args.preflight_dir / "PREFLIGHT.json").read_text()) + if preflight["status"] != "ready": + raise ValueError("YLQ preflight is not accepting.") + candidate_path = args.preflight_dir / "candidates.tsv" + pair_path = args.preflight_dir / "pair_manifest.tsv" + if sha256(candidate_path) != preflight["artifacts"]["candidates_sha256"]: + raise ValueError("Candidate table hash changed.") + if sha256(pair_path) != preflight["artifacts"]["pairs_sha256"]: + raise ValueError("Pair manifest hash changed.") + candidates = pd.read_csv(candidate_path, sep="\t") + pairs = pd.read_csv(pair_path, sep="\t") + if candidates["cdr3"].duplicated().any(): + raise ValueError("YLQ candidate table is not exact-CDR3 deduplicated.") + ylq = candidates["is_ylq"].to_numpy(int) + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + donors = candidates["donor_key"].astype(str).to_numpy() + lengths = candidates["length"].to_numpy(int) + if not (np.all(ylq[q] == 1) and np.all(ylq[p] == 1) and np.all(ylq[n] == 0)): + raise ValueError("Pair manifest does not contain YLQ/YLQ/non-YLQ triplets.") + if not (np.all(donors[q] != donors[p]) and np.all(donors[q] != donors[n]) + and np.all(donors[p] != donors[n])): + raise ValueError("Pair manifest is not fully donor-disjoint within triplets.") + if not np.all(lengths[p] == lengths[n]): + raise ValueError("Negative comparator is not exact-length matched to the positive comparator.") + pairs["label"] = "YLQPRTFLL" + models = parse_models(args.model) + config, model_report = validate_run_configs(models) + embeddings, extraction = extract_embeddings( + candidates.rename(columns={"candidate_index": "row_index"}), models, config, + args.tokenizer, 128, args.output_dir, + ) + + metrics = {} + bootstraps = {} + matrices_by_metric = {} + for metric in ("cosine", "euclidean"): + matrices = {name: distance_matrix(value, metric) for name, value in embeddings.items()} + matrices_by_metric[metric] = matrices + metrics[metric] = {} + retrieval_tables = {} + for name, matrix in matrices.items(): + pair_value, per_pair_label = pair_metrics(matrix, pairs) + pair_value.update({ + "within_mean": float(per_pair_label.loc[0, "within_mean"]), + "between_mean": float(per_pair_label.loc[0, "between_mean"]), + "between_minus_within": float( + per_pair_label.loc[0, "between_mean"] - per_pair_label.loc[0, "within_mean"] + ), + }) + retrieval_value, per_query = binary_retrieval(matrix, candidates) + metrics[metric][name] = {"pairwise_and_contrast": pair_value, "retrieval": retrieval_value} + retrieval_tables[name] = per_query + per_query.to_csv(args.output_dir / f"retrieval_{metric}_{name}.tsv", sep="\t", index=False) + bootstraps[metric] = bootstrap_ylq( + matrices, pairs, retrieval_tables, args.bootstrap, args.seed + ) + + lengths = candidates["length"].to_numpy(float) + length_control, _ = pair_metrics(np.abs(lengths[:, None] - lengths[None, :]), pairs) + comp = composition_matrix(candidates) + composition_control = {} + for metric in ("cosine", "euclidean"): + composition_control[metric], _ = pair_metrics(distance_matrix(comp, metric), pairs) + vj_control, _ = pair_metrics(vj_distance(candidates), pairs) + controls = { + "exact_length": length_control, + "amino_acid_composition": composition_control, + "v_j_identity": vj_control, + "shuffled_labels": shuffle_null( + matrices_by_metric["cosine"], candidates, args.permutations, args.seed + ), + } + assert_finite_tree(metrics, "metrics") + assert_finite_tree(bootstraps, "bootstraps") + assert_finite_tree(controls, "controls") + stable_json(args.output_dir / "metrics.json", metrics) + stable_json(args.output_dir / "bootstrap.json", bootstraps) + stable_json(args.output_dir / "controls.json", controls) + pairs.to_csv(args.output_dir / "pair_manifest.tsv", sep="\t", index=False) + candidates.to_csv(args.output_dir / "candidates.tsv", sep="\t", index=False) + artifact_hashes = { + path.name: sha256(path) for path in sorted(args.output_dir.iterdir()) if path.is_file() + } + result = { + "status": "complete", "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "target": "exact YLQPRTFLL in dominant exact MHC context", + "primary_context": preflight["primary_context"], + "positive_cdr3": preflight["positive_cdr3"], + "positive_donors": preflight["positive_donors"], + "negative_cdr3": preflight["same_context_non_ylq_negative_cdr3"], + "pairs": len(pairs), "models": model_report, "extraction": extraction, + "motif_expansion_performed": False, + "selection_statement": "All four prespecified frozen checkpoints are reported; YLQ outcomes selected none.", + "artifact_sha256": artifact_hashes, + } + stable_json(args.output_dir / "RESULTS.json", result) + print(json.dumps(result, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_ylq_motif_pooled.py b/benchmark/evaluate_vdjdb_ylq_motif_pooled.py new file mode 100644 index 0000000..9516cf2 --- /dev/null +++ b/benchmark/evaluate_vdjdb_ylq_motif_pooled.py @@ -0,0 +1,388 @@ +"""CPU-only frozen evaluation on pooled official VDJdb motif-member clonotypes.""" + +from __future__ import annotations + +import argparse +import json +import math +import os +from pathlib import Path + +import numpy as np +import pandas as pd +from sklearn.metrics import average_precision_score, roc_auc_score + +from benchmark.evaluate_vdjdb_frozen import ( + AA, + assert_finite_tree, + extract_embeddings, + parse_models, + sha256, + stable_json, + validate_run_configs, +) + + +def vector_distance(left: np.ndarray, right: np.ndarray, metric: str) -> np.ndarray: + left = left.astype(np.float64, copy=False) + right = right.astype(np.float64, copy=False) + if metric == "cosine": + denominator = np.linalg.norm(left, axis=1) * np.linalg.norm(right, axis=1) + if np.any(denominator == 0): + raise ValueError("Zero-norm vector prevents cosine distance.") + return np.maximum(0.0, 1.0 - np.sum(left * right, axis=1) / denominator) + if metric == "euclidean": + return np.linalg.norm(left - right, axis=1) + raise ValueError(metric) + + +def primary_distances(array: np.ndarray, pairs: pd.DataFrame, metric: str) -> tuple[np.ndarray, np.ndarray]: + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + return vector_distance(array[q], array[p], metric), vector_distance(array[q], array[n], metric) + + +def pair_metrics(within: np.ndarray, between: np.ndarray) -> dict: + truth = np.concatenate((np.ones(len(within), dtype=int), np.zeros(len(between), dtype=int))) + score = -np.concatenate((within, between)) + within_mean = float(within.mean()) + between_mean = float(between.mean()) + if between_mean == 0: + ratio = 1.0 if within_mean == 0 else float("inf") + else: + ratio = within_mean / between_mean + pooled = math.sqrt((float(within.var()) + float(between.var())) / 2.0) + separation = (between_mean - within_mean) / pooled if pooled > 0 else 0.0 + return { + "pairs_per_class": len(within), + "within_mean": within_mean, + "between_mean": between_mean, + "between_minus_within": between_mean - within_mean, + "within_between_ratio": ratio, + "standardized_separation": separation, + "same_label_auroc": float(roc_auc_score(truth, score)), + "same_label_auprc_balanced": float(average_precision_score(truth, score)), + } + + +def pooled_retrieval(array: np.ndarray, candidates: pd.DataFrame, metric: str) -> tuple[dict, pd.DataFrame]: + positive = candidates["is_ylq"].to_numpy(int).astype(bool) + cdr3 = candidates["cdr3"].astype(str).to_numpy() + if metric == "cosine": + norms = np.linalg.norm(array, axis=1, keepdims=True) + if np.any(norms == 0): + raise ValueError("Zero-norm latent prevents cosine retrieval.") + prepared = array / norms + else: + prepared = array.astype(np.float64, copy=False) + rows = [] + all_indices = np.arange(len(candidates)) + for query in np.flatnonzero(positive): + if metric == "cosine": + distance = np.maximum(0.0, 1.0 - prepared @ prepared[query]) + else: + distance = np.linalg.norm(prepared - prepared[query], axis=1) + allowed = all_indices[all_indices != query] + relevant = positive[allowed] + total_relevant = int(relevant.sum()) + order = np.argsort(distance[allowed], kind="mergesort") + ranked = relevant[order] + hits = ranked[:total_relevant].astype(float) + precision = np.cumsum(hits) / np.arange(1, total_relevant + 1) + rows.append({ + "query_index": int(query), + "query_cdr3": cdr3[query], + "relevant_pooled": total_relevant, + "precision_at_1": float(ranked[0]), + "precision_at_5": float(ranked[:5].mean()), + "precision_at_10": float(ranked[:10].mean()), + "ap_at_r": float((precision * hits).sum() / total_relevant), + }) + table = pd.DataFrame(rows) + return { + "eligible_positive_queries": len(table), + "gallery_excludes_query_only": True, + "donor_filter": "none_pooled_by_user_protocol", + "precision_at_1": float(table["precision_at_1"].mean()), + "precision_at_5": float(table["precision_at_5"].mean()), + "precision_at_10": float(table["precision_at_10"].mean()), + "map_at_r": float(table["ap_at_r"].mean()), + }, table + + +def bootstrap_clonotypes( + pair_values: dict[str, tuple[np.ndarray, np.ndarray]], + pairs: pd.DataFrame, + retrieval: dict[str, pd.DataFrame], + replicates: int, + seed: int, +) -> dict: + clusters = sorted(set(pairs["query_cdr3"].astype(str)).union( + *(set(table["query_cdr3"].astype(str)) for table in retrieval.values()))) + cluster_index = {value: index for index, value in enumerate(clusters)} + pair_cluster = pairs["query_cdr3"].map(cluster_index).to_numpy(int) + rng = np.random.default_rng(seed) + weights = rng.multinomial( + len(clusters), np.full(len(clusters), 1 / len(clusters)), size=replicates + ) + values_by_model: dict[str, dict[str, np.ndarray]] = {} + for name, (within, between) in pair_values.items(): + result = {metric: np.empty(replicates) for metric in ( + "within_between_ratio", "between_minus_within", "auroc", "auprc", + "precision_at_1", "map_at_r", + )} + query_table = retrieval[name] + query_cluster = query_table["query_cdr3"].map(cluster_index).to_numpy(int) + query_p1 = query_table["precision_at_1"].to_numpy(float) + query_ap = query_table["ap_at_r"].to_numpy(float) + truth = np.concatenate((np.ones(len(within), dtype=int), np.zeros(len(between), dtype=int))) + score = -np.concatenate((within, between)) + for replicate, cluster_weight in enumerate(weights): + pair_weight = cluster_weight[pair_cluster].astype(float) + within_mean = float(np.average(within, weights=pair_weight)) + between_mean = float(np.average(between, weights=pair_weight)) + result["within_between_ratio"][replicate] = within_mean / between_mean + result["between_minus_within"][replicate] = between_mean - within_mean + sample_weight = np.concatenate((pair_weight, pair_weight)) + result["auroc"][replicate] = roc_auc_score(truth, score, sample_weight=sample_weight) + result["auprc"][replicate] = average_precision_score( + truth, score, sample_weight=sample_weight + ) + query_weight = cluster_weight[query_cluster].astype(float) + result["precision_at_1"][replicate] = np.average(query_p1, weights=query_weight) + result["map_at_r"][replicate] = np.average(query_ap, weights=query_weight) + values_by_model[name] = result + + def interval(values: np.ndarray) -> list[float]: + return [float(np.percentile(values, 2.5)), float(np.percentile(values, 97.5))] + + report = { + "replicates": replicates, + "cluster": "query exact CDR3 clonotype", + "paired_across_frozen_models": True, + "models": { + name: {metric: {"ci95": interval(values)} for metric, values in model_values.items()} + for name, model_values in values_by_model.items() + }, + "paired_differences_rtp_minus_other": {}, + } + for other in ("r", "p", "rp"): + report["paired_differences_rtp_minus_other"][other] = { + metric: { + "ci95": interval(values_by_model["rtp"][metric] - values_by_model[other][metric]), + "direction": "negative_favors_rtp" if metric == "within_between_ratio" + else "positive_favors_rtp", + } + for metric in values_by_model["rtp"] + } + return report + + +def composition_features(candidates: pd.DataFrame) -> np.ndarray: + result = np.zeros((len(candidates), len(AA)), dtype=float) + for row, sequence in enumerate(candidates["cdr3"].astype(str)): + for column, aa in enumerate(AA): + result[row, column] = sequence.count(aa) / len(sequence) + return result + + +def vj_pair_values(candidates: pd.DataFrame, pairs: pd.DataFrame) -> tuple[np.ndarray, np.ndarray]: + v = candidates["v_call"].fillna("").astype(str).to_numpy() + j = candidates["j_call"].fillna("").astype(str).to_numpy() + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + + def value(left: np.ndarray, right: np.ndarray) -> np.ndarray: + v_mismatch = (v[left] == "") | (v[right] == "") | (v[left] != v[right]) + j_mismatch = (j[left] == "") | (j[right] == "") | (j[left] != j[right]) + return (v_mismatch.astype(float) + j_mismatch.astype(float)) / 2.0 + + return value(q, p), value(q, n) + + +def shuffled_label_control( + pair_values: dict[str, tuple[np.ndarray, np.ndarray]], + candidates: pd.DataFrame, + pairs: pd.DataFrame, + permutations: int, + seed: int, +) -> dict: + rng = np.random.default_rng(seed + 30000) + labels = candidates["is_ylq"].to_numpy(int).astype(bool) + lengths = candidates["length"].to_numpy(int) + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + groups = [np.flatnonzero(lengths == length) for length in sorted(set(lengths))] + observed = { + name: float(between.mean() - within.mean()) + for name, (within, between) in pair_values.items() + } + null = {name: np.full(permutations, np.nan) for name in pair_values} + valid_pair_counts = [] + for replicate in range(permutations): + shuffled = labels.copy() + for group in groups: + shuffled[group] = rng.permutation(shuffled[group]) + same_mask = shuffled[q] & shuffled[p] + different_mask = shuffled[q] ^ shuffled[n] + valid_pair_counts.append((int(same_mask.sum()), int(different_mask.sum()))) + if not same_mask.any() or not different_mask.any(): + continue + for name, (within, between) in pair_values.items(): + null[name][replicate] = float( + between[different_mask].mean() - within[same_mask].mean() + ) + models = {} + for name, values in null.items(): + finite = values[np.isfinite(values)] + if len(finite) < permutations * 0.95: + raise ValueError(f"Too few valid shuffled-label replicates for {name}: {len(finite)}") + models[name] = { + "observed_between_minus_within": observed[name], + "null_ci95": [float(np.percentile(finite, 2.5)), float(np.percentile(finite, 97.5))], + "one_sided_p": float((1 + np.sum(finite >= observed[name])) / (1 + len(finite))), + } + return { + "permutations": permutations, + "strata": "exact CDR3 length", + "fixed_edge_design": "primary query-positive and query-negative edges; labels permuted", + "valid_same_pair_range": [min(value[0] for value in valid_pair_counts), + max(value[0] for value in valid_pair_counts)], + "valid_different_pair_range": [min(value[1] for value in valid_pair_counts), + max(value[1] for value in valid_pair_counts)], + "models": models, + } + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--preflight-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--bootstrap", type=int, default=2000) + parser.add_argument("--permutations", type=int, default=1000) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + preflight = json.loads((args.preflight_dir / "PREFLIGHT.json").read_text(encoding="utf-8")) + if preflight["status"] != "ready": + raise ValueError("Pooled official-motif preflight is not accepting.") + candidate_path = args.preflight_dir / "candidates.tsv" + pair_path = args.preflight_dir / "pair_manifest.tsv" + if sha256(candidate_path) != preflight["artifacts"]["candidates_sha256"]: + raise ValueError("Candidate hash changed after CPU gate.") + if sha256(pair_path) != preflight["artifacts"]["pairs_sha256"]: + raise ValueError("Pair hash changed after CPU gate.") + candidates = pd.read_csv(candidate_path, sep="\t") + pairs = pd.read_csv(pair_path, sep="\t") + if candidates["cdr3"].duplicated().any(): + raise ValueError("Candidate table is not exact-CDR3 deduplicated.") + if set(candidates["mhc_a"]) != {"HLA-A*02:01"} or set(candidates["mhc_b"]) != {"B2M"} \ + or set(candidates["mhc_class"]) != {"MHCI"}: + raise ValueError("Candidate table is not restricted to exact A*02:01/B2M/MHCI.") + if candidates["motif_cids"].fillna("").eq("").any(): + raise ValueError("A candidate lacks explicit official motif membership.") + labels = candidates["is_ylq"].to_numpy(int) + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + if not (np.all(labels[q] == 1) and np.all(labels[p] == 1) and np.all(labels[n] == 0)): + raise ValueError("Pair manifest does not contain YLQ/YLQ/non-YLQ triplets.") + if not (np.all(q != p) and np.all(q != n) and np.all(p != n)): + raise ValueError("Pair manifest contains repeated clonotypes within a triplet.") + if not np.all(candidates["length"].to_numpy(int)[p] == candidates["length"].to_numpy(int)[n]): + raise ValueError("Negative comparator is not exact-length matched.") + + models = parse_models(args.model) + config, model_report = validate_run_configs(models) + embeddings, extraction = extract_embeddings( + candidates, models, config, args.tokenizer, args.batch_size, args.output_dir + ) + metrics: dict[str, dict] = {} + bootstraps: dict[str, dict] = {} + cosine_pair_values: dict[str, tuple[np.ndarray, np.ndarray]] = {} + for metric in ("cosine", "euclidean"): + metrics[metric] = {} + pair_values = {} + retrieval_tables = {} + for name, array in embeddings.items(): + within, between = primary_distances(array, pairs, metric) + pair_values[name] = (within, between) + np.savez_compressed( + args.output_dir / f"primary_distances_{metric}_{name}.npz", + within=within, between=between, + ) + retrieval_value, retrieval_table = pooled_retrieval(array, candidates, metric) + retrieval_table.to_csv( + args.output_dir / f"retrieval_{metric}_{name}.tsv", sep="\t", index=False + ) + retrieval_tables[name] = retrieval_table + metrics[metric][name] = { + "pairwise_and_contrast": pair_metrics(within, between), + "retrieval": retrieval_value, + } + bootstraps[metric] = bootstrap_clonotypes( + pair_values, pairs, retrieval_tables, args.bootstrap, args.seed + ) + if metric == "cosine": + cosine_pair_values = pair_values + + lengths = candidates["length"].to_numpy(float) + length_within = np.abs(lengths[q] - lengths[p]) + length_between = np.abs(lengths[q] - lengths[n]) + composition = composition_features(candidates) + composition_control = {} + for metric in ("cosine", "euclidean"): + within = vector_distance(composition[q], composition[p], metric) + between = vector_distance(composition[q], composition[n], metric) + composition_control[metric] = pair_metrics(within, between) + vj_within, vj_between = vj_pair_values(candidates, pairs) + controls = { + "exact_length": pair_metrics(length_within, length_between), + "amino_acid_composition": composition_control, + "v_j_identity": pair_metrics(vj_within, vj_between), + "shuffled_labels_cosine": shuffled_label_control( + cosine_pair_values, candidates, pairs, args.permutations, args.seed + ), + } + assert_finite_tree(metrics, "metrics") + assert_finite_tree(bootstraps, "bootstraps") + assert_finite_tree(controls, "controls") + stable_json(args.output_dir / "metrics.json", metrics) + stable_json(args.output_dir / "bootstrap.json", bootstraps) + stable_json(args.output_dir / "controls.json", controls) + candidates.to_csv(args.output_dir / "candidates.tsv", sep="\t", index=False) + pairs.to_csv(args.output_dir / "pair_manifest.tsv", sep="\t", index=False) + hashes = {path.name: sha256(path) for path in sorted(args.output_dir.iterdir()) if path.is_file()} + result = { + "status": "complete", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "target": "exact YLQPRTFLL, official motif-member, pooled HLA-A*02:01/B2M/MHCI", + "positive_cdr3": preflight["positive_cdr3"], + "negative_cdr3": preflight["negative_cdr3"], + "candidate_cdr3": preflight["candidate_cdr3"], + "pairs": len(pairs), + "pooling": preflight["pooling"], + "models": model_report, + "extraction": extraction, + "artifact_sha256": hashes, + "selection_statement": "All four prespecified frozen checkpoints reported; no YLQ-based selection.", + "circularity_caveat": preflight["circularity_caveat"], + "claim_scope": "within-VDJdb motif/epitope organization; not cross-donor or independent motif evidence", + "exploratory_n40_protocol": preflight["exploratory_n40_protocol"], + "compact_control_selection": preflight["compact_control_selection"], + "models_trained": False, + } + stable_json(args.output_dir / "RESULTS.json", result) + print(json.dumps(result, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_trb_joint.py b/benchmark/prepare_trb_joint.py new file mode 100644 index 0000000..d958624 --- /dev/null +++ b/benchmark/prepare_trb_joint.py @@ -0,0 +1,648 @@ +"""Prepare the identity-aligned TRB benchmark used by joint codec training. + +The TCRemP Parquet intentionally contains only numeric embedding columns. Its +authoritative row identities live in the representations TSV written beside it +from the same ``analysis_repertoire`` by TCRemP. This preparation therefore +uses that sidecar's ``clone_id`` values, verifies every AIRR and pgen record by +biological identity, and refuses a bare row-count-only alignment. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import logging +import os +from pathlib import Path + +import numpy as np +import pandas as pd +import pyarrow as pa +import pyarrow.parquet as pq + + +VALID_AA = set("ACDEFGHIKLMNPQRSTVWY") +IDENTITY_COLUMNS = ["junction_aa", "v_identity", "j_identity", "locus_identity"] +PGEN_COLUMNS = ["log10_pgen", "log10_pgen_1mm"] + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--airr-path", required=True) + parser.add_argument("--embeddings-path", required=True) + parser.add_argument("--representations-path", required=True) + parser.add_argument("--pgen-path", required=True) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--tcremp-writer-source") + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--train-fraction", type=float, default=0.8) + parser.add_argument("--val-fraction", type=float, default=0.1) + parser.add_argument("--min-len", type=int, default=1) + parser.add_argument("--max-len", type=int, default=40) + parser.add_argument("--embedding-batch-size", type=int, default=256) + parser.add_argument("--standardizer-chunk-size", type=int, default=1024) + return parser.parse_args() + + +def setup_logging(path: Path) -> logging.Logger: + path.parent.mkdir(parents=True, exist_ok=True) + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s | %(levelname)s | %(message)s", + handlers=[logging.StreamHandler(), logging.FileHandler(path, encoding="utf-8")], + force=True, + ) + return logging.getLogger("prepare_trb_joint") + + +def normalize_gene(value: object) -> str: + value = str(value).strip().upper() + return value.split("*", 1)[0] + + +def normalize_locus(value: object) -> str: + normalized = str(value).strip().lower() + aliases = {"trb": "beta", "b": "beta"} + return aliases.get(normalized, normalized) + + +def add_identity_columns( + table: pd.DataFrame, + *, + cdr3_col: str, + v_col: str, + j_col: str, + locus_col: str | None = None, + locus_value: str = "beta", +) -> pd.DataFrame: + required = {cdr3_col, v_col, j_col} + if locus_col is not None: + required.add(locus_col) + missing = required.difference(table.columns) + if missing: + raise ValueError(f"Source table is missing identity columns: {sorted(missing)}") + result = table.copy() + result["junction_aa"] = result[cdr3_col].astype(str).str.strip().str.upper() + result["v_identity"] = result[v_col].map(normalize_gene) + result["j_identity"] = result[j_col].map(normalize_gene) + if locus_col is None: + result["locus_identity"] = normalize_locus(locus_value) + else: + result["locus_identity"] = result[locus_col].map(normalize_locus) + return result + + +def identity_strings(table: pd.DataFrame) -> pd.Series: + return table[IDENTITY_COLUMNS].astype(str).agg("\x1f".join, axis=1) + + +def require_unique_identity(table: pd.DataFrame, label: str) -> None: + duplicated = table.duplicated(IDENTITY_COLUMNS, keep=False) + if duplicated.any(): + examples = table.loc[duplicated, IDENTITY_COLUMNS].head(5).to_dict("records") + raise ValueError(f"{label} contains duplicate biological identities: {examples}") + + +def validate_writer_contract(path: str | None) -> dict: + if not path: + raise ValueError( + "--tcremp-writer-source is required: the clone-id sidecar contract must be auditable." + ) + source_path = Path(path) + source = source_path.read_text(encoding="utf-8") + required_fragments = [ + "clone_representations = get_representations_df(analysis_repertoire", + "embeddings = run_tcremp_embedding(\n analysis_repertoire", + "embeddings.to_parquet", + "index=False", + ] + missing = [fragment for fragment in required_fragments if fragment not in source] + if missing: + raise ValueError(f"TCRemP writer contract is not recognizable; missing {missing}") + return { + "path": str(source_path), + "sha256": hashlib.sha256(source.encode("utf-8")).hexdigest(), + "evidence": ( + "representations clone_id and embedding rows are emitted from the same " + "analysis_repertoire before index-free Parquet serialization" + ), + } + + +def prepare_identity_table( + airr: pd.DataFrame, + pgen: pd.DataFrame, + representations: pd.DataFrame, + *, + min_len: int, + max_len: int, +) -> tuple[pd.DataFrame, dict]: + airr = add_identity_columns( + airr, + cdr3_col="junction_aa", + v_col="v_call", + j_col="j_call", + locus_col="locus", + ) + pgen = add_identity_columns( + pgen, + cdr3_col="junction_aa", + v_col="v_call", + j_col="j_call", + locus_col="locus", + ) + representations = add_identity_columns( + representations, + cdr3_col="cdr3aa_TRB", + v_col="v_TRB", + j_col="j_TRB", + locus_value="beta", + ) + if "clone_id" not in representations.columns: + raise ValueError("TCRemP representations must contain clone_id.") + if representations["clone_id"].isna().any() or representations["clone_id"].duplicated().any(): + raise ValueError("TCRemP clone_id values must be complete and unique.") + for column in PGEN_COLUMNS: + if column not in pgen.columns: + raise ValueError(f"pgen table is missing required target {column!r}.") + + require_unique_identity(airr, "AIRR") + require_unique_identity(pgen, "pgen") + require_unique_identity(representations, "TCRemP representations") + + representation_identity = representations[["clone_id", *IDENTITY_COLUMNS]].copy() + joined = airr.merge( + representation_identity, + on=IDENTITY_COLUMNS, + how="inner", + validate="one_to_one", + ) + if len(joined) != len(airr) or len(joined) != len(representations): + raise ValueError( + "AIRR and TCRemP representations do not match one-to-one by CDR3/V/J/locus: " + f"airr={len(airr)} representations={len(representations)} matched={len(joined)}" + ) + joined = joined.merge( + pgen[[*IDENTITY_COLUMNS, *PGEN_COLUMNS]], + on=IDENTITY_COLUMNS, + how="inner", + validate="one_to_one", + ) + if len(joined) != len(airr) or len(joined) != len(pgen): + raise ValueError( + "AIRR and pgen targets do not match one-to-one by CDR3/V/J/locus: " + f"airr={len(airr)} pgen={len(pgen)} matched={len(joined)}" + ) + + report = { + "rows_input": int(len(joined)), + "rows_after_locus_filter": 0, + "dropped_missing": 0, + "dropped_invalid_chars": 0, + "dropped_too_short": 0, + "dropped_too_long": 0, + "dropped_duplicate_cdr3": 0, + "dropped_non_finite_pgen": 0, + } + keep = pd.Series(True, index=joined.index) + locus_ok = joined["locus_identity"].eq("beta") + report["rows_after_locus_filter"] = int(locus_ok.sum()) + keep &= locus_ok + + missing = joined["junction_aa"].isin(["", "NAN", "NONE"]) + report["dropped_missing"] = int((keep & missing).sum()) + keep &= ~missing + invalid = ~joined["junction_aa"].map(lambda sequence: set(sequence) <= VALID_AA) + report["dropped_invalid_chars"] = int((keep & invalid).sum()) + keep &= ~invalid + too_short = joined["junction_aa"].str.len().lt(min_len) + report["dropped_too_short"] = int((keep & too_short).sum()) + keep &= ~too_short + too_long = joined["junction_aa"].str.len().gt(max_len) + report["dropped_too_long"] = int((keep & too_long).sum()) + keep &= ~too_long + joined = joined.loc[keep].copy() + + duplicated = joined["junction_aa"].duplicated(keep="first") + report["dropped_duplicate_cdr3"] = int(duplicated.sum()) + joined = joined.loc[~duplicated].copy() + + target_values = joined[PGEN_COLUMNS].apply(pd.to_numeric, errors="coerce") + finite = np.isfinite(target_values.to_numpy(dtype=np.float64)).all(axis=1) + report["dropped_non_finite_pgen"] = int((~finite).sum()) + joined = joined.loc[finite].copy() + joined[PGEN_COLUMNS] = target_values.loc[finite].to_numpy(dtype=np.float64) + if joined.empty: + raise ValueError("No rows remain after benchmark validation.") + + record_ids = identity_strings(joined).map( + lambda value: hashlib.sha256(value.encode("utf-8")).hexdigest() + ) + joined.insert(0, "record_id", record_ids.to_numpy()) + joined = joined.reset_index(drop=True) + joined.insert(0, "row_index", np.arange(len(joined), dtype=np.int64)) + report["rows_kept"] = int(len(joined)) + return joined, report + + +def make_splits( + table: pd.DataFrame, + *, + train_fraction: float, + val_fraction: float, + seed: int, +) -> tuple[dict[str, np.ndarray], dict]: + if not 0 < train_fraction < 1 or not 0 <= val_fraction < 1: + raise ValueError("Split fractions are invalid.") + if train_fraction + val_fraction >= 1: + raise ValueError("train_fraction + val_fraction must be less than one.") + order = np.random.default_rng(seed).permutation(len(table)) + train_end = int(len(table) * train_fraction) + val_end = train_end + int(len(table) * val_fraction) + splits = { + "train": order[:train_end], + "val": order[train_end:val_end], + "test": order[val_end:], + } + table["split"] = "" + for name, indices in splits.items(): + table.loc[indices, "split"] = name + sets = { + name: set(table.iloc[indices]["junction_aa"].tolist()) + for name, indices in splits.items() + } + overlaps = { + "train_val": len(sets["train"] & sets["val"]), + "train_test": len(sets["train"] & sets["test"]), + "val_test": len(sets["val"] & sets["test"]), + } + if any(overlaps.values()) or (table["split"] == "").any(): + raise ValueError(f"Split construction failed: overlaps={overlaps}") + return splits, overlaps + + +def parquet_embedding_columns(parquet: pq.ParquetFile) -> list[str]: + columns = [ + field.name + for field in parquet.schema_arrow + if pa.types.is_integer(field.type) or pa.types.is_floating(field.type) + ] + if not columns: + raise ValueError("TCRemP Parquet has no numeric embedding columns.") + if "clone_id" in parquet.schema_arrow.names: + raise ValueError( + "This preparation expects identity in the authoritative sidecar; " + "a physical clone_id column requires a dedicated direct-id reader." + ) + return columns + + +def materialize_embeddings( + parquet_path: str, + representations: pd.DataFrame, + table: pd.DataFrame, + output_path: Path, + *, + batch_size: int, +) -> tuple[np.memmap, dict]: + parquet = pq.ParquetFile(parquet_path) + columns = parquet_embedding_columns(parquet) + if parquet.metadata.num_rows != len(representations): + raise ValueError( + "TCRemP Parquet and authoritative clone-id sidecar row counts differ: " + f"parquet={parquet.metadata.num_rows} sidecar={len(representations)}" + ) + source_clone_ids = representations["clone_id"].astype(str).to_numpy() + destination_by_clone = { + str(clone_id): int(row_index) + for clone_id, row_index in zip(table["clone_id"], table["row_index"]) + } + temporary_path = output_path.with_suffix(".npy.tmp") + temporary_path.unlink(missing_ok=True) + output = np.lib.format.open_memmap( + temporary_path, + mode="w+", + dtype=np.float32, + shape=(len(table), len(columns)), + ) + written = np.zeros(len(table), dtype=bool) + source_offset = 0 + try: + for record_batch in parquet.iter_batches(batch_size=batch_size, columns=columns): + matrix = record_batch.to_pandas().to_numpy(dtype=np.float32, copy=False) + if not np.isfinite(matrix).all(): + raise ValueError("TCRemP source embeddings contain NaN or infinite values.") + batch_ids = source_clone_ids[source_offset : source_offset + len(matrix)] + for source_row, clone_id in enumerate(batch_ids): + destination = destination_by_clone.get(clone_id) + if destination is not None: + if written[destination]: + raise ValueError(f"Duplicate embedding clone_id {clone_id!r}.") + output[destination] = matrix[source_row] + written[destination] = True + source_offset += len(matrix) + if source_offset != len(representations) or not written.all(): + missing = table.loc[~written, "clone_id"].head(10).tolist() + raise ValueError( + "Embedding identity materialization was incomplete: " + f"source={source_offset}/{len(representations)} " + f"written={int(written.sum())}/{len(table)} missing={missing}" + ) + output.flush() + output._mmap.close() + temporary_path.replace(output_path) + except Exception: + output._mmap.close() + temporary_path.unlink(missing_ok=True) + raise + matrix = np.load(output_path, mmap_mode="r") + return matrix, { + "source_rows": int(parquet.metadata.num_rows), + "selected_rows": int(len(table)), + "dimension": int(len(columns)), + "dtype": str(matrix.dtype), + "all_finite": True, + "mapping": "TCRemP representations clone_id sidecar writer contract", + } + + +def combine_moments( + count: int, + mean: np.ndarray, + m2: np.ndarray, + batch: np.ndarray, +) -> tuple[int, np.ndarray, np.ndarray]: + batch_count = len(batch) + batch_mean = batch.mean(axis=0, dtype=np.float64) + batch_m2 = batch.var(axis=0, dtype=np.float64) * batch_count + if count == 0: + return batch_count, batch_mean, batch_m2 + delta = batch_mean - mean + total = count + batch_count + return ( + total, + mean + delta * (batch_count / total), + m2 + batch_m2 + delta * delta * (count * batch_count / total), + ) + + +def write_standardizer( + path: Path, + table: pd.DataFrame, + embeddings: np.ndarray, + train_indices: np.ndarray, + *, + chunk_size: int, +) -> dict: + count = 0 + mean = np.zeros(embeddings.shape[1], dtype=np.float64) + m2 = np.zeros(embeddings.shape[1], dtype=np.float64) + for start in range(0, len(train_indices), chunk_size): + indices = train_indices[start : start + chunk_size] + batch = np.asarray(embeddings[indices], dtype=np.float32) + if not np.isfinite(batch).all(): + raise ValueError("TCRemP train targets contain non-finite values.") + count, mean, m2 = combine_moments(count, mean, m2, batch) + raw_std = np.sqrt(m2 / count) + zero_variance = raw_std < 1e-8 + std = np.where(zero_variance, 1.0, raw_std) + + pgen_stats = {} + for column in PGEN_COLUMNS: + values = table.iloc[train_indices][column].to_numpy(dtype=np.float64) + if not np.isfinite(values).all(): + raise ValueError(f"Training target {column} contains non-finite values.") + target_std = float(values.std()) + if target_std < 1e-8: + target_std = 1.0 + pgen_stats[column] = {"mean": float(values.mean()), "std": target_std} + default = pgen_stats["log10_pgen_1mm"] + np.savez( + path, + tcremp_mean=mean.astype(np.float32), + tcremp_std=std.astype(np.float32), + pgen_mean=np.float32(default["mean"]), + pgen_std=np.float32(default["std"]), + pgen_target=np.asarray("log10_pgen_1mm"), + log10_pgen_mean=np.float32(pgen_stats["log10_pgen"]["mean"]), + log10_pgen_std=np.float32(pgen_stats["log10_pgen"]["std"]), + log10_pgen_1mm_mean=np.float32(default["mean"]), + log10_pgen_1mm_std=np.float32(default["std"]), + train_rows=np.int64(count), + ) + return { + "fit_split": "train", + "train_rows": int(count), + "embedding_dimension": int(embeddings.shape[1]), + "zero_variance_embedding_dimensions": int(zero_variance.sum()), + "pgen": pgen_stats, + "default_pgen_target": "log10_pgen_1mm", + } + + +def sha256_file(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as source: + for block in iter(lambda: source.read(1024 * 1024), b""): + digest.update(block) + return digest.hexdigest() + + +def source_info(path: str, *, hash_file: bool) -> dict: + source = Path(path) + stat = source.stat() + result = {"path": str(source), "size_bytes": int(stat.st_size), "mtime_ns": int(stat.st_mtime_ns)} + if hash_file: + result["sha256"] = sha256_file(source) + return result + + +def summarize_target(table: pd.DataFrame, indices: np.ndarray, column: str) -> dict: + values = table.iloc[indices][column].to_numpy(dtype=np.float64) + return { + "rows": int(len(values)), + "finite": int(np.isfinite(values).sum()), + "mean": float(values.mean()), + "std": float(values.std()), + "min": float(values.min()), + "max": float(values.max()), + } + + +def main() -> None: + args = parse_args() + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + ready_path = output_dir / "READY.json" + if ready_path.exists(): + raise FileExistsError(f"Refusing to overwrite an already ready benchmark: {ready_path}") + log = setup_logging(output_dir / "prepare.log") + log.info("starting identity-aligned TRB benchmark preparation") + writer_contract = validate_writer_contract(args.tcremp_writer_source) + + airr = pd.read_csv(args.airr_path, sep="\t") + pgen = pd.read_csv(args.pgen_path, sep="\t") + representations = pd.read_csv(args.representations_path, sep="\t") + table, cleaning = prepare_identity_table( + airr, + pgen, + representations, + min_len=args.min_len, + max_len=args.max_len, + ) + splits, overlaps = make_splits( + table, + train_fraction=args.train_fraction, + val_fraction=args.val_fraction, + seed=args.seed, + ) + embeddings, embedding_summary = materialize_embeddings( + args.embeddings_path, + representations, + table, + output_dir / "embeddings.npy", + batch_size=args.embedding_batch_size, + ) + normalizer = write_standardizer( + output_dir / "target_standardizer.npz", + table, + embeddings, + splits["train"], + chunk_size=args.standardizer_chunk_size, + ) + + output_columns = [ + "row_index", + "record_id", + "clone_id", + "junction_aa", + "v_call", + "j_call", + "locus", + *PGEN_COLUMNS, + "split", + ] + table[output_columns].to_parquet(output_dir / "dataset.parquet", index=False) + table[output_columns].to_csv(output_dir / "dataset.tsv", sep="\t", index=False) + table[["row_index", "record_id", "clone_id"]].to_csv( + output_dir / "embedding_row_id.tsv", sep="\t", index=False + ) + + manifest_dir = output_dir / "manifests" + manifest_dir.mkdir(exist_ok=True) + manifest_columns = [ + "row_index", + "record_id", + "clone_id", + "junction_aa", + "v_call", + "j_call", + *PGEN_COLUMNS, + ] + for name, indices in splits.items(): + table.iloc[np.sort(indices)][manifest_columns].to_csv( + manifest_dir / f"{name}.tsv", sep="\t", index=False + ) + train = splits["train"] + for name, indices in { + "1k": train[: min(1_000, len(train))], + "10k": train[: min(10_000, len(train))], + "all": train, + }.items(): + pd.DataFrame({"row_index": np.sort(indices)}).to_csv( + manifest_dir / f"train_{name}.tsv", sep="\t", index=False + ) + + summary = { + "slurm": { + "job_id": os.environ.get("SLURM_JOB_ID"), + "node": os.environ.get("SLURMD_NODENAME"), + "cpus_per_task": os.environ.get("SLURM_CPUS_PER_TASK"), + }, + "status": "ready", + "benchmark": "TRB joint IRRM-CODEC", + "seed": args.seed, + "max_len": args.max_len, + "sources": { + "airr": source_info(args.airr_path, hash_file=True), + "tcremp_embeddings": source_info(args.embeddings_path, hash_file=False), + "tcremp_representations": source_info(args.representations_path, hash_file=True), + "pgen": source_info(args.pgen_path, hash_file=True), + "tcremp_writer": writer_contract, + }, + "alignment": { + "method": ( + "TCRemP authoritative representations clone_id sidecar; AIRR and pgen " + "joined one-to-one by normalized CDR3/V/J/locus identity" + ), + "row_order_only": False, + "airr_rows": int(len(airr)), + "representations_rows": int(len(representations)), + "pgen_rows": int(len(pgen)), + "identity_matches_before_cleaning": int(cleaning["rows_input"]), + "selected_embedding_rows": int(embedding_summary["selected_rows"]), + }, + "cleaning": cleaning, + "dataset": { + "rows": int(len(table)), + "unique_record_ids": int(table["record_id"].nunique()), + "unique_clone_ids": int(table["clone_id"].nunique()), + "unique_cdr3": int(table["junction_aa"].nunique()), + "cdr3_length_min": int(table["junction_aa"].str.len().min()), + "cdr3_length_max": int(table["junction_aa"].str.len().max()), + }, + "embeddings": embedding_summary, + "splits": { + "sizes": {name: int(len(indices)) for name, indices in splits.items()}, + "fractions": { + "train": args.train_fraction, + "val": args.val_fraction, + "test": 1.0 - args.train_fraction - args.val_fraction, + }, + "cdr3_overlap": overlaps, + }, + "targets": { + column: { + name: summarize_target(table, indices, column) + for name, indices in splits.items() + } + for column in PGEN_COLUMNS + }, + "standardizer": normalizer, + "checks": { + "identity_alignment": True, + "valid_amino_acids": True, + "length_at_most_40": bool(table["junction_aa"].str.len().le(args.max_len).all()), + "unique_cdr3": bool(table["junction_aa"].is_unique), + "finite_pgen_targets": bool( + np.isfinite(table[PGEN_COLUMNS].to_numpy(dtype=np.float64)).all() + ), + "finite_embeddings": bool(embedding_summary["all_finite"]), + "non_overlapping_splits": not any(overlaps.values()), + "train_only_standardization": normalizer["fit_split"] == "train", + }, + "outputs": { + "dataset_parquet": str(output_dir / "dataset.parquet"), + "dataset_tsv": str(output_dir / "dataset.tsv"), + "embeddings_npy": str(output_dir / "embeddings.npy"), + "embedding_row_ids": str(output_dir / "embedding_row_id.tsv"), + "manifests": str(manifest_dir), + "standardizer": str(output_dir / "target_standardizer.npz"), + "log": str(output_dir / "prepare.log"), + }, + } + if not all(summary["checks"].values()): + raise ValueError(f"Final readiness checks failed: {summary['checks']}") + (output_dir / "dataset_summary.json").write_text( + json.dumps(summary, indent=2), encoding="utf-8" + ) + ready_path.write_text(json.dumps(summary, indent=2), encoding="utf-8") + log.info("benchmark ready at %s", output_dir) + log.info("rows=%d embedding_shape=%s splits=%s", len(table), embeddings.shape, summary["splits"]) + if isinstance(embeddings, np.memmap): + embeddings._mmap.close() + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_vdjdb_epitope_cohort.py b/benchmark/prepare_vdjdb_epitope_cohort.py new file mode 100644 index 0000000..0b7a572 --- /dev/null +++ b/benchmark/prepare_vdjdb_epitope_cohort.py @@ -0,0 +1,420 @@ +"""Prepare an auditable, leakage-controlled VDJdb TRB cohort. + +This command intentionally stops before full embedding extraction or evaluation. +It filters and hashes the source, removes exact benchmark overlaps, locks an +objective label rule, and smoke-loads one frozen encoder checkpoint on CPU. +""" + +from __future__ import annotations + +import argparse +import csv +import hashlib +import json +import math +import os +import re +from collections import Counter, defaultdict +from dataclasses import asdict +from pathlib import Path +from typing import Iterable + +VALID_AA = frozenset("ACDEFGHIKLMNPQRSTVWY") +MISSING = frozenset({"", "NA", "N/A", "NONE", "NULL", "UNKNOWN"}) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--vdjdb-tsv", type=Path, required=True) + parser.add_argument("--benchmark-dir", type=Path, required=True) + parser.add_argument("--checkpoint", type=Path, required=True) + parser.add_argument("--run-config", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--min-support", type=int, default=50) + parser.add_argument("--min-donors", type=int, default=2) + parser.add_argument("--sensitivity-thresholds", type=int, nargs="+", default=[25, 50, 100]) + parser.add_argument("--min-vdjdb-score", type=float, default=1.0) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def sha256_file(path: Path, chunk_size: int = 1024 * 1024) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(chunk_size): + digest.update(chunk) + return digest.hexdigest() + + +def stable_json(path: Path, payload: object) -> None: + path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def clean_text(value: object) -> str: + return re.sub(r"\s+", " ", str(value or "").strip()) + + +def normalized_context(value: object) -> str: + text = clean_text(value).upper() + return "" if text in MISSING else text + + +def parse_json_object(raw: str) -> dict: + try: + value = json.loads(raw or "{}") + except json.JSONDecodeError: + return {} + return value if isinstance(value, dict) else {} + + +def normalize_vdjdb_row(row: dict[str, str], min_score: float) -> tuple[dict | None, str]: + if normalized_context(row.get("gene")) != "TRB": + return None, "not_trb" + if normalized_context(row.get("species")) not in {"HOMOSAPIENS", "HOMO SAPIENS"}: + return None, "not_human" + + sequence = normalized_context(row.get("cdr3")) + if not sequence or len(sequence) > 40 or set(sequence).difference(VALID_AA): + return None, "invalid_cdr3" + + fix = parse_json_object(row.get("cdr3fix", "")) + if fix.get("good") is not True: + return None, "cdr3fix_not_good" + fixed_sequence = normalized_context(fix.get("cdr3")) + if fixed_sequence and fixed_sequence != sequence: + return None, "cdr3fix_changes_sequence" + + epitope = normalized_context(row.get("antigen.epitope")) + mhc_a = normalized_context(row.get("mhc.a")) + mhc_b = normalized_context(row.get("mhc.b")) + mhc_class = normalized_context(row.get("mhc.class")) + if not epitope or not mhc_a or not mhc_class: + return None, "missing_epitope_or_mhc" + + try: + score = float(row.get("vdjdb.score", "nan")) + except ValueError: + score = math.nan + if not math.isfinite(score) or score < min_score: + return None, "low_or_invalid_score" + + meta = parse_json_object(row.get("meta", "")) + subject = clean_text(meta.get("subject.id") or meta.get("subject_id")) + reference = clean_text(row.get("reference.id")) + study = clean_text(meta.get("study.id") or meta.get("study_id") or reference) + if not subject: + return None, "missing_donor" + donor_key = f"{study}|{subject}" + label = "|".join((epitope, mhc_a, mhc_b or "-", mhc_class)) + return { + "cdr3": sequence, + "label": label, + "epitope": epitope, + "mhc_a": mhc_a, + "mhc_b": mhc_b, + "mhc_class": mhc_class, + "donor_key": donor_key, + "reference_id": reference, + "v_call": normalized_context(row.get("v.segm")), + "j_call": normalized_context(row.get("j.segm")), + "vdjdb_score": score, + "length": len(sequence), + }, "accepted_row" + + +def read_benchmark_sequences(benchmark_dir: Path) -> tuple[dict[str, set[str]], dict[str, str]]: + split_sequences: dict[str, set[str]] = {} + hashes: dict[str, str] = {} + for split in ("train", "val", "test"): + path = benchmark_dir / "manifests" / f"{split}.tsv" + hashes[str(path)] = sha256_file(path) + sequences: set[str] = set() + with path.open("r", encoding="utf-8", newline="") as handle: + reader = csv.DictReader(handle, delimiter="\t") + if "junction_aa" not in (reader.fieldnames or []): + raise ValueError(f"Missing junction_aa in {path}") + for row in reader: + sequences.add(normalized_context(row["junction_aa"])) + split_sequences[split] = sequences + return split_sequences, hashes + + +def prepare_records( + vdjdb_tsv: Path, + benchmark_sequences: dict[str, set[str]], + min_score: float, +) -> tuple[list[dict], dict]: + counts: Counter[str] = Counter() + by_sequence: dict[str, list[dict]] = defaultdict(list) + with vdjdb_tsv.open("r", encoding="utf-8", newline="") as handle: + reader = csv.DictReader(handle, delimiter="\t") + required = { + "gene", "cdr3", "species", "mhc.a", "mhc.b", "mhc.class", + "antigen.epitope", "reference.id", "vdjdb.score", "meta", "cdr3fix", + "v.segm", "j.segm", + } + missing = required.difference(reader.fieldnames or []) + if missing: + raise ValueError(f"VDJdb source is missing columns: {sorted(missing)}") + for row in reader: + counts["source_rows"] += 1 + normalized, reason = normalize_vdjdb_row(row, min_score=min_score) + counts[reason] += 1 + if normalized is not None: + by_sequence[normalized["cdr3"]].append(normalized) + + retained: list[dict] = [] + overlap_by_split: Counter[str] = Counter() + for sequence, rows in sorted(by_sequence.items()): + labels = {row["label"] for row in rows} + if len(labels) != 1: + counts["ambiguous_multilabel_clonotypes"] += 1 + continue + donors = {row["donor_key"] for row in rows} + if len(donors) != 1: + counts["multi_donor_clonotypes"] += 1 + continue + overlapping_splits = [ + split for split, sequences in benchmark_sequences.items() if sequence in sequences + ] + if overlapping_splits: + counts["benchmark_overlap_clonotypes"] += 1 + for split in overlapping_splits: + overlap_by_split[split] += 1 + continue + representative = min( + rows, + key=lambda item: ( + item["label"], item["donor_key"], item["reference_id"], -item["vdjdb_score"] + ), + ).copy() + representative["source_rows"] = len(rows) + retained.append(representative) + + counts["deduplicated_nonoverlap_clonotypes"] = len(retained) + report = { + "filter_counts": dict(sorted(counts.items())), + "benchmark_overlap_by_split": dict(sorted(overlap_by_split.items())), + } + return retained, report + + +def label_summary(records: Iterable[dict]) -> list[dict]: + groups: dict[str, list[dict]] = defaultdict(list) + for record in records: + groups[record["label"]].append(record) + summaries = [] + for label, rows in sorted(groups.items()): + lengths = sorted(row["length"] for row in rows) + summaries.append({ + "label": label, + "epitope": rows[0]["epitope"], + "mhc_a": rows[0]["mhc_a"], + "mhc_b": rows[0]["mhc_b"], + "mhc_class": rows[0]["mhc_class"], + "unique_cdr3": len(rows), + "donors": len({row["donor_key"] for row in rows}), + "length_min": lengths[0], + "length_median": lengths[len(lengths) // 2], + "length_max": lengths[-1], + }) + return summaries + + +def write_tsv(path: Path, rows: list[dict], fields: list[str]) -> None: + with path.open("w", encoding="utf-8", newline="") as handle: + writer = csv.DictWriter(handle, fieldnames=fields, delimiter="\t", lineterminator="\n") + writer.writeheader() + writer.writerows({field: row.get(field, "") for field in fields} for row in rows) + + +def smoke_checkpoint( + checkpoint_path: Path, + run_config_path: Path, + tokenizer_path: Path, + sequences: list[str], +) -> dict: + import torch + + from irrm_codec.multitask_data import resolve_encoder_tokenizer + from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer + from irrm_codec.tokenization import PAD_ID + + run_config = json.loads(run_config_path.read_text(encoding="utf-8")) + training = run_config["training"] + expected = { + "tokenizer_type": "data_anchor", + "latent_dim": 128, + "encoder_layers": 4, + "decoder_layers": 4, + "tcremp_loss_weight": 1.0, + "pgen_loss_weight": 1.0, + "reconstruction_loss_weight": 1.0, + "seed": 42, + } + observed = {key: training[key] for key in expected} + if observed != expected: + raise ValueError(f"Frozen checkpoint run is not the locked DATA-ANCHOR R+T+P model: {observed}") + + payload = torch.load(checkpoint_path, map_location="cpu", weights_only=False) + model_config = IRRMCodecConfig(**payload["model_config"]) + if asdict(model_config) != run_config["model"]: + raise ValueError("Checkpoint model_config differs from run_config.json") + model = IRRMCodecTransformer(model_config) + model.load_state_dict(payload["model_state"], strict=True) + model.eval() + tokenizer = resolve_encoder_tokenizer("data_anchor", str(tokenizer_path)) + if tokenizer.vocab_size != model_config.input_vocab_size: + raise ValueError("Tokenizer vocabulary does not match checkpoint input embedding") + encoded = [tokenizer.encode(sequence, model_config.max_sequence_len) for sequence in sequences[:2]] + width = max(map(len, encoded)) + tokens = torch.full((len(encoded), width), PAD_ID, dtype=torch.long) + for index, ids in enumerate(encoded): + tokens[index, : len(ids)] = torch.tensor(ids) + with torch.no_grad(): + latent = model.encode(tokens, tokens.ne(PAD_ID)) + if latent.shape != (len(encoded), model_config.latent_dim) or not torch.isfinite(latent).all(): + raise ValueError(f"Frozen encoder smoke output is invalid: {tuple(latent.shape)}") + return { + "checkpoint_epoch_zero_based": int(payload["epoch"]), + "checkpoint_best_val_loss": float(payload["best_val_loss"]), + "model_config": asdict(model_config), + "tokenizer_type": tokenizer.name, + "tokenizer_vocab_size": tokenizer.vocab_size, + "smoke_sequences": sequences[:2], + "smoke_token_lengths": [len(ids) for ids in encoded], + "smoke_latent_shape": list(latent.shape), + "smoke_latent_finite": True, + } + + +def main() -> None: + args = parse_args() + if args.min_support < 2 or args.min_donors < 2: + raise ValueError("Primary support and donor thresholds must both be at least two.") + output = args.output_dir + if output.exists(): + raise FileExistsError(f"Refusing to overwrite existing preflight directory: {output}") + output.mkdir(parents=True) + + benchmark_sequences, benchmark_hashes = read_benchmark_sequences(args.benchmark_dir) + records, inventory = prepare_records( + args.vdjdb_tsv, benchmark_sequences, min_score=args.min_vdjdb_score + ) + summaries = label_summary(records) + eligible_labels = { + row["label"] for row in summaries + if row["unique_cdr3"] >= args.min_support and row["donors"] >= args.min_donors + } + cohort = [row for row in records if row["label"] in eligible_labels] + if len(eligible_labels) < 2: + raise ValueError( + f"Primary rule yielded {len(eligible_labels)} eligible labels; at least two are required." + ) + + fields = [ + "cdr3", "label", "epitope", "mhc_a", "mhc_b", "mhc_class", "donor_key", + "reference_id", "vdjdb_score", "length", "source_rows", + ] + write_tsv(output / "cohort.tsv", cohort, fields) + write_tsv( + output / "label_summary.tsv", + summaries, + ["label", "epitope", "mhc_a", "mhc_b", "mhc_class", "unique_cdr3", "donors", + "length_min", "length_median", "length_max"], + ) + sensitivity = [] + for threshold in sorted(set(args.sensitivity_thresholds + [args.min_support])): + selected = [ + row for row in summaries + if row["unique_cdr3"] >= threshold and row["donors"] >= args.min_donors + ] + sensitivity.append({ + "min_unique_cdr3": threshold, + "min_donors": args.min_donors, + "eligible_labels": len(selected), + "eligible_clonotypes": sum(row["unique_cdr3"] for row in selected), + }) + write_tsv( + output / "threshold_sensitivity.tsv", sensitivity, + ["min_unique_cdr3", "min_donors", "eligible_labels", "eligible_clonotypes"], + ) + + checkpoint = smoke_checkpoint( + args.checkpoint, args.run_config, args.tokenizer, + [row["cdr3"] for row in cohort], + ) + protocol = { + "study_type": "single-cohort preflight; model comparison unresolved", + "primary_label": "antigen.epitope|mhc.a|mhc.b-or-dash|mhc.class", + "primary_selection": { + "all_labels_meeting_rule": True, + "min_unique_cdr3": args.min_support, + "min_donors": args.min_donors, + "vdjdb_score_min": args.min_vdjdb_score, + "exact_cdr3_deduplication": True, + "ambiguous_multilabel_cdr3_removed": True, + "multi_donor_cdr3_removed_for_clustered_inference": True, + "all_locked_benchmark_split_overlaps_removed": True, + }, + "future_metrics_after_model_protocol_acceptance": { + "primary": "per-label within/between cosine-distance ratio; lower is better", + "secondary_distance": "Euclidean", + "pairwise": ["same-label AUROC", "same-label AUPRC with sampled prevalence reported"], + "retrieval": ["donor-excluded precision@1/5/10", "donor-excluded MAP@R"], + "negative_control": "between-label pairs matched on ordered CDR3 lengths", + "nulls": [ + "absolute length-difference score", + "1000 label permutations within length bins and study/donor strata", + ], + "uncertainty": "2000 donor-cluster bootstrap replicates, fixed seed", + "visualization": "descriptive only; no UMAP/scaler/metric learning fit on evaluation data", + }, + "seed": args.seed, + "embedding_extraction_authorized": False, + "blocking_gate": "accept cohort and resolve matched model-comparison protocol", + } + stable_json(output / "evaluation_protocol.json", protocol) + stable_json(output / "inventory.json", inventory) + + manifest = { + "status": "ready_for_cohort_review_not_embedding_extraction", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "source": { + "path": str(args.vdjdb_tsv), + "sha256": sha256_file(args.vdjdb_tsv), + "bytes": args.vdjdb_tsv.stat().st_size, + }, + "benchmark": { + "path": str(args.benchmark_dir), + "manifest_sha256": benchmark_hashes, + "unique_sequences_by_split": { + split: len(values) for split, values in benchmark_sequences.items() + }, + }, + "frozen_checkpoint": { + "path": str(args.checkpoint), + "sha256": sha256_file(args.checkpoint), + "run_config_path": str(args.run_config), + "run_config_sha256": sha256_file(args.run_config), + "tokenizer_path": str(args.tokenizer), + "tokenizer_sha256": sha256_file(args.tokenizer), + **checkpoint, + }, + "cohort": { + "eligible_labels": len(eligible_labels), + "unique_cdr3": len(cohort), + "donors": len({row["donor_key"] for row in cohort}), + "cohort_sha256": sha256_file(output / "cohort.tsv"), + "label_summary_sha256": sha256_file(output / "label_summary.tsv"), + }, + "embedding_extraction_performed": False, + "evaluation_performed": False, + } + stable_json(output / "PREFLIGHT.json", manifest) + print(json.dumps(manifest, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_vdjdb_ylq.py b/benchmark/prepare_vdjdb_ylq.py new file mode 100644 index 0000000..1f8ca75 --- /dev/null +++ b/benchmark/prepare_vdjdb_ylq.py @@ -0,0 +1,216 @@ +"""Prepare an exact-peptide, dominant-MHC YLQ VDJdb evaluation cohort.""" + +from __future__ import annotations + +import argparse +import csv +import json +import os +from collections import Counter, defaultdict +from pathlib import Path + +import numpy as np + +from benchmark.prepare_vdjdb_epitope_cohort import ( + prepare_records, + read_benchmark_sequences, + sha256_file, + stable_json, + write_tsv, +) + + +TARGET_PEPTIDE = "YLQPRTFLL" +AA = "ACDEFGHIKLMNPQRSTVWY" + + +def composition(sequence: str) -> np.ndarray: + return np.asarray([sequence.count(aa) / len(sequence) for aa in AA], dtype=float) + + +def context(record: dict) -> tuple[str, str, str]: + return record["mhc_a"], record["mhc_b"] or "-", record["mhc_class"] + + +def build_pairs(positives: list[dict], negatives: list[dict], seed: int) -> tuple[list[dict], dict]: + rng = np.random.default_rng(seed) + positive_pairs = [ + (left, right) + for left in range(len(positives)) + for right in range(left + 1, len(positives)) + if positives[left]["donor_key"] != positives[right]["donor_key"] + ] + rng.shuffle(positive_pairs) + negative_by_length: dict[int, list[int]] = defaultdict(list) + negative_composition = [] + for index, record in enumerate(negatives): + negative_by_length[int(record["length"])].append(index) + negative_composition.append(composition(record["cdr3"])) + negative_composition = np.asarray(negative_composition) + usage: Counter[int] = Counter() + rows = [] + for pair_number, (query, positive) in enumerate(positive_pairs): + if rng.integers(2): + query, positive = positive, query + query_record = positives[query] + positive_record = positives[positive] + candidates = [ + index for index in negative_by_length[int(positive_record["length"])] + if negatives[index]["donor_key"] not in { + query_record["donor_key"], positive_record["donor_key"] + } + ] + if not candidates: + raise ValueError( + f"No exact-length donor-disjoint negative for positive length {positive_record['length']}." + ) + target_composition = composition(positive_record["cdr3"]) + def rank(index: int) -> tuple: + candidate = negatives[index] + v_missing = not positive_record["v_call"] or not candidate["v_call"] + j_missing = not positive_record["j_call"] or not candidate["j_call"] + v_mismatch = int(v_missing or candidate["v_call"] != positive_record["v_call"]) + j_mismatch = int(j_missing or candidate["j_call"] != positive_record["j_call"]) + comp_l1 = float(np.abs(negative_composition[index] - target_composition).sum()) + return v_mismatch + j_mismatch, usage[index], comp_l1, candidate["cdr3"] + negative = min(candidates, key=rank) + usage[negative] += 1 + negative_record = negatives[negative] + rows.append({ + "pair_id": pair_number, + "query_index": query, + "positive_index": positive, + "negative_index": len(positives) + negative, + "query_donor": query_record["donor_key"], + "positive_donor": positive_record["donor_key"], + "negative_donor": negative_record["donor_key"], + "query_length": query_record["length"], + "positive_length": positive_record["length"], + "negative_length": negative_record["length"], + "v_exact_match": int( + bool(positive_record["v_call"]) + and positive_record["v_call"] == negative_record["v_call"] + ), + "j_exact_match": int( + bool(positive_record["j_call"]) + and positive_record["j_call"] == negative_record["j_call"] + ), + "vj_exact_match": int( + bool(positive_record["v_call"] and positive_record["j_call"]) + and positive_record["v_call"] == negative_record["v_call"] + and positive_record["j_call"] == negative_record["j_call"] + ), + "composition_l1": float( + np.abs(negative_composition[negative] - target_composition).sum() + ), + }) + if not rows: + raise ValueError("No donor-disjoint positive YLQ pairs are available.") + report = { + "positive_pairs": len(rows), + "exact_length_fraction": 1.0, + "v_exact_match_fraction": float(np.mean([row["v_exact_match"] for row in rows])), + "j_exact_match_fraction": float(np.mean([row["j_exact_match"] for row in rows])), + "vj_exact_match_fraction": float(np.mean([row["vj_exact_match"] for row in rows])), + "mean_composition_l1": float(np.mean([row["composition_l1"] for row in rows])), + "unique_negatives_used": len(usage), + "max_negative_reuse": max(usage.values()), + } + return rows, report + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--vdjdb-tsv", type=Path, required=True) + parser.add_argument("--benchmark-dir", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--min-positive-cdr3", type=int, default=50) + parser.add_argument("--min-positive-donors", type=int, default=2) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + + benchmark, benchmark_hashes = read_benchmark_sequences(args.benchmark_dir) + records, inventory = prepare_records(args.vdjdb_tsv, benchmark, min_score=1.0) + exact_peptide = [record for record in records if record["epitope"] == TARGET_PEPTIDE] + distribution = [] + by_context: dict[tuple[str, str, str], list[dict]] = defaultdict(list) + for record in exact_peptide: + by_context[context(record)].append(record) + for key, rows in sorted(by_context.items(), key=lambda item: (-len(item[1]), item[0])): + distribution.append({ + "mhc_a": key[0], "mhc_b": key[1], "mhc_class": key[2], + "unique_cdr3": len(rows), "donors": len({row["donor_key"] for row in rows}), + }) + if not distribution: + raise ValueError("No exact YLQPRTFLL records remain after leakage filtering.") + dominant = distribution[0] + dominant_context = (dominant["mhc_a"], dominant["mhc_b"], dominant["mhc_class"]) + if dominant["unique_cdr3"] < args.min_positive_cdr3 or dominant["donors"] < args.min_positive_donors: + stable_json(args.output_dir / "BLOCKED.json", { + "status": "blocked_insufficient_support", "mhc_distribution": distribution, + }) + raise ValueError("Dominant exact YLQ peptide+MHC context has insufficient support.") + + positives = [ + record for record in exact_peptide if context(record) == dominant_context + ] + negatives = [ + record for record in records + if record["epitope"] != TARGET_PEPTIDE and context(record) == dominant_context + ] + if len(negatives) < 50: + raise ValueError(f"Only {len(negatives)} same-context non-YLQ negatives remain.") + candidates = [] + candidate_fields = [ + "candidate_index", "is_ylq", "cdr3", "epitope", "mhc_a", "mhc_b", "mhc_class", + "donor_key", "reference_id", "v_call", "j_call", "vdjdb_score", "length", "source_rows", + ] + for index, record in enumerate([*positives, *negatives]): + candidate = dict(record) + candidate["candidate_index"] = index + candidate["is_ylq"] = int(index < len(positives)) + candidates.append(candidate) + write_tsv(args.output_dir / "candidates.tsv", candidates, candidate_fields) + write_tsv( + args.output_dir / "mhc_distribution.tsv", distribution, + ["mhc_a", "mhc_b", "mhc_class", "unique_cdr3", "donors"], + ) + pairs, match_report = build_pairs(positives, negatives, seed=args.seed) + pair_fields = list(pairs[0]) + write_tsv(args.output_dir / "pair_manifest.tsv", pairs, pair_fields) + stable_json(args.output_dir / "inventory.json", inventory) + manifest = { + "status": "ready", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "target_peptide_definition": "exact equality to YLQPRTFLL", + "primary_context_rule": "dominant exact peptide+MHC context after all filters", + "primary_context": { + **dominant, + "label": "|".join(dominant_context), + }, + "mhc_distribution": distribution, + "positive_cdr3": len(positives), + "positive_donors": len({row["donor_key"] for row in positives}), + "same_context_non_ylq_negative_cdr3": len(negatives), + "same_context_non_ylq_negative_donors": len({row["donor_key"] for row in negatives}), + "matching": match_report, + "leakage": inventory, + "source": {"path": str(args.vdjdb_tsv), "sha256": sha256_file(args.vdjdb_tsv)}, + "benchmark_manifest_sha256": benchmark_hashes, + "artifacts": { + "candidates_sha256": sha256_file(args.output_dir / "candidates.tsv"), + "pairs_sha256": sha256_file(args.output_dir / "pair_manifest.tsv"), + "mhc_distribution_sha256": sha256_file(args.output_dir / "mhc_distribution.tsv"), + }, + "motif_expansion_performed": False, + "embedding_extraction_performed": False, + } + stable_json(args.output_dir / "PREFLIGHT.json", manifest) + print(json.dumps(manifest, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_vdjdb_ylq_motif_pooled.py b/benchmark/prepare_vdjdb_ylq_motif_pooled.py new file mode 100644 index 0000000..701d984 --- /dev/null +++ b/benchmark/prepare_vdjdb_ylq_motif_pooled.py @@ -0,0 +1,458 @@ +"""Prepare pooled exact-YLQ evaluation data from official VDJdb motif members.""" + +from __future__ import annotations + +import argparse +import csv +import json +import math +import os +from collections import Counter, defaultdict +from pathlib import Path + +import numpy as np + +from benchmark.prepare_vdjdb_epitope_cohort import ( + VALID_AA, + clean_text, + normalized_context, + parse_json_object, + read_benchmark_sequences, + sha256_file, + stable_json, + write_tsv, +) + + +TARGET_PEPTIDE = "YLQPRTFLL" +TARGET_CONTEXT = ("HLA-A*02:01", "B2M", "MHCI") +AA = "ACDEFGHIKLMNPQRSTVWY" + + +def composition(sequence: str) -> np.ndarray: + return np.asarray([sequence.count(aa) / len(sequence) for aa in AA], dtype=float) + + +def read_official_members(path: Path) -> tuple[dict[tuple[str, str], set[str]], dict]: + counts: Counter[str] = Counter() + membership: dict[tuple[str, str], set[str]] = defaultdict(set) + with path.open("r", encoding="utf-8", newline="") as handle: + reader = csv.DictReader(handle, delimiter="\t") + required = { + "species", "antigen.epitope", "mhc.a", "mhc.b", "mhc.class", "gene", + "cdr3aa", "cid", "csz", "v.segm", "j.segm", + } + missing = required.difference(reader.fieldnames or []) + if missing: + raise ValueError(f"Official cluster-members file lacks columns: {sorted(missing)}") + for row in reader: + counts["source_rows"] += 1 + if normalized_context(row["species"]) != "HOMOSAPIENS": + continue + if normalized_context(row["gene"]) != "TRB": + continue + context = ( + normalized_context(row["mhc.a"]), normalized_context(row["mhc.b"]), + normalized_context(row["mhc.class"]), + ) + if context != TARGET_CONTEXT: + continue + counts["exact_context_trb_rows"] += 1 + sequence = normalized_context(row["cdr3aa"]) + peptide = normalized_context(row["antigen.epitope"]) + cid = clean_text(row["cid"]) + if not sequence or len(sequence) > 40 or set(sequence).difference(VALID_AA): + counts["invalid_member_cdr3"] += 1 + continue + if not peptide or not cid: + counts["missing_member_label_or_cid"] += 1 + continue + membership[(sequence, peptide)].add(cid) + counts["valid_exact_context_membership_rows"] += 1 + if peptide == TARGET_PEPTIDE: + counts["exact_ylq_membership_rows"] += 1 + report = { + "counts": dict(sorted(counts.items())), + "unique_sequence_peptide_memberships": len(membership), + "unique_ylq_member_cdr3": len({key[0] for key in membership if key[1] == TARGET_PEPTIDE}), + } + return membership, report + + +def read_joined_records( + vdjdb_path: Path, + membership: dict[tuple[str, str], set[str]], + benchmark: dict[str, set[str]], + min_score: float, +) -> tuple[list[dict], dict]: + counts: Counter[str] = Counter() + overlap: Counter[str] = Counter() + grouped: dict[str, list[dict]] = defaultdict(list) + with vdjdb_path.open("r", encoding="utf-8", newline="") as handle: + reader = csv.DictReader(handle, delimiter="\t") + required = { + "gene", "cdr3", "v.segm", "j.segm", "species", "mhc.a", "mhc.b", + "mhc.class", "antigen.epitope", "reference.id", "vdjdb.score", "meta", "cdr3fix", + } + missing = required.difference(reader.fieldnames or []) + if missing: + raise ValueError(f"Pinned VDJdb table lacks columns: {sorted(missing)}") + for row in reader: + counts["source_rows"] += 1 + if normalized_context(row["gene"]) != "TRB": + continue + if normalized_context(row["species"]) != "HOMOSAPIENS": + continue + context = ( + normalized_context(row["mhc.a"]), normalized_context(row["mhc.b"]), + normalized_context(row["mhc.class"]), + ) + if context != TARGET_CONTEXT: + continue + counts["exact_context_trb_rows"] += 1 + sequence = normalized_context(row["cdr3"]) + if not sequence or len(sequence) > 40 or set(sequence).difference(VALID_AA): + counts["invalid_cdr3"] += 1 + continue + fix = parse_json_object(row.get("cdr3fix", "")) + if fix.get("good") is not True: + counts["cdr3fix_not_good"] += 1 + continue + fixed = normalized_context(fix.get("cdr3")) + if fixed and fixed != sequence: + counts["cdr3fix_changes_sequence"] += 1 + continue + try: + score = float(row["vdjdb.score"]) + except ValueError: + score = math.nan + if not math.isfinite(score) or score < min_score: + counts["low_or_invalid_score"] += 1 + continue + peptide = normalized_context(row["antigen.epitope"]) + key = (sequence, peptide) + if key not in membership: + counts["not_official_motif_member"] += 1 + continue + counts["exact_official_membership_join_rows"] += 1 + overlapping = [split for split, sequences in benchmark.items() if sequence in sequences] + if overlapping: + counts["benchmark_overlap_rows"] += 1 + for split in overlapping: + overlap[split] += 1 + continue + meta = parse_json_object(row.get("meta", "")) + subject = clean_text(meta.get("subject.id") or meta.get("subject_id")) + study = clean_text(meta.get("study.id") or meta.get("study_id") or row["reference.id"]) + grouped[sequence].append({ + "cdr3": sequence, + "epitope": peptide, + "mhc_a": TARGET_CONTEXT[0], + "mhc_b": TARGET_CONTEXT[1], + "mhc_class": TARGET_CONTEXT[2], + "v_call": normalized_context(row["v.segm"]), + "j_call": normalized_context(row["j.segm"]), + "reference_id": clean_text(row["reference.id"]), + "vdjdb_score": score, + "donor_key": f"{study}|{subject}" if subject else "", + "motif_cids": membership[key], + "length": len(sequence), + }) + + retained = [] + for sequence, rows in sorted(grouped.items()): + epitopes = {row["epitope"] for row in rows} + if len(epitopes) != 1: + counts["ambiguous_multilabel_cdr3"] += 1 + continue + representative = min( + rows, + key=lambda row: ( + -row["vdjdb_score"], row["epitope"], row["v_call"], row["j_call"], + row["reference_id"], + ), + ).copy() + representative["source_rows"] = len(rows) + representative["donor_count_descriptive_only"] = len({ + row["donor_key"] for row in rows if row["donor_key"] + }) + representative["motif_cids"] = ",".join(sorted({ + cid for row in rows for cid in row["motif_cids"] + })) + retained.append(representative) + counts["pooled_exact_cdr3_after_dedup"] = len(retained) + return retained, { + "filter_counts": dict(sorted(counts.items())), + "benchmark_overlap_rows_by_split": dict(sorted(overlap.items())), + } + + +def build_pairs(positives: list[dict], negatives: list[dict], seed: int) -> tuple[list[dict], dict]: + rng = np.random.default_rng(seed) + positive_pairs = [(left, right) for left in range(len(positives)) + for right in range(left + 1, len(positives))] + rng.shuffle(positive_pairs) + negative_by_length: dict[int, list[int]] = defaultdict(list) + negative_composition = np.asarray([composition(record["cdr3"]) for record in negatives]) + for index, record in enumerate(negatives): + negative_by_length[int(record["length"])].append(index) + usage: Counter[int] = Counter() + rows = [] + excluded_no_control_pairs = 0 + forced_orientation_pairs = 0 + for pair_id, (query, positive) in enumerate(positive_pairs): + query_supported = bool(negative_by_length.get(int(positives[query]["length"]), [])) + positive_supported = bool(negative_by_length.get(int(positives[positive]["length"]), [])) + if not query_supported and not positive_supported: + excluded_no_control_pairs += 1 + continue + if query_supported and not positive_supported: + query, positive = positive, query + forced_orientation_pairs += 1 + elif not query_supported and positive_supported: + forced_orientation_pairs += 1 + elif rng.integers(2): + query, positive = positive, query + qrow, prow = positives[query], positives[positive] + candidates = negative_by_length.get(int(prow["length"]), []) + if not candidates: + raise ValueError(f"No exact-length official-motif negative for length {prow['length']}.") + target = composition(prow["cdr3"]) + + def rank(index: int) -> tuple: + candidate = negatives[index] + v_mismatch = int(not prow["v_call"] or not candidate["v_call"] + or prow["v_call"] != candidate["v_call"]) + j_mismatch = int(not prow["j_call"] or not candidate["j_call"] + or prow["j_call"] != candidate["j_call"]) + comp_l1 = float(np.abs(negative_composition[index] - target).sum()) + return comp_l1, v_mismatch + j_mismatch, usage[index], candidate["cdr3"] + + negative = min(candidates, key=rank) + usage[negative] += 1 + nrow = negatives[negative] + rows.append({ + "pair_id": pair_id, + "query_index": query, + "positive_index": positive, + "negative_index": len(positives) + negative, + "query_cdr3": qrow["cdr3"], + "positive_cdr3": prow["cdr3"], + "negative_cdr3": nrow["cdr3"], + "query_length": qrow["length"], + "positive_length": prow["length"], + "negative_length": nrow["length"], + "v_exact_match": int(bool(prow["v_call"]) + and prow["v_call"] == nrow["v_call"]), + "j_exact_match": int(bool(prow["j_call"]) + and prow["j_call"] == nrow["j_call"]), + "composition_l1": float(np.abs(negative_composition[negative] - target).sum()), + }) + if not rows: + raise ValueError("No distinct pooled positive CDR3 pairs are available.") + return rows, { + "positive_pairs": len(rows), + "all_possible_positive_pairs": len(positive_pairs), + "excluded_pairs_both_endpoints_lack_exact_length_controls": excluded_no_control_pairs, + "forced_orientation_to_supported_comparator": forced_orientation_pairs, + "donor_constraint": "none_pooled_by_user_protocol", + "distinct_cdr3_triplets": True, + "exact_length_fraction": 1.0, + "v_exact_match_fraction": float(np.mean([row["v_exact_match"] for row in rows])), + "j_exact_match_fraction": float(np.mean([row["j_exact_match"] for row in rows])), + "mean_composition_l1": float(np.mean([row["composition_l1"] for row in rows])), + "unique_negatives_used": len(usage), + "max_negative_reuse": max(usage.values()), + } + + +def select_compact_negatives( + positives: list[dict], negatives: list[dict], per_positive: int, seed: int, +) -> tuple[list[dict], list[dict], list[dict], dict]: + """Select globally unique same-length controls in seeded per-stratum rounds.""" + if per_positive < 1: + raise ValueError("Controls per positive must be positive.") + negative_by_length: dict[int, list[int]] = defaultdict(list) + negative_composition = np.asarray([composition(record["cdr3"]) for record in negatives]) + for index, record in enumerate(negatives): + negative_by_length[int(record["length"])].append(index) + positive_by_length: dict[int, list[int]] = defaultdict(list) + for index, record in enumerate(positives): + positive_by_length[int(record["length"])].append(index) + + selected: list[int] = [] + used: set[int] = set() + assignments = [] + strata = [] + for length in sorted(positive_by_length): + positive_indices = sorted(positive_by_length[length], key=lambda index: positives[index]["cdr3"]) + rng = np.random.default_rng(seed + length) + positive_indices = [positive_indices[index] for index in rng.permutation(len(positive_indices))] + available_in_stratum = negative_by_length.get(length, []) + for slot in range(1, per_positive + 1): + for positive_index in positive_indices: + candidates = [index for index in available_in_stratum if index not in used] + if not candidates: + break + positive = positives[positive_index] + target = composition(positive["cdr3"]) + + def rank(index: int) -> tuple: + candidate = negatives[index] + comp_l1 = float(np.abs(negative_composition[index] - target).sum()) + v_mismatch = int(not positive["v_call"] or not candidate["v_call"] + or positive["v_call"] != candidate["v_call"]) + j_mismatch = int(not positive["j_call"] or not candidate["j_call"] + or positive["j_call"] != candidate["j_call"]) + return comp_l1, v_mismatch + j_mismatch, candidate["cdr3"] + + chosen = min(candidates, key=rank) + used.add(chosen) + selected.append(chosen) + control = negatives[chosen] + assignments.append({ + "selection_order": len(assignments), + "length": length, + "slot_for_positive": slot, + "positive_cdr3": positive["cdr3"], + "control_cdr3": control["cdr3"], + "composition_l1": float(np.abs(negative_composition[chosen] - target).sum()), + "v_exact_match": int(bool(positive["v_call"]) + and positive["v_call"] == control["v_call"]), + "j_exact_match": int(bool(positive["j_call"]) + and positive["j_call"] == control["j_call"]), + }) + selected_count = sum(1 for row in assignments if row["length"] == length) + target_count = per_positive * len(positive_indices) + strata.append({ + "length": length, + "positive_cdr3": len(positive_indices), + "eligible_negative_cdr3": len(available_in_stratum), + "nominal_target": target_count, + "selected_unique_controls": selected_count, + "shortfall": target_count - selected_count, + "all_available_retained_if_short": int(len(available_in_stratum) < target_count), + }) + selected_records = [negatives[index] for index in selected] + if len({record["cdr3"] for record in selected_records}) != len(selected_records): + raise ValueError("Compact control selector reused a CDR3.") + report = { + "selection_seed": seed, + "controls_per_positive_cap": per_positive, + "nominal_global_cap": per_positive * len(positives), + "eligible_controls_before_compaction": len(negatives), + "selected_unique_controls": len(selected_records), + "selection_without_replacement": True, + "gallery_control_reuse": 0, + "selection_priority": "minimum AA-composition L1, then V/J mismatch count, then CDR3", + "length_strata": strata, + } + return selected_records, assignments, strata, report + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--vdjdb-tsv", type=Path, required=True) + parser.add_argument("--cluster-members", type=Path, required=True) + parser.add_argument("--motif-pwms", type=Path, required=True) + parser.add_argument("--benchmark-dir", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--min-score", type=float, default=1.0) + parser.add_argument("--min-positives", type=int, default=50) + parser.add_argument("--min-negatives", type=int, default=100) + parser.add_argument("--controls-per-positive", type=int, default=4) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + + benchmark, benchmark_hashes = read_benchmark_sequences(args.benchmark_dir) + membership, motif_report = read_official_members(args.cluster_members) + records, join_report = read_joined_records( + args.vdjdb_tsv, membership, benchmark, args.min_score + ) + positives = [record for record in records if record["epitope"] == TARGET_PEPTIDE] + eligible_negatives = [record for record in records if record["epitope"] != TARGET_PEPTIDE] + if len(positives) < args.min_positives or len(eligible_negatives) < args.min_negatives: + blocked = { + "status": "blocked_insufficient_official_motif_support", + "positive_cdr3": len(positives), "negative_cdr3": len(eligible_negatives), + "motif": motif_report, "join": join_report, + } + stable_json(args.output_dir / "BLOCKED.json", blocked) + raise ValueError( + f"Insufficient support after join: {len(positives)} positives, " + f"{len(eligible_negatives)} negatives" + ) + + negatives, control_assignments, length_strata, control_report = select_compact_negatives( + positives, eligible_negatives, args.controls_per_positive, args.seed + ) + + candidates = [] + fields = [ + "candidate_index", "is_ylq", "cdr3", "epitope", "mhc_a", "mhc_b", "mhc_class", + "v_call", "j_call", "reference_id", "vdjdb_score", "length", "motif_cids", + "source_rows", "donor_count_descriptive_only", + ] + for index, record in enumerate([*positives, *negatives]): + candidate = dict(record) + candidate["candidate_index"] = index + candidate["is_ylq"] = int(index < len(positives)) + candidates.append(candidate) + if len({row["cdr3"] for row in candidates}) != len(candidates): + raise ValueError("Candidate set is not exact-CDR3 deduplicated.") + write_tsv(args.output_dir / "candidates.tsv", candidates, fields) + write_tsv( + args.output_dir / "control_selection.tsv", control_assignments, + list(control_assignments[0]), + ) + write_tsv(args.output_dir / "control_length_strata.tsv", length_strata, list(length_strata[0])) + pairs, matching = build_pairs(positives, negatives, args.seed) + write_tsv(args.output_dir / "pair_manifest.tsv", pairs, list(pairs[0])) + manifest = { + "status": "ready", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "target_peptide": TARGET_PEPTIDE, + "exact_context": {"mhc_a": TARGET_CONTEXT[0], "mhc_b": TARGET_CONTEXT[1], + "mhc_class": TARGET_CONTEXT[2]}, + "pooling": "all records pooled; donor metadata is descriptive only and never constrains pairs/retrieval", + "positive_cdr3": len(positives), + "negative_cdr3": len(negatives), + "eligible_negative_cdr3_before_compaction": len(eligible_negatives), + "candidate_cdr3": len(candidates), + "matching": matching, + "compact_control_selection": control_report, + "motif_inventory": motif_report, + "vdjdb_join_and_quality": join_report, + "sources": { + "vdjdb": {"path": str(args.vdjdb_tsv), "sha256": sha256_file(args.vdjdb_tsv)}, + "cluster_members": {"path": str(args.cluster_members), + "sha256": sha256_file(args.cluster_members)}, + "motif_pwms": {"path": str(args.motif_pwms), "sha256": sha256_file(args.motif_pwms)}, + "benchmark_manifests": benchmark_hashes, + }, + "artifacts": { + "candidates_sha256": sha256_file(args.output_dir / "candidates.tsv"), + "pairs_sha256": sha256_file(args.output_dir / "pair_manifest.tsv"), + "control_selection_sha256": sha256_file(args.output_dir / "control_selection.tsv"), + "control_length_strata_sha256": sha256_file(args.output_dir / "control_length_strata.tsv"), + }, + "official_motif_rule": ( + "Exact sequence+peptide membership in official cluster_members.txt after exact " + "HomoSapiens/TRB/HLA-A*02:01/B2M/MHCI filtering; no PWM scanning or motif mining." + ), + "circularity_caveat": ( + "Official motif membership is sequence-cluster-conditioned. This evaluates within-VDJdb " + "motif/epitope organization, not independent epitope evidence beyond sequence motif/composition." + ), + "exploratory_n40_protocol": True, + "embedding_extraction_performed": False, + } + stable_json(args.output_dir / "PREFLIGHT.json", manifest) + print(json.dumps(manifest, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/docs/anchored_tokenizer_study.md b/docs/anchored_tokenizer_study.md new file mode 100644 index 0000000..bc72e4c --- /dev/null +++ b/docs/anchored_tokenizer_study.md @@ -0,0 +1,70 @@ +# Leakage-safe sequence-only anchored tokenizer study + +## Formal mapping + +For a validated amino-acid CDR3 string `s`, each candidate implements + +`T(s) = [a_N(s), WP(m(s)), a_C(s)]`, + +where `a_N(s)` and `a_C(s)` are literal substrings of `s`, `m(s)` is exactly +the intervening substring, and `WP` is a WordPiece model fitted only to middle +spans from a benchmark-disjoint independently generated TRB corpus. Concatenating +the decoded token surfaces must reproduce `s` byte-for-byte. The encoder accepts +only `s`; neither `v_call` nor `j_call` is an inference input. The reconstruction +decoder remains the unchanged 25-token character decoder. + +All tokenizers reserve PAD/BOS/EOS/UNK IDs 0/1/2/3. Normal validated inputs never +emit UNK. Input tokens have exactly one of three boundary types: `N_ANCHOR`, +`MIDDLE_WORDPIECE`, or `C_ANCHOR`. + +## Candidates + +1. **EDGE-3 (`edge_k`)** protects the first and last three residues as one token + each. Its vocabulary exhaustively enumerates every 3-mer over the 20 + standard amino acids (8,000 tokens per side). This makes every valid literal + edge representable without observing evaluation sequences. K=3 is + the largest feasible non-overlapping choice because the locked benchmark's + recorded minimum CDR3 length is seven; K=4 would require eight residues and + failed the CPU coverage gate. Inputs shorter than six or containing invalid + amino acids fail closed. +2. **DATA-ANCHOR (`data_anchor`)** mines literal prefixes and suffixes of length + 2–8 from locked train rows only. A motif is retained when it has at least 50 + train occurrences and at least 25 occurrences within one annotated V (N side) + or J (C side) gene. V/J calls restrict the train-only library construction but + are discarded before encoding. All 20 one-residue identity fallbacks are + reserved constants (not learned motifs), guaranteeing sequence-only coverage + without held-out fitting. +3. **GERMLINE-ANCHOR (`germline_anchor`)** translates the functional V and J + CDR3-compatible segments in the documented OLGA human `TRB_orig` model using + its V/J anchor-index CSVs. Literal prefixes/suffixes of length 1–8 are retained + only if at least 20 locked train sequences support them. The exact source-file + hashes are recorded. All 20 one-residue identity fallbacks are reserved + constants; multi-residue germline motifs remain reference-derived and + train-supported. Encoding still operates solely by literal sequence match. + +For variable anchors, all matching prefix/suffix pairs that do not overlap are +considered. Selection maximizes total protected length, then N length, then C +length, then uses lexical order. Distinct same-length literal matches cannot both +match the same edge; collision counts and overlap-driven fallback counts are +nonetheless audited. If no identity fallback pair exists, encoding fails closed. + +## Corpus and leakage controls + +The preferred central corpus is a deterministic 500,000-row subset streamed from +the independently generated OLGA human TRB corpus +`/projects/immunestatus/vdjrearm/sample/TRB_1e7.tsv.gz`. Its generation script, +OLGA model files, and corpus are hashed. Every locked train, validation, and test +CDR3 is removed before fitting, duplicates and invalid rows are removed, and the +recorded final overlap must be zero. The external corpus influences central +WordPiece only; DATA and GERMLINE anchor retention uses locked train evidence +only. Validation and test strings are used solely for post-fit audits and metrics. + +## Matched experiment rule + +All three candidates use full R+T+P supervision, seed 42, d-model 320, latent 128, +four encoder and four decoder layers, batch 64, 40 epochs, AdamW at 3e-4, and the +locked train-only normalizer. Apart from input tokenizer path/type and the implied +input embedding vocabulary size/parameter count, configurations match the selected +character baseline. Selection uses validation metrics only; test metrics are +descriptive. Any annotation-aware V/J-input condition would be a separate modality +and is outside this study. diff --git a/docs/vdjdb_epitope_validation.md b/docs/vdjdb_epitope_validation.md new file mode 100644 index 0000000..a182f1e --- /dev/null +++ b/docs/vdjdb_epitope_validation.md @@ -0,0 +1,59 @@ +# VDJdb epitope-separation validation gate + +This study asks whether frozen IRRM-CODEC latent vectors separate epitope/MHC +labels: within-label distances must be lower than matched between-label +distances. It is a quantitative held-out validation, not a visualization study. + +## Cohort rule (locked before embeddings) + +- Source: official VDJdb `2025-07-30` `vdjdb.txt`; the CPU preflight records its + byte size and SHA-256. +- Retain human TRB rows with canonical CDR3 amino acids (length at most 40), + `cdr3fix.good=true` without a sequence-changing fix, VDJdb score at least 1, + a peptide, MHC-A and MHC class, and a subject identifier. +- The label is the exact normalized tuple `(epitope, mhc.a, mhc.b, mhc.class)`. + This avoids pooling the same peptide across distinct MHC contexts. +- Donors are keyed by `(study-or-reference, subject.id)` so generic identifiers + such as `donor1` do not collide across studies. +- Deduplicate exact CDR3s. Remove CDR3s assigned to multiple labels, CDR3s + observed under multiple donors (for unambiguous donor-cluster inference), and + overlaps with any locked benchmark train, validation, or test split. +- Primary cohort: every label with at least 50 unique remaining CDR3s and at + least two donors. Report fixed threshold sensitivities at 25, 50, and 100. + +The CPU job writes the immutable candidate table, per-label counts, overlap and +filter counts, threshold sensitivity, hashes, and a finite two-sequence CPU +smoke encoding. It explicitly does not extract the full embedding matrix. + +## Model-comparison gate + +The completed DATA-ANCHOR run is R+T+P only. The required primary matrix is +matched DATA-ANCHOR R-only, P-only, R+P, and R+T+P encoders, with the same train +data, tokenizer bundle, seed, architecture, optimizer, batch size, 40-epoch +budget, and validation-only checkpoint selection. R+P versus R+T+P is the direct +test of TCRemP's incremental value conditional on reconstruction and pgen. +T-only and R+T are useful optional attribution conditions, but are not required +for this primary comparison. The current multi-task implementation always +constructs the shared encoder, decoder, TCRemP head, and pgen head. Therefore +zeroing unused loss weights yields checkpoint-compatible P-only encoders; its +decoder and TCRemP head remain present but intentionally untrained, and their +metrics are not interpretable. + +A separate, narrower auxiliary-head analysis uses R-only, R+T, R+P, and R+T+P. +The existing character-tokenizer quartet can answer that question for the char +condition, but cannot be mixed with DATA-ANCHOR R+T+P: tokenizer vocabulary, +input embeddings, latent width, and objective would be confounded. + +No embeddings or outcome metrics are produced until the cohort and matched +model-comparison matrix are accepted. + +## Future metrics (preregistered) + +Primary: per-label within/between cosine-distance ratio (lower is better), with +length-matched between-label pairs. Secondary: Euclidean contrast, same-label +pair AUROC/AUPRC, donor-excluded precision@1/5/10, and MAP@R. Controls are an +absolute length-difference score and 1,000 label permutations within length and +study/donor strata. Uncertainty uses 2,000 donor-cluster bootstrap replicates. +All compared checkpoints use the same cohort, pair manifest, and resamples. +UMAP is not a primary endpoint and no scaler or metric learner is fit on these +held-out records. diff --git a/irrm_codec/anchored_tokenization.py b/irrm_codec/anchored_tokenization.py new file mode 100644 index 0000000..bab2431 --- /dev/null +++ b/irrm_codec/anchored_tokenization.py @@ -0,0 +1,186 @@ +"""Sequence-only terminal-anchor tokenizers with a WordPiece middle. + +The serialized bundle keeps protected literal N/C anchors in one input token and +uses an independently trained WordPiece model only for the remaining middle. +No V/J annotation is accepted by the runtime encoder. +""" + +from __future__ import annotations + +import json +from dataclasses import dataclass +from pathlib import Path + +from tokenizers import Tokenizer + +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID, VALID_AA + + +SPECIAL_TOKENS = ["[PAD]", "[BOS]", "[EOS]", "[UNK]"] +EXPECTED_SPECIAL_IDS = { + "[PAD]": PAD_ID, + "[BOS]": BOS_ID, + "[EOS]": EOS_ID, + "[UNK]": UNK_ID, +} +SUPPORTED_KINDS = {"edge_k", "data_anchor", "germline_anchor"} + + +@dataclass(frozen=True) +class AnchoredEncoding: + ids: list[int] + tokens: list[str] + boundary_types: list[str] + n_anchor: str + middle: str + c_anchor: str + + +def _normalize(sequence: str, max_len: int) -> str: + sequence = "" if sequence is None else str(sequence).strip().upper() + if not sequence: + raise ValueError("Sequence must not be empty.") + invalid = sorted(set(sequence).difference(VALID_AA)) + if invalid: + raise ValueError(f"Sequence contains unsupported amino acids: {invalid}") + if len(sequence) > max_len: + raise ValueError( + f"Sequence length {len(sequence)} exceeds max_len={max_len}." + ) + return sequence + + +class AnchoredTokenizer: + """Runtime encoder for an immutable anchored-tokenizer bundle.""" + + def __init__(self, bundle_path: str | Path): + self.bundle_path = Path(bundle_path) + payload = json.loads(self.bundle_path.read_text(encoding="utf-8")) + kind = payload.get("tokenizer_type") + if kind not in SUPPORTED_KINDS: + raise ValueError(f"Unsupported anchored tokenizer type: {kind!r}.") + self.kind = str(kind) + self.k = int(payload.get("k") or 0) + self.n_anchors = tuple(payload["n_anchors"]) + self.c_anchors = tuple(payload["c_anchors"]) + self.n_anchor_set = set(self.n_anchors) + self.c_anchor_set = set(self.c_anchors) + self.vocab = {str(token): int(identifier) for token, identifier in payload["vocab"].items()} + self.id_to_token = {identifier: token for token, identifier in self.vocab.items()} + if len(self.vocab) != len(self.id_to_token): + raise ValueError("Anchored vocabulary IDs must be unique.") + for token, expected in EXPECTED_SPECIAL_IDS.items(): + if self.vocab.get(token) != expected: + raise ValueError( + f"Anchored tokenizer has {token}={self.vocab.get(token)}, expected {expected}." + ) + expected_ids = list(range(len(self.vocab))) + if sorted(self.id_to_token) != expected_ids: + raise ValueError("Anchored vocabulary IDs must be contiguous from zero.") + central_path = self.bundle_path.parent / payload["central_tokenizer_file"] + self.central = Tokenizer.from_file(str(central_path)) + for token, expected in EXPECTED_SPECIAL_IDS.items(): + if self.central.token_to_id(token) != expected: + raise ValueError( + f"Central WordPiece has {token}={self.central.token_to_id(token)}, expected {expected}." + ) + self.central_to_input = { + int(key): int(value) for key, value in payload["central_to_input"].items() + } + self.input_to_central = {value: key for key, value in self.central_to_input.items()} + + @property + def vocab_size(self) -> int: + return len(self.vocab) + + def _select_anchors(self, sequence: str) -> tuple[str, str]: + if self.kind == "edge_k": + if len(sequence) < 2 * self.k: + raise ValueError( + f"EDGE-{self.k} requires sequence length >= {2 * self.k}, got {len(sequence)}." + ) + n_anchor = sequence[: self.k] + c_anchor = sequence[-self.k :] + if n_anchor not in self.n_anchor_set or c_anchor not in self.c_anchor_set: + raise ValueError( + f"EDGE-{self.k} literal is absent from the exhaustive anchor inventory: {sequence!r}." + ) + return n_anchor, c_anchor + + n_matches = [anchor for anchor in self.n_anchors if sequence.startswith(anchor)] + c_matches = [anchor for anchor in self.c_anchors if sequence.endswith(anchor)] + feasible = [ + (n_anchor, c_anchor) + for n_anchor in n_matches + for c_anchor in c_matches + if len(n_anchor) + len(c_anchor) <= len(sequence) + ] + if not feasible: + raise ValueError(f"No non-overlapping protected anchor pair matches {sequence!r}.") + # Longest combined literal coverage, then longer N, then longer C, then lexical. + return min( + feasible, + key=lambda pair: ( + -(len(pair[0]) + len(pair[1])), + -len(pair[0]), + -len(pair[1]), + pair[0], + pair[1], + ), + ) + + def encode_with_boundaries(self, sequence: str, max_len: int) -> AnchoredEncoding: + sequence = _normalize(sequence, max_len=max_len) + n_anchor, c_anchor = self._select_anchors(sequence) + middle = sequence[len(n_anchor) : len(sequence) - len(c_anchor)] + central_encoding = self.central.encode(middle) if middle else None + central_ids = [] if central_encoding is None else central_encoding.ids + if UNK_ID in central_ids: + raise ValueError(f"Central WordPiece emitted [UNK] for middle {middle!r}.") + try: + input_middle_ids = [self.central_to_input[identifier] for identifier in central_ids] + n_id = self.vocab[f"[N:{n_anchor}]"] + c_id = self.vocab[f"[C:{c_anchor}]"] + except KeyError as error: + raise ValueError(f"Anchored tokenizer bundle is missing token {error.args[0]!r}.") from error + ids = [n_id, *input_middle_ids, c_id] + if len(ids) > max_len: + raise ValueError( + f"Sequence {sequence!r} encodes to {len(ids)} tokens, exceeding max_len={max_len}." + ) + tokens = [self.id_to_token[identifier] for identifier in ids] + return AnchoredEncoding( + ids=ids, + tokens=tokens, + boundary_types=["N_ANCHOR", *(["MIDDLE_WORDPIECE"] * len(input_middle_ids)), "C_ANCHOR"], + n_anchor=n_anchor, + middle=middle, + c_anchor=c_anchor, + ) + + def encode(self, sequence: str, max_len: int) -> list[int]: + return self.encode_with_boundaries(sequence, max_len).ids + + def decode(self, ids: list[int]) -> str: + tokens = [self.id_to_token[int(identifier)] for identifier in ids] + if len(tokens) < 2 or not tokens[0].startswith("[N:") or not tokens[-1].startswith("[C:"): + raise ValueError("Anchored encoding must start with N_ANCHOR and end with C_ANCHOR.") + n_anchor = tokens[0][3:-1] + c_anchor = tokens[-1][3:-1] + central_ids = [self.input_to_central[int(identifier)] for identifier in ids[1:-1]] + middle = self.central.decode(central_ids, skip_special_tokens=True) if central_ids else "" + return f"{n_anchor}{middle}{c_anchor}" + + +class AnchoredUnpaddedEncodeFn: + """Picklable callable used by multi-worker benchmark DataLoaders.""" + + def __init__(self, tokenizer: AnchoredTokenizer): + self.tokenizer = tokenizer + + def __call__(self, sequence: str, max_len: int) -> list[int]: + return self.tokenizer.encode(sequence, max_len) + + +def load_anchored_tokenizer(path: str | Path) -> AnchoredTokenizer: + return AnchoredTokenizer(path) diff --git a/irrm_codec/multitask_data.py b/irrm_codec/multitask_data.py new file mode 100644 index 0000000..1550b74 --- /dev/null +++ b/irrm_codec/multitask_data.py @@ -0,0 +1,368 @@ +"""Prepared-benchmark data pipeline for joint IRRM-CODEC training.""" + +from dataclasses import dataclass +from pathlib import Path +from typing import Callable + +import numpy as np +import pandas as pd +import torch +from torch.utils.data import DataLoader, Dataset + +from irrm_codec.tokenization import ( + AA_VOCAB, + PAD_ID, + encode_raw, + encode_reconstruction_pair, +) +REQUIRED_DATASET_COLUMNS = { + "row_index", + "junction_aa", + "split", + "log10_pgen", + "log10_pgen_1mm", +} + + +@dataclass(frozen=True) +class TargetStandardizer: + tcremp_mean: np.ndarray + tcremp_std: np.ndarray + pgen_mean: float + pgen_std: float + pgen_target: str + train_rows: int + + def save(self, path: str | Path) -> None: + path = Path(path) + path.parent.mkdir(parents=True, exist_ok=True) + np.savez( + path, + tcremp_mean=self.tcremp_mean.astype(np.float32), + tcremp_std=self.tcremp_std.astype(np.float32), + pgen_mean=np.float32(self.pgen_mean), + pgen_std=np.float32(self.pgen_std), + pgen_target=np.asarray(self.pgen_target), + train_rows=np.int64(self.train_rows), + ) + + @classmethod + def load(cls, path: str | Path) -> "TargetStandardizer": + with np.load(path, allow_pickle=False) as payload: + return cls( + tcremp_mean=payload["tcremp_mean"].astype(np.float32), + tcremp_std=payload["tcremp_std"].astype(np.float32), + pgen_mean=float(payload["pgen_mean"]), + pgen_std=float(payload["pgen_std"]), + pgen_target=str(payload["pgen_target"]), + train_rows=int(payload["train_rows"]), + ) + + def as_torch(self, device: torch.device) -> dict[str, torch.Tensor]: + return { + "tcremp_mean": torch.from_numpy(self.tcremp_mean).to(device), + "tcremp_std": torch.from_numpy(self.tcremp_std).to(device), + "pgen_mean": torch.tensor(self.pgen_mean, dtype=torch.float32, device=device), + "pgen_std": torch.tensor(self.pgen_std, dtype=torch.float32, device=device), + } + + +@dataclass(frozen=True) +class EncoderTokenizer: + name: str + vocab_size: int + path: str | None + encode: Callable[[str, int], list[int]] + + +def resolve_encoder_tokenizer( + tokenizer_type: str, + tokenizer_path: str | None = None, +) -> EncoderTokenizer: + if tokenizer_type == "char": + if tokenizer_path: + raise ValueError("--tokenizer-path is only valid for WordPiece input.") + return EncoderTokenizer( + name="char", + vocab_size=len(AA_VOCAB), + path=None, + encode=encode_raw, + ) + if tokenizer_type in {"edge_k", "data_anchor", "germline_anchor"}: + if not tokenizer_path: + raise ValueError("--tokenizer-path is required for anchored input.") + from irrm_codec.anchored_tokenization import ( + AnchoredUnpaddedEncodeFn, + load_anchored_tokenizer, + ) + + tokenizer = load_anchored_tokenizer(tokenizer_path) + if tokenizer.kind != tokenizer_type: + raise ValueError( + f"Tokenizer bundle kind {tokenizer.kind!r} does not match {tokenizer_type!r}." + ) + return EncoderTokenizer( + name=tokenizer.kind, + vocab_size=tokenizer.vocab_size, + path=str(Path(tokenizer_path)), + encode=AnchoredUnpaddedEncodeFn(tokenizer), + ) + if tokenizer_type != "wordpiece": + raise ValueError(f"Unsupported tokenizer type: {tokenizer_type!r}.") + if not tokenizer_path: + raise ValueError("--tokenizer-path is required for WordPiece input.") + + from irrm_codec.wordpiece_tokenization import ( + WordpieceUnpaddedEncodeFn, + load_wordpiece_tokenizer, + wordpiece_vocab_size, + ) + + tokenizer = load_wordpiece_tokenizer(tokenizer_path) + + return EncoderTokenizer( + name="wordpiece", + vocab_size=wordpiece_vocab_size(tokenizer), + path=str(Path(tokenizer_path)), + encode=WordpieceUnpaddedEncodeFn(tokenizer), + ) + + +def load_prepared_benchmark( + data_dir: str | Path, +) -> tuple[pd.DataFrame, np.ndarray]: + data_dir = Path(data_dir) + dataset_path = data_dir / "dataset.parquet" + embeddings_path = data_dir / "embeddings.npy" + if not dataset_path.exists(): + raise FileNotFoundError( + f"Prepared benchmark table is missing: {dataset_path}. " + "Run python -m benchmark.prepare_splits first." + ) + if not embeddings_path.exists(): + raise FileNotFoundError( + f"Prepared TCRemP matrix is missing: {embeddings_path}. " + "Run python -m benchmark.prepare_splits first." + ) + + table = pd.read_parquet(dataset_path) + missing = REQUIRED_DATASET_COLUMNS.difference(table.columns) + if missing: + raise ValueError(f"Prepared dataset is missing columns: {sorted(missing)}") + if table.empty: + raise ValueError("Prepared benchmark is empty.") + if table["row_index"].duplicated().any(): + raise ValueError("row_index must be unique in the prepared benchmark.") + expected = np.arange(len(table), dtype=np.int64) + actual = table["row_index"].to_numpy(dtype=np.int64) + if not np.array_equal(actual, expected): + raise ValueError( + "dataset.parquet must be ordered by contiguous row_index so it aligns " + "with embeddings.npy." + ) + if not set(table["split"].unique()).issubset({"train", "val", "test"}): + raise ValueError("split contains values other than train/val/test.") + + embeddings = np.load(embeddings_path, mmap_mode="r") + if embeddings.ndim != 2: + raise ValueError(f"Expected a 2D TCRemP matrix, got {embeddings.shape}.") + if embeddings.shape[0] != len(table): + raise ValueError( + f"TCRemP rows ({embeddings.shape[0]}) do not match dataset rows ({len(table)})." + ) + if embeddings.dtype.kind not in {"f", "i", "u"}: + raise ValueError(f"TCRemP matrix must be numeric, got dtype={embeddings.dtype}.") + + for column in ("log10_pgen", "log10_pgen_1mm"): + values = table[column].to_numpy(dtype=np.float64) + if not np.isfinite(values).all(): + raise ValueError(f"Prepared target {column} contains non-finite values.") + return table, embeddings + + +def read_manifest_indices(data_dir: str | Path, name: str) -> np.ndarray: + path = Path(data_dir) / "manifests" / f"{name}.tsv" + if not path.exists(): + raise FileNotFoundError(f"Benchmark manifest is missing: {path}") + manifest = pd.read_csv(path, sep="\t", usecols=["row_index"]) + indices = manifest["row_index"].to_numpy(dtype=np.int64) + if len(indices) == 0: + raise ValueError(f"Benchmark manifest is empty: {path}") + if len(np.unique(indices)) != len(indices): + raise ValueError(f"Benchmark manifest contains duplicate row_index values: {path}") + return indices + + +def select_split_indices( + table: pd.DataFrame, + data_dir: str | Path, + split: str, + train_subset: str = "all", +) -> np.ndarray: + if split == "train": + manifest_name = "train" if train_subset == "all" else f"train_{train_subset}" + elif split in {"val", "test"}: + manifest_name = split + else: + raise ValueError(f"Unsupported split: {split!r}.") + + indices = read_manifest_indices(data_dir, manifest_name) + if indices.min() < 0 or indices.max() >= len(table): + raise ValueError(f"Manifest {manifest_name} contains out-of-range row indices.") + observed = set(table.iloc[indices]["split"].unique()) + if observed != {split}: + raise ValueError( + f"Manifest {manifest_name} points to split values {sorted(observed)}, expected {split}." + ) + return indices + + +def _combine_moments( + count_a: int, + mean_a: np.ndarray, + m2_a: np.ndarray, + batch: np.ndarray, +) -> tuple[int, np.ndarray, np.ndarray]: + batch_count = len(batch) + batch_mean = batch.mean(axis=0, dtype=np.float64) + batch_var = batch.var(axis=0, dtype=np.float64) + batch_m2 = batch_var * batch_count + if count_a == 0: + return batch_count, batch_mean, batch_m2 + delta = batch_mean - mean_a + total = count_a + batch_count + mean = mean_a + delta * (batch_count / total) + m2 = m2_a + batch_m2 + delta * delta * (count_a * batch_count / total) + return total, mean, m2 + + +def compute_target_standardizer( + table: pd.DataFrame, + embeddings: np.ndarray, + train_indices: np.ndarray, + pgen_target: str, + chunk_size: int = 1024, +) -> TargetStandardizer: + if pgen_target not in {"log10_pgen", "log10_pgen_1mm"}: + raise ValueError(f"Unsupported pgen target: {pgen_target!r}.") + if chunk_size < 1: + raise ValueError("chunk_size must be positive.") + + count = 0 + mean = np.zeros(embeddings.shape[1], dtype=np.float64) + m2 = np.zeros(embeddings.shape[1], dtype=np.float64) + for start in range(0, len(train_indices), chunk_size): + indices = train_indices[start : start + chunk_size] + batch = np.asarray(embeddings[indices], dtype=np.float32) + if not np.isfinite(batch).all(): + raise ValueError("TCRemP train targets contain NaN or infinite values.") + count, mean, m2 = _combine_moments(count, mean, m2, batch) + if count != len(train_indices) or count < 1: + raise ValueError("Could not compute train-target statistics.") + std = np.sqrt(m2 / count) + std = np.where(std < 1e-8, 1.0, std) + + pgen = table.iloc[train_indices][pgen_target].to_numpy(dtype=np.float64) + pgen_mean = float(pgen.mean()) + pgen_std = float(pgen.std()) + if pgen_std < 1e-8: + pgen_std = 1.0 + return TargetStandardizer( + tcremp_mean=mean.astype(np.float32), + tcremp_std=std.astype(np.float32), + pgen_mean=pgen_mean, + pgen_std=pgen_std, + pgen_target=pgen_target, + train_rows=count, + ) + + +class MultiTaskBenchmarkDataset(Dataset): + def __init__( + self, + table: pd.DataFrame, + embeddings: np.ndarray, + indices: np.ndarray, + encoder_tokenizer: EncoderTokenizer, + pgen_target: str, + max_sequence_len: int = 40, + ): + self.table = table + self.embeddings = embeddings + self.indices = np.asarray(indices, dtype=np.int64) + self.encoder_tokenizer = encoder_tokenizer + self.pgen_target = pgen_target + self.max_sequence_len = max_sequence_len + + def __len__(self) -> int: + return len(self.indices) + + def __getitem__(self, index: int) -> dict: + row_index = int(self.indices[index]) + row = self.table.iloc[row_index] + sequence = str(row["junction_aa"]) + encoder_tokens = self.encoder_tokenizer.encode(sequence, self.max_sequence_len) + decoder_input, reconstruction_target = encode_reconstruction_pair( + sequence, + max_len=self.max_sequence_len, + ) + return { + "row_index": row_index, + "sequence": sequence, + "encoder_tokens": torch.tensor(encoder_tokens, dtype=torch.long), + "decoder_input": torch.tensor(decoder_input, dtype=torch.long), + "reconstruction_target": torch.tensor( + reconstruction_target, + dtype=torch.long, + ), + "tcremp_target": torch.from_numpy( + np.asarray(self.embeddings[row_index], dtype=np.float32).copy() + ), + "pgen_target": torch.tensor(float(row[self.pgen_target]), dtype=torch.float32), + } + + +def collate_multitask(batch: list[dict]) -> dict: + encoder_tokens = torch.nn.utils.rnn.pad_sequence( + [item["encoder_tokens"] for item in batch], + batch_first=True, + padding_value=PAD_ID, + ) + decoder_input = torch.nn.utils.rnn.pad_sequence( + [item["decoder_input"] for item in batch], + batch_first=True, + padding_value=PAD_ID, + ) + reconstruction_target = torch.nn.utils.rnn.pad_sequence( + [item["reconstruction_target"] for item in batch], + batch_first=True, + padding_value=PAD_ID, + ) + return { + "row_index": torch.tensor([item["row_index"] for item in batch], dtype=torch.long), + "sequence": [item["sequence"] for item in batch], + "encoder_tokens": encoder_tokens, + "encoder_mask": encoder_tokens.ne(PAD_ID), + "decoder_input": decoder_input, + "reconstruction_target": reconstruction_target, + "tcremp_target": torch.stack([item["tcremp_target"] for item in batch]), + "pgen_target": torch.stack([item["pgen_target"] for item in batch]), + } + + +def build_multitask_dataloader( + dataset: MultiTaskBenchmarkDataset, + batch_size: int, + shuffle: bool, + num_workers: int = 0, + pin_memory: bool = False, +) -> DataLoader: + return DataLoader( + dataset, + batch_size=batch_size, + shuffle=shuffle, + num_workers=num_workers, + collate_fn=collate_multitask, + pin_memory=pin_memory, + persistent_workers=num_workers > 0, + ) diff --git a/irrm_codec/multitask_losses.py b/irrm_codec/multitask_losses.py new file mode 100644 index 0000000..e454026 --- /dev/null +++ b/irrm_codec/multitask_losses.py @@ -0,0 +1,101 @@ +"""Losses for joint IRRM-CODEC Transformer training.""" + +from dataclasses import dataclass + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from irrm_codec.tokenization import PAD_ID + + +@dataclass(frozen=True) +class MultiTaskLossWeights: + tcremp: float = 1.0 + pgen: float = 1.0 + reconstruction: float = 1.0 + + +class IRRMCodecMultiTaskLoss(nn.Module): + """Combine normalized losses without mixing incompatible target scales. + + The TCRemP and pgen heads predict standardized train-target values. TCRemP + cosine loss is nevertheless computed after de-standardization, so the model + is optimized and evaluated in the original embedding geometry as well. + """ + + def __init__( + self, + weights: MultiTaskLossWeights | None = None, + tcremp_mse_fraction: float = 0.7, + pgen_huber_delta: float = 0.5, + label_smoothing: float = 0.0, + ): + super().__init__() + if not 0.0 <= tcremp_mse_fraction <= 1.0: + raise ValueError("tcremp_mse_fraction must lie in [0, 1].") + self.weights = weights or MultiTaskLossWeights() + self.tcremp_mse_fraction = tcremp_mse_fraction + self.pgen_huber_delta = pgen_huber_delta + self.label_smoothing = label_smoothing + + def forward( + self, + outputs: dict[str, torch.Tensor | None], + *, + tcremp_target: torch.Tensor, + pgen_target: torch.Tensor, + reconstruction_target: torch.Tensor, + tcremp_mean: torch.Tensor, + tcremp_std: torch.Tensor, + pgen_mean: torch.Tensor, + pgen_std: torch.Tensor, + ) -> dict[str, torch.Tensor]: + pred_tcremp_std = outputs["tcremp_standardized"] + pred_pgen_std = outputs["pgen_standardized"] + reconstruction_logits = outputs["reconstruction_logits"] + if pred_tcremp_std is None or pred_pgen_std is None or reconstruction_logits is None: + raise ValueError("All three task outputs are required for joint training.") + + safe_tcremp_std = tcremp_std.clamp_min(1e-8) + target_tcremp_std = (tcremp_target - tcremp_mean) / safe_tcremp_std + tcremp_mse = F.mse_loss(pred_tcremp_std, target_tcremp_std) + pred_tcremp_raw = pred_tcremp_std * safe_tcremp_std + tcremp_mean + tcremp_cosine = 1.0 - F.cosine_similarity( + pred_tcremp_raw, + tcremp_target, + dim=-1, + ).mean() + tcremp_loss = ( + self.tcremp_mse_fraction * tcremp_mse + + (1.0 - self.tcremp_mse_fraction) * tcremp_cosine + ) + + safe_pgen_std = pgen_std.clamp_min(1e-8) + target_pgen_std = (pgen_target - pgen_mean) / safe_pgen_std + pgen_loss = F.huber_loss( + pred_pgen_std, + target_pgen_std, + delta=self.pgen_huber_delta, + ) + + reconstruction_loss = F.cross_entropy( + reconstruction_logits.reshape(-1, reconstruction_logits.size(-1)), + reconstruction_target.reshape(-1), + ignore_index=PAD_ID, + label_smoothing=self.label_smoothing, + ) + + total = ( + self.weights.tcremp * tcremp_loss + + self.weights.pgen * pgen_loss + + self.weights.reconstruction * reconstruction_loss + ) + return { + "loss": total, + "tcremp_loss": tcremp_loss, + "tcremp_mse_standardized": tcremp_mse, + "tcremp_cosine_loss_raw": tcremp_cosine, + "pgen_loss": pgen_loss, + "reconstruction_loss": reconstruction_loss, + } diff --git a/irrm_codec/multitask_metrics.py b/irrm_codec/multitask_metrics.py new file mode 100644 index 0000000..2f82276 --- /dev/null +++ b/irrm_codec/multitask_metrics.py @@ -0,0 +1,230 @@ +"""Streaming metrics for joint IRRM-CODEC experiments.""" + +import math + +import numpy as np +import torch + +from irrm_codec.tokenization import AA_VOCAB, EOS_ID, PAD_ID + + +def _trim_token_row(tokens: list[int]) -> list[int]: + result = [] + for token in tokens: + if token == EOS_ID: + break + if token != PAD_ID: + result.append(token) + return result + + +def levenshtein_distance(left: list[int], right: list[int]) -> int: + if len(left) < len(right): + left, right = right, left + previous = list(range(len(right) + 1)) + for i, left_token in enumerate(left, start=1): + current = [i] + for j, right_token in enumerate(right, start=1): + current.append( + min( + current[-1] + 1, + previous[j] + 1, + previous[j - 1] + int(left_token != right_token), + ) + ) + previous = current + return previous[-1] + + +def _rankdata(values: np.ndarray) -> np.ndarray: + """Return average ranks, including correct handling of tied values.""" + order = np.argsort(values, kind="mergesort") + sorted_values = values[order] + ranks = np.empty(len(values), dtype=np.float64) + start = 0 + while start < len(values): + end = start + 1 + while end < len(values) and sorted_values[end] == sorted_values[start]: + end += 1 + ranks[order[start:end]] = (start + end - 1) / 2.0 + start = end + return ranks + + +def _pearson(left: np.ndarray, right: np.ndarray) -> float: + left_centered = left - left.mean() + right_centered = right - right.mean() + denominator = math.sqrt( + float(np.dot(left_centered, left_centered)) + * float(np.dot(right_centered, right_centered)) + ) + if denominator == 0: + return float("nan") + return float(np.dot(left_centered, right_centered) / denominator) + + +class MultiTaskMetricAccumulator: + def __init__(self): + self.samples = 0 + self.loss_weight = 0 + self.loss_sums: dict[str, float] = {} + + self.tcremp_squared_error = 0.0 + self.tcremp_elements = 0 + self.tcremp_cosine_sum = 0.0 + + self.pgen_squared_error = 0.0 + self.pgen_absolute_error = 0.0 + self.pgen_error = 0.0 + self.pgen_sum_pred = 0.0 + self.pgen_sum_target = 0.0 + self.pgen_sum_pred_sq = 0.0 + self.pgen_sum_target_sq = 0.0 + self.pgen_sum_cross = 0.0 + self.pgen_predictions: list[float] = [] + self.pgen_targets: list[float] = [] + + self.correct_tokens = 0 + self.valid_tokens = 0 + self.generated_samples = 0 + self.exact_matches = 0 + self.length_matches = 0 + self.edit_distance_sum = 0.0 + self.generated_tokens = 0 + self.generated_valid_amino_acids = 0 + + @torch.no_grad() + def update( + self, + *, + outputs: dict[str, torch.Tensor | None], + losses: dict[str, torch.Tensor], + tcremp_target: torch.Tensor, + pgen_target: torch.Tensor, + reconstruction_target: torch.Tensor, + standardizer: dict[str, torch.Tensor], + generated_tokens: torch.Tensor | None = None, + ) -> None: + batch_size = int(tcremp_target.size(0)) + self.samples += batch_size + self.loss_weight += batch_size + for name, value in losses.items(): + self.loss_sums[name] = self.loss_sums.get(name, 0.0) + float(value) * batch_size + + pred_tcremp_std = outputs["tcremp_standardized"] + pred_pgen_std = outputs["pgen_standardized"] + logits = outputs["reconstruction_logits"] + if pred_tcremp_std is None or pred_pgen_std is None or logits is None: + raise ValueError("All outputs are required to accumulate multitask metrics.") + + pred_tcremp = ( + pred_tcremp_std * standardizer["tcremp_std"] + + standardizer["tcremp_mean"] + ) + tcremp_diff = pred_tcremp - tcremp_target + self.tcremp_squared_error += float(tcremp_diff.square().sum()) + self.tcremp_elements += tcremp_diff.numel() + cosine = torch.nn.functional.cosine_similarity( + pred_tcremp, + tcremp_target, + dim=-1, + ) + self.tcremp_cosine_sum += float(cosine.sum()) + + pred_pgen = pred_pgen_std * standardizer["pgen_std"] + standardizer["pgen_mean"] + pgen_diff = pred_pgen - pgen_target + self.pgen_squared_error += float(pgen_diff.square().sum()) + self.pgen_absolute_error += float(pgen_diff.abs().sum()) + self.pgen_error += float(pgen_diff.sum()) + self.pgen_sum_pred += float(pred_pgen.sum()) + self.pgen_sum_target += float(pgen_target.sum()) + self.pgen_sum_pred_sq += float(pred_pgen.square().sum()) + self.pgen_sum_target_sq += float(pgen_target.square().sum()) + self.pgen_sum_cross += float((pred_pgen * pgen_target).sum()) + self.pgen_predictions.extend(pred_pgen.detach().cpu().tolist()) + self.pgen_targets.extend(pgen_target.detach().cpu().tolist()) + + token_predictions = logits.argmax(dim=-1) + valid = reconstruction_target.ne(PAD_ID) + self.correct_tokens += int(token_predictions.eq(reconstruction_target).logical_and(valid).sum()) + self.valid_tokens += int(valid.sum()) + + if generated_tokens is not None: + for predicted, target in zip( + generated_tokens.detach().cpu().tolist(), + reconstruction_target.detach().cpu().tolist(), + ): + predicted_trimmed = _trim_token_row(predicted) + target_trimmed = _trim_token_row(target) + self.generated_samples += 1 + self.exact_matches += int(predicted_trimmed == target_trimmed) + self.length_matches += int(len(predicted_trimmed) == len(target_trimmed)) + self.edit_distance_sum += levenshtein_distance( + predicted_trimmed, + target_trimmed, + ) + self.generated_tokens += len(predicted_trimmed) + self.generated_valid_amino_acids += sum( + token > AA_VOCAB["-"] for token in predicted_trimmed + ) + + def compute(self, include_spearman: bool = True) -> dict[str, float | int]: + if self.samples == 0: + return {} + metrics: dict[str, float | int] = { + name: total / max(self.loss_weight, 1) + for name, total in self.loss_sums.items() + } + n = self.samples + pgen_rmse = math.sqrt(self.pgen_squared_error / n) + target_total_variance = self.pgen_sum_target_sq - self.pgen_sum_target**2 / n + r2 = ( + 1.0 - self.pgen_squared_error / target_total_variance + if target_total_variance > 0 + else float("nan") + ) + pred_var = self.pgen_sum_pred_sq - self.pgen_sum_pred**2 / n + target_var = target_total_variance + covariance = self.pgen_sum_cross - self.pgen_sum_pred * self.pgen_sum_target / n + pearson_denom = math.sqrt(max(pred_var, 0.0) * max(target_var, 0.0)) + pearson = covariance / pearson_denom if pearson_denom > 0 else float("nan") + if math.isfinite(pearson): + pearson = max(-1.0, min(1.0, pearson)) + + metrics.update( + { + "samples": n, + "tcremp_mse_raw": self.tcremp_squared_error + / max(self.tcremp_elements, 1), + "tcremp_cosine_raw": self.tcremp_cosine_sum / n, + "pgen_rmse_raw": pgen_rmse, + "pgen_mae_raw": self.pgen_absolute_error / n, + "pgen_bias_raw": self.pgen_error / n, + "pgen_r2_raw": r2, + "pgen_pearson_raw": pearson, + "reconstruction_token_accuracy_teacher_forced": self.correct_tokens + / max(self.valid_tokens, 1), + } + ) + if include_spearman: + pgen_pred = np.asarray(self.pgen_predictions, dtype=np.float64) + pgen_target = np.asarray(self.pgen_targets, dtype=np.float64) + metrics["pgen_spearman_raw"] = _pearson( + _rankdata(pgen_pred), + _rankdata(pgen_target), + ) + if self.generated_samples: + metrics.update( + { + "reconstruction_exact_match": self.exact_matches + / self.generated_samples, + "reconstruction_length_accuracy": self.length_matches + / self.generated_samples, + "reconstruction_mean_edit_distance": self.edit_distance_sum + / self.generated_samples, + "generated_samples": self.generated_samples, + "reconstruction_valid_aa_fraction": self.generated_valid_amino_acids + / max(self.generated_tokens, 1), + } + ) + return metrics diff --git a/irrm_codec/multitask_transformer.py b/irrm_codec/multitask_transformer.py new file mode 100644 index 0000000..bf31ecc --- /dev/null +++ b/irrm_codec/multitask_transformer.py @@ -0,0 +1,318 @@ +"""Shared-bottleneck Transformer for the joint IRRM-CODEC objectives. + +The model maps an amino-acid sequence to one compact latent vector and exposes +three task heads: + +1. TCRemP embedding distillation; +2. log10(pgen) regression; +3. autoregressive amino-acid sequence reconstruction. + +The heads return values in the standardized target spaces used during training. +The corresponding train-set means and standard deviations belong in the saved +checkpoint metadata and must be applied when reporting raw-space metrics. +""" + +from dataclasses import dataclass + +import torch +import torch.nn as nn + +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID + + +@dataclass(frozen=True) +class IRRMCodecConfig: + input_vocab_size: int = 25 + output_vocab_size: int = 25 + share_input_output_embeddings: bool = True + max_sequence_len: int = 40 + d_model: int = 320 + latent_dim: int = 320 + nhead: int = 8 + encoder_layers: int = 4 + decoder_layers: int = 4 + ff_dim: int = 1280 + dropout: float = 0.1 + tcremp_dim: int = 9000 + tcremp_head_dim: int = 1024 + pgen_head_dim: int = 256 + decoder_memory_tokens: int = 4 + + def validate(self) -> None: + if self.d_model % self.nhead != 0: + raise ValueError("d_model must be divisible by nhead.") + if self.max_sequence_len < 1: + raise ValueError("max_sequence_len must be positive.") + if self.latent_dim < 1: + raise ValueError("latent_dim must be positive.") + if self.decoder_memory_tokens < 1: + raise ValueError("decoder_memory_tokens must be positive.") + if self.input_vocab_size < 1 or self.output_vocab_size < 1: + raise ValueError("Input and output vocabularies must be non-empty.") + if ( + self.share_input_output_embeddings + and self.input_vocab_size != self.output_vocab_size + ): + raise ValueError( + "Input and output vocabulary sizes must match when embeddings are shared." + ) + + +class SequenceTransformerEncoder(nn.Module): + """Encode a padded amino-acid token sequence into one latent vector.""" + + def __init__(self, config: IRRMCodecConfig, token_embedding: nn.Embedding): + super().__init__() + self.config = config + self.token_embedding = token_embedding + self.cls_token = nn.Parameter(torch.empty(1, 1, config.d_model)) + self.position_embedding = nn.Parameter( + torch.empty(1, config.max_sequence_len + 1, config.d_model) + ) + layer = nn.TransformerEncoderLayer( + d_model=config.d_model, + nhead=config.nhead, + dim_feedforward=config.ff_dim, + dropout=config.dropout, + activation="gelu", + batch_first=True, + norm_first=True, + ) + self.transformer = nn.TransformerEncoder(layer, num_layers=config.encoder_layers) + self.latent_projection = nn.Sequential( + nn.LayerNorm(config.d_model), + nn.Linear(config.d_model, config.latent_dim), + nn.GELU(), + nn.LayerNorm(config.latent_dim), + ) + self.dropout = nn.Dropout(config.dropout) + self.reset_parameters() + + def reset_parameters(self) -> None: + nn.init.normal_(self.cls_token, std=0.02) + nn.init.normal_(self.position_embedding, std=0.02) + + def forward(self, tokens: torch.Tensor, mask: torch.Tensor | None = None) -> torch.Tensor: + if tokens.ndim != 2: + raise ValueError(f"Expected tokens [batch, sequence], got {tuple(tokens.shape)}.") + if tokens.size(1) > self.config.max_sequence_len: + raise ValueError( + f"Sequence width {tokens.size(1)} exceeds max_sequence_len=" + f"{self.config.max_sequence_len}." + ) + + if mask is None: + mask = tokens.ne(PAD_ID) + else: + mask = mask.bool() + if mask.shape != tokens.shape: + raise ValueError("mask must have the same [batch, sequence] shape as tokens.") + if not mask.any(dim=1).all(): + raise ValueError("Every sequence must contain at least one non-padding token.") + + batch_size = tokens.size(0) + cls = self.cls_token.expand(batch_size, -1, -1) + x = torch.cat([cls, self.token_embedding(tokens)], dim=1) + x = self.dropout(x + self.position_embedding[:, : x.size(1)]) + + cls_is_valid = torch.ones(batch_size, 1, dtype=torch.bool, device=tokens.device) + valid_mask = torch.cat([cls_is_valid, mask], dim=1) + encoded = self.transformer(x, src_key_padding_mask=~valid_mask) + return self.latent_projection(encoded[:, 0]) + + +class TCRemPHead(nn.Module): + def __init__(self, config: IRRMCodecConfig): + super().__init__() + self.network = nn.Sequential( + nn.LayerNorm(config.latent_dim), + nn.Linear(config.latent_dim, config.tcremp_head_dim), + nn.GELU(), + nn.Dropout(config.dropout), + nn.Linear(config.tcremp_head_dim, config.tcremp_dim), + ) + + def forward(self, latent: torch.Tensor) -> torch.Tensor: + return self.network(latent) + + +class PgenHead(nn.Module): + def __init__(self, config: IRRMCodecConfig): + super().__init__() + self.network = nn.Sequential( + nn.LayerNorm(config.latent_dim), + nn.Linear(config.latent_dim, config.pgen_head_dim), + nn.GELU(), + nn.Dropout(config.dropout), + nn.Linear(config.pgen_head_dim, 1), + ) + + def forward(self, latent: torch.Tensor) -> torch.Tensor: + return self.network(latent).squeeze(-1) + + +class SequenceReconstructionHead(nn.Module): + """Autoregressive decoder conditioned only on the compact latent vector.""" + + def __init__(self, config: IRRMCodecConfig, token_embedding: nn.Embedding): + super().__init__() + self.config = config + self.token_embedding = token_embedding + self.position_embedding = nn.Parameter( + torch.empty(1, config.max_sequence_len + 1, config.d_model) + ) + self.memory_projection = nn.Linear( + config.latent_dim, + config.decoder_memory_tokens * config.d_model, + ) + layer = nn.TransformerDecoderLayer( + d_model=config.d_model, + nhead=config.nhead, + dim_feedforward=config.ff_dim, + dropout=config.dropout, + activation="gelu", + batch_first=True, + norm_first=True, + ) + self.transformer = nn.TransformerDecoder(layer, num_layers=config.decoder_layers) + self.output_norm = nn.LayerNorm(config.d_model) + self.output_projection = nn.Linear( + config.d_model, + config.output_vocab_size, + bias=False, + ) + self.output_projection.weight = token_embedding.weight + self.dropout = nn.Dropout(config.dropout) + nn.init.normal_(self.position_embedding, std=0.02) + + def _memory(self, latent: torch.Tensor) -> torch.Tensor: + batch_size = latent.size(0) + return self.memory_projection(latent).reshape( + batch_size, + self.config.decoder_memory_tokens, + self.config.d_model, + ) + + def forward(self, latent: torch.Tensor, decoder_input: torch.Tensor) -> torch.Tensor: + if decoder_input.ndim != 2: + raise ValueError("decoder_input must have shape [batch, sequence].") + if decoder_input.size(0) != latent.size(0): + raise ValueError("latent and decoder_input batch sizes do not match.") + if decoder_input.size(1) > self.config.max_sequence_len + 1: + raise ValueError("decoder_input is longer than the configured reconstruction limit.") + + x = self.token_embedding(decoder_input) + x = self.dropout(x + self.position_embedding[:, : x.size(1)]) + causal_mask = torch.triu( + torch.ones( + decoder_input.size(1), + decoder_input.size(1), + dtype=torch.bool, + device=decoder_input.device, + ), + diagonal=1, + ) + decoded = self.transformer( + tgt=x, + memory=self._memory(latent), + tgt_mask=causal_mask, + tgt_key_padding_mask=decoder_input.eq(PAD_ID), + ) + return self.output_projection(self.output_norm(decoded)) + + @torch.no_grad() + def generate( + self, + latent: torch.Tensor, + max_new_tokens: int | None = None, + bos_id: int = BOS_ID, + eos_id: int = EOS_ID, + pad_id: int = PAD_ID, + ) -> torch.Tensor: + limit = self.config.max_sequence_len + 1 + if max_new_tokens is not None: + limit = min(limit, max_new_tokens) + + generated = torch.full( + (latent.size(0), 1), + bos_id, + dtype=torch.long, + device=latent.device, + ) + finished = torch.zeros(latent.size(0), dtype=torch.bool, device=latent.device) + for _ in range(limit): + logits = self(latent, generated) + next_token = logits[:, -1].argmax(dim=-1) + next_token = torch.where(finished, torch.full_like(next_token, pad_id), next_token) + generated = torch.cat([generated, next_token.unsqueeze(1)], dim=1) + finished = finished | next_token.eq(eos_id) + if finished.all(): + break + return generated[:, 1:] + + +class IRRMCodecTransformer(nn.Module): + """One shared sequence encoder and three jointly trainable task heads.""" + + def __init__(self, config: IRRMCodecConfig | None = None): + super().__init__() + self.config = config or IRRMCodecConfig() + self.config.validate() + self.encoder_token_embedding = nn.Embedding( + self.config.input_vocab_size, + self.config.d_model, + padding_idx=PAD_ID, + ) + if self.config.share_input_output_embeddings: + self.decoder_token_embedding = self.encoder_token_embedding + else: + self.decoder_token_embedding = nn.Embedding( + self.config.output_vocab_size, + self.config.d_model, + padding_idx=PAD_ID, + ) + self.encoder = SequenceTransformerEncoder( + self.config, + self.encoder_token_embedding, + ) + self.tcremp_head = TCRemPHead(self.config) + self.pgen_head = PgenHead(self.config) + self.reconstruction_head = SequenceReconstructionHead( + self.config, + self.decoder_token_embedding, + ) + + def encode(self, tokens: torch.Tensor, mask: torch.Tensor | None = None) -> torch.Tensor: + return self.encoder(tokens, mask) + + def forward( + self, + tokens: torch.Tensor, + mask: torch.Tensor | None = None, + decoder_input: torch.Tensor | None = None, + ) -> dict[str, torch.Tensor | None]: + latent = self.encode(tokens, mask) + reconstruction_logits = None + if decoder_input is not None: + reconstruction_logits = self.reconstruction_head(latent, decoder_input) + return { + "latent": latent, + "tcremp_standardized": self.tcremp_head(latent), + "pgen_standardized": self.pgen_head(latent), + "reconstruction_logits": reconstruction_logits, + } + + @torch.no_grad() + def reconstruct( + self, + tokens: torch.Tensor, + mask: torch.Tensor | None = None, + max_new_tokens: int | None = None, + ) -> torch.Tensor: + was_training = self.training + self.eval() + latent = self.encode(tokens, mask) + generated = self.reconstruction_head.generate(latent, max_new_tokens=max_new_tokens) + if was_training: + self.train() + return generated diff --git a/irrm_codec/tokenization.py b/irrm_codec/tokenization.py index f8638d0..cadb514 100644 --- a/irrm_codec/tokenization.py +++ b/irrm_codec/tokenization.py @@ -32,6 +32,7 @@ BOS_ID = AA_VOCAB[""] EOS_ID = AA_VOCAB[""] UNK_ID = AA_VOCAB[""] +SPECIAL_IDS = {PAD_ID, BOS_ID, EOS_ID, UNK_ID} GAP_TOKEN = "-" VALID_AA = set("ACDEFGHIKLMNPQRSTVWY") @@ -76,6 +77,25 @@ def encode(seq, max_len=40): return tokens[:max_len] +def encode_raw(seq, max_len=40): + """Encode an unpadded amino-acid sequence for the Transformer codec.""" + normalized = normalize_sequence(seq) + invalid = sorted({char for char in normalized if char not in VALID_AA}) + if invalid: + raise ValueError(f"Sequence contains unsupported amino acids: {invalid}") + if len(normalized) > max_len: + raise ValueError( + f"Sequence length {len(normalized)} exceeds max_len={max_len}." + ) + return [AA_VOCAB[char] for char in normalized] + + +def encode_reconstruction_pair(seq, max_len=40): + """Return teacher-forcing input and target for autoregressive reconstruction.""" + amino_acids = encode_raw(seq, max_len=max_len) + return [BOS_ID, *amino_acids], [*amino_acids, EOS_ID] + + def strip_gaps(seq): normalized = normalize_sequence(seq) return normalized.replace(GAP_TOKEN, "") @@ -86,7 +106,7 @@ def decode(tokens, stop_at_eos=True, remove_gaps=False): for token in tokens: if token == EOS_ID and stop_at_eos: break - if token <= UNK_ID: + if token in SPECIAL_IDS: continue decoded.append(ID2AA[token]) sequence = "".join(decoded) diff --git a/irrm_codec/train_multitask.py b/irrm_codec/train_multitask.py new file mode 100644 index 0000000..d2298ea --- /dev/null +++ b/irrm_codec/train_multitask.py @@ -0,0 +1,685 @@ +"""Train and evaluate the shared-bottleneck IRRM-CODEC Transformer.""" + +import argparse +import json +import logging +import math +from dataclasses import asdict +from pathlib import Path + +import numpy as np +import torch +from tqdm.auto import tqdm + +from irrm_codec.multitask_data import ( + MultiTaskBenchmarkDataset, + TargetStandardizer, + build_multitask_dataloader, + compute_target_standardizer, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, +) +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_metrics import MultiTaskMetricAccumulator +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB +from irrm_codec.utils import save_json, set_seed, setup_logging + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--data-dir", default="data/benchmark/trb") + parser.add_argument("--output-dir", default="artifacts/multitask/char") + parser.add_argument("--train-subset", choices=["1k", "10k", "all"], default="all") + parser.add_argument( + "--pgen-target", + choices=["log10_pgen", "log10_pgen_1mm"], + default="log10_pgen_1mm", + ) + parser.add_argument( + "--tokenizer-type", + choices=["char", "wordpiece", "edge_k", "data_anchor", "germline_anchor"], + default="char", + ) + parser.add_argument("--tokenizer-path") + parser.add_argument("--max-sequence-len", type=int, default=40) + + parser.add_argument("--d-model", type=int, default=320) + parser.add_argument("--latent-dim", type=int, default=320) + parser.add_argument("--nhead", type=int, default=8) + parser.add_argument("--encoder-layers", type=int, default=4) + parser.add_argument("--decoder-layers", type=int, default=4) + parser.add_argument("--ff-dim", type=int, default=1280) + parser.add_argument("--dropout", type=float, default=0.1) + parser.add_argument("--tcremp-head-dim", type=int, default=1024) + parser.add_argument("--pgen-head-dim", type=int, default=256) + parser.add_argument("--decoder-memory-tokens", type=int, default=4) + + parser.add_argument("--tcremp-loss-weight", type=float, default=1.0) + parser.add_argument("--pgen-loss-weight", type=float, default=1.0) + parser.add_argument("--reconstruction-loss-weight", type=float, default=1.0) + parser.add_argument("--tcremp-mse-fraction", type=float, default=0.7) + parser.add_argument("--pgen-huber-delta", type=float, default=0.5) + parser.add_argument("--label-smoothing", type=float, default=0.0) + + parser.add_argument("--batch-size", type=int, default=64) + parser.add_argument("--epochs", type=int, default=40) + parser.add_argument("--lr", type=float, default=3e-4) + parser.add_argument("--weight-decay", type=float, default=1e-4) + parser.add_argument("--gradient-accumulation-steps", type=int, default=1) + parser.add_argument("--max-grad-norm", type=float, default=1.0) + parser.add_argument("--early-stopping-patience", type=int, default=6) + parser.add_argument("--scheduler-factor", type=float, default=0.5) + parser.add_argument("--scheduler-patience", type=int, default=2) + parser.add_argument("--scheduler-min-lr", type=float, default=1e-6) + parser.add_argument("--standardizer-chunk-size", type=int, default=1024) + parser.add_argument( + "--standardizer-path", + help=( + "Locked train-only target standardizer. Defaults to " + "/target_standardizer.npz for train-subset=all." + ), + ) + + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--num-workers", type=int, default=0) + parser.add_argument("--device", choices=["auto", "cpu", "cuda"], default="auto") + parser.add_argument("--amp", action=argparse.BooleanOptionalAction, default=True) + parser.add_argument("--resume") + parser.add_argument("--log-interval", type=int, default=20) + parser.add_argument("--no-progress", action="store_true") + parser.add_argument("--skip-generation-metrics", action="store_true") + parser.add_argument( + "--save-test-predictions", + action=argparse.BooleanOptionalAction, + default=True, + help="Save per-batch latent vectors and raw-space test predictions for analysis.", + ) + parser.add_argument( + "--val-generation-every", + type=int, + default=0, + help="Compute slow autoregressive validation metrics every N epochs; 0 disables them.", + ) + parser.add_argument( + "--max-train-batches", + type=int, + default=0, + help="Debug limit; 0 uses the whole train loader.", + ) + parser.add_argument( + "--max-eval-batches", + type=int, + default=0, + help="Debug limit; 0 uses the whole validation/test loader.", + ) + return parser.parse_args() + + +def validate_args(args: argparse.Namespace) -> None: + positive = { + "batch_size": args.batch_size, + "epochs": args.epochs, + "gradient_accumulation_steps": args.gradient_accumulation_steps, + "standardizer_chunk_size": args.standardizer_chunk_size, + } + invalid = [name for name, value in positive.items() if value < 1] + if invalid: + raise ValueError(f"These arguments must be positive: {invalid}") + for name in ( + "tcremp_loss_weight", + "pgen_loss_weight", + "reconstruction_loss_weight", + ): + if getattr(args, name) < 0: + raise ValueError(f"--{name.replace('_', '-')} must be non-negative.") + if ( + args.tcremp_loss_weight + + args.pgen_loss_weight + + args.reconstruction_loss_weight + == 0 + ): + raise ValueError("At least one task loss weight must be positive.") + + +def choose_device(requested: str) -> torch.device: + if requested == "auto": + return torch.device("cuda" if torch.cuda.is_available() else "cpu") + if requested == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("--device=cuda was requested, but CUDA is not available.") + return torch.device(requested) + + +def move_batch_to_device(batch: dict, device: torch.device) -> dict: + return { + key: value.to(device, non_blocking=True) if torch.is_tensor(value) else value + for key, value in batch.items() + } + + +def _batch_limit(loader, requested: int) -> int: + return min(len(loader), requested) if requested > 0 else len(loader) + + +def run_epoch( + *, + model: IRRMCodecTransformer, + criterion: IRRMCodecMultiTaskLoss, + loader, + standardizer_tensors: dict[str, torch.Tensor], + device: torch.device, + optimizer: torch.optim.Optimizer | None, + scaler, + gradient_accumulation_steps: int, + max_grad_norm: float, + amp_enabled: bool, + generate: bool, + max_batches: int, + log_interval: int, + show_progress: bool, + stage: str, + prediction_dir: Path | None = None, +) -> dict[str, float | int]: + is_train = optimizer is not None + model.train(is_train) + accumulator = MultiTaskMetricAccumulator() + limit = _batch_limit(loader, max_batches) + progress = tqdm( + loader, + total=limit, + desc=stage, + leave=False, + dynamic_ncols=True, + disable=not show_progress, + ) + if is_train: + optimizer.zero_grad(set_to_none=True) + prediction_files = [] + if prediction_dir is not None: + prediction_dir.mkdir(parents=True, exist_ok=True) + + for step, batch in enumerate(progress, start=1): + if step > limit: + break + batch = move_batch_to_device(batch, device) + with torch.set_grad_enabled(is_train): + with torch.autocast( + device_type=device.type, + dtype=torch.float16, + enabled=amp_enabled, + ): + outputs = model( + batch["encoder_tokens"], + batch["encoder_mask"], + batch["decoder_input"], + ) + losses = criterion( + outputs, + tcremp_target=batch["tcremp_target"], + pgen_target=batch["pgen_target"], + reconstruction_target=batch["reconstruction_target"], + **standardizer_tensors, + ) + if not torch.isfinite(losses["loss"]): + raise FloatingPointError( + f"Non-finite {stage} loss at batch {step}: " + f"{float(losses['loss'].detach())}" + ) + + if is_train: + scaled_loss = losses["loss"] / gradient_accumulation_steps + scaler.scale(scaled_loss).backward() + should_step = ( + step % gradient_accumulation_steps == 0 or step == limit + ) + if should_step: + scaler.unscale_(optimizer) + if max_grad_norm > 0: + torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm) + scaler.step(optimizer) + scaler.update() + optimizer.zero_grad(set_to_none=True) + + generated_tokens = None + if generate: + generated_tokens = model.reconstruction_head.generate(outputs["latent"]) + accumulator.update( + outputs=outputs, + losses=losses, + tcremp_target=batch["tcremp_target"], + pgen_target=batch["pgen_target"], + reconstruction_target=batch["reconstruction_target"], + standardizer=standardizer_tensors, + generated_tokens=generated_tokens, + ) + if prediction_dir is not None: + pred_tcremp = ( + outputs["tcremp_standardized"] * standardizer_tensors["tcremp_std"] + + standardizer_tensors["tcremp_mean"] + ) + pred_pgen = ( + outputs["pgen_standardized"] * standardizer_tensors["pgen_std"] + + standardizer_tensors["pgen_mean"] + ) + prediction_path = prediction_dir / f"batch_{step:05d}.npz" + arrays = { + "row_index": batch["row_index"].detach().cpu().numpy(), + "latent": outputs["latent"].detach().float().cpu().numpy(), + "tcremp_prediction": pred_tcremp.detach().float().cpu().numpy(), + "pgen_prediction": pred_pgen.detach().float().cpu().numpy(), + "pgen_target": batch["pgen_target"].detach().float().cpu().numpy(), + "reconstruction_target": batch["reconstruction_target"].detach().cpu().numpy(), + } + if generated_tokens is not None: + arrays["generated_tokens"] = generated_tokens.detach().cpu().numpy() + np.savez(prediction_path, **arrays) + prediction_files.append(prediction_path.name) + if show_progress and (step == limit or (log_interval > 0 and step % log_interval == 0)): + interim = accumulator.compute(include_spearman=False) + progress.set_postfix( + loss=f"{interim['loss']:.4f}", + cosine=f"{interim['tcremp_cosine_raw']:.4f}", + pgen_rmse=f"{interim['pgen_rmse_raw']:.4f}", + token_acc=f"{interim['reconstruction_token_accuracy_teacher_forced']:.4f}", + ) + progress.close() + metrics = accumulator.compute() + if prediction_dir is not None: + save_json( + prediction_dir / "manifest.json", + { + "stage": stage, + "samples": metrics.get("samples", 0), + "batches": len(prediction_files), + "files": prediction_files, + "metrics": metrics, + }, + ) + return metrics + + +def save_checkpoint( + path: Path, + *, + model: IRRMCodecTransformer, + optimizer: torch.optim.Optimizer, + scheduler, + scaler, + epoch: int, + metrics: dict, + best_val_loss: float, + epochs_without_improvement: int, + model_config: IRRMCodecConfig, + tokenizer_info: dict, + args: argparse.Namespace, +) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + payload = { + "model_state": model.state_dict(), + "optimizer_state": optimizer.state_dict(), + "scheduler_state": scheduler.state_dict(), + "scaler_state": scaler.state_dict(), + "epoch": epoch, + "metrics": metrics, + "best_val_loss": best_val_loss, + "epochs_without_improvement": epochs_without_improvement, + "model_config": asdict(model_config), + "tokenizer": tokenizer_info, + "training_args": vars(args), + "standardizer_path": "target_standardizer.npz", + } + temporary = path.with_suffix(path.suffix + ".tmp") + torch.save(payload, temporary) + temporary.replace(path) + + +def configs_match(expected: IRRMCodecConfig, payload: dict) -> bool: + return asdict(expected) == payload + + +def main() -> None: + args = parse_args() + validate_args(args) + set_seed(args.seed) + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + logger = setup_logging(output_dir / "train.log") + device = choose_device(args.device) + amp_enabled = bool(args.amp and device.type == "cuda") + + logger.info("loading prepared benchmark from %s", Path(args.data_dir).resolve()) + table, embeddings = load_prepared_benchmark(args.data_dir) + train_indices = select_split_indices( + table, + args.data_dir, + "train", + train_subset=args.train_subset, + ) + val_indices = select_split_indices(table, args.data_dir, "val") + test_indices = select_split_indices(table, args.data_dir, "test") + tokenizer = resolve_encoder_tokenizer(args.tokenizer_type, args.tokenizer_path) + + output_standardizer_path = output_dir / "target_standardizer.npz" + locked_standardizer_path = ( + Path(args.standardizer_path) + if args.standardizer_path + else Path(args.data_dir) / "target_standardizer.npz" + ) + if args.resume and output_standardizer_path.exists(): + standardizer = TargetStandardizer.load(output_standardizer_path) + if standardizer.pgen_target != args.pgen_target: + raise ValueError("Resume checkpoint and requested pgen target do not match.") + if standardizer.train_rows != len(train_indices): + raise ValueError("Resume standardizer and requested train subset do not match.") + if len(standardizer.tcremp_mean) != embeddings.shape[1]: + raise ValueError("Resume standardizer and TCRemP dimension do not match.") + elif args.train_subset == "all" and locked_standardizer_path.exists(): + logger.info("loading locked benchmark standardizer from %s", locked_standardizer_path) + standardizer = TargetStandardizer.load(locked_standardizer_path) + if standardizer.pgen_target != args.pgen_target: + raise ValueError("Locked benchmark standardizer pgen target does not match.") + if standardizer.train_rows != len(train_indices): + raise ValueError("Locked benchmark standardizer train row count does not match.") + if len(standardizer.tcremp_mean) != embeddings.shape[1]: + raise ValueError("Locked benchmark standardizer TCRemP dimension does not match.") + standardizer.save(output_standardizer_path) + else: + logger.info( + "computing train-only target statistics rows=%d embedding_dim=%d", + len(train_indices), + embeddings.shape[1], + ) + standardizer = compute_target_standardizer( + table, + embeddings, + train_indices, + args.pgen_target, + chunk_size=args.standardizer_chunk_size, + ) + standardizer.save(output_standardizer_path) + standardizer_tensors = standardizer.as_torch(device) + + datasets = { + "train": MultiTaskBenchmarkDataset( + table, + embeddings, + train_indices, + tokenizer, + args.pgen_target, + args.max_sequence_len, + ), + "val": MultiTaskBenchmarkDataset( + table, + embeddings, + val_indices, + tokenizer, + args.pgen_target, + args.max_sequence_len, + ), + "test": MultiTaskBenchmarkDataset( + table, + embeddings, + test_indices, + tokenizer, + args.pgen_target, + args.max_sequence_len, + ), + } + loaders = { + split: build_multitask_dataloader( + dataset, + args.batch_size, + shuffle=split == "train", + num_workers=args.num_workers, + pin_memory=device.type == "cuda", + ) + for split, dataset in datasets.items() + } + + model_config = IRRMCodecConfig( + input_vocab_size=tokenizer.vocab_size, + output_vocab_size=len(AA_VOCAB), + share_input_output_embeddings=tokenizer.name == "char", + max_sequence_len=args.max_sequence_len, + d_model=args.d_model, + latent_dim=args.latent_dim, + nhead=args.nhead, + encoder_layers=args.encoder_layers, + decoder_layers=args.decoder_layers, + ff_dim=args.ff_dim, + dropout=args.dropout, + tcremp_dim=int(embeddings.shape[1]), + tcremp_head_dim=args.tcremp_head_dim, + pgen_head_dim=args.pgen_head_dim, + decoder_memory_tokens=args.decoder_memory_tokens, + ) + model = IRRMCodecTransformer(model_config).to(device) + criterion = IRRMCodecMultiTaskLoss( + weights=MultiTaskLossWeights( + tcremp=args.tcremp_loss_weight, + pgen=args.pgen_loss_weight, + reconstruction=args.reconstruction_loss_weight, + ), + tcremp_mse_fraction=args.tcremp_mse_fraction, + pgen_huber_delta=args.pgen_huber_delta, + label_smoothing=args.label_smoothing, + ) + optimizer = torch.optim.AdamW( + model.parameters(), + lr=args.lr, + weight_decay=args.weight_decay, + ) + scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau( + optimizer, + mode="min", + factor=args.scheduler_factor, + patience=args.scheduler_patience, + min_lr=args.scheduler_min_lr, + ) + scaler = torch.cuda.amp.GradScaler(enabled=amp_enabled) + + tokenizer_info = { + "type": tokenizer.name, + "path": tokenizer.path, + "input_vocab_size": tokenizer.vocab_size, + "output_vocab_size": len(AA_VOCAB), + } + parameter_count = sum(parameter.numel() for parameter in model.parameters()) + save_json( + output_dir / "run_config.json", + { + "model": asdict(model_config), + "tokenizer": tokenizer_info, + "training": vars(args), + "device": str(device), + "amp_enabled": amp_enabled, + "parameter_count": parameter_count, + }, + ) + save_json( + output_dir / "data_stats.json", + { + "data_dir": str(Path(args.data_dir).resolve()), + "train_subset": args.train_subset, + "train_rows": len(train_indices), + "val_rows": len(val_indices), + "test_rows": len(test_indices), + "tcremp_dim": int(embeddings.shape[1]), + "pgen_target": args.pgen_target, + "standardizer": str(output_standardizer_path), + "locked_standardizer_source": ( + str(locked_standardizer_path) + if args.train_subset == "all" and locked_standardizer_path.exists() + else None + ), + }, + ) + logger.info( + "model ready tokenizer=%s input_vocab=%d output_vocab=%d parameters=%d " + "train=%d val=%d test=%d device=%s amp=%s", + tokenizer.name, + tokenizer.vocab_size, + len(AA_VOCAB), + parameter_count, + len(train_indices), + len(val_indices), + len(test_indices), + device, + amp_enabled, + ) + + start_epoch = 1 + best_val_loss = math.inf + epochs_without_improvement = 0 + history: list[dict] = [] + if args.resume: + checkpoint = torch.load(args.resume, map_location=device) + if not configs_match(model_config, checkpoint["model_config"]): + raise ValueError("Resume checkpoint model configuration does not match this run.") + if checkpoint.get("tokenizer") != tokenizer_info: + raise ValueError("Resume checkpoint tokenizer configuration does not match this run.") + model.load_state_dict(checkpoint["model_state"]) + optimizer.load_state_dict(checkpoint["optimizer_state"]) + scheduler.load_state_dict(checkpoint["scheduler_state"]) + scaler.load_state_dict(checkpoint["scaler_state"]) + start_epoch = int(checkpoint["epoch"]) + 1 + best_val_loss = float(checkpoint["best_val_loss"]) + epochs_without_improvement = int(checkpoint["epochs_without_improvement"]) + history_path = output_dir / "history.json" + if history_path.exists(): + history = json.loads(history_path.read_text(encoding="utf-8")) + logger.info("resumed checkpoint=%s at epoch=%d", args.resume, start_epoch) + + for epoch in range(start_epoch, args.epochs + 1): + train_metrics = run_epoch( + model=model, + criterion=criterion, + loader=loaders["train"], + standardizer_tensors=standardizer_tensors, + device=device, + optimizer=optimizer, + scaler=scaler, + gradient_accumulation_steps=args.gradient_accumulation_steps, + max_grad_norm=args.max_grad_norm, + amp_enabled=amp_enabled, + generate=False, + max_batches=args.max_train_batches, + log_interval=args.log_interval, + show_progress=not args.no_progress, + stage=f"train {epoch}/{args.epochs}", + prediction_dir=None, + ) + generate_val = ( + args.val_generation_every > 0 + and epoch % args.val_generation_every == 0 + ) + val_metrics = run_epoch( + model=model, + criterion=criterion, + loader=loaders["val"], + standardizer_tensors=standardizer_tensors, + device=device, + optimizer=None, + scaler=scaler, + gradient_accumulation_steps=1, + max_grad_norm=0, + amp_enabled=amp_enabled, + generate=generate_val, + max_batches=args.max_eval_batches, + log_interval=args.log_interval, + show_progress=not args.no_progress, + stage=f"val {epoch}/{args.epochs}", + prediction_dir=None, + ) + scheduler.step(val_metrics["loss"]) + history.append( + { + "epoch": epoch, + "lr": optimizer.param_groups[0]["lr"], + "train": train_metrics, + "val": val_metrics, + } + ) + save_json(output_dir / "history.json", history) + + improved = val_metrics["loss"] < best_val_loss + if improved: + best_val_loss = float(val_metrics["loss"]) + epochs_without_improvement = 0 + else: + epochs_without_improvement += 1 + checkpoint_kwargs = { + "model": model, + "optimizer": optimizer, + "scheduler": scheduler, + "scaler": scaler, + "epoch": epoch, + "metrics": val_metrics, + "best_val_loss": best_val_loss, + "epochs_without_improvement": epochs_without_improvement, + "model_config": model_config, + "tokenizer_info": tokenizer_info, + "args": args, + } + save_checkpoint(output_dir / "last.pt", **checkpoint_kwargs) + if improved: + save_checkpoint(output_dir / "best.pt", **checkpoint_kwargs) + + logger.info( + "epoch=%d train_loss=%.4f val_loss=%.4f val_cosine=%.4f " + "val_pgen_rmse=%.4f val_token_acc=%.4f best_val_loss=%.4f patience=%d/%d", + epoch, + train_metrics["loss"], + val_metrics["loss"], + val_metrics["tcremp_cosine_raw"], + val_metrics["pgen_rmse_raw"], + val_metrics["reconstruction_token_accuracy_teacher_forced"], + best_val_loss, + epochs_without_improvement, + args.early_stopping_patience, + ) + if ( + args.early_stopping_patience > 0 + and epochs_without_improvement >= args.early_stopping_patience + ): + logger.info("early stopping at epoch=%d", epoch) + break + + best_checkpoint = torch.load(output_dir / "best.pt", map_location=device) + model.load_state_dict(best_checkpoint["model_state"]) + test_metrics = run_epoch( + model=model, + criterion=criterion, + loader=loaders["test"], + standardizer_tensors=standardizer_tensors, + device=device, + optimizer=None, + scaler=scaler, + gradient_accumulation_steps=1, + max_grad_norm=0, + amp_enabled=amp_enabled, + generate=not args.skip_generation_metrics, + max_batches=args.max_eval_batches, + log_interval=args.log_interval, + show_progress=not args.no_progress, + stage="test", + prediction_dir=( + output_dir / "test_predictions" if args.save_test_predictions else None + ), + ) + test_metrics.update( + { + "best_checkpoint_epoch": int(best_checkpoint["epoch"]), + "best_checkpoint_val_loss": float(best_checkpoint["best_val_loss"]), + "parameter_count": parameter_count, + "tokenizer_type": tokenizer.name, + "train_subset": args.train_subset, + } + ) + save_json(output_dir / "test_metrics.json", test_metrics) + logger.info("test metrics: %s", json.dumps(test_metrics, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py new file mode 100644 index 0000000..190a01e --- /dev/null +++ b/irrm_codec/wordpiece_tokenization.py @@ -0,0 +1,69 @@ +"""Validated WordPiece input tokenization for the joint IRRM-CODEC model.""" + +from pathlib import Path + +from tokenizers import Tokenizer + +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID, VALID_AA + + +EXPECTED_SPECIAL_IDS = { + "[PAD]": PAD_ID, + "[BOS]": BOS_ID, + "[EOS]": EOS_ID, + "[UNK]": UNK_ID, +} + + +def validate_wordpiece_tokenizer(tokenizer: Tokenizer, source: str | Path) -> None: + for token, expected_id in EXPECTED_SPECIAL_IDS.items(): + actual_id = tokenizer.token_to_id(token) + if actual_id != expected_id: + raise ValueError( + f"Tokenizer at {source} has {token}={actual_id}, expected {expected_id}." + ) + + +def load_wordpiece_tokenizer(path: str | Path) -> Tokenizer: + path = Path(path) + tokenizer = Tokenizer.from_file(str(path)) + validate_wordpiece_tokenizer(tokenizer, path) + return tokenizer + + +def encode_wordpiece_unpadded( + sequence: str, + tokenizer: Tokenizer, + max_len: int, +) -> list[int]: + sequence = "" if sequence is None else str(sequence).strip().upper() + if not sequence: + raise ValueError("Sequence must not be empty.") + invalid = sorted(set(sequence).difference(VALID_AA)) + if invalid: + raise ValueError(f"Sequence contains unsupported amino acids: {invalid}") + token_ids = tokenizer.encode(sequence).ids + if not token_ids: + raise ValueError("WordPiece encoding must contain at least one token.") + if UNK_ID in token_ids: + raise ValueError(f"WordPiece encoding contains [UNK] for sequence {sequence!r}.") + if len(token_ids) > max_len: + raise ValueError( + f"Sequence {sequence!r} encodes to {len(token_ids)} tokens, " + f"exceeding max_len={max_len}." + ) + return token_ids + + +class WordpieceUnpaddedEncodeFn: + """Picklable callable used by multi-worker benchmark DataLoaders.""" + + def __init__(self, tokenizer: Tokenizer): + self.tokenizer = tokenizer + + def __call__(self, sequence: str, max_len: int) -> list[int]: + return encode_wordpiece_unpadded(sequence, self.tokenizer, max_len) + + +def wordpiece_vocab_size(tokenizer: Tokenizer) -> int: + return tokenizer.get_vocab_size() diff --git a/requirements.txt b/requirements.txt index 679e3bb..394cc7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,7 @@ notebook ipykernel ipywidgets tqdm +tokenizers>=0.20,<1 wandb torch==2.4.1 mirpy-lib @ git+https://github.com/antigenomics/mirpy.git@11a5fd1ac12edd22e12a2bb167ab9dfb55ccefd4 diff --git a/scripts/preflight_anchored_tokenizers.py b/scripts/preflight_anchored_tokenizers.py new file mode 100644 index 0000000..2313df4 --- /dev/null +++ b/scripts/preflight_anchored_tokenizers.py @@ -0,0 +1,203 @@ +"""CPU gate for the three leakage-safe anchored tokenizers.""" + +from __future__ import annotations + +import argparse +import gc +import hashlib +import json +import platform +from dataclasses import asdict +from pathlib import Path + +import torch + +from irrm_codec.anchored_tokenization import AnchoredTokenizer +from irrm_codec.multitask_data import ( + MultiTaskBenchmarkDataset, + TargetStandardizer, + collate_multitask, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, +) +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB + + +CANDIDATES = ("edge_k", "data_anchor", "germline_anchor") + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", required=True) + parser.add_argument("--tokenizer-root", required=True) + parser.add_argument("--baseline-run-config", required=True) + parser.add_argument("--output-path", required=True) + args = parser.parse_args() + + data_dir = Path(args.data_dir) + root = Path(args.tokenizer_root) + baseline_path = Path(args.baseline_run_config) + baseline = json.loads(baseline_path.read_text(encoding="utf-8")) + if ( + baseline["model"]["latent_dim"] != 128 + or baseline["model"]["encoder_layers"] != 4 + or baseline["model"]["decoder_layers"] != 4 + ): + raise ValueError("Baseline is not the validation-selected char d128 4+4 model.") + ready = json.loads((data_dir / "READY.json").read_text(encoding="utf-8")) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Locked benchmark is not ready.") + preparation = json.loads((root / "preparation_manifest.json").read_text(encoding="utf-8")) + if preparation["external_corpus"]["overlap_after_filter"] != 0: + raise ValueError("External tokenizer corpus overlaps the locked benchmark.") + if preparation["inference_modality"] != "sequence_only": + raise ValueError("Anchored study is not sequence-only.") + + table, embeddings = load_prepared_benchmark(data_dir) + split_indices = {split: select_split_indices(table, data_dir, split) for split in ("train", "val", "test")} + standardizer = TargetStandardizer.load(data_dir / "target_standardizer.npz") + if standardizer.train_rows != len(split_indices["train"]) or standardizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Locked train-only normalizer does not match the benchmark.") + + expected_training = { + "train_subset":"all","pgen_target":"log10_pgen_1mm","tokenizer_type":"char", + "tokenizer_path":None,"max_sequence_len":40,"d_model":320,"latent_dim":128,"nhead":8, + "encoder_layers":4,"decoder_layers":4,"ff_dim":1280,"dropout":0.1, + "tcremp_head_dim":1024,"pgen_head_dim":256,"decoder_memory_tokens":4, + "tcremp_loss_weight":1.0,"pgen_loss_weight":1.0,"reconstruction_loss_weight":1.0, + "tcremp_mse_fraction":0.7,"pgen_huber_delta":0.5,"label_smoothing":0.0, + "batch_size":64,"epochs":40,"lr":0.0003,"weight_decay":0.0001, + "gradient_accumulation_steps":1,"max_grad_norm":1.0,"early_stopping_patience":0, + "scheduler_factor":0.5,"scheduler_patience":2,"scheduler_min_lr":1e-6, + "seed":42,"num_workers":8,"amp":True,"skip_generation_metrics":False, + "save_test_predictions":False,"val_generation_every":0,"max_train_batches":0, + "max_eval_batches":0, + } + mismatches = { + key: {"expected": value, "actual": baseline["training"].get(key)} + for key, value in expected_training.items() if baseline["training"].get(key) != value + } + if mismatches: + raise ValueError(f"Selected baseline differs from locked settings: {mismatches}") + + standardizer_tensors = standardizer.as_torch(torch.device("cpu")) + candidate_reports = {} + for kind in CANDIDATES: + directory = root / kind + bundle_path = directory / "anchored_tokenizer.json" + config = json.loads((directory / "tokenizer_config.json").read_text(encoding="utf-8")) + validation = json.loads((directory / "validation_report.json").read_text(encoding="utf-8")) + if config["bundle_sha256"] != sha256(bundle_path): + raise ValueError(f"{kind} bundle checksum changed.") + if config["inference_modality"] != "sequence_only" or config["accepts_v_call_or_j_call"]: + raise ValueError(f"{kind} violates sequence-only inference.") + if not all(validation["checks"].values()): + raise ValueError(f"{kind} preparation checks are not all accepting.") + runtime = AnchoredTokenizer(bundle_path) + roundtrip_rows = 0 + max_encoded = 0 + for split, indices in split_indices.items(): + for sequence in table.iloc[indices]["junction_aa"].astype(str): + encoded = runtime.encode_with_boundaries(sequence, 40) + if runtime.decode(encoded.ids) != sequence: + raise ValueError(f"{kind} roundtrip failed in {split} for {sequence!r}.") + if encoded.n_anchor != sequence[:len(encoded.n_anchor)] or encoded.c_anchor != sequence[-len(encoded.c_anchor):]: + raise ValueError(f"{kind} protected token does not match a literal edge.") + if encoded.boundary_types[0] != "N_ANCHOR" or encoded.boundary_types[-1] != "C_ANCHOR": + raise ValueError(f"{kind} boundary typing failed.") + max_encoded = max(max_encoded, len(encoded.ids)) + roundtrip_rows += 1 + if max_encoded > 40: + raise ValueError(f"{kind} exceeds max input length.") + + tokenizer = resolve_encoder_tokenizer(kind, str(bundle_path)) + dataset = MultiTaskBenchmarkDataset( + table, embeddings, split_indices["train"][:2], tokenizer, "log10_pgen_1mm", 40 + ) + batch = collate_multitask([dataset[0], dataset[1]]) + model_payload = dict(baseline["model"]) + model_payload["input_vocab_size"] = tokenizer.vocab_size + model_payload["output_vocab_size"] = len(AA_VOCAB) + model_payload["share_input_output_embeddings"] = False + model_config = IRRMCodecConfig(**model_payload) + model_config.validate() + changed_model_fields = sorted( + key for key, value in asdict(model_config).items() if value != baseline["model"][key] + ) + if changed_model_fields != ["input_vocab_size", "share_input_output_embeddings"]: + raise ValueError(f"{kind} changed unexpected model fields: {changed_model_fields}") + torch.manual_seed(42) + model = IRRMCodecTransformer(model_config) + outputs = model(batch["encoder_tokens"], batch["encoder_mask"], batch["decoder_input"]) + losses = IRRMCodecMultiTaskLoss(weights=MultiTaskLossWeights(1.0, 1.0, 1.0))( + outputs, + tcremp_target=batch["tcremp_target"], + pgen_target=batch["pgen_target"], + reconstruction_target=batch["reconstruction_target"], + **standardizer_tensors, + ) + losses["loss"].backward() + if not torch.isfinite(losses["loss"]): + raise FloatingPointError(f"{kind} finite smoke gate failed.") + candidate_reports[kind] = { + "tokenizer_type": kind, + "bundle_path": str(bundle_path), + "bundle_sha256": sha256(bundle_path), + "input_vocab_size": tokenizer.vocab_size, + "roundtrip_rows": roundtrip_rows, + "max_encoded_length": max_encoded, + "parameter_count": sum(parameter.numel() for parameter in model.parameters()), + "parameter_delta_vs_char": sum(parameter.numel() for parameter in model.parameters()) - baseline["parameter_count"], + "changed_model_fields_vs_char": changed_model_fields, + "changed_training_fields_vs_char": ["tokenizer_type", "tokenizer_path"], + "finite_full_multitask_smoke_loss": True, + "smoke_loss": float(losses["loss"].detach()), + } + del runtime, tokenizer, dataset, batch, model, outputs, losses + gc.collect() + + report = { + "status": "ready", + "selection_rule": { + "primary": "minimum best-checkpoint full validation objective", + "secondary": ["validation pgen RMSE", "validation reconstruction", "validation TCRemP"], + "test_metrics_used_for_selection": False, + }, + "study_constraints": { + "sequence_only_inference": True, + "v_j_calls_are_model_inputs": False, + "char_decoder_vocab_size": len(AA_VOCAB), + "configs_differ_only_in_tokenizer_and_implied_input_embedding": True, + }, + "baseline": { + "job_id": "1425949", + "run_config_sha256": sha256(baseline_path), + "parameter_count": baseline["parameter_count"], + }, + "benchmark": { + "rows": len(table), + "split_rows": {split: len(value) for split, value in split_indices.items()}, + "normalizer_fit_split": "train", + "normalizer_train_rows": standardizer.train_rows, + }, + "candidates": candidate_reports, + "runtime": {"python": platform.python_version(), "torch": torch.__version__}, + } + output = Path(args.output_path) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(report, indent=2), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/scripts/preflight_data_anchor_objectives.py b/scripts/preflight_data_anchor_objectives.py new file mode 100644 index 0000000..37e285e --- /dev/null +++ b/scripts/preflight_data_anchor_objectives.py @@ -0,0 +1,221 @@ +"""CPU gate for matched DATA-ANCHOR objective-ablation training runs.""" + +from __future__ import annotations + +import argparse +import gc +import hashlib +import json +import os +from dataclasses import asdict +from pathlib import Path + +import torch + +from irrm_codec.multitask_data import ( + MultiTaskBenchmarkDataset, + TargetStandardizer, + collate_multitask, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, +) +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer + + +CONDITIONS = { + "r": {"reconstruction": 1.0, "tcremp": 0.0, "pgen": 0.0}, + "p": {"reconstruction": 0.0, "tcremp": 0.0, "pgen": 1.0}, + "rp": {"reconstruction": 1.0, "tcremp": 0.0, "pgen": 1.0}, +} + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def stable_json(path: Path, value: object) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--reference-run-config", type=Path, required=True) + parser.add_argument("--output-root", type=Path, required=True) + args = parser.parse_args() + + ready = json.loads((args.data_dir / "READY.json").read_text(encoding="utf-8")) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Locked benchmark READY.json is not accepting.") + reference = json.loads(args.reference_run_config.read_text(encoding="utf-8")) + training = reference["training"] + required = { + "data_dir": str(args.data_dir), + "train_subset": "all", + "pgen_target": "log10_pgen_1mm", + "tokenizer_type": "data_anchor", + "tokenizer_path": str(args.tokenizer), + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 128, + "nhead": 8, + "encoder_layers": 4, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4, + "tcremp_loss_weight": 1.0, + "pgen_loss_weight": 1.0, + "reconstruction_loss_weight": 1.0, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0.0, + "batch_size": 64, + "epochs": 40, + "lr": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1.0, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 1e-6, + "seed": 42, + "num_workers": 8, + "amp": True, + "skip_generation_metrics": False, + "save_test_predictions": False, + "val_generation_every": 0, + "max_train_batches": 0, + "max_eval_batches": 0, + } + mismatches = { + key: {"expected": value, "actual": training.get(key)} + for key, value in required.items() if training.get(key) != value + } + if mismatches: + raise ValueError(f"Completed DATA-ANCHOR reference is not the locked run: {mismatches}") + + table, embeddings = load_prepared_benchmark(args.data_dir) + indices = { + split: select_split_indices(table, args.data_dir, split) + for split in ("train", "val", "test") + } + normalizer = TargetStandardizer.load(args.data_dir / "target_standardizer.npz") + if normalizer.train_rows != len(indices["train"]) or normalizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Train-only normalizer does not match the locked train manifest.") + tokenizer = resolve_encoder_tokenizer("data_anchor", str(args.tokenizer)) + config = IRRMCodecConfig(**reference["model"]) + if tokenizer.vocab_size != config.input_vocab_size: + raise ValueError("Tokenizer vocabulary does not match reference input embedding.") + dataset = MultiTaskBenchmarkDataset( + table, embeddings, indices["train"][:2], tokenizer, "log10_pgen_1mm", 40 + ) + batch = collate_multitask([dataset[0], dataset[1]]) + standardized = normalizer.as_torch(torch.device("cpu")) + + reports = {} + configs_dir = args.output_root / "configs" + for name, weights in CONDITIONS.items(): + torch.manual_seed(42) + model = IRRMCodecTransformer(config) + outputs = model(batch["encoder_tokens"], batch["encoder_mask"], batch["decoder_input"]) + criterion = IRRMCodecMultiTaskLoss( + weights=MultiTaskLossWeights( + tcremp=weights["tcremp"], + pgen=weights["pgen"], + reconstruction=weights["reconstruction"], + ) + ) + losses = criterion( + outputs, + tcremp_target=batch["tcremp_target"], + pgen_target=batch["pgen_target"], + reconstruction_target=batch["reconstruction_target"], + **standardized, + ) + losses["loss"].backward() + encoder_grads = [ + parameter.grad for parameter in model.encoder.parameters() if parameter.grad is not None + ] + if not torch.isfinite(losses["loss"]) or not encoder_grads or not all( + torch.isfinite(gradient).all() for gradient in encoder_grads + ): + raise FloatingPointError(f"{name} has non-finite loss or encoder gradient.") + condition_config = { + "condition": name, + "experiment_id": f"data-anchor-{name}-seed42", + "loss_weights": weights, + "model": asdict(config), + "training_reference": str(args.reference_run_config), + "training_reference_sha256": sha256(args.reference_run_config), + "benchmark_ready_sha256": sha256(args.data_dir / "READY.json"), + "normalizer_sha256": sha256(args.data_dir / "target_standardizer.npz"), + "tokenizer_sha256": sha256(args.tokenizer), + "seed": 42, + "epochs": 40, + "batch_size": 64, + "optimizer": "AdamW", + "learning_rate": 0.0003, + "inactive_head_metrics_interpretable": False, + } + config_path = configs_dir / f"{name}.json" + stable_json(config_path, condition_config) + reports[name] = { + "config_path": str(config_path), + "config_sha256": sha256(config_path), + "smoke_loss": float(losses["loss"].detach()), + "finite_encoder_gradient": True, + "parameter_count": sum(parameter.numel() for parameter in model.parameters()), + "architecture_equal_to_full_reference": asdict(config) == reference["model"], + } + del model, outputs, losses, criterion + gc.collect() + + report = { + "status": "ready", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "required_conditions": ["r", "p", "rp"], + "fixed_reference": { + "condition": "rtp", + "job_id": "1426222", + "run_config": str(args.reference_run_config), + "run_config_sha256": sha256(args.reference_run_config), + "parameter_count": reference["parameter_count"], + }, + "checks": { + "locked_benchmark": True, + "locked_train_only_normalizer": True, + "same_data_splits": True, + "same_data_anchor_tokenizer": True, + "same_model_architecture": True, + "same_seed_optimizer_budget": True, + "only_loss_weights_differ": True, + "finite_smoke_losses_and_encoder_gradients": True, + "output_directories_isolated": True, + }, + "hashes": { + "benchmark_ready": sha256(args.data_dir / "READY.json"), + "normalizer": sha256(args.data_dir / "target_standardizer.npz"), + "tokenizer": sha256(args.tokenizer), + }, + "splits": {split: len(value) for split, value in indices.items()}, + "conditions": reports, + "note": "P-only retains the identical decoder and TCRemP head; their inactive metrics are non-interpretable.", + } + stable_json(args.output_root / "PREFLIGHT.json", report) + print(json.dumps(report, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/scripts/preflight_phase1_rq1.py b/scripts/preflight_phase1_rq1.py new file mode 100644 index 0000000..ba5a3c4 --- /dev/null +++ b/scripts/preflight_phase1_rq1.py @@ -0,0 +1,132 @@ +"""Validate the locked TRB benchmark and Phase-1 runtime on a Slurm CPU node.""" + +import argparse +import hashlib +import json +import platform +import subprocess +from pathlib import Path + +import numpy as np +import torch + +from irrm_codec.multitask_data import ( + TargetStandardizer, + load_prepared_benchmark, + select_split_indices, +) +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(16 * 1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", required=True) + parser.add_argument("--output-path", required=True) + args = parser.parse_args() + + data_dir = Path(args.data_dir).resolve() + ready = json.loads((data_dir / "READY.json").read_text(encoding="utf-8")) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Locked benchmark READY checks are not all true.") + + table, embeddings = load_prepared_benchmark(data_dir) + split_indices = { + split: select_split_indices(table, data_dir, split) + for split in ("train", "val", "test") + } + standardizer = TargetStandardizer.load(data_dir / "target_standardizer.npz") + if standardizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Unexpected locked pgen target.") + if standardizer.train_rows != len(split_indices["train"]): + raise ValueError("Locked standardizer was not fit on the full train split.") + if len(standardizer.tcremp_mean) != embeddings.shape[1]: + raise ValueError("Locked TCRemP standardizer dimension mismatch.") + + torch.manual_seed(42) + model_config = IRRMCodecConfig( + input_vocab_size=len(AA_VOCAB), + output_vocab_size=len(AA_VOCAB), + max_sequence_len=8, + d_model=32, + latent_dim=24, + nhead=4, + encoder_layers=1, + decoder_layers=1, + ff_dim=64, + dropout=0.0, + tcremp_dim=12, + tcremp_head_dim=24, + pgen_head_dim=12, + decoder_memory_tokens=2, + ) + model = IRRMCodecTransformer(model_config) + tokens = torch.randint(5, len(AA_VOCAB), (2, 6)) + decoder_input = torch.randint(5, len(AA_VOCAB), (2, 7)) + outputs = model(tokens, tokens.ne(0), decoder_input) + losses = IRRMCodecMultiTaskLoss()( + outputs, + tcremp_target=torch.randn(2, 12), + pgen_target=torch.randn(2), + reconstruction_target=torch.randint(5, len(AA_VOCAB), (2, 7)), + tcremp_mean=torch.zeros(12), + tcremp_std=torch.ones(12), + pgen_mean=torch.tensor(0.0), + pgen_std=torch.tensor(1.0), + ) + losses["loss"].backward() + if not torch.isfinite(losses["loss"]): + raise FloatingPointError("Runtime smoke-test loss is non-finite.") + + artifact_paths = [ + data_dir / "READY.json", + data_dir / "dataset.parquet", + data_dir / "embeddings.npy", + data_dir / "target_standardizer.npz", + *(data_dir / "manifests" / f"{name}.tsv" for name in ("train", "val", "test")), + ] + revision = subprocess.check_output( + ["git", "rev-parse", "HEAD"], text=True + ).strip() + report = { + "status": "ready", + "git_revision": revision, + "benchmark_path": str(data_dir), + "benchmark_ready_summary": ready, + "prepared_artifact_sha256": { + str(path.relative_to(data_dir)): sha256(path) for path in artifact_paths + }, + "dataset_rows": len(table), + "embedding_shape": list(embeddings.shape), + "embedding_dtype": str(embeddings.dtype), + "split_rows": {name: len(values) for name, values in split_indices.items()}, + "standardizer": { + "pgen_target": standardizer.pgen_target, + "train_rows": standardizer.train_rows, + "tcremp_dim": len(standardizer.tcremp_mean), + }, + "runtime": { + "python": platform.python_version(), + "torch": torch.__version__, + "torch_cuda_build": torch.version.cuda, + "smoke_loss_finite": True, + }, + } + output_path = Path(args.output_path) + output_path.parent.mkdir(parents=True, exist_ok=True) + temporary = output_path.with_suffix(output_path.suffix + ".tmp") + temporary.write_text(json.dumps(report, indent=2), encoding="utf-8") + temporary.replace(output_path) + + +if __name__ == "__main__": + main() diff --git a/scripts/preflight_rq5_depths.py b/scripts/preflight_rq5_depths.py new file mode 100644 index 0000000..285ea8e --- /dev/null +++ b/scripts/preflight_rq5_depths.py @@ -0,0 +1,164 @@ +"""Validate RQ5 Stage-2 encoder-depth candidates against the selected d128 run.""" + +import argparse +import gc +import hashlib +import json +import platform +from dataclasses import asdict +from pathlib import Path + +import torch + +from irrm_codec.multitask_data import TargetStandardizer, load_prepared_benchmark, select_split_indices +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--baseline-run-config", required=True) + parser.add_argument("--d128-test-metrics", required=True) + parser.add_argument("--d320-test-metrics", required=True) + parser.add_argument("--d512-test-metrics", required=True) + parser.add_argument("--data-dir", required=True) + parser.add_argument("--output-path", required=True) + args = parser.parse_args() + + baseline_path = Path(args.baseline_run_config) + baseline = json.loads(baseline_path.read_text()) + width_metrics = { + "128": json.loads(Path(args.d128_test_metrics).read_text()), + "320": json.loads(Path(args.d320_test_metrics).read_text()), + "512": json.loads(Path(args.d512_test_metrics).read_text()), + } + validation_losses = { + width: metrics["best_checkpoint_val_loss"] for width, metrics in width_metrics.items() + } + if min(validation_losses, key=validation_losses.get) != "128": + raise ValueError(f"latent_dim=128 was not selected by validation: {validation_losses}") + + data_dir = Path(args.data_dir) + ready = json.loads((data_dir / "READY.json").read_text()) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Locked benchmark READY checks failed.") + table, embeddings = load_prepared_benchmark(data_dir) + splits = {name: select_split_indices(table, data_dir, name) for name in ("train", "val", "test")} + standardizer = TargetStandardizer.load(data_dir / "target_standardizer.npz") + if standardizer.train_rows != len(splits["train"]) or standardizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Locked train-only normalizer does not match the selected d128 run.") + + expected_training = { + "train_subset": "all", "pgen_target": "log10_pgen_1mm", "tokenizer_type": "char", + "tokenizer_path": None, "max_sequence_len": 40, "d_model": 320, "latent_dim": 128, + "nhead": 8, "encoder_layers": 4, "decoder_layers": 4, "ff_dim": 1280, + "dropout": 0.1, "tcremp_head_dim": 1024, "pgen_head_dim": 256, + "decoder_memory_tokens": 4, "tcremp_loss_weight": 1.0, "pgen_loss_weight": 1.0, + "reconstruction_loss_weight": 1.0, "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, "label_smoothing": 0.0, "batch_size": 64, + "epochs": 40, "lr": 0.0003, "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, "max_grad_norm": 1.0, + "early_stopping_patience": 0, "scheduler_factor": 0.5, "scheduler_patience": 2, + "scheduler_min_lr": 1e-6, "seed": 42, "num_workers": 8, "amp": True, + "skip_generation_metrics": False, "save_test_predictions": False, + "val_generation_every": 0, "max_train_batches": 0, "max_eval_batches": 0, + } + mismatches = { + key: {"expected": expected, "actual": baseline["training"].get(key)} + for key, expected in expected_training.items() + if baseline["training"].get(key) != expected + } + if mismatches: + raise ValueError(f"Selected d128 run differs from locked RQ5 settings: {mismatches}") + if baseline["model"]["latent_dim"] != 128 or baseline["model"]["encoder_layers"] != 4: + raise ValueError("Selected baseline is not the completed d128, 4+4-layer run.") + if baseline["parameter_count"] != width_metrics["128"]["parameter_count"]: + raise ValueError("Selected d128 run/metric parameter counts disagree.") + + results = {} + for depth in (2, 6): + torch.manual_seed(42) + model_payload = dict(baseline["model"]) + model_payload["encoder_layers"] = depth + config = IRRMCodecConfig(**model_payload) + config.validate() + changed_model_fields = sorted( + key for key, value in asdict(config).items() if value != baseline["model"][key] + ) + if changed_model_fields != ["encoder_layers"]: + raise ValueError(f"encoder-depth {depth} changed unexpected model fields: {changed_model_fields}") + + model = IRRMCodecTransformer(config) + parameter_count = sum(parameter.numel() for parameter in model.parameters()) + tokens = torch.randint(5, len(AA_VOCAB), (2, 12)) + decoder_input = torch.randint(5, len(AA_VOCAB), (2, 13)) + outputs = model(tokens, tokens.ne(0), decoder_input) + losses = IRRMCodecMultiTaskLoss(weights=MultiTaskLossWeights(1.0, 1.0, 1.0))( + outputs, + tcremp_target=torch.randn(2, embeddings.shape[1]), + pgen_target=torch.randn(2), + reconstruction_target=torch.randint(5, len(AA_VOCAB), (2, 13)), + tcremp_mean=torch.zeros(embeddings.shape[1]), + tcremp_std=torch.ones(embeddings.shape[1]), + pgen_mean=torch.tensor(0.0), + pgen_std=torch.tensor(1.0), + ) + losses["loss"].backward() + finite = bool(torch.isfinite(losses["loss"])) + if not finite: + raise FloatingPointError(f"encoder-depth {depth} smoke loss is non-finite.") + results[str(depth)] = { + "encoder_layers": depth, + "decoder_layers": config.decoder_layers, + "latent_dim": config.latent_dim, + "parameter_count": parameter_count, + "parameter_delta_vs_e4": parameter_count - baseline["parameter_count"], + "changed_model_fields_vs_e4": changed_model_fields, + "changed_training_fields_vs_e4": [], + "finite_full_multitask_smoke_loss": finite, + "smoke_loss": float(losses["loss"].detach()), + "model_config": asdict(config), + } + del model, outputs, losses + gc.collect() + + report = { + "status": "ready", + "interpretation": "RQ5 Stage 2 varies encoder_layers only; latent_dim=128 and decoder_layers=4 remain fixed.", + "selection": { + "criterion": "minimum best-checkpoint validation loss only", + "validation_losses": validation_losses, + "selected_latent_dim": 128, + "test_metrics_used_for_selection": False, + }, + "baseline": { + "job_id": "1425949", "run_config_path": str(baseline_path.resolve()), + "run_config_sha256": sha256(baseline_path), "latent_dim": 128, + "encoder_layers": 4, "decoder_layers": 4, + "parameter_count": baseline["parameter_count"], "non_depth_training_fields_match": True, + }, + "benchmark": { + "path": str(data_dir.resolve()), "ready_sha256": sha256(data_dir / "READY.json"), + "rows": len(table), "embedding_shape": list(embeddings.shape), + "split_rows": {key: len(value) for key, value in splits.items()}, + "normalizer_fit_split": "train", "normalizer_train_rows": standardizer.train_rows, + }, + "candidates": results, + "runtime": {"python": platform.python_version(), "torch": torch.__version__}, + } + output = Path(args.output_path) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(report, indent=2), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/scripts/preflight_rq5_widths.py b/scripts/preflight_rq5_widths.py new file mode 100644 index 0000000..f6a5b75 --- /dev/null +++ b/scripts/preflight_rq5_widths.py @@ -0,0 +1,140 @@ +"""Validate RQ5 latent-width candidates against the completed d320 baseline.""" + +import argparse +import hashlib +import json +import platform +from dataclasses import asdict +from pathlib import Path + +import torch + +from irrm_codec.multitask_data import TargetStandardizer, load_prepared_benchmark, select_split_indices +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--baseline-run-config", required=True) + parser.add_argument("--baseline-test-metrics", required=True) + parser.add_argument("--data-dir", required=True) + parser.add_argument("--output-path", required=True) + args = parser.parse_args() + + baseline_path = Path(args.baseline_run_config) + baseline = json.loads(baseline_path.read_text()) + baseline_metrics = json.loads(Path(args.baseline_test_metrics).read_text()) + data_dir = Path(args.data_dir) + ready = json.loads((data_dir / "READY.json").read_text()) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Locked benchmark READY checks failed.") + table, embeddings = load_prepared_benchmark(data_dir) + splits = {name: select_split_indices(table, data_dir, name) for name in ("train", "val", "test")} + standardizer = TargetStandardizer.load(data_dir / "target_standardizer.npz") + if standardizer.train_rows != len(splits["train"]) or standardizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Locked train-only normalizer does not match baseline.") + + expected_training = { + "train_subset": "all", "pgen_target": "log10_pgen_1mm", "tokenizer_type": "char", + "tokenizer_path": None, "max_sequence_len": 40, "d_model": 320, "nhead": 8, + "encoder_layers": 4, "decoder_layers": 4, "ff_dim": 1280, "dropout": 0.1, + "tcremp_head_dim": 1024, "pgen_head_dim": 256, "decoder_memory_tokens": 4, + "tcremp_loss_weight": 1.0, "pgen_loss_weight": 1.0, "reconstruction_loss_weight": 1.0, + "tcremp_mse_fraction": 0.7, "pgen_huber_delta": 0.5, "label_smoothing": 0.0, + "batch_size": 64, "epochs": 40, "lr": 0.0003, "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, "max_grad_norm": 1.0, + "early_stopping_patience": 0, "scheduler_factor": 0.5, "scheduler_patience": 2, + "scheduler_min_lr": 1e-6, "seed": 42, "num_workers": 8, "amp": True, + "skip_generation_metrics": False, "save_test_predictions": False, + "val_generation_every": 0, "max_train_batches": 0, "max_eval_batches": 0, + } + mismatches = { + key: {"expected": expected, "actual": baseline["training"].get(key)} + for key, expected in expected_training.items() + if baseline["training"].get(key) != expected + } + if mismatches: + raise ValueError(f"Completed d320 baseline differs from locked RQ5 settings: {mismatches}") + if baseline["model"]["latent_dim"] != 320 or baseline["parameter_count"] != baseline_metrics["parameter_count"]: + raise ValueError("d320 baseline model/metric metadata is inconsistent.") + + results = {} + torch.manual_seed(42) + for width in (128, 512): + model_payload = dict(baseline["model"]) + model_payload["latent_dim"] = width + config = IRRMCodecConfig(**model_payload) + config.validate() + changed_model_fields = sorted( + key for key, value in asdict(config).items() if value != baseline["model"][key] + ) + if changed_model_fields != ["latent_dim"]: + raise ValueError(f"d{width} changed unexpected model fields: {changed_model_fields}") + model = IRRMCodecTransformer(config) + parameter_count = sum(parameter.numel() for parameter in model.parameters()) + tokens = torch.randint(5, len(AA_VOCAB), (2, 12)) + decoder_input = torch.randint(5, len(AA_VOCAB), (2, 13)) + outputs = model(tokens, tokens.ne(0), decoder_input) + losses = IRRMCodecMultiTaskLoss(weights=MultiTaskLossWeights(1.0, 1.0, 1.0))( + outputs, + tcremp_target=torch.randn(2, embeddings.shape[1]), + pgen_target=torch.randn(2), + reconstruction_target=torch.randint(5, len(AA_VOCAB), (2, 13)), + tcremp_mean=torch.zeros(embeddings.shape[1]), + tcremp_std=torch.ones(embeddings.shape[1]), + pgen_mean=torch.tensor(0.0), + pgen_std=torch.tensor(1.0), + ) + losses["loss"].backward() + finite = bool(torch.isfinite(losses["loss"])) + if not finite: + raise FloatingPointError(f"d{width} smoke loss is non-finite.") + results[str(width)] = { + "latent_dim": width, + "parameter_count": parameter_count, + "parameter_delta_vs_d320": parameter_count - baseline["parameter_count"], + "changed_model_fields_vs_d320": changed_model_fields, + "changed_training_fields_vs_d320": [], + "finite_full_multitask_smoke_loss": finite, + "smoke_loss": float(losses["loss"].detach()), + "model_config": asdict(config), + } + del model, outputs, losses + + report = { + "status": "ready", + "interpretation": "RQ5 width is latent_dim only; d_model=320 and nhead=8 remain fixed.", + "baseline": { + "job_id": "1425897", + "run_config_path": str(baseline_path.resolve()), + "run_config_sha256": sha256(baseline_path), + "latent_dim": 320, + "parameter_count": baseline["parameter_count"], + "non_width_training_fields_match": True, + }, + "benchmark": { + "path": str(data_dir.resolve()), "ready_sha256": sha256(data_dir / "READY.json"), + "rows": len(table), "embedding_shape": list(embeddings.shape), + "split_rows": {key: len(value) for key, value in splits.items()}, + "normalizer_fit_split": "train", "normalizer_train_rows": standardizer.train_rows, + }, + "candidates": results, + "runtime": {"python": platform.python_version(), "torch": torch.__version__}, + } + output = Path(args.output_path) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(report, indent=2), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/scripts/preflight_vdjdb_evaluation.py b/scripts/preflight_vdjdb_evaluation.py new file mode 100644 index 0000000..8d4b96c --- /dev/null +++ b/scripts/preflight_vdjdb_evaluation.py @@ -0,0 +1,80 @@ +"""Small CPU-only functional gate for frozen VDJdb evaluation statistics.""" + +from __future__ import annotations + +import argparse +import json +import os +from pathlib import Path + +import numpy as np +import pandas as pd + +from benchmark.evaluate_vdjdb_frozen import ( + assert_finite_tree, + bootstrap_primary, + build_pair_manifest, + controls, + distance_matrix, + pair_metrics, + retrieval_metrics, + sha256, +) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--cohort-preflight", type=Path, required=True) + parser.add_argument("--evaluation-script", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args() + + preflight = json.loads(args.cohort_preflight.read_text(encoding="utf-8")) + if sha256(args.cohort) != preflight["cohort"]["cohort_sha256"]: + raise ValueError("Cohort hash changed after preparation.") + full = pd.read_csv(args.cohort, sep="\t") + chosen = [] + for _, group in full.groupby("label", sort=True): + if group["donor_key"].nunique() >= 2: + chosen.append(group.head(20)) + if len(chosen) == 4: + break + cohort = pd.concat(chosen, ignore_index=True) + pairs = build_pair_manifest(cohort, limit=50, seed=42) + rng = np.random.default_rng(42) + arrays = {name: rng.normal(size=(len(cohort), 16)) for name in ("r", "p", "rp", "rtp")} + matrices = {name: distance_matrix(value, "cosine") for name, value in arrays.items()} + retrieval = {} + report = {} + for name, matrix in matrices.items(): + pair_report, _ = pair_metrics(matrix, pairs) + retrieval_report, retrieval[name] = retrieval_metrics(matrix, cohort) + report[name] = {"pairs": pair_report, "retrieval": retrieval_report} + report["bootstrap"] = bootstrap_primary(matrices, pairs, retrieval, replicates=20, seed=42) + report["controls"] = controls(cohort, pairs, matrices, permutations=20, seed=42) + assert_finite_tree(report) + payload = { + "status": "ready", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "cohort_sha256": sha256(args.cohort), + "evaluation_script_sha256": sha256(args.evaluation_script), + "smoke_rows": len(cohort), + "smoke_pairs": len(pairs), + "checks": { + "pair_contrast": True, + "pairwise_auroc_auprc": True, + "donor_excluded_retrieval": True, + "cosine_distance": True, + "euclidean_distance": bool(np.isfinite(distance_matrix(arrays["r"], "euclidean")).all()), + "donor_cluster_bootstrap": True, + "length_composition_and_shuffle_controls": True, + "finite_results": True, + }, + } + args.output.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(json.dumps(payload, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/scripts/preflight_wordpiece_rq4.py b/scripts/preflight_wordpiece_rq4.py new file mode 100644 index 0000000..1cc30e8 --- /dev/null +++ b/scripts/preflight_wordpiece_rq4.py @@ -0,0 +1,140 @@ +"""CPU preflight for the locked RQ4 WordPiece benchmark runs.""" + +import argparse +import hashlib +import json +import platform +from pathlib import Path + +import torch + +from irrm_codec.multitask_data import ( + MultiTaskBenchmarkDataset, + TargetStandardizer, + collate_multitask, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, +) +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", required=True) + parser.add_argument("--tokenizer-dir", required=True) + parser.add_argument("--output-path", required=True) + args = parser.parse_args() + + data_dir = Path(args.data_dir) + tokenizer_dir = Path(args.tokenizer_dir) + tokenizer_path = tokenizer_dir / "tokenizer.json" + config = json.loads((tokenizer_dir / "tokenizer_config.json").read_text()) + validation = json.loads((tokenizer_dir / "validation_report.json").read_text()) + if config["training_split"] != "train" or not validation["train_only_fit"]: + raise ValueError("Tokenizer provenance does not prove train-only fitting.") + if not all(validation["checks"].values()): + raise ValueError("Tokenizer validation checks are not all true.") + if sha256(tokenizer_path) != config["tokenizer_sha256"]: + raise ValueError("Tokenizer checksum does not match immutable config.") + train_manifest = data_dir / "manifests" / "train.tsv" + if sha256(train_manifest) != config["train_manifest_sha256"]: + raise ValueError("Locked train-manifest checksum changed.") + + ready = json.loads((data_dir / "READY.json").read_text()) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Locked benchmark is not ready.") + table, embeddings = load_prepared_benchmark(data_dir) + train_indices = select_split_indices(table, data_dir, "train") + val_indices = select_split_indices(table, data_dir, "val") + test_indices = select_split_indices(table, data_dir, "test") + standardizer = TargetStandardizer.load(data_dir / "target_standardizer.npz") + if standardizer.train_rows != len(train_indices) or standardizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Locked train-only target standardizer does not match RQ4.") + if len(standardizer.tcremp_mean) != embeddings.shape[1]: + raise ValueError("Locked TCRemP standardizer has the wrong dimension.") + + tokenizer = resolve_encoder_tokenizer("wordpiece", str(tokenizer_path)) + dataset = MultiTaskBenchmarkDataset( + table, embeddings, train_indices[:2], tokenizer, "log10_pgen_1mm", 40 + ) + batch = collate_multitask([dataset[0], dataset[1]]) + torch.manual_seed(42) + model_config = IRRMCodecConfig( + input_vocab_size=tokenizer.vocab_size, + output_vocab_size=len(AA_VOCAB), + share_input_output_embeddings=False, + max_sequence_len=40, + d_model=32, + latent_dim=24, + nhead=4, + encoder_layers=1, + decoder_layers=1, + ff_dim=64, + dropout=0.0, + tcremp_dim=embeddings.shape[1], + tcremp_head_dim=24, + pgen_head_dim=12, + decoder_memory_tokens=2, + ) + model = IRRMCodecTransformer(model_config) + outputs = model(batch["encoder_tokens"], batch["encoder_mask"], batch["decoder_input"]) + standardizer_tensors = standardizer.as_torch(torch.device("cpu")) + losses = IRRMCodecMultiTaskLoss(weights=MultiTaskLossWeights(1.0, 1.0, 1.0))( + outputs, + tcremp_target=batch["tcremp_target"], + pgen_target=batch["pgen_target"], + reconstruction_target=batch["reconstruction_target"], + **standardizer_tensors, + ) + losses["loss"].backward() + if not torch.isfinite(losses["loss"]): + raise FloatingPointError("WordPiece smoke loss is non-finite.") + + report = { + "status": "ready", + "tokenizer": { + "path": str(tokenizer_path.resolve()), + "sha256": sha256(tokenizer_path), + "vocab_size": tokenizer.vocab_size, + "special_token_ids": config["special_token_ids"], + "train_manifest_sha256": config["train_manifest_sha256"], + "train_only_fit": True, + }, + "benchmark": { + "path": str(data_dir.resolve()), + "ready_sha256": sha256(data_dir / "READY.json"), + "rows": len(table), + "embedding_shape": list(embeddings.shape), + "split_rows": { + "train": len(train_indices), "val": len(val_indices), "test": len(test_indices) + }, + "normalizer_fit_split": "train", + "normalizer_train_rows": standardizer.train_rows, + }, + "model_smoke": { + "input_vocab_size": tokenizer.vocab_size, + "output_vocab_size": len(AA_VOCAB), + "shared_input_output_embeddings": False, + "finite_loss": True, + "loss": float(losses["loss"].detach()), + }, + "runtime": {"python": platform.python_version(), "torch": torch.__version__}, + } + output_path = Path(args.output_path) + output_path.parent.mkdir(parents=True, exist_ok=True) + output_path.write_text(json.dumps(report, indent=2), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/scripts/preflight_wordpiece_sweep.py b/scripts/preflight_wordpiece_sweep.py new file mode 100644 index 0000000..9c106a2 --- /dev/null +++ b/scripts/preflight_wordpiece_sweep.py @@ -0,0 +1,189 @@ +"""CPU gate for the leakage-safe TRB WordPiece vocabulary sweep.""" + +import argparse +import gc +import hashlib +import json +import platform +from dataclasses import asdict +from pathlib import Path + +import torch + +from irrm_codec.multitask_data import ( + MultiTaskBenchmarkDataset, + TargetStandardizer, + collate_multitask, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, +) +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB + + +VOCAB_SIZES = (44, 64, 128, 256, 512, 1024, 2048, 4096) + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", required=True) + parser.add_argument("--tokenizer-root", required=True) + parser.add_argument("--baseline-run-config", required=True) + parser.add_argument("--output-path", required=True) + args = parser.parse_args() + + data_dir = Path(args.data_dir) + tokenizer_root = Path(args.tokenizer_root) + baseline_path = Path(args.baseline_run_config) + baseline = json.loads(baseline_path.read_text()) + if ( + baseline["model"]["latent_dim"] != 128 + or baseline["model"]["encoder_layers"] != 4 + or baseline["model"]["decoder_layers"] != 4 + ): + raise ValueError("Baseline is not the validation-selected char d128 4+4 model.") + + ready = json.loads((data_dir / "READY.json").read_text()) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Locked benchmark is not ready.") + table, embeddings = load_prepared_benchmark(data_dir) + split_indices = { + split: select_split_indices(table, data_dir, split) for split in ("train", "val", "test") + } + standardizer = TargetStandardizer.load(data_dir / "target_standardizer.npz") + if standardizer.train_rows != len(split_indices["train"]): + raise ValueError("Locked standardizer is not train-only for the locked manifest.") + if standardizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Locked standardizer uses the wrong pgen target.") + + expected_training = { + "train_subset": "all", "pgen_target": "log10_pgen_1mm", "tokenizer_type": "char", + "tokenizer_path": None, "max_sequence_len": 40, "d_model": 320, "latent_dim": 128, + "nhead": 8, "encoder_layers": 4, "decoder_layers": 4, "ff_dim": 1280, + "dropout": 0.1, "tcremp_head_dim": 1024, "pgen_head_dim": 256, + "decoder_memory_tokens": 4, "tcremp_loss_weight": 1.0, "pgen_loss_weight": 1.0, + "reconstruction_loss_weight": 1.0, "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, "label_smoothing": 0.0, "batch_size": 64, + "epochs": 40, "lr": 0.0003, "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, "max_grad_norm": 1.0, + "early_stopping_patience": 0, "scheduler_factor": 0.5, "scheduler_patience": 2, + "scheduler_min_lr": 1e-6, "seed": 42, "num_workers": 8, "amp": True, + "skip_generation_metrics": False, "save_test_predictions": False, + "val_generation_every": 0, "max_train_batches": 0, "max_eval_batches": 0, + } + mismatches = { + key: {"expected": expected, "actual": baseline["training"].get(key)} + for key, expected in expected_training.items() + if baseline["training"].get(key) != expected + } + if mismatches: + raise ValueError(f"Selected char baseline differs from locked Stage-A settings: {mismatches}") + + train_manifest = data_dir / "manifests" / "train.tsv" + standardizer_tensors = standardizer.as_torch(torch.device("cpu")) + candidates = {} + for vocab_size in VOCAB_SIZES: + token_dir = tokenizer_root / f"v{vocab_size}-seed42" + config = json.loads((token_dir / "tokenizer_config.json").read_text()) + validation = json.loads((token_dir / "validation_report.json").read_text()) + tokenizer_path = token_dir / "tokenizer.json" + if config["actual_vocab_size"] != vocab_size or config["requested_vocab_size"] != vocab_size: + raise ValueError(f"WordPiece v{vocab_size} actual/requested size mismatch.") + if config["training_split"] != "train" or config["training_rows"] != 79_544: + raise ValueError(f"WordPiece v{vocab_size} lacks train-only provenance.") + if config["train_manifest_sha256"] != sha256(train_manifest): + raise ValueError(f"WordPiece v{vocab_size} train manifest checksum changed.") + if config["tokenizer_sha256"] != sha256(tokenizer_path): + raise ValueError(f"WordPiece v{vocab_size} tokenizer checksum changed.") + if not all(validation["checks"].values()): + raise ValueError(f"WordPiece v{vocab_size} validation checks are not all true.") + + tokenizer = resolve_encoder_tokenizer("wordpiece", str(tokenizer_path)) + dataset = MultiTaskBenchmarkDataset( + table, embeddings, split_indices["train"][:2], tokenizer, "log10_pgen_1mm", 40 + ) + batch = collate_multitask([dataset[0], dataset[1]]) + model_payload = dict(baseline["model"]) + model_payload["input_vocab_size"] = vocab_size + model_payload["output_vocab_size"] = len(AA_VOCAB) + model_payload["share_input_output_embeddings"] = False + model_config = IRRMCodecConfig(**model_payload) + model_config.validate() + changed_model_fields = sorted( + key for key, value in asdict(model_config).items() if value != baseline["model"][key] + ) + if changed_model_fields != ["input_vocab_size", "share_input_output_embeddings"]: + raise ValueError(f"WordPiece v{vocab_size} changed unexpected model fields: {changed_model_fields}") + torch.manual_seed(42) + model = IRRMCodecTransformer(model_config) + outputs = model(batch["encoder_tokens"], batch["encoder_mask"], batch["decoder_input"]) + losses = IRRMCodecMultiTaskLoss(weights=MultiTaskLossWeights(1.0, 1.0, 1.0))( + outputs, + tcremp_target=batch["tcremp_target"], + pgen_target=batch["pgen_target"], + reconstruction_target=batch["reconstruction_target"], + **standardizer_tensors, + ) + losses["loss"].backward() + if not torch.isfinite(losses["loss"]): + raise FloatingPointError(f"WordPiece v{vocab_size} smoke loss is non-finite.") + candidates[str(vocab_size)] = { + "requested_vocab_size": vocab_size, + "actual_vocab_size": tokenizer.vocab_size, + "tokenizer_sha256": config["tokenizer_sha256"], + "vocab_sha256": config["vocab_sha256"], + "token_statistics_sha256": config["token_statistics_sha256"], + "parameter_count": sum(parameter.numel() for parameter in model.parameters()), + "parameter_delta_vs_char": sum(parameter.numel() for parameter in model.parameters()) + - baseline["parameter_count"], + "changed_model_fields_vs_char": changed_model_fields, + "changed_training_fields_vs_char": ["tokenizer_type", "tokenizer_path"], + "separate_wordpiece_encoder_char_decoder": True, + "finite_full_multitask_smoke_loss": True, + "smoke_loss": float(losses["loss"].detach()), + } + del model, outputs, losses, dataset, batch + gc.collect() + + report = { + "status": "ready", + "selection_rule": { + "primary": "minimum best-checkpoint full validation objective", + "secondary": ["validation pgen RMSE", "validation reconstruction", "validation TCRemP"], + "test_metrics_used_for_selection": False, + }, + "baseline": { + "job_id": "1425949", + "run_config_sha256": sha256(baseline_path), + "parameter_count": baseline["parameter_count"], + "non_tokenizer_training_fields_match": True, + }, + "benchmark": { + "path": str(data_dir.resolve()), + "ready_sha256": sha256(data_dir / "READY.json"), + "rows": len(table), + "embedding_shape": list(embeddings.shape), + "split_rows": {split: len(indices) for split, indices in split_indices.items()}, + "normalizer_fit_split": "train", + "normalizer_train_rows": standardizer.train_rows, + }, + "candidates": candidates, + "runtime": {"python": platform.python_version(), "torch": torch.__version__}, + } + output = Path(args.output_path) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(report, indent=2), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/scripts/prepare_anchored_tokenizers.py b/scripts/prepare_anchored_tokenizers.py new file mode 100644 index 0000000..2e575ab --- /dev/null +++ b/scripts/prepare_anchored_tokenizers.py @@ -0,0 +1,553 @@ +"""Prepare three leakage-safe sequence-only terminal-anchor tokenizers. + +This script is intentionally a CPU batch workload: it streams an independently +generated OLGA TRB corpus, removes every locked benchmark sequence, mines anchor +libraries from train-only evidence, fits central WordPiece models, and audits +exact round trips on every locked split. +""" + +from __future__ import annotations + +import argparse +import csv +import gzip +import hashlib +import itertools +import json +import math +import shutil +import tempfile +from collections import Counter, defaultdict +from pathlib import Path + +import numpy as np +from tokenizers import Tokenizer +from tokenizers.decoders import WordPiece as WordPieceDecoder +from tokenizers.models import WordPiece +from tokenizers.pre_tokenizers import Whitespace +from tokenizers.trainers import WordPieceTrainer + +from irrm_codec.anchored_tokenization import AnchoredTokenizer, SPECIAL_TOKENS +from irrm_codec.multitask_data import load_prepared_benchmark, select_split_indices +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID, VALID_AA +from irrm_codec.wordpiece_tokenization import validate_wordpiece_tokenizer + + +ALPHABET = "ACDEFGHIKLMNPQRSTVWY" +CENTRAL_VOCAB_SIZE = 256 +EDGE_K = 3 +MAX_ANCHOR_LEN = 8 +MIN_DATA_TOTAL_SUPPORT = 50 +MIN_DATA_GENE_SUPPORT = 25 +MIN_GERMLINE_SUPPORT = 20 +SPECIAL_IDS = {"pad": PAD_ID, "bos": BOS_ID, "eos": EOS_ID, "unk": UNK_ID} +CODONS = { + "TTT":"F","TTC":"F","TTA":"L","TTG":"L","TCT":"S","TCC":"S","TCA":"S","TCG":"S", + "TAT":"Y","TAC":"Y","TAA":"*","TAG":"*","TGT":"C","TGC":"C","TGA":"*","TGG":"W", + "CTT":"L","CTC":"L","CTA":"L","CTG":"L","CCT":"P","CCC":"P","CCA":"P","CCG":"P", + "CAT":"H","CAC":"H","CAA":"Q","CAG":"Q","CGT":"R","CGC":"R","CGA":"R","CGG":"R", + "ATT":"I","ATC":"I","ATA":"I","ATG":"M","ACT":"T","ACC":"T","ACA":"T","ACG":"T", + "AAT":"N","AAC":"N","AAA":"K","AAG":"K","AGT":"S","AGC":"S","AGA":"R","AGG":"R", + "GTT":"V","GTC":"V","GTA":"V","GTG":"V","GCT":"A","GCC":"A","GCA":"A","GCG":"A", + "GAT":"D","GAC":"D","GAA":"E","GAG":"E","GGT":"G","GGC":"G","GGA":"G","GGG":"G", +} + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def translate(nt: str) -> str: + return "".join(CODONS.get(nt[index:index + 3].upper(), "X") for index in range(0, len(nt) - 2, 3)) + + +def canonical_call(value: object) -> str: + return str(value).split(",", 1)[0].split("*", 1)[0].strip() + + +def select_pair(sequence: str, n_anchors: tuple[str, ...], c_anchors: tuple[str, ...]) -> tuple[str, str, bool]: + n_matches = [anchor for anchor in n_anchors if sequence.startswith(anchor)] + c_matches = [anchor for anchor in c_anchors if sequence.endswith(anchor)] + feasible = [(n, c) for n in n_matches for c in c_matches if len(n) + len(c) <= len(sequence)] + if not feasible: + raise ValueError(f"No feasible anchor pair for {sequence!r}.") + pair = min(feasible, key=lambda value: (-(len(value[0]) + len(value[1])), -len(value[0]), -len(value[1]), value)) + raw_longest_overlap = bool(n_matches and c_matches and len(n_matches[0]) + len(c_matches[0]) > len(sequence)) + return pair[0], pair[1], raw_longest_overlap + + +def build_data_anchors(train) -> tuple[tuple[str, ...], tuple[str, ...], dict]: + side_payload = {} + libraries = [] + for side, gene_column in (("N", "v_call"), ("C", "j_call")): + total = Counter() + by_gene: dict[str, Counter] = defaultdict(Counter) + for sequence, raw_gene in zip(train["junction_aa"], train[gene_column], strict=True): + gene = canonical_call(raw_gene) + for length in range(1, min(MAX_ANCHOR_LEN, len(sequence)) + 1): + motif = sequence[:length] if side == "N" else sequence[-length:] + total[motif] += 1 + by_gene[motif][gene] += 1 + retained = set(ALPHABET) + evidence = {} + for motif, count in total.items(): + top_gene, top_count = by_gene[motif].most_common(1)[0] + if len(motif) >= 2 and count >= MIN_DATA_TOTAL_SUPPORT and top_count >= MIN_DATA_GENE_SUPPORT: + retained.add(motif) + evidence[motif] = { + "train_count": count, + "top_gene": top_gene, + "top_gene_count": top_count, + "top_gene_fraction": top_count / count, + } + library = tuple(sorted(retained, key=lambda value: (-len(value), value))) + libraries.append(library) + side_payload[side] = { + "candidate_rule": ( + f"train-only literal {side} flanks length 2..{MAX_ANCHOR_LEN}; total support >= " + f"{MIN_DATA_TOTAL_SUPPORT} and support within at least one annotated gene >= " + f"{MIN_DATA_GENE_SUPPORT}; exhaustive one-residue identity fallbacks" + ), + "retained": len(library), + "evidence": evidence, + } + return libraries[0], libraries[1], side_payload + + +def read_olga_genes(model_params: Path, section: str) -> dict[str, str]: + genes = {} + active = False + marker = f"#GeneChoice;{section}_gene;" + for raw_line in model_params.read_text(encoding="utf-8").splitlines(): + if raw_line.startswith("#"): + active = raw_line.startswith(marker) + continue + if active and raw_line.startswith("%"): + fields = raw_line[1:].strip().split(";") + if len(fields) >= 2: + genes[fields[0].strip()] = fields[1].strip().upper() + if not genes: + raise ValueError(f"No {section} genes found in {model_params}.") + return genes + + +def read_anchor_csv(path: Path) -> dict[str, int]: + with path.open(encoding="utf-8", newline="") as handle: + rows = list(csv.DictReader(handle)) + return { + row["gene"]: int(row["anchor_index"]) + for row in rows + if row["function"].strip("()") == "F" + } + + +def build_germline_anchors(train, model_dir: Path) -> tuple[tuple[str, ...], tuple[str, ...], dict]: + params = model_dir / "model_params.txt" + v_anchor_path = model_dir / "V_gene_CDR3_anchors.csv" + j_anchor_path = model_dir / "J_gene_CDR3_anchors.csv" + v_genes = read_olga_genes(params, "V") + j_genes = read_olga_genes(params, "J") + v_indices = read_anchor_csv(v_anchor_path) + j_indices = read_anchor_csv(j_anchor_path) + reference = {"N": defaultdict(set), "C": defaultdict(set)} + for gene, index in v_indices.items(): + if gene not in v_genes: + continue + amino = translate(v_genes[gene][index:]) + for length in range(1, min(MAX_ANCHOR_LEN, len(amino)) + 1): + motif = amino[:length] + if set(motif) <= VALID_AA: + reference["N"][motif].add(gene) + for gene, index in j_indices.items(): + if gene not in j_genes: + continue + frame_start = index % 3 + amino = translate(j_genes[gene][frame_start:index + 3]) + for length in range(1, min(MAX_ANCHOR_LEN, len(amino)) + 1): + motif = amino[-length:] + if set(motif) <= VALID_AA: + reference["C"][motif].add(gene) + + payload = {} + libraries = [] + for side in ("N", "C"): + support = Counter() + for sequence in train["junction_aa"]: + for motif in reference[side]: + if (sequence.startswith(motif) if side == "N" else sequence.endswith(motif)): + support[motif] += 1 + retained = { + motif for motif, count in support.items() + if count >= MIN_GERMLINE_SUPPORT and len(motif) >= 2 + } + # Exhaustive one-residue identity fallbacks are constants, not learned motifs. + retained.update(ALPHABET) + library = tuple(sorted(retained, key=lambda value: (-len(value), value))) + libraries.append(library) + payload[side] = { + "retained": len(library), + "minimum_train_support": MIN_GERMLINE_SUPPORT, + "motifs": { + motif: {"train_support": support[motif], "source_genes": sorted(reference[side][motif])} + for motif in library + }, + } + payload["source_files"] = { + path.name: sha256(path) for path in (params, v_anchor_path, j_anchor_path) + } + payload["derivation"] = ( + "Functional OLGA TRB_orig V sequences translated from each V CDR3 anchor; functional J " + "sequences translated in the frame ending at each J conserved-F anchor; literal prefixes/" + "suffixes length 1..8 retained only with train support >=20." + ) + return libraries[0], libraries[1], payload + + +def stream_external_corpus(source: Path, output: Path, benchmark_sequences: set[str], rows: int) -> dict: + accepted = 0 + source_rows = 0 + rejected_overlap = 0 + rejected_invalid = 0 + rejected_duplicate = 0 + seen = set() + with gzip.open(source, "rt", encoding="utf-8") as input_handle, output.open("w", encoding="utf-8") as out: + header = input_handle.readline().rstrip("\n").split("\t") + aa_index = header.index("junction_aa") + for line in input_handle: + source_rows += 1 + fields = line.rstrip("\n").split("\t") + if len(fields) <= aa_index: + rejected_invalid += 1 + continue + sequence = fields[aa_index].strip().upper() + if not (8 <= len(sequence) <= 40 and set(sequence) <= VALID_AA and sequence.startswith("C") and sequence.endswith("F")): + rejected_invalid += 1 + continue + if sequence in benchmark_sequences: + rejected_overlap += 1 + continue + if sequence in seen: + rejected_duplicate += 1 + continue + seen.add(sequence) + out.write(f"{sequence}\n") + accepted += 1 + if accepted == rows: + break + if accepted != rows: + raise ValueError(f"Requested {rows} disjoint external rows but obtained {accepted}.") + return { + "source_path": str(source), + "source_sha256": sha256(source), + "source_rows_scanned": source_rows, + "accepted_unique_rows": accepted, + "benchmark_overlap_rejected": rejected_overlap, + "invalid_rejected": rejected_invalid, + "duplicate_rejected": rejected_duplicate, + "output_sha256": sha256(output), + "overlap_after_filter": len(seen.intersection(benchmark_sequences)), + "selection": "first valid unique rows in source order after locked-benchmark exclusion", + } + + +def fit_central_wordpiece(middle_path: Path, output_path: Path) -> Tokenizer: + tokenizer = Tokenizer(WordPiece(unk_token="[UNK]")) + tokenizer.pre_tokenizer = Whitespace() + tokenizer.decoder = WordPieceDecoder(prefix="##") + tokenizer.train( + [str(middle_path)], + WordPieceTrainer( + vocab_size=CENTRAL_VOCAB_SIZE, + min_frequency=2, + special_tokens=SPECIAL_TOKENS, + continuing_subword_prefix="##", + show_progress=False, + ), + ) + validate_wordpiece_tokenizer(tokenizer, middle_path) + if tokenizer.get_vocab_size() != CENTRAL_VOCAB_SIZE: + raise ValueError( + f"Central WordPiece requested {CENTRAL_VOCAB_SIZE}, got {tokenizer.get_vocab_size()}." + ) + tokenizer.save(str(output_path)) + return tokenizer + + +def write_bundle(directory: Path, kind: str, n_anchors: tuple[str, ...], c_anchors: tuple[str, ...], central: Tokenizer, provenance: dict) -> Path: + vocab = {token: identifier for identifier, token in enumerate(SPECIAL_TOKENS)} + for anchor in sorted(n_anchors): + vocab[f"[N:{anchor}]"] = len(vocab) + for anchor in sorted(c_anchors): + vocab[f"[C:{anchor}]"] = len(vocab) + central_by_id = {identifier: token for token, identifier in central.get_vocab().items()} + central_to_input = {} + for central_id in range(len(SPECIAL_TOKENS), central.get_vocab_size()): + token = f"[M:{central_by_id[central_id]}]" + central_to_input[str(central_id)] = len(vocab) + vocab[token] = len(vocab) + bundle = { + "format_version": 1, + "tokenizer_type": kind, + "inference_modality": "sequence_only", + "accepts_v_call_or_j_call": False, + "k": EDGE_K if kind == "edge_k" else None, + "special_token_ids": SPECIAL_IDS, + "central_tokenizer_file": "central_tokenizer.json", + "central_to_input": central_to_input, + "n_anchors": list(n_anchors), + "c_anchors": list(c_anchors), + "vocab": vocab, + "vocab_size": len(vocab), + "boundary_types": ["N_ANCHOR", "MIDDLE_WORDPIECE", "C_ANCHOR"], + "selection_rule": ( + f"literal first/last {EDGE_K} residues" if kind == "edge_k" else + "longest non-overlapping prefix/suffix pair; maximum total length, then N length, then C length, then lexical" + ), + "unknown_behavior": ( + f"fail closed only for invalid amino acids or length <{2 * EDGE_K}; every standard-amino-acid EDGE-{EDGE_K} literal is exhaustively enumerated" + if kind == "edge_k" else + "exhaustive one-residue identity fallbacks guarantee valid-amino-acid coverage without heldout fitting; otherwise fail closed" + ), + "provenance": provenance, + } + path = directory / "anchored_tokenizer.json" + path.write_text(json.dumps(bundle, indent=2), encoding="utf-8") + return path + + +def audit(kind: str, bundle_path: Path, sequences: dict[str, list[str]], train_pgen: np.ndarray) -> tuple[dict, list[dict]]: + tokenizer = AnchoredTokenizer(bundle_path) + counts = np.zeros(tokenizer.vocab_size, dtype=np.int64) + presence = np.zeros(tokenizer.vocab_size, dtype=np.int64) + position_sum = np.zeros(tokenizer.vocab_size, dtype=np.float64) + pgen_sum = np.zeros(tokenizer.vocab_size, dtype=np.float64) + reports = {} + for split, values in sequences.items(): + lengths, n_lengths, c_lengths = [], [], [] + mismatches = boundary_failures = overlap_adjustments = 0 + n_used, c_used = Counter(), Counter() + for row_number, sequence in enumerate(values): + encoded = tokenizer.encode_with_boundaries(sequence, 40) + mismatches += int(tokenizer.decode(encoded.ids) != sequence) + boundary_failures += int( + encoded.boundary_types[0] != "N_ANCHOR" + or encoded.boundary_types[-1] != "C_ANCHOR" + or encoded.n_anchor != sequence[:len(encoded.n_anchor)] + or encoded.c_anchor != sequence[-len(encoded.c_anchor):] + ) + lengths.append(len(encoded.ids)) + n_lengths.append(len(encoded.n_anchor)) + c_lengths.append(len(encoded.c_anchor)) + n_used[encoded.n_anchor] += 1 + c_used[encoded.c_anchor] += 1 + if kind != "edge_k": + _n, _c, adjusted = select_pair(sequence, tokenizer.n_anchors, tokenizer.c_anchors) + overlap_adjustments += int(adjusted) + if split == "train": + unique = np.unique(encoded.ids) + counts += np.bincount(encoded.ids, minlength=tokenizer.vocab_size) + presence[unique] += 1 + denominator = max(len(encoded.ids) - 1, 1) + for position, identifier in enumerate(encoded.ids): + position_sum[identifier] += position / denominator + pgen_sum[unique] += float(train_pgen[row_number]) + reports[split] = { + "rows": len(values), + "roundtrip_mismatches": mismatches, + "indel_or_substitution_failures": mismatches, + "boundary_failures": boundary_failures, + "token_length_mean": float(np.mean(lengths)), + "token_length_p95": float(np.quantile(lengths, 0.95)), + "token_length_max": int(max(lengths)), + "mean_n_anchor_length": float(np.mean(n_lengths)), + "mean_c_anchor_length": float(np.mean(c_lengths)), + "n_anchor_length_gt1_coverage": float(np.mean(np.asarray(n_lengths) > 1)), + "c_anchor_length_gt1_coverage": float(np.mean(np.asarray(c_lengths) > 1)), + "unique_n_anchors_used": len(n_used), + "unique_c_anchors_used": len(c_used), + "longest_pair_overlap_adjustments": overlap_adjustments, + "same_length_literal_collisions": 0, + } + global_mean = float(train_pgen.mean()) + global_std = float(train_pgen.std()) + rows = [] + for identifier in range(tokenizer.vocab_size): + token = tokenizer.id_to_token[identifier] + present = int(presence[identifier]) + absent = len(sequences["train"]) - present + present_mean = float(pgen_sum[identifier] / present) if present else math.nan + absent_mean = float((train_pgen.sum() - pgen_sum[identifier]) / absent) if absent else math.nan + fraction = present / len(sequences["train"]) + association = ( + (present_mean - global_mean) * math.sqrt(fraction * (1 - fraction)) / global_std + if present and absent and global_std > 0 else math.nan + ) + boundary = "SPECIAL" if identifier < 4 else ( + "N_ANCHOR" if token.startswith("[N:") else "C_ANCHOR" if token.startswith("[C:") else "MIDDLE_WORDPIECE" + ) + rows.append({ + "token_id": identifier, + "token": token, + "boundary_type": boundary, + "train_occurrence_count": int(counts[identifier]), + "train_sequence_count": present, + "train_mean_normalized_position": ( + float(position_sum[identifier] / counts[identifier]) if counts[identifier] else "" + ), + "train_log10_pgen_1mm_mean_present": present_mean if present else "", + "train_log10_pgen_1mm_mean_absent": absent_mean if absent else "", + "train_pgen_presence_correlation": association if math.isfinite(association) else "", + }) + return reports, rows + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", required=True) + parser.add_argument("--output-root", required=True) + parser.add_argument("--external-corpus", required=True) + parser.add_argument("--generation-script", required=True) + parser.add_argument("--olga-model-dir", required=True) + parser.add_argument("--external-rows", type=int, default=500_000) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.seed != 42 or args.external_rows < 100_000: + raise ValueError("Anchored study requires seed 42 and a genuinely larger external corpus.") + + data_dir = Path(args.data_dir) + output_root = Path(args.output_root) + if (output_root / "READY.json").exists(): + raise FileExistsError(f"Refusing to overwrite immutable tokenizer root {output_root}.") + output_root.mkdir(parents=True, exist_ok=True) + table, _ = load_prepared_benchmark(data_dir) + indices = {split: select_split_indices(table, data_dir, split) for split in ("train", "val", "test")} + sequences = {split: table.iloc[value]["junction_aa"].astype(str).tolist() for split, value in indices.items()} + train = table.iloc[indices["train"]].reset_index(drop=True) + benchmark_sequences = set(table["junction_aa"].astype(str)) + train_manifest = data_dir / "manifests" / "train.tsv" + + corpus_path = output_root / "olga_trb_disjoint_500k.txt" + corpus_report = stream_external_corpus( + Path(args.external_corpus), corpus_path, benchmark_sequences, args.external_rows + ) + corpus_report.update({ + "generation_script": str(Path(args.generation_script)), + "generation_script_sha256": sha256(Path(args.generation_script)), + "declared_generator": "olga-generate_sequences --VDJ_model_folder=../model/Homo+sapiens/TRB_orig/", + "fit_usage": "central WordPiece only; never anchors or evaluation metrics", + }) + + edge_n = tuple("".join(value) for value in itertools.product(ALPHABET, repeat=EDGE_K)) + edge_c = tuple("".join(value) for value in itertools.product(ALPHABET, repeat=EDGE_K)) + data_n, data_c, data_provenance = build_data_anchors(train) + germ_n, germ_c, germ_provenance = build_germline_anchors(train, Path(args.olga_model_dir)) + candidates = { + "edge_k": (edge_n, edge_c, { + "anchor_fit": "exhaustive standard-amino-acid K-mer literal space on each side; no observed sequences used", + "k": EDGE_K, + "canonical_anchor_count_per_side": len(edge_n), + }), + "data_anchor": (data_n, data_c, { + "anchor_fit": "locked train rows only; V/J calls restrict candidate support but are not runtime inputs", + "train_manifest_sha256": sha256(train_manifest), + "mining": data_provenance, + }), + "germline_anchor": (germ_n, germ_c, { + "anchor_fit": "OLGA TRB_orig germline-compatible motifs retained by locked train support only", + "train_manifest_sha256": sha256(train_manifest), + "germline": germ_provenance, + }), + } + + top_manifest = { + "status": "preparation_complete", + "inference_modality": "sequence_only", + "forbidden_model_inputs": ["v_call", "j_call"], + "seed": args.seed, + "locked_split_rows": {split: len(value) for split, value in indices.items()}, + "train_manifest_sha256": sha256(train_manifest), + "external_corpus": corpus_report, + "central_wordpiece_vocab_size": CENTRAL_VOCAB_SIZE, + "candidates": {}, + } + train_pgen = train["log10_pgen_1mm"].to_numpy(np.float64) + for kind, (n_anchors, c_anchors, provenance) in candidates.items(): + final_dir = output_root / kind + if final_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {final_dir}.") + with tempfile.TemporaryDirectory(prefix=f".{kind}-", dir=output_root) as temporary: + candidate_dir = Path(temporary) + middle_path = candidate_dir / "central_corpus.txt" + with corpus_path.open(encoding="utf-8") as input_handle, middle_path.open("w", encoding="utf-8") as out: + for line in input_handle: + sequence = line.strip() + if kind == "edge_k": + n_anchor, c_anchor = sequence[:EDGE_K], sequence[-EDGE_K:] + else: + n_anchor, c_anchor, _ = select_pair(sequence, n_anchors, c_anchors) + middle = sequence[len(n_anchor):len(sequence) - len(c_anchor)] + if middle: + out.write(f"{middle}\n") + central_path = candidate_dir / "central_tokenizer.json" + central = fit_central_wordpiece(middle_path, central_path) + provenance = dict(provenance) + provenance.update({ + "central_corpus_sha256": sha256(middle_path), + "external_raw_corpus_sha256": sha256(corpus_path), + "central_fit_rows_source": args.external_rows, + "heldout_raw_sequences_used_for_fit": False, + }) + bundle_path = write_bundle(candidate_dir, kind, n_anchors, c_anchors, central, provenance) + reports, token_rows = audit(kind, bundle_path, sequences, train_pgen) + if any( + report[check] + for report in reports.values() + for check in ("roundtrip_mismatches", "boundary_failures") + ): + raise ValueError(f"{kind} failed exact round-trip/boundary audit: {reports}") + if max(report["token_length_max"] for report in reports.values()) > 40: + raise ValueError(f"{kind} exceeds model max input length: {reports}") + with (candidate_dir / "token_statistics.tsv").open("w", encoding="utf-8", newline="") as handle: + writer = csv.DictWriter(handle, fieldnames=list(token_rows[0])) + writer.writeheader() + writer.writerows(token_rows) + validation = { + "status": "prepared", + "checks": { + "sequence_only_inference": True, + "special_ids_0_1_2_3": True, + "train_only_anchor_fit": True, + "no_val_test_vocab_or_anchor_fit": True, + "external_corpus_benchmark_overlap_zero": corpus_report["overlap_after_filter"] == 0, + "exact_roundtrip_all_splits": True, + "no_indels_substitutions_all_splits": True, + "literal_protected_boundaries_all_splits": True, + "max_encoded_length_at_most_40": True, + }, + "encoding": reports, + } + (candidate_dir / "validation_report.json").write_text(json.dumps(validation, indent=2), encoding="utf-8") + config = json.loads(bundle_path.read_text(encoding="utf-8")) + config["bundle_sha256"] = sha256(bundle_path) + config["central_tokenizer_sha256"] = sha256(central_path) + config["token_statistics_sha256"] = sha256(candidate_dir / "token_statistics.tsv") + (candidate_dir / "tokenizer_config.json").write_text(json.dumps(config, indent=2), encoding="utf-8") + candidate_dir.rename(final_dir) + top_manifest["candidates"][kind] = { + "path": str(final_dir), + "input_vocab_size": config["vocab_size"], + "n_anchor_count": len(n_anchors), + "c_anchor_count": len(c_anchors), + "bundle_sha256": config["bundle_sha256"], + "central_tokenizer_sha256": config["central_tokenizer_sha256"], + "encoding": reports, + } + (output_root / "preparation_manifest.json").write_text(json.dumps(top_manifest, indent=2), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/scripts/prepare_wordpiece_rq4.py b/scripts/prepare_wordpiece_rq4.py new file mode 100644 index 0000000..ce21df5 --- /dev/null +++ b/scripts/prepare_wordpiece_rq4.py @@ -0,0 +1,177 @@ +"""Train and validate the immutable RQ4 WordPiece tokenizer on TRB train only.""" + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +from tokenizers import Tokenizer +from tokenizers.decoders import WordPiece as WordPieceDecoder +from tokenizers.models import WordPiece +from tokenizers.pre_tokenizers import Whitespace +from tokenizers.trainers import WordPieceTrainer + +from irrm_codec.multitask_data import load_prepared_benchmark, select_split_indices +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID +from irrm_codec.wordpiece_tokenization import validate_wordpiece_tokenizer + + +SPECIAL_TOKENS = ["[PAD]", "[BOS]", "[EOS]", "[UNK]"] +PREFIX = "##" + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def encode_report(tokenizer: Tokenizer, sequences: list[str]) -> dict: + token_lengths = [] + unknown_sequences = 0 + roundtrip_mismatches = 0 + for sequence in sequences: + encoding = tokenizer.encode(sequence) + token_lengths.append(len(encoding.ids)) + unknown_sequences += int(UNK_ID in encoding.ids) + decoded = tokenizer.decode(encoding.ids, skip_special_tokens=True) + roundtrip_mismatches += int(decoded != sequence) + values = np.asarray(token_lengths, dtype=np.int64) + return { + "rows": len(sequences), + "unknown_sequences": unknown_sequences, + "roundtrip_mismatches": roundtrip_mismatches, + "token_length_min": int(values.min()), + "token_length_max": int(values.max()), + "token_length_mean": float(values.mean()), + "token_length_p50": float(np.quantile(values, 0.5)), + "token_length_p95": float(np.quantile(values, 0.95)), + } + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", required=True) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--vocab-size", type=int, default=256) + parser.add_argument("--min-frequency", type=int, default=2) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + + if args.seed != 42: + raise ValueError("RQ4 tokenizer seed must remain fixed at 42.") + if args.vocab_size != 256: + raise ValueError("RQ4 uses the preregistered 256-token WordPiece vocabulary.") + output_dir = Path(args.output_dir) + tokenizer_path = output_dir / "tokenizer.json" + if tokenizer_path.exists(): + raise FileExistsError(f"Refusing to overwrite immutable tokenizer: {tokenizer_path}") + output_dir.mkdir(parents=True, exist_ok=True) + + data_dir = Path(args.data_dir) + table, _embeddings = load_prepared_benchmark(data_dir) + split_indices = { + split: select_split_indices(table, data_dir, split) + for split in ("train", "val", "test") + } + train_manifest = data_dir / "manifests" / "train.tsv" + sequences = { + split: table.iloc[indices]["junction_aa"].astype(str).tolist() + for split, indices in split_indices.items() + } + + corpus_path = output_dir / "train_cdr3.txt" + corpus_path.write_text( + "".join(f"{sequence}\n" for sequence in sequences["train"]), + encoding="utf-8", + ) + tokenizer = Tokenizer(WordPiece(unk_token="[UNK]")) + tokenizer.pre_tokenizer = Whitespace() + tokenizer.decoder = WordPieceDecoder(prefix=PREFIX) + tokenizer.train( + [str(corpus_path)], + WordPieceTrainer( + vocab_size=args.vocab_size, + min_frequency=args.min_frequency, + special_tokens=SPECIAL_TOKENS, + continuing_subword_prefix=PREFIX, + show_progress=False, + ), + ) + validate_wordpiece_tokenizer(tokenizer, "newly trained RQ4 tokenizer") + actual_vocab_size = tokenizer.get_vocab_size() + if actual_vocab_size != args.vocab_size: + raise ValueError( + f"Requested vocabulary {args.vocab_size}, got {actual_vocab_size}." + ) + + reports = {split: encode_report(tokenizer, values) for split, values in sequences.items()} + for split, report in reports.items(): + if report["unknown_sequences"] or report["roundtrip_mismatches"]: + raise ValueError(f"Tokenizer failed {split} coverage/roundtrip validation: {report}") + if report["token_length_max"] > 40: + raise ValueError(f"Tokenizer exceeds model width on {split}: {report}") + + tokenizer.save(str(tokenizer_path)) + tokenizer.model.save(str(output_dir)) + special_ids = { + "pad": PAD_ID, + "bos": BOS_ID, + "eos": EOS_ID, + "unk": UNK_ID, + } + config = { + "status": "immutable", + "tokenizer_type": "wordpiece", + "seed": args.seed, + "requested_vocab_size": args.vocab_size, + "actual_vocab_size": actual_vocab_size, + "min_frequency": args.min_frequency, + "continuing_subword_prefix": PREFIX, + "special_tokens": SPECIAL_TOKENS, + "special_token_ids": special_ids, + "training_split": "train", + "training_rows": len(split_indices["train"]), + "train_manifest_path": str(train_manifest.resolve()), + "train_manifest_sha256": sha256(train_manifest), + "corpus_path": str(corpus_path.resolve()), + "corpus_sha256": sha256(corpus_path), + "tokenizer_path": str(tokenizer_path.resolve()), + } + (output_dir / "tokenizer_config.json").write_text( + json.dumps(config, indent=2), encoding="utf-8" + ) + validation = { + "status": "ready", + "train_only_fit": True, + "split_rows": {split: len(indices) for split, indices in split_indices.items()}, + "split_index_overlap": { + "train_val": int(np.intersect1d(split_indices["train"], split_indices["val"]).size), + "train_test": int(np.intersect1d(split_indices["train"], split_indices["test"]).size), + "val_test": int(np.intersect1d(split_indices["val"], split_indices["test"]).size), + }, + "encoding": reports, + "checks": { + "special_ids_match_model": True, + "train_manifest_matches_locked_split": True, + "no_split_overlap": True, + "no_unknown_tokens": True, + "roundtrip_exact": True, + "all_encoded_lengths_at_most_40": True, + }, + } + (output_dir / "validation_report.json").write_text( + json.dumps(validation, indent=2), encoding="utf-8" + ) + config["tokenizer_sha256"] = sha256(tokenizer_path) + config["vocab_sha256"] = sha256(output_dir / "vocab.txt") + (output_dir / "tokenizer_config.json").write_text( + json.dumps(config, indent=2), encoding="utf-8" + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/prepare_wordpiece_sweep.py b/scripts/prepare_wordpiece_sweep.py new file mode 100644 index 0000000..9d6680c --- /dev/null +++ b/scripts/prepare_wordpiece_sweep.py @@ -0,0 +1,354 @@ +"""Train and audit the leakage-safe TRB WordPiece vocabulary sweep.""" + +import argparse +import csv +import hashlib +import json +import math +import tempfile +from pathlib import Path + +import numpy as np +from tokenizers import Tokenizer +from tokenizers.decoders import WordPiece as WordPieceDecoder +from tokenizers.models import WordPiece +from tokenizers.pre_tokenizers import Whitespace +from tokenizers.trainers import WordPieceTrainer + +from irrm_codec.multitask_data import load_prepared_benchmark, select_split_indices +from irrm_codec.tokenization import BOS_ID, EOS_ID, PAD_ID, UNK_ID +from irrm_codec.wordpiece_tokenization import validate_wordpiece_tokenizer + + +SPECIAL_TOKENS = ["[PAD]", "[BOS]", "[EOS]", "[UNK]"] +PREFIX = "##" +DEFAULT_VOCAB_SIZES = (44, 64, 128, 256, 512, 1024, 2048, 4096) + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def _safe_float(value: float) -> float | None: + return float(value) if math.isfinite(value) else None + + +def audit_tokenizer( + tokenizer: Tokenizer, + sequences: dict[str, list[str]], + train_pgen: np.ndarray, +) -> tuple[dict, list[dict]]: + vocab_size = tokenizer.get_vocab_size() + token_by_id = {identifier: token for token, identifier in tokenizer.get_vocab().items()} + split_counts = {split: np.zeros(vocab_size, dtype=np.int64) for split in sequences} + split_presence = {split: np.zeros(vocab_size, dtype=np.int64) for split in sequences} + reports = {} + train_start = np.zeros(vocab_size, dtype=np.int64) + train_end = np.zeros(vocab_size, dtype=np.int64) + train_internal = np.zeros(vocab_size, dtype=np.int64) + train_position_sum = np.zeros(vocab_size, dtype=np.float64) + train_pgen_present_sum = np.zeros(vocab_size, dtype=np.float64) + train_low_presence = np.zeros(vocab_size, dtype=np.int64) + train_high_presence = np.zeros(vocab_size, dtype=np.int64) + low_threshold, high_threshold = np.quantile(train_pgen, [0.25, 0.75]) + + for split, values in sequences.items(): + token_lengths = [] + unknown_sequences = 0 + roundtrip_mismatches = 0 + for row_number, (sequence, encoding) in enumerate( + zip(values, tokenizer.encode_batch(values), strict=True) + ): + ids = encoding.ids + token_lengths.append(len(ids)) + unknown_sequences += int(UNK_ID in ids) + roundtrip_mismatches += int( + tokenizer.decode(ids, skip_special_tokens=True) != sequence + ) + split_counts[split] += np.bincount(ids, minlength=vocab_size) + unique_ids = np.unique(ids) + split_presence[split][unique_ids] += 1 + if split == "train": + train_start[ids[0]] += 1 + train_end[ids[-1]] += 1 + if len(ids) > 2: + train_internal += np.bincount(ids[1:-1], minlength=vocab_size) + denominator = max(len(ids) - 1, 1) + for position, token_id in enumerate(ids): + train_position_sum[token_id] += position / denominator + pgen = float(train_pgen[row_number]) + train_pgen_present_sum[unique_ids] += pgen + if pgen <= low_threshold: + train_low_presence[unique_ids] += 1 + if pgen >= high_threshold: + train_high_presence[unique_ids] += 1 + lengths = np.asarray(token_lengths, dtype=np.int64) + reports[split] = { + "rows": len(values), + "unknown_sequences": unknown_sequences, + "roundtrip_mismatches": roundtrip_mismatches, + "token_length_min": int(lengths.min()), + "token_length_max": int(lengths.max()), + "token_length_mean": float(lengths.mean()), + "token_length_p50": float(np.quantile(lengths, 0.5)), + "token_length_p95": float(np.quantile(lengths, 0.95)), + } + + train_rows = len(sequences["train"]) + train_global_mean = float(train_pgen.mean()) + train_global_std = float(train_pgen.std()) + low_rows = int(np.count_nonzero(train_pgen <= low_threshold)) + high_rows = int(np.count_nonzero(train_pgen >= high_threshold)) + total_train_occurrences = int(split_counts["train"].sum()) + global_start_fraction = train_rows / total_train_occurrences + global_end_fraction = train_rows / total_train_occurrences + rows = [] + for token_id in range(vocab_size): + count = int(split_counts["train"][token_id]) + present = int(split_presence["train"][token_id]) + absent = train_rows - present + mean_present = ( + train_pgen_present_sum[token_id] / present if present else math.nan + ) + mean_absent = ( + (float(train_pgen.sum()) - train_pgen_present_sum[token_id]) / absent + if absent + else math.nan + ) + presence_fraction = present / train_rows + association = ( + (mean_present - train_global_mean) + * math.sqrt(presence_fraction * (1.0 - presence_fraction)) + / train_global_std + if present and absent and train_global_std > 0 + else math.nan + ) + high_rate = (train_high_presence[token_id] + 0.5) / (high_rows + 1.0) + low_rate = (train_low_presence[token_id] + 0.5) / (low_rows + 1.0) + start_fraction = train_start[token_id] / count if count else math.nan + end_fraction = train_end[token_id] / count if count else math.nan + rows.append( + { + "token_id": token_id, + "token": token_by_id[token_id], + "surface": token_by_id[token_id].removeprefix(PREFIX), + "is_special": token_id < len(SPECIAL_TOKENS), + "train_count": count, + "val_count": int(split_counts["val"][token_id]), + "test_count": int(split_counts["test"][token_id]), + "train_sequence_count": present, + "train_sequence_fraction": presence_fraction, + "train_start_count": int(train_start[token_id]), + "train_internal_count": int(train_internal[token_id]), + "train_end_count": int(train_end[token_id]), + "train_mean_normalized_position": _safe_float( + train_position_sum[token_id] / count if count else math.nan + ), + "start_log2_enrichment": _safe_float( + math.log2(start_fraction / global_start_fraction) + if count and start_fraction > 0 + else math.nan + ), + "end_log2_enrichment": _safe_float( + math.log2(end_fraction / global_end_fraction) + if count and end_fraction > 0 + else math.nan + ), + "train_pgen_mean_present": _safe_float(mean_present), + "train_pgen_mean_absent": _safe_float(mean_absent), + "train_pgen_mean_difference": _safe_float(mean_present - mean_absent), + "train_pgen_presence_correlation": _safe_float(association), + "high_vs_low_pgen_log2_enrichment": _safe_float(math.log2(high_rate / low_rate)), + } + ) + + eligible = [row for row in rows if not row["is_special"] and row["train_sequence_count"] >= 50] + summary = { + "encoding": reports, + "pgen_association": { + "split": "train", + "target": "log10_pgen_1mm", + "global_mean": train_global_mean, + "global_std": train_global_std, + "low_quartile_threshold": float(low_threshold), + "high_quartile_threshold": float(high_threshold), + "interpretation": "Descriptive token-presence associations only; not biological or causal claims.", + }, + "top_tokens": { + "frequency": sorted(eligible, key=lambda row: row["train_count"], reverse=True)[:25], + "absolute_pgen_association": sorted( + eligible, + key=lambda row: abs(row["train_pgen_presence_correlation"] or 0.0), + reverse=True, + )[:25], + "start_enrichment": sorted( + eligible, key=lambda row: row["start_log2_enrichment"] or -math.inf, reverse=True + )[:25], + "end_enrichment": sorted( + eligible, key=lambda row: row["end_log2_enrichment"] or -math.inf, reverse=True + )[:25], + }, + } + return summary, rows + + +def write_token_statistics(path: Path, rows: list[dict]) -> None: + with path.open("w", encoding="utf-8", newline="") as handle: + writer = csv.DictWriter(handle, fieldnames=list(rows[0])) + writer.writeheader() + writer.writerows(rows) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", required=True) + parser.add_argument("--output-root", required=True) + parser.add_argument("--vocab-sizes", nargs="+", type=int, default=list(DEFAULT_VOCAB_SIZES)) + parser.add_argument("--min-frequency", type=int, default=2) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + vocab_sizes = tuple(args.vocab_sizes) + if args.seed != 42 or vocab_sizes != DEFAULT_VOCAB_SIZES: + raise ValueError("WordPiece Stage A requires seed 42 and the locked eight-size sweep.") + + data_dir = Path(args.data_dir) + output_root = Path(args.output_root) + output_root.mkdir(parents=True, exist_ok=True) + table, _embeddings = load_prepared_benchmark(data_dir) + split_indices = { + split: select_split_indices(table, data_dir, split) for split in ("train", "val", "test") + } + sequences = { + split: table.iloc[indices]["junction_aa"].astype(str).tolist() + for split, indices in split_indices.items() + } + train_pgen = table.iloc[split_indices["train"]]["log10_pgen_1mm"].to_numpy(np.float64) + train_manifest = data_dir / "manifests" / "train.tsv" + corpus_path = output_root / "train_cdr3.txt" + corpus_text = "".join(f"{sequence}\n" for sequence in sequences["train"]) + if corpus_path.exists() and corpus_path.read_text(encoding="utf-8") != corpus_text: + raise ValueError("Existing WordPiece sweep corpus differs from the locked train split.") + corpus_path.write_text(corpus_text, encoding="utf-8") + + sweep = { + "status": "ready", + "tokenizer_type": "wordpiece", + "vocab_sizes": list(vocab_sizes), + "seed": args.seed, + "training_split": "train", + "training_rows": len(split_indices["train"]), + "train_manifest_sha256": sha256(train_manifest), + "corpus_sha256": sha256(corpus_path), + "tokenizers": [], + } + for vocab_size in vocab_sizes: + final_dir = output_root / f"v{vocab_size}-seed42" + if final_dir.exists(): + raise FileExistsError(f"Refusing to overwrite immutable tokenizer directory: {final_dir}") + with tempfile.TemporaryDirectory(prefix=f".v{vocab_size}-", dir=output_root) as temporary: + token_dir = Path(temporary) + tokenizer = Tokenizer(WordPiece(unk_token="[UNK]")) + tokenizer.pre_tokenizer = Whitespace() + tokenizer.decoder = WordPieceDecoder(prefix=PREFIX) + tokenizer.train( + [str(corpus_path)], + WordPieceTrainer( + vocab_size=vocab_size, + min_frequency=args.min_frequency, + special_tokens=SPECIAL_TOKENS, + continuing_subword_prefix=PREFIX, + show_progress=False, + ), + ) + validate_wordpiece_tokenizer(tokenizer, f"WordPiece v{vocab_size}") + actual_vocab_size = tokenizer.get_vocab_size() + if actual_vocab_size != vocab_size: + raise ValueError( + f"Requested WordPiece vocabulary {vocab_size}, got {actual_vocab_size}; size is infeasible." + ) + audit, rows = audit_tokenizer(tokenizer, sequences, train_pgen) + for split, report in audit["encoding"].items(): + if report["unknown_sequences"] or report["roundtrip_mismatches"]: + raise ValueError(f"WordPiece v{vocab_size} failed {split}: {report}") + if report["token_length_max"] > 40: + raise ValueError(f"WordPiece v{vocab_size} exceeds max length on {split}: {report}") + tokenizer_path = token_dir / "tokenizer.json" + tokenizer.save(str(tokenizer_path)) + tokenizer.model.save(str(token_dir)) + write_token_statistics(token_dir / "token_statistics.tsv", rows) + config = { + "status": "immutable", + "tokenizer_type": "wordpiece", + "seed": args.seed, + "requested_vocab_size": vocab_size, + "actual_vocab_size": actual_vocab_size, + "min_frequency": args.min_frequency, + "continuing_subword_prefix": PREFIX, + "special_tokens": SPECIAL_TOKENS, + "special_token_ids": {"pad": PAD_ID, "bos": BOS_ID, "eos": EOS_ID, "unk": UNK_ID}, + "training_split": "train", + "training_rows": len(split_indices["train"]), + "train_manifest_path": str(train_manifest.resolve()), + "train_manifest_sha256": sha256(train_manifest), + "corpus_path": str(corpus_path.resolve()), + "corpus_sha256": sha256(corpus_path), + } + (token_dir / "audit_report.json").write_text(json.dumps(audit, indent=2), encoding="utf-8") + validation = { + "status": "ready", + "train_only_fit": True, + "split_rows": {split: len(indices) for split, indices in split_indices.items()}, + "split_index_overlap": { + "train_val": int(np.intersect1d(split_indices["train"], split_indices["val"]).size), + "train_test": int(np.intersect1d(split_indices["train"], split_indices["test"]).size), + "val_test": int(np.intersect1d(split_indices["val"], split_indices["test"]).size), + }, + "encoding": audit["encoding"], + "checks": { + "special_ids_match_model": True, + "requested_vocab_size_feasible": True, + "train_manifest_matches_locked_split": True, + "no_split_overlap": True, + "no_unknown_tokens": True, + "roundtrip_exact": True, + "all_encoded_lengths_at_most_40": True, + "pgen_association_train_only": True, + }, + } + (token_dir / "validation_report.json").write_text( + json.dumps(validation, indent=2), encoding="utf-8" + ) + config.update( + { + "tokenizer_sha256": sha256(tokenizer_path), + "vocab_sha256": sha256(token_dir / "vocab.txt"), + "token_statistics_sha256": sha256(token_dir / "token_statistics.tsv"), + "audit_report_sha256": sha256(token_dir / "audit_report.json"), + } + ) + (token_dir / "tokenizer_config.json").write_text( + json.dumps(config, indent=2), encoding="utf-8" + ) + token_dir.rename(final_dir) + sweep["tokenizers"].append( + { + "requested_vocab_size": vocab_size, + "actual_vocab_size": actual_vocab_size, + "directory": str(final_dir.resolve()), + "tokenizer_sha256": config["tokenizer_sha256"], + "vocab_sha256": config["vocab_sha256"], + "token_statistics_sha256": config["token_statistics_sha256"], + "max_encoded_lengths": { + split: audit["encoding"][split]["token_length_max"] for split in sequences + }, + } + ) + (output_root / "sweep_manifest.json").write_text(json.dumps(sweep, indent=2), encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/slurm/evaluate_vdjdb_frozen.sbatch b/slurm/evaluate_vdjdb_frozen.sbatch new file mode 100644 index 0000000..bf92e2d --- /dev/null +++ b/slurm/evaluate_vdjdb_frozen.sbatch @@ -0,0 +1,34 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-vdjdb-eval +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=08:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +VALIDATION_ROOT="$ROOT_DIR/experiments/trb/vdjdb-data-anchor-validation" +COHORT_DIR="$VALIDATION_ROOT/cohort-preflight-1426341" +OUTPUT_DIR="$VALIDATION_ROOT/evaluation-${SLURM_JOB_ID}" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +for condition in r p rp; do + test -f "$ROOT_DIR/experiments/trb/data-anchor-$condition-seed42/best.pt" + test -f "$ROOT_DIR/experiments/trb/data-anchor-$condition-seed42/run_config.json" +done +test -f "$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" +test -f "$COHORT_DIR/PREFLIGHT.json" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m benchmark.evaluate_vdjdb_frozen \ + --cohort "$COHORT_DIR/cohort.tsv" --cohort-preflight "$COHORT_DIR/PREFLIGHT.json" \ + --tokenizer "$TOKENIZER" --output-dir "$OUTPUT_DIR" \ + --model "r:$ROOT_DIR/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT_DIR/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "p:$ROOT_DIR/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT_DIR/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rp:$ROOT_DIR/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT_DIR/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "rtp:$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/run_config.json" \ + --batch-size 128 --max-pairs-per-label 2000 --bootstrap 2000 --permutations 1000 --seed 42 diff --git a/slurm/evaluate_vdjdb_ylq_frozen.sbatch b/slurm/evaluate_vdjdb_ylq_frozen.sbatch new file mode 100644 index 0000000..268dcf0 --- /dev/null +++ b/slurm/evaluate_vdjdb_ylq_frozen.sbatch @@ -0,0 +1,25 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-ylq-eval +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=08:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.err + +set -euo pipefail +PREFLIGHT_DIR="${1:?YLQ preflight directory is required}" +ROOT="/home/evlasova/irrm-codec" +OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-data-anchor-validation/evaluation-${SLURM_JOB_ID}" +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +test -f "$PREFLIGHT_DIR/PREFLIGHT.json" +cd "$ROOT" +"$PYTHON" -m benchmark.evaluate_vdjdb_ylq_frozen \ + --preflight-dir "$PREFLIGHT_DIR" --tokenizer "$TOKENIZER" --output-dir "$OUTPUT" \ + --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" \ + --bootstrap 2000 --permutations 1000 --seed 42 diff --git a/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch b/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch new file mode 100644 index 0000000..40e13a0 --- /dev/null +++ b/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch @@ -0,0 +1,25 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-ylq-motif-eval +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=08:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.err + +set -euo pipefail +PREFLIGHT_DIR="${1:?Official-motif pooled preflight directory is required}" +ROOT="/home/evlasova/irrm-codec" +OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-official-motif-pooled/evaluation-${SLURM_JOB_ID}" +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +test -f "$PREFLIGHT_DIR/PREFLIGHT.json" +cd "$ROOT" +"$PYTHON" -m benchmark.evaluate_vdjdb_ylq_motif_pooled \ + --preflight-dir "$PREFLIGHT_DIR" --tokenizer "$TOKENIZER" --output-dir "$OUTPUT" \ + --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" \ + --batch-size 128 --bootstrap 2000 --permutations 1000 --seed 42 diff --git a/slurm/install_wordpiece_dependency.sbatch b/slurm/install_wordpiece_dependency.sbatch new file mode 100644 index 0000000..c4fb239 --- /dev/null +++ b/slurm/install_wordpiece_dependency.sbatch @@ -0,0 +1,14 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-wp-dependency +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=1 +#SBATCH --mem=4G +#SBATCH --time=00:20:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.err + +set -euo pipefail +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +"$PYTHON_BIN" -m pip install --disable-pip-version-check "tokenizers==0.23.1" +"$PYTHON_BIN" -c 'import tokenizers; assert tokenizers.__version__ == "0.23.1"; print(tokenizers.__version__)' diff --git a/slurm/preflight_data_anchor_objectives.sbatch b/slurm/preflight_data_anchor_objectives.sbatch new file mode 100644 index 0000000..3ec90c4 --- /dev/null +++ b/slurm/preflight_data_anchor_objectives.sbatch @@ -0,0 +1,30 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-data-obj-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/data-anchor-objective-matrix/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/data-anchor-objective-matrix/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +REFERENCE="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/run_config.json" +OUTPUT_ROOT="$ROOT_DIR/experiments/trb/data-anchor-objective-matrix" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER" +test -f "$REFERENCE" +test ! -e "$OUTPUT_ROOT/PREFLIGHT.json" +mkdir -p "$OUTPUT_ROOT" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.preflight_data_anchor_objectives \ + --data-dir "$DATA_DIR" \ + --tokenizer "$TOKENIZER" \ + --reference-run-config "$REFERENCE" \ + --output-root "$OUTPUT_ROOT" diff --git a/slurm/preflight_phase1_rq1.sbatch b/slurm/preflight_phase1_rq1.sbatch new file mode 100644 index 0000000..9b21d16 --- /dev/null +++ b/slurm/preflight_phase1_rq1.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq1-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=4 +#SBATCH --mem=8G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/phase1-rq1-char-seed42/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/phase1-rq1-char-seed42/preflight-%j.err + +set -euo pipefail + +ROOT_DIR="/home/evlasova/irrm-codec" +cd "$ROOT_DIR" +export PYTHONPATH="$ROOT_DIR${PYTHONPATH:+:$PYTHONPATH}" + +/home/evlasova/.conda/envs/irrm-codec/bin/python scripts/preflight_phase1_rq1.py \ + --data-dir "$ROOT_DIR/data/benchmark/trb" \ + --output-path "$ROOT_DIR/experiments/trb/phase1-rq1-char-seed42/preflight.json" diff --git a/slurm/preflight_rq5_depths.sbatch b/slurm/preflight_rq5_depths.sbatch new file mode 100644 index 0000000..75ea2d3 --- /dev/null +++ b/slurm/preflight_rq5_depths.sbatch @@ -0,0 +1,21 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq5-depth-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=4 +#SBATCH --mem=16G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-depths-seed42/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-depths-seed42/preflight-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.preflight_rq5_depths \ + --baseline-run-config "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-seed42/run_config.json" \ + --d128-test-metrics "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-seed42/test_metrics.json" \ + --d320-test-metrics "$ROOT_DIR/experiments/trb/rq1-char-rtp-seed42/test_metrics.json" \ + --d512-test-metrics "$ROOT_DIR/experiments/trb/rq5-char-rtp-d512-seed42/test_metrics.json" \ + --data-dir "$ROOT_DIR/data/benchmark/trb" \ + --output-path "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-depths-seed42/preflight.json" diff --git a/slurm/preflight_rq5_widths.sbatch b/slurm/preflight_rq5_widths.sbatch new file mode 100644 index 0000000..4767e3f --- /dev/null +++ b/slurm/preflight_rq5_widths.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq5-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=4 +#SBATCH --mem=16G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-widths-seed42/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-widths-seed42/preflight-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.preflight_rq5_widths \ + --baseline-run-config "$ROOT_DIR/experiments/trb/rq1-char-rtp-seed42/run_config.json" \ + --baseline-test-metrics "$ROOT_DIR/experiments/trb/rq1-char-rtp-seed42/test_metrics.json" \ + --data-dir "$ROOT_DIR/data/benchmark/trb" \ + --output-path "$ROOT_DIR/experiments/trb/rq5-char-rtp-widths-seed42/preflight.json" diff --git a/slurm/preflight_vdjdb_epitope.sbatch b/slurm/preflight_vdjdb_epitope.sbatch new file mode 100644 index 0000000..9caa497 --- /dev/null +++ b/slurm/preflight_vdjdb_epitope.sbatch @@ -0,0 +1,38 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-vdjdb-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +OUTPUT_ROOT="$ROOT_DIR/experiments/trb/vdjdb-data-anchor-validation" +OUTPUT_DIR="$OUTPUT_ROOT/cohort-preflight-${SLURM_JOB_ID}" +VDJDB_SOURCE="/projects/immunestatus/vdjdb/vdjdb-2025-07-30/vdjdb.txt" +BENCHMARK_DIR="$ROOT_DIR/data/benchmark/trb" +EXPERIMENT_DIR="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$VDJDB_SOURCE" +test -f "$BENCHMARK_DIR/READY.json" +test -f "$EXPERIMENT_DIR/best.pt" +test -f "$EXPERIMENT_DIR/run_config.json" +test -f "$TOKENIZER" +mkdir -p "$OUTPUT_ROOT" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m benchmark.prepare_vdjdb_epitope_cohort \ + --vdjdb-tsv "$VDJDB_SOURCE" \ + --benchmark-dir "$BENCHMARK_DIR" \ + --checkpoint "$EXPERIMENT_DIR/best.pt" \ + --run-config "$EXPERIMENT_DIR/run_config.json" \ + --tokenizer "$TOKENIZER" \ + --output-dir "$OUTPUT_DIR" \ + --min-support 50 --min-donors 2 \ + --sensitivity-thresholds 25 50 100 \ + --min-vdjdb-score 1 --seed 42 diff --git a/slurm/preflight_vdjdb_evaluation.sbatch b/slurm/preflight_vdjdb_evaluation.sbatch new file mode 100644 index 0000000..316db21 --- /dev/null +++ b/slurm/preflight_vdjdb_evaluation.sbatch @@ -0,0 +1,25 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-vdjdb-eval-gate +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=4 +#SBATCH --mem=16G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +VALIDATION_ROOT="$ROOT_DIR/experiments/trb/vdjdb-data-anchor-validation" +COHORT_DIR="$VALIDATION_ROOT/cohort-preflight-1426341" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +OUTPUT="$VALIDATION_ROOT/evaluation-code-preflight-${SLURM_JOB_ID}.json" + +test -x "$PYTHON_BIN" +test -f "$COHORT_DIR/PREFLIGHT.json" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.preflight_vdjdb_evaluation \ + --cohort "$COHORT_DIR/cohort.tsv" \ + --cohort-preflight "$COHORT_DIR/PREFLIGHT.json" \ + --evaluation-script "$ROOT_DIR/benchmark/evaluate_vdjdb_frozen.py" \ + --output "$OUTPUT" diff --git a/slurm/prepare_anchored_tokenizers.sbatch b/slurm/prepare_anchored_tokenizers.sbatch new file mode 100644 index 0000000..68722a5 --- /dev/null +++ b/slurm/prepare_anchored_tokenizers.sbatch @@ -0,0 +1,35 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-anchor-preflight +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=08:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/anchored-seed42/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/anchored-seed42/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42" +SOURCE_ROOT="/projects/immunestatus/vdjrearm" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test ! -e "$TOKENIZER_ROOT/READY.json" +mkdir -p "$TOKENIZER_ROOT" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.prepare_anchored_tokenizers \ + --data-dir "$DATA_DIR" \ + --output-root "$TOKENIZER_ROOT" \ + --external-corpus "$SOURCE_ROOT/sample/TRB_1e7.tsv.gz" \ + --generation-script "$SOURCE_ROOT/scripts/sample_murugan.sh" \ + --olga-model-dir "$SOURCE_ROOT/model/Homo+sapiens/TRB_orig" \ + --external-rows 500000 --seed 42 +"$PYTHON_BIN" -m scripts.preflight_anchored_tokenizers \ + --data-dir "$DATA_DIR" \ + --tokenizer-root "$TOKENIZER_ROOT" \ + --baseline-run-config "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-seed42/run_config.json" \ + --output-path "$TOKENIZER_ROOT/preflight.json" +"$PYTHON_BIN" -c 'import json,pathlib; p=pathlib.Path("/home/evlasova/irrm-codec/experiments/trb/tokenizers/anchored-seed42"); r=json.loads((p/"preflight.json").read_text()); assert r["status"]=="ready"; (p/"READY.json").write_text(json.dumps({"status":"ready","preflight_job_id":__import__("os").environ["SLURM_JOB_ID"]},indent=2))' diff --git a/slurm/prepare_trb_joint.sbatch b/slurm/prepare_trb_joint.sbatch new file mode 100644 index 0000000..7fbdc23 --- /dev/null +++ b/slurm/prepare_trb_joint.sbatch @@ -0,0 +1,29 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-trb-prepare +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/data/benchmark/trb-prepare-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/data/benchmark/trb-prepare-%j.err + +set -euo pipefail + +ROOT_DIR="/home/evlasova/irrm-codec" +OUTPUT_DIR="$ROOT_DIR/data/benchmark/trb" +cd "$ROOT_DIR" + +/home/evlasova/.conda/envs/irrm-codec/bin/python -m benchmark.prepare_trb_joint \ + --airr-path /projects/immunestatus/vdjrearm/airr_format/trb_background_100k.tsv \ + --embeddings-path /projects/immunestatus/vdjrearm/tcremp/trb_background_100k_tcremp.parquet \ + --representations-path /projects/immunestatus/vdjrearm/tcremp/trb_background_100k_tcremp_representations.tsv \ + --pgen-path /projects/immunestatus/vdjrearm/pgen_1mm_background_100k/trb_background_100k_pgen.tsv \ + --tcremp-writer-source /home/evlasova/tcremp-git/tcremp/tcremp/tcremp_run.py \ + --output-dir "$OUTPUT_DIR" \ + --seed 42 \ + --train-fraction 0.8 \ + --val-fraction 0.1 \ + --max-len 40 \ + --embedding-batch-size 256 \ + --standardizer-chunk-size 1024 diff --git a/slurm/prepare_vdjdb_ylq.sbatch b/slurm/prepare_vdjdb_ylq.sbatch new file mode 100644 index 0000000..0a24613 --- /dev/null +++ b/slurm/prepare_vdjdb_ylq.sbatch @@ -0,0 +1,20 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-ylq-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.err + +set -euo pipefail +ROOT="/home/evlasova/irrm-codec" +OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-data-anchor-validation/preflight-${SLURM_JOB_ID}" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +mkdir -p "$ROOT/experiments/trb/vdjdb-ylq-data-anchor-validation" +cd "$ROOT" +"$PYTHON" -m benchmark.prepare_vdjdb_ylq \ + --vdjdb-tsv /projects/immunestatus/vdjdb/vdjdb-2025-07-30/vdjdb.txt \ + --benchmark-dir "$ROOT/data/benchmark/trb" --output-dir "$OUTPUT" \ + --min-positive-cdr3 50 --min-positive-donors 2 --seed 42 diff --git a/slurm/prepare_vdjdb_ylq_motif_pooled.sbatch b/slurm/prepare_vdjdb_ylq_motif_pooled.sbatch new file mode 100644 index 0000000..e821345 --- /dev/null +++ b/slurm/prepare_vdjdb_ylq_motif_pooled.sbatch @@ -0,0 +1,24 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-ylq-motif-pre +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.err + +set -euo pipefail +ROOT="/home/evlasova/irrm-codec" +SNAPSHOT="/projects/immunestatus/vdjdb/vdjdb-2025-07-30" +OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-official-motif-pooled/preflight-${SLURM_JOB_ID}" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +mkdir -p "$ROOT/experiments/trb/vdjdb-ylq-official-motif-pooled" +cd "$ROOT" +"$PYTHON" -m benchmark.prepare_vdjdb_ylq_motif_pooled \ + --vdjdb-tsv "$SNAPSHOT/vdjdb.txt" \ + --cluster-members "$SNAPSHOT/cluster_members.txt" \ + --motif-pwms "$SNAPSHOT/motif_pwms.txt" \ + --benchmark-dir "$ROOT/data/benchmark/trb" \ + --output-dir "$OUTPUT" --min-score 1 --min-positives 40 --min-negatives 100 \ + --controls-per-positive 4 --seed 42 diff --git a/slurm/prepare_wordpiece_rq4.sbatch b/slurm/prepare_wordpiece_rq4.sbatch new file mode 100644 index 0000000..6ec7cee --- /dev/null +++ b/slurm/prepare_wordpiece_rq4.sbatch @@ -0,0 +1,29 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq4-wp-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER_DIR="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-seed42" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -f "$DATA_DIR/READY.json" +test ! -e "$TOKENIZER_DIR/tokenizer.json" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.prepare_wordpiece_rq4 \ + --data-dir "$DATA_DIR" \ + --output-dir "$TOKENIZER_DIR" \ + --vocab-size 256 \ + --min-frequency 2 \ + --seed 42 +"$PYTHON_BIN" -m scripts.preflight_wordpiece_rq4 \ + --data-dir "$DATA_DIR" \ + --tokenizer-dir "$TOKENIZER_DIR" \ + --output-path "$TOKENIZER_DIR/preflight.json" diff --git a/slurm/prepare_wordpiece_sweep.sbatch b/slurm/prepare_wordpiece_sweep.sbatch new file mode 100644 index 0000000..eb63c9e --- /dev/null +++ b/slurm/prepare_wordpiece_sweep.sbatch @@ -0,0 +1,30 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-wp-sweep-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-sweep-seed42/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-sweep-seed42/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-sweep-seed42" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -f "$DATA_DIR/READY.json" +test ! -e "$TOKENIZER_ROOT/sweep_manifest.json" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.prepare_wordpiece_sweep \ + --data-dir "$DATA_DIR" \ + --output-root "$TOKENIZER_ROOT" \ + --vocab-sizes 44 64 128 256 512 1024 2048 4096 \ + --min-frequency 2 \ + --seed 42 +"$PYTHON_BIN" -m scripts.preflight_wordpiece_sweep \ + --data-dir "$DATA_DIR" \ + --tokenizer-root "$TOKENIZER_ROOT" \ + --baseline-run-config "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-seed42/run_config.json" \ + --output-path "$TOKENIZER_ROOT/preflight.json" diff --git a/slurm/train_anchored_tokenizer.sbatch b/slurm/train_anchored_tokenizer.sbatch new file mode 100644 index 0000000..728bb29 --- /dev/null +++ b/slurm/train_anchored_tokenizer.sbatch @@ -0,0 +1,56 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-anchor-rtp +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail +KIND="${1:?Tokenizer kind is required}" +case "$KIND" in + edge_k|data_anchor|germline_anchor) ;; + *) echo "Refusing unregistered anchored tokenizer" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42" +TOKENIZER_PATH="$TOKENIZER_ROOT/$KIND/anchored_tokenizer.json" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +case "$KIND" in + edge_k) EXPERIMENT_ID="anchor-edge3-rtp-seed42" ;; + data_anchor) EXPERIMENT_ID="anchor-data-rtp-seed42" ;; + germline_anchor) EXPERIMENT_ID="anchor-germline-rtp-seed42" ;; +esac +OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER_ROOT/READY.json" +test -f "$TOKENIZER_ROOT/preflight.json" +test -f "$TOKENIZER_PATH" +mkdir -p "$OUTPUT_DIR" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite completed experiment: $OUTPUT_DIR" >&2; exit 3 +fi +cd "$ROOT_DIR" +printf '{"job_id":"%s","experiment_id":"%s","tokenizer_type":"%s","node":"%s","cuda_visible_devices":"%s"}\n' \ + "$SLURM_JOB_ID" "$EXPERIMENT_ID" "$KIND" "${SLURMD_NODENAME:-unknown}" \ + "${CUDA_VISIBLE_DEVICES:-unknown}" > "$OUTPUT_DIR/slurm_runtime.json" +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" --train-subset all --pgen-target log10_pgen_1mm \ + --tokenizer-type "$KIND" --tokenizer-path "$TOKENIZER_PATH" \ + --max-sequence-len 40 --d-model 320 --latent-dim 128 --nhead 8 \ + --encoder-layers 4 --decoder-layers 4 --ff-dim 1280 --dropout 0.1 \ + --tcremp-head-dim 1024 --pgen-head-dim 256 --decoder-memory-tokens 4 \ + --tcremp-loss-weight 1 --pgen-loss-weight 1 --reconstruction-loss-weight 1 \ + --tcremp-mse-fraction 0.7 --pgen-huber-delta 0.5 --label-smoothing 0 \ + --batch-size 64 --epochs 40 --lr 0.0003 --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 --max-grad-norm 1 --early-stopping-patience 0 \ + --scheduler-factor 0.5 --scheduler-patience 2 --scheduler-min-lr 0.000001 \ + --seed 42 --num-workers 8 --device cuda --amp --no-progress --no-save-test-predictions diff --git a/slurm/train_data_anchor_objective.sbatch b/slurm/train_data_anchor_objective.sbatch new file mode 100644 index 0000000..c625aa2 --- /dev/null +++ b/slurm/train_data_anchor_objective.sbatch @@ -0,0 +1,57 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-data-obj +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail +CONDITION="${1:?Condition r, p, or rp is required}" +case "$CONDITION" in + r) RECON=1; TCREMP=0; PGEN=0 ;; + p) RECON=0; TCREMP=0; PGEN=1 ;; + rp) RECON=1; TCREMP=0; PGEN=1 ;; + *) echo "Refusing unregistered DATA-ANCHOR objective condition" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +MATRIX_ROOT="$ROOT_DIR/experiments/trb/data-anchor-objective-matrix" +PREFLIGHT="$MATRIX_ROOT/PREFLIGHT.json" +CONDITION_CONFIG="$MATRIX_ROOT/configs/$CONDITION.json" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/data-anchor-$CONDITION-seed42" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER" +test -f "$PREFLIGHT" +test -f "$CONDITION_CONFIG" +"$PYTHON_BIN" -c 'import json,sys; p=json.load(open(sys.argv[1])); assert p["status"]=="ready" and all(p["checks"].values()); c=json.load(open(sys.argv[2])); assert c["condition"]==sys.argv[3]' "$PREFLIGHT" "$CONDITION_CONFIG" "$CONDITION" +mkdir -p "$OUTPUT_DIR" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite completed experiment: $OUTPUT_DIR" >&2; exit 3 +fi +cd "$ROOT_DIR" +printf '{"job_id":"%s","condition":"%s","node":"%s","cuda_visible_devices":"%s","preflight_sha256":"%s","condition_config_sha256":"%s"}\n' \ + "$SLURM_JOB_ID" "$CONDITION" "${SLURMD_NODENAME:-unknown}" "${CUDA_VISIBLE_DEVICES:-unknown}" \ + "$(sha256sum "$PREFLIGHT" | cut -d' ' -f1)" "$(sha256sum "$CONDITION_CONFIG" | cut -d' ' -f1)" \ + > "$OUTPUT_DIR/slurm_runtime.json" +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" --train-subset all --pgen-target log10_pgen_1mm \ + --tokenizer-type data_anchor --tokenizer-path "$TOKENIZER" \ + --max-sequence-len 40 --d-model 320 --latent-dim 128 --nhead 8 \ + --encoder-layers 4 --decoder-layers 4 --ff-dim 1280 --dropout 0.1 \ + --tcremp-head-dim 1024 --pgen-head-dim 256 --decoder-memory-tokens 4 \ + --tcremp-loss-weight "$TCREMP" --pgen-loss-weight "$PGEN" --reconstruction-loss-weight "$RECON" \ + --tcremp-mse-fraction 0.7 --pgen-huber-delta 0.5 --label-smoothing 0 \ + --batch-size 64 --epochs 40 --lr 0.0003 --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 --max-grad-norm 1 --early-stopping-patience 0 \ + --scheduler-factor 0.5 --scheduler-patience 2 --scheduler-min-lr 0.000001 \ + --seed 42 --num-workers 8 --device cuda --amp --no-progress --no-save-test-predictions diff --git a/slurm/train_phase1_rq1_char.sbatch b/slurm/train_phase1_rq1_char.sbatch new file mode 100644 index 0000000..61550a5 --- /dev/null +++ b/slurm/train_phase1_rq1_char.sbatch @@ -0,0 +1,82 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq1-char +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail + +EXPERIMENT_ID="${1:?experiment id is required}" +TCREMP_WEIGHT="${2:?TCRemP loss weight is required}" +PGEN_WEIGHT="${3:?pgen loss weight is required}" +RECONSTRUCTION_WEIGHT="${4:?reconstruction loss weight is required}" + +case "$EXPERIMENT_ID:$TCREMP_WEIGHT:$PGEN_WEIGHT:$RECONSTRUCTION_WEIGHT" in + rq1-char-r-seed42:0:0:1|rq1-char-rtp-seed42:1:1:1) ;; + *) echo "Refusing unregistered Phase-1 configuration" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" +CONFIG_PATH="$OUTPUT_DIR/experiment_config.json" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -f "$DATA_DIR/READY.json" +test -f "$DATA_DIR/target_standardizer.npz" +test -f "$CONFIG_PATH" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite an existing completed experiment: $OUTPUT_DIR" >&2 + exit 3 +fi + +cd "$ROOT_DIR" +printf '{"job_id":"%s","experiment_id":"%s","node":"%s","cuda_visible_devices":"%s"}\n' \ + "$SLURM_JOB_ID" "$EXPERIMENT_ID" "${SLURMD_NODENAME:-unknown}" "${CUDA_VISIBLE_DEVICES:-unknown}" \ + > "$OUTPUT_DIR/slurm_runtime.json" + +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" \ + --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" \ + --train-subset all \ + --pgen-target log10_pgen_1mm \ + --tokenizer-type char \ + --max-sequence-len 40 \ + --d-model 320 \ + --latent-dim 320 \ + --nhead 8 \ + --encoder-layers 4 \ + --decoder-layers 4 \ + --ff-dim 1280 \ + --dropout 0.1 \ + --tcremp-head-dim 1024 \ + --pgen-head-dim 256 \ + --decoder-memory-tokens 4 \ + --tcremp-loss-weight "$TCREMP_WEIGHT" \ + --pgen-loss-weight "$PGEN_WEIGHT" \ + --reconstruction-loss-weight "$RECONSTRUCTION_WEIGHT" \ + --tcremp-mse-fraction 0.7 \ + --pgen-huber-delta 0.5 \ + --label-smoothing 0 \ + --batch-size 64 \ + --epochs 40 \ + --lr 0.0003 \ + --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 \ + --max-grad-norm 1 \ + --early-stopping-patience 0 \ + --scheduler-factor 0.5 \ + --scheduler-patience 2 \ + --scheduler-min-lr 0.000001 \ + --seed 42 \ + --num-workers 8 \ + --device cuda \ + --amp \ + --no-progress \ + --no-save-test-predictions diff --git a/slurm/train_phase2_rq23_char.sbatch b/slurm/train_phase2_rq23_char.sbatch new file mode 100644 index 0000000..2465c74 --- /dev/null +++ b/slurm/train_phase2_rq23_char.sbatch @@ -0,0 +1,82 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq23-char +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail + +EXPERIMENT_ID="${1:?experiment id is required}" +TCREMP_WEIGHT="${2:?TCRemP loss weight is required}" +PGEN_WEIGHT="${3:?pgen loss weight is required}" +RECONSTRUCTION_WEIGHT="${4:?reconstruction loss weight is required}" + +case "$EXPERIMENT_ID:$TCREMP_WEIGHT:$PGEN_WEIGHT:$RECONSTRUCTION_WEIGHT" in + rq2-char-rt-seed42:1:0:1|rq2-char-rp-seed42:0:1:1) ;; + *) echo "Refusing unregistered Phase-2 configuration" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" +CONFIG_PATH="$OUTPUT_DIR/experiment_config.json" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -f "$DATA_DIR/READY.json" +test -f "$DATA_DIR/target_standardizer.npz" +test -f "$CONFIG_PATH" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite an existing completed experiment: $OUTPUT_DIR" >&2 + exit 3 +fi + +cd "$ROOT_DIR" +printf '{"job_id":"%s","experiment_id":"%s","node":"%s","cuda_visible_devices":"%s"}\n' \ + "$SLURM_JOB_ID" "$EXPERIMENT_ID" "${SLURMD_NODENAME:-unknown}" "${CUDA_VISIBLE_DEVICES:-unknown}" \ + > "$OUTPUT_DIR/slurm_runtime.json" + +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" \ + --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" \ + --train-subset all \ + --pgen-target log10_pgen_1mm \ + --tokenizer-type char \ + --max-sequence-len 40 \ + --d-model 320 \ + --latent-dim 320 \ + --nhead 8 \ + --encoder-layers 4 \ + --decoder-layers 4 \ + --ff-dim 1280 \ + --dropout 0.1 \ + --tcremp-head-dim 1024 \ + --pgen-head-dim 256 \ + --decoder-memory-tokens 4 \ + --tcremp-loss-weight "$TCREMP_WEIGHT" \ + --pgen-loss-weight "$PGEN_WEIGHT" \ + --reconstruction-loss-weight "$RECONSTRUCTION_WEIGHT" \ + --tcremp-mse-fraction 0.7 \ + --pgen-huber-delta 0.5 \ + --label-smoothing 0 \ + --batch-size 64 \ + --epochs 40 \ + --lr 0.0003 \ + --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 \ + --max-grad-norm 1 \ + --early-stopping-patience 0 \ + --scheduler-factor 0.5 \ + --scheduler-patience 2 \ + --scheduler-min-lr 0.000001 \ + --seed 42 \ + --num-workers 8 \ + --device cuda \ + --amp \ + --no-progress \ + --no-save-test-predictions diff --git a/slurm/train_rq4_wordpiece.sbatch b/slurm/train_rq4_wordpiece.sbatch new file mode 100644 index 0000000..fdfd73d --- /dev/null +++ b/slurm/train_rq4_wordpiece.sbatch @@ -0,0 +1,84 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq4-wp +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail + +EXPERIMENT_ID="${1:?experiment id is required}" +TCREMP_WEIGHT="${2:?TCRemP loss weight is required}" +PGEN_WEIGHT="${3:?pgen loss weight is required}" +RECONSTRUCTION_WEIGHT="${4:?reconstruction loss weight is required}" +case "$EXPERIMENT_ID:$TCREMP_WEIGHT:$PGEN_WEIGHT:$RECONSTRUCTION_WEIGHT" in + rq4-wordpiece-r-seed42:0:0:1|rq4-wordpiece-rtp-seed42:1:1:1) ;; + *) echo "Refusing unregistered RQ4 configuration" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER_DIR="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-seed42" +TOKENIZER_PATH="$TOKENIZER_DIR/tokenizer.json" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER_DIR/preflight.json" +test -f "$TOKENIZER_PATH" +test -f "$OUTPUT_DIR/experiment_config.json" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite completed experiment: $OUTPUT_DIR" >&2 + exit 3 +fi + +cd "$ROOT_DIR" +printf '{"job_id":"%s","experiment_id":"%s","node":"%s","cuda_visible_devices":"%s"}\n' \ + "$SLURM_JOB_ID" "$EXPERIMENT_ID" "${SLURMD_NODENAME:-unknown}" "${CUDA_VISIBLE_DEVICES:-unknown}" \ + > "$OUTPUT_DIR/slurm_runtime.json" + +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" \ + --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" \ + --train-subset all \ + --pgen-target log10_pgen_1mm \ + --tokenizer-type wordpiece \ + --tokenizer-path "$TOKENIZER_PATH" \ + --max-sequence-len 40 \ + --d-model 320 \ + --latent-dim 320 \ + --nhead 8 \ + --encoder-layers 4 \ + --decoder-layers 4 \ + --ff-dim 1280 \ + --dropout 0.1 \ + --tcremp-head-dim 1024 \ + --pgen-head-dim 256 \ + --decoder-memory-tokens 4 \ + --tcremp-loss-weight "$TCREMP_WEIGHT" \ + --pgen-loss-weight "$PGEN_WEIGHT" \ + --reconstruction-loss-weight "$RECONSTRUCTION_WEIGHT" \ + --tcremp-mse-fraction 0.7 \ + --pgen-huber-delta 0.5 \ + --label-smoothing 0 \ + --batch-size 64 \ + --epochs 40 \ + --lr 0.0003 \ + --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 \ + --max-grad-norm 1 \ + --early-stopping-patience 0 \ + --scheduler-factor 0.5 \ + --scheduler-patience 2 \ + --scheduler-min-lr 0.000001 \ + --seed 42 \ + --num-workers 8 \ + --device cuda \ + --amp \ + --no-progress \ + --no-save-test-predictions diff --git a/slurm/train_rq5_depth.sbatch b/slurm/train_rq5_depth.sbatch new file mode 100644 index 0000000..ff80d86 --- /dev/null +++ b/slurm/train_rq5_depth.sbatch @@ -0,0 +1,46 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq5-depth +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail +EXPERIMENT_ID="${1:?experiment id is required}" +ENCODER_LAYERS="${2:?encoder layer count is required}" +case "$EXPERIMENT_ID:$ENCODER_LAYERS" in + rq5-char-rtp-d128-e2d4-seed42:2|rq5-char-rtp-d128-e6d4-seed42:6) ;; + *) echo "Refusing unregistered RQ5 depth" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +test -f "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-depths-seed42/preflight.json" +test -f "$DATA_DIR/READY.json" +test -f "$OUTPUT_DIR/experiment_config.json" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite completed experiment: $OUTPUT_DIR" >&2; exit 3 +fi + +cd "$ROOT_DIR" +printf '{"job_id":"%s","experiment_id":"%s","node":"%s","cuda_visible_devices":"%s"}\n' \ + "$SLURM_JOB_ID" "$EXPERIMENT_ID" "${SLURMD_NODENAME:-unknown}" "${CUDA_VISIBLE_DEVICES:-unknown}" \ + > "$OUTPUT_DIR/slurm_runtime.json" +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" --train-subset all --pgen-target log10_pgen_1mm \ + --tokenizer-type char --max-sequence-len 40 --d-model 320 --latent-dim 128 \ + --nhead 8 --encoder-layers "$ENCODER_LAYERS" --decoder-layers 4 --ff-dim 1280 --dropout 0.1 \ + --tcremp-head-dim 1024 --pgen-head-dim 256 --decoder-memory-tokens 4 \ + --tcremp-loss-weight 1 --pgen-loss-weight 1 --reconstruction-loss-weight 1 \ + --tcremp-mse-fraction 0.7 --pgen-huber-delta 0.5 --label-smoothing 0 \ + --batch-size 64 --epochs 40 --lr 0.0003 --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 --max-grad-norm 1 --early-stopping-patience 0 \ + --scheduler-factor 0.5 --scheduler-patience 2 --scheduler-min-lr 0.000001 \ + --seed 42 --num-workers 8 --device cuda --amp --no-progress --no-save-test-predictions diff --git a/slurm/train_rq5_width.sbatch b/slurm/train_rq5_width.sbatch new file mode 100644 index 0000000..84a2bd7 --- /dev/null +++ b/slurm/train_rq5_width.sbatch @@ -0,0 +1,46 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rq5-width +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail +EXPERIMENT_ID="${1:?experiment id is required}" +LATENT_DIM="${2:?latent dimension is required}" +case "$EXPERIMENT_ID:$LATENT_DIM" in + rq5-char-rtp-d128-seed42:128|rq5-char-rtp-d512-seed42:512) ;; + *) echo "Refusing unregistered RQ5 width" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +test -f "$ROOT_DIR/experiments/trb/rq5-char-rtp-widths-seed42/preflight.json" +test -f "$DATA_DIR/READY.json" +test -f "$OUTPUT_DIR/experiment_config.json" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite completed experiment: $OUTPUT_DIR" >&2; exit 3 +fi + +cd "$ROOT_DIR" +printf '{"job_id":"%s","experiment_id":"%s","node":"%s","cuda_visible_devices":"%s"}\n' \ + "$SLURM_JOB_ID" "$EXPERIMENT_ID" "${SLURMD_NODENAME:-unknown}" "${CUDA_VISIBLE_DEVICES:-unknown}" \ + > "$OUTPUT_DIR/slurm_runtime.json" +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" --train-subset all --pgen-target log10_pgen_1mm \ + --tokenizer-type char --max-sequence-len 40 --d-model 320 --latent-dim "$LATENT_DIM" \ + --nhead 8 --encoder-layers 4 --decoder-layers 4 --ff-dim 1280 --dropout 0.1 \ + --tcremp-head-dim 1024 --pgen-head-dim 256 --decoder-memory-tokens 4 \ + --tcremp-loss-weight 1 --pgen-loss-weight 1 --reconstruction-loss-weight 1 \ + --tcremp-mse-fraction 0.7 --pgen-huber-delta 0.5 --label-smoothing 0 \ + --batch-size 64 --epochs 40 --lr 0.0003 --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 --max-grad-norm 1 --early-stopping-patience 0 \ + --scheduler-factor 0.5 --scheduler-patience 2 --scheduler-min-lr 0.000001 \ + --seed 42 --num-workers 8 --device cuda --amp --no-progress --no-save-test-predictions diff --git a/slurm/train_wordpiece_sweep.sbatch b/slurm/train_wordpiece_sweep.sbatch new file mode 100644 index 0000000..bfc4c6a --- /dev/null +++ b/slurm/train_wordpiece_sweep.sbatch @@ -0,0 +1,52 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-wp-sweep +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail +VOCAB_SIZE="${1:?WordPiece vocabulary size is required}" +case "$VOCAB_SIZE" in + 44|64|128|256|512|1024|2048|4096) ;; + *) echo "Refusing unregistered WordPiece vocabulary size" >&2; exit 2 ;; +esac + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-sweep-seed42" +TOKENIZER_DIR="$TOKENIZER_ROOT/v${VOCAB_SIZE}-seed42" +TOKENIZER_PATH="$TOKENIZER_DIR/tokenizer.json" +EXPERIMENT_ID="wp-sweep-v${VOCAB_SIZE}-rtp-seed42" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER_ROOT/preflight.json" +test -f "$TOKENIZER_PATH" +mkdir -p "$OUTPUT_DIR" +if test -e "$OUTPUT_DIR/best.pt" || test -e "$OUTPUT_DIR/test_metrics.json"; then + echo "Refusing to overwrite completed experiment: $OUTPUT_DIR" >&2; exit 3 +fi + +cd "$ROOT_DIR" +printf '{"job_id":"%s","experiment_id":"%s","vocab_size":%s,"node":"%s","cuda_visible_devices":"%s"}\n' \ + "$SLURM_JOB_ID" "$EXPERIMENT_ID" "$VOCAB_SIZE" "${SLURMD_NODENAME:-unknown}" \ + "${CUDA_VISIBLE_DEVICES:-unknown}" > "$OUTPUT_DIR/slurm_runtime.json" +"$PYTHON_BIN" -m irrm_codec.train_multitask \ + --data-dir "$DATA_DIR" --standardizer-path "$DATA_DIR/target_standardizer.npz" \ + --output-dir "$OUTPUT_DIR" --train-subset all --pgen-target log10_pgen_1mm \ + --tokenizer-type wordpiece --tokenizer-path "$TOKENIZER_PATH" \ + --max-sequence-len 40 --d-model 320 --latent-dim 128 --nhead 8 \ + --encoder-layers 4 --decoder-layers 4 --ff-dim 1280 --dropout 0.1 \ + --tcremp-head-dim 1024 --pgen-head-dim 256 --decoder-memory-tokens 4 \ + --tcremp-loss-weight 1 --pgen-loss-weight 1 --reconstruction-loss-weight 1 \ + --tcremp-mse-fraction 0.7 --pgen-huber-delta 0.5 --label-smoothing 0 \ + --batch-size 64 --epochs 40 --lr 0.0003 --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 --max-grad-norm 1 --early-stopping-patience 0 \ + --scheduler-factor 0.5 --scheduler-patience 2 --scheduler-min-lr 0.000001 \ + --seed 42 --num-workers 8 --device cuda --amp --no-progress --no-save-test-predictions diff --git a/tests/test_anchored_tokenization.py b/tests/test_anchored_tokenization.py new file mode 100644 index 0000000..1fa4413 --- /dev/null +++ b/tests/test_anchored_tokenization.py @@ -0,0 +1,90 @@ +import json +import tempfile +import unittest +from pathlib import Path + +from tokenizers import Tokenizer +from tokenizers.decoders import WordPiece as WordPieceDecoder +from tokenizers.models import WordPiece + +from irrm_codec.anchored_tokenization import AnchoredTokenizer, SPECIAL_TOKENS +from irrm_codec.multitask_data import resolve_encoder_tokenizer + + +class AnchoredTokenizerTest(unittest.TestCase): + def make_bundle(self, root: Path, kind: str, n_anchors: list[str], c_anchors: list[str]): + central_vocab = {token: identifier for identifier, token in enumerate(SPECIAL_TOKENS)} + for amino_acid in "ACDEFGHIKLMNPQRSTVWY": + central_vocab[amino_acid] = len(central_vocab) + for amino_acid in "ACDEFGHIKLMNPQRSTVWY": + central_vocab[f"##{amino_acid}"] = len(central_vocab) + central = Tokenizer(WordPiece(vocab=central_vocab, unk_token="[UNK]")) + central.decoder = WordPieceDecoder(prefix="##") + central.save(str(root / "central_tokenizer.json")) + + vocab = {token: identifier for identifier, token in enumerate(SPECIAL_TOKENS)} + for anchor in sorted(n_anchors): + vocab[f"[N:{anchor}]"] = len(vocab) + for anchor in sorted(c_anchors): + vocab[f"[C:{anchor}]"] = len(vocab) + central_to_input = {} + by_id = {identifier: token for token, identifier in central_vocab.items()} + for identifier in range(4, len(central_vocab)): + central_to_input[str(identifier)] = len(vocab) + vocab[f"[M:{by_id[identifier]}]"] = len(vocab) + payload = { + "tokenizer_type": kind, + "k": 3 if kind == "edge_k" else None, + "central_tokenizer_file": "central_tokenizer.json", + "n_anchors": n_anchors, + "c_anchors": c_anchors, + "central_to_input": central_to_input, + "vocab": vocab, + } + path = root / "anchored_tokenizer.json" + path.write_text(json.dumps(payload), encoding="utf-8") + return path + + def test_edge_roundtrip_and_boundary_types(self): + with tempfile.TemporaryDirectory() as temporary: + path = self.make_bundle(Path(temporary), "edge_k", ["CAS"], ["QYF"]) + tokenizer = AnchoredTokenizer(path) + encoding = tokenizer.encode_with_boundaries("CASSLGQETQYF", 40) + self.assertEqual(tokenizer.decode(encoding.ids), "CASSLGQETQYF") + self.assertEqual(encoding.n_anchor, "CAS") + self.assertEqual(encoding.middle, "SLGQET") + self.assertEqual(encoding.c_anchor, "QYF") + self.assertEqual(encoding.boundary_types[0], "N_ANCHOR") + self.assertEqual(encoding.boundary_types[-1], "C_ANCHOR") + self.assertNotIn(3, encoding.ids) + + def test_variable_longest_nonoverlapping_selection(self): + with tempfile.TemporaryDirectory() as temporary: + path = self.make_bundle( + Path(temporary), "data_anchor", ["CASSL", "CASS", "C"], ["ETQYF", "TQYF", "F"] + ) + tokenizer = AnchoredTokenizer(path) + encoding = tokenizer.encode_with_boundaries("CASSLGQETQYF", 40) + self.assertEqual((encoding.n_anchor, encoding.c_anchor), ("CASSL", "ETQYF")) + self.assertEqual(encoding.middle, "GQ") + self.assertEqual(tokenizer.decode(encoding.ids), "CASSLGQETQYF") + + def test_fail_closed_unknown_anchor(self): + with tempfile.TemporaryDirectory() as temporary: + path = self.make_bundle(Path(temporary), "edge_k", ["CAS"], ["QYF"]) + tokenizer = AnchoredTokenizer(path) + with self.assertRaisesRegex(ValueError, "absent from the exhaustive"): + tokenizer.encode("CARSLGQETQYF", 40) + + def test_resolver_keeps_sequence_only_interface(self): + with tempfile.TemporaryDirectory() as temporary: + path = self.make_bundle(Path(temporary), "germline_anchor", ["CASS", "C"], ["TQYF", "F"]) + resolved = resolve_encoder_tokenizer("germline_anchor", str(path)) + self.assertEqual(resolved.name, "germline_anchor") + self.assertEqual(resolved.path, str(path)) + self.assertGreater(resolved.vocab_size, 4) + self.assertTrue(resolved.encode("CASSLGQETQYF", 40)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_multitask_baselines.py b/tests/test_multitask_baselines.py new file mode 100644 index 0000000..f5dc463 --- /dev/null +++ b/tests/test_multitask_baselines.py @@ -0,0 +1,191 @@ +import json +import logging +import tempfile +import unittest +from pathlib import Path +from unittest.mock import patch + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.multitask_data import TargetStandardizer, resolve_encoder_tokenizer +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss, MultiTaskLossWeights +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import AA_VOCAB, EOS_ID, encode_raw, encode_reconstruction_pair + + +class CharacterTokenizerTest(unittest.TestCase): + def test_character_reconstruction_pair(self): + encoded = encode_raw("CASSLGQETQYF", max_len=40) + decoder_input, target = encode_reconstruction_pair("CASSLGQETQYF", max_len=40) + self.assertEqual(decoder_input[1:], encoded) + self.assertEqual(target[:-1], encoded) + self.assertEqual(target[-1], EOS_ID) + self.assertEqual(resolve_encoder_tokenizer("char").vocab_size, len(AA_VOCAB)) + + def test_character_tokenizer_rejects_overflow(self): + with self.assertRaises(ValueError): + encode_raw("A" * 41, max_len=40) + + +class LockedStandardizerTest(unittest.TestCase): + def test_loader_accepts_benchmark_normalizer_with_extra_keys(self): + with tempfile.TemporaryDirectory() as temporary: + path = Path(temporary) / "target_standardizer.npz" + np.savez( + path, + tcremp_mean=np.zeros(12, dtype=np.float32), + tcremp_std=np.ones(12, dtype=np.float32), + pgen_mean=np.float32(-8.3), + pgen_std=np.float32(2.5), + pgen_target=np.asarray("log10_pgen_1mm"), + train_rows=np.int64(79_544), + log10_pgen_mean=np.float32(-10.4), + ) + loaded = TargetStandardizer.load(path) + self.assertEqual(loaded.pgen_target, "log10_pgen_1mm") + self.assertEqual(loaded.train_rows, 79_544) + self.assertEqual(loaded.tcremp_mean.shape, (12,)) + + +class MatchedBaselineLossTest(unittest.TestCase): + def test_tiny_locked_benchmark_trains_and_writes_terminal_artifacts(self): + from irrm_codec.train_multitask import main + + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + data_dir = root / "data" + manifests = data_dir / "manifests" + output_dir = root / "output" + manifests.mkdir(parents=True) + table = pd.DataFrame( + { + "row_index": range(6), + "junction_aa": ["CASSF", "CASRF", "CAT", "CQQ", "CAR", "CAS"], + "split": ["train", "train", "train", "val", "test", "test"], + "log10_pgen": [-5.0, -6.0, -7.0, -6.0, -7.0, -8.0], + "log10_pgen_1mm": [-4.0, -5.0, -6.0, -5.0, -6.0, -7.0], + } + ) + table.to_parquet(data_dir / "dataset.parquet", index=False) + embeddings = np.arange(72, dtype=np.float32).reshape(6, 12) + np.save(data_dir / "embeddings.npy", embeddings) + for name, rows in (("train", [0, 1, 2]), ("val", [3]), ("test", [4, 5])): + pd.DataFrame({"row_index": rows}).to_csv( + manifests / f"{name}.tsv", sep="\t", index=False + ) + np.savez( + data_dir / "target_standardizer.npz", + tcremp_mean=embeddings[:3].mean(axis=0), + tcremp_std=embeddings[:3].std(axis=0), + pgen_mean=np.float32(-5.0), + pgen_std=np.float32(np.std([-4.0, -5.0, -6.0])), + pgen_target=np.asarray("log10_pgen_1mm"), + train_rows=np.int64(3), + ) + argv = [ + "train_multitask", + "--data-dir", str(data_dir), + "--output-dir", str(output_dir), + "--standardizer-path", str(data_dir / "target_standardizer.npz"), + "--d-model", "32", + "--latent-dim", "24", + "--nhead", "4", + "--encoder-layers", "1", + "--decoder-layers", "1", + "--ff-dim", "64", + "--tcremp-head-dim", "24", + "--pgen-head-dim", "12", + "--decoder-memory-tokens", "2", + "--batch-size", "2", + "--epochs", "1", + "--early-stopping-patience", "0", + "--num-workers", "0", + "--device", "cpu", + "--no-amp", + "--no-progress", + "--skip-generation-metrics", + "--no-save-test-predictions", + ] + with patch("sys.argv", argv): + main() + self.assertTrue((output_dir / "best.pt").is_file()) + self.assertTrue((output_dir / "last.pt").is_file()) + metrics = json.loads((output_dir / "test_metrics.json").read_text()) + self.assertEqual(metrics["samples"], 2) + self.assertEqual(metrics["tokenizer_type"], "char") + logging.shutdown() + + def test_phase1_configs_are_matched_except_condition_and_weights(self): + root = Path(__file__).resolve().parents[1] + r = json.loads( + (root / "experiments/trb/rq1-char-r-seed42/experiment_config.json").read_text() + ) + rtp = json.loads( + (root / "experiments/trb/rq1-char-rtp-seed42/experiment_config.json").read_text() + ) + for key in ( + "base_git_revision", + "saved_pr_revision", + "data_dir", + "tokenizer", + "seed", + "train_subset", + "pgen_target", + "model", + "training", + ): + self.assertEqual(r[key], rtp[key], key) + self.assertEqual(r["loss"]["reconstruction"], 1.0) + self.assertEqual(rtp["loss"]["reconstruction"], 1.0) + self.assertEqual((r["loss"]["tcremp"], r["loss"]["pgen"]), (0.0, 0.0)) + self.assertEqual((rtp["loss"]["tcremp"], rtp["loss"]["pgen"]), (1.0, 1.0)) + + def test_reconstruction_and_multitask_configs_share_architecture(self): + torch.manual_seed(42) + config = IRRMCodecConfig( + input_vocab_size=len(AA_VOCAB), + output_vocab_size=len(AA_VOCAB), + max_sequence_len=8, + d_model=32, + latent_dim=24, + nhead=4, + encoder_layers=1, + decoder_layers=1, + ff_dim=64, + dropout=0.0, + tcremp_dim=12, + tcremp_head_dim=24, + pgen_head_dim=12, + decoder_memory_tokens=2, + ) + model = IRRMCodecTransformer(config) + tokens = torch.randint(5, len(AA_VOCAB), (3, 6)) + decoder_input = torch.randint(5, len(AA_VOCAB), (3, 7)) + target = torch.randint(5, len(AA_VOCAB), (3, 7)) + outputs = model(tokens, tokens.ne(0), decoder_input) + common = dict( + outputs=outputs, + tcremp_target=torch.randn(3, 12), + pgen_target=torch.randn(3), + reconstruction_target=target, + tcremp_mean=torch.zeros(12), + tcremp_std=torch.ones(12), + pgen_mean=torch.tensor(0.0), + pgen_std=torch.tensor(1.0), + ) + r_losses = IRRMCodecMultiTaskLoss( + MultiTaskLossWeights(tcremp=0.0, pgen=0.0, reconstruction=1.0) + )(**common) + rtp_losses = IRRMCodecMultiTaskLoss( + MultiTaskLossWeights(tcremp=1.0, pgen=1.0, reconstruction=1.0) + )(**common) + self.assertTrue(torch.isfinite(r_losses["loss"])) + self.assertTrue(torch.isfinite(rtp_losses["loss"])) + self.assertTrue(torch.allclose(r_losses["loss"], r_losses["reconstruction_loss"])) + self.assertGreater(float(rtp_losses["loss"]), float(r_losses["loss"])) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_prepare_trb_joint.py b/tests/test_prepare_trb_joint.py new file mode 100644 index 0000000..b4ef90f --- /dev/null +++ b/tests/test_prepare_trb_joint.py @@ -0,0 +1,104 @@ +import tempfile +import unittest +from pathlib import Path + +import numpy as np +import pandas as pd + +from benchmark.prepare_trb_joint import ( + add_identity_columns, + make_splits, + prepare_identity_table, + write_standardizer, +) + + +class JointTRBPreparationTest(unittest.TestCase): + def sources(self): + airr = pd.DataFrame( + { + "junction_aa": ["CASSF", "CASRF", "CAT", "CAA"], + "v_call": ["TRBV1", "TRBV2", "TRBV3", "TRBV4"], + "j_call": ["TRBJ1", "TRBJ2", "TRBJ1", "TRBJ2"], + "locus": ["beta"] * 4, + } + ) + pgen = airr.copy() + pgen["log10_pgen"] = [-5.0, -6.0, -7.0, -8.0] + pgen["log10_pgen_1mm"] = [-4.0, -5.0, -6.0, -7.0] + representations = pd.DataFrame( + { + "clone_id": [12, 10, 13, 11], + "cdr3aa_TRB": ["CAT", "CASSF", "CAA", "CASRF"], + "v_TRB": ["TRBV3*01", "TRBV1*01", "TRBV4*01", "TRBV2*01"], + "j_TRB": ["TRBJ1*01", "TRBJ1*01", "TRBJ2*01", "TRBJ2*01"], + } + ) + return airr, pgen, representations + + def test_identity_join_does_not_depend_on_row_order(self): + airr, pgen, representations = self.sources() + table, report = prepare_identity_table( + airr, + pgen.sample(frac=1.0, random_state=2), + representations, + min_len=1, + max_len=40, + ) + self.assertEqual(report["rows_kept"], 4) + observed = dict(zip(table["junction_aa"], table["clone_id"])) + self.assertEqual(observed, {"CASSF": 10, "CASRF": 11, "CAT": 12, "CAA": 13}) + self.assertTrue(table["record_id"].is_unique) + + def test_non_finite_targets_are_removed_before_fixed_split(self): + airr, pgen, representations = self.sources() + pgen.loc[1, "log10_pgen_1mm"] = -np.inf + table, report = prepare_identity_table( + airr, pgen, representations, min_len=1, max_len=40 + ) + self.assertEqual(report["dropped_non_finite_pgen"], 1) + splits, overlaps = make_splits( + table, train_fraction=0.5, val_fraction=0.25, seed=42 + ) + self.assertEqual({name: len(rows) for name, rows in splits.items()}, {"train": 1, "val": 0, "test": 2}) + self.assertEqual(overlaps, {"train_val": 0, "train_test": 0, "val_test": 0}) + + def test_standardizer_uses_only_train_rows(self): + airr, pgen, representations = self.sources() + table, _ = prepare_identity_table( + airr, pgen, representations, min_len=1, max_len=40 + ) + embeddings = np.arange(20, dtype=np.float32).reshape(4, 5) + with tempfile.TemporaryDirectory() as temporary: + output = Path(temporary) / "target_standardizer.npz" + summary = write_standardizer( + output, + table, + embeddings, + np.array([0, 2]), + chunk_size=1, + ) + with np.load(output, allow_pickle=False) as standardizer: + np.testing.assert_allclose( + standardizer["tcremp_mean"], embeddings[[0, 2]].mean(axis=0) + ) + self.assertEqual(int(standardizer["train_rows"]), 2) + self.assertEqual(str(standardizer["pgen_target"]), "log10_pgen_1mm") + self.assertEqual(summary["fit_split"], "train") + + def test_identity_normalizes_gene_alleles(self): + table = add_identity_columns( + pd.DataFrame( + {"cdr3": [" cassf "], "v": ["TRBV7-6*01"], "j": ["TRBJ2-7*01"]} + ), + cdr3_col="cdr3", + v_col="v", + j_col="j", + ) + self.assertEqual(table.loc[0, "junction_aa"], "CASSF") + self.assertEqual(table.loc[0, "v_identity"], "TRBV7-6") + self.assertEqual(table.loc[0, "j_identity"], "TRBJ2-7") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_vdjdb_cohort.py b/tests/test_vdjdb_cohort.py new file mode 100644 index 0000000..9b84319 --- /dev/null +++ b/tests/test_vdjdb_cohort.py @@ -0,0 +1,54 @@ +import json +import unittest + +from benchmark.prepare_vdjdb_epitope_cohort import normalize_vdjdb_row + + +def row(**changes): + value = { + "gene": "TRB", + "cdr3": "CASSLGQETQYF", + "species": "HomoSapiens", + "mhc.a": "HLA-A*02:01", + "mhc.b": "B2M", + "mhc.class": "MHCI", + "antigen.epitope": "GILGFVFTL", + "reference.id": "PMID:1", + "vdjdb.score": "2", + "meta": json.dumps({"subject.id": "donor1", "study.id": "study1"}), + "cdr3fix": json.dumps({"good": True, "cdr3": "CASSLGQETQYF"}), + } + value.update(changes) + return value + + +class NormalizeVDJdbRowTests(unittest.TestCase): + def test_accepts_unmodified_human_trb_and_builds_scoped_donor(self): + normalized, reason = normalize_vdjdb_row(row(), min_score=1) + self.assertEqual(reason, "accepted_row") + self.assertEqual(normalized["donor_key"], "study1|donor1") + self.assertEqual( + normalized["label"], "GILGFVFTL|HLA-A*02:01|B2M|MHCI" + ) + + def test_rejects_sequence_changing_fix(self): + normalized, reason = normalize_vdjdb_row( + row(cdr3fix=json.dumps({"good": True, "cdr3": "CASSIRSSYEQYF"})), + min_score=1, + ) + self.assertIsNone(normalized) + self.assertEqual(reason, "cdr3fix_changes_sequence") + + def test_rejects_missing_donor_and_low_score(self): + normalized, reason = normalize_vdjdb_row( + row(meta="{}"), min_score=1 + ) + self.assertIsNone(normalized) + self.assertEqual(reason, "missing_donor") + normalized, reason = normalize_vdjdb_row(row(**{"vdjdb.score": "0"}), min_score=1) + self.assertIsNone(normalized) + self.assertEqual(reason, "low_or_invalid_score") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_vdjdb_ylq.py b/tests/test_vdjdb_ylq.py new file mode 100644 index 0000000..d7ef3f8 --- /dev/null +++ b/tests/test_vdjdb_ylq.py @@ -0,0 +1,45 @@ +import unittest + +from benchmark.prepare_vdjdb_ylq import build_pairs + + +def record(cdr3: str, donor: str, v_call: str = "TRBV1", j_call: str = "TRBJ1") -> dict: + return { + "cdr3": cdr3, + "donor_key": donor, + "length": len(cdr3), + "v_call": v_call, + "j_call": j_call, + } + + +class YLQPairConstructionTests(unittest.TestCase): + def test_pairs_are_exact_length_and_fully_donor_disjoint(self) -> None: + positives = [ + record("CASS", "study|p1"), + record("CASR", "study|p2"), + record("CAST", "study|p3"), + ] + negatives = [ + record("CATG", "study|n1"), + record("CAVG", "study|n2", v_call="TRBV2"), + ] + pairs, report = build_pairs(positives, negatives, seed=42) + self.assertEqual(len(pairs), 3) + self.assertEqual(report["exact_length_fraction"], 1.0) + for pair in pairs: + self.assertEqual(pair["positive_length"], pair["negative_length"]) + self.assertEqual( + len({pair["query_donor"], pair["positive_donor"], pair["negative_donor"]}), + 3, + ) + + def test_missing_exact_length_negative_is_blocking(self) -> None: + positives = [record("CASS", "p1"), record("CASR", "p2")] + negatives = [record("CASSL", "n1")] + with self.assertRaisesRegex(ValueError, "No exact-length donor-disjoint negative"): + build_pairs(positives, negatives, seed=42) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_vdjdb_ylq_motif_pooled.py b/tests/test_vdjdb_ylq_motif_pooled.py new file mode 100644 index 0000000..2c6df16 --- /dev/null +++ b/tests/test_vdjdb_ylq_motif_pooled.py @@ -0,0 +1,129 @@ +import csv +import json +import tempfile +import unittest +from pathlib import Path + +from benchmark.prepare_vdjdb_ylq_motif_pooled import ( + build_pairs, + read_joined_records, + read_official_members, + select_compact_negatives, +) + + +class OfficialMotifPooledTests(unittest.TestCase): + def test_official_members_require_exact_context_and_chain(self) -> None: + fields = [ + "species", "antigen.epitope", "mhc.a", "mhc.b", "mhc.class", "gene", + "cdr3aa", "cid", "csz", "v.segm", "j.segm", + ] + rows = [ + ["HomoSapiens", "YLQPRTFLL", "HLA-A*02:01", "B2M", "MHCI", "TRB", + "CASST", "H.B.YLQPRTFLL.1", "5", "TRBV1", "TRBJ1"], + ["HomoSapiens", "YLQPRTFLL", "HLA-A*02", "B2M", "MHCI", "TRB", + "CASSA", "wrong_mhc", "5", "TRBV1", "TRBJ1"], + ["HomoSapiens", "YLQPRTFLL", "HLA-A*02:01", "B2M", "MHCI", "TRA", + "CAVAA", "wrong_chain", "5", "TRAV1", "TRAJ1"], + ] + with tempfile.TemporaryDirectory() as directory: + path = Path(directory) / "cluster_members.txt" + with path.open("w", newline="", encoding="utf-8") as handle: + writer = csv.writer(handle, delimiter="\t") + writer.writerow(fields) + writer.writerows(rows) + membership, report = read_official_members(path) + self.assertEqual(membership, {("CASST", "YLQPRTFLL"): {"H.B.YLQPRTFLL.1"}}) + self.assertEqual(report["counts"]["exact_context_trb_rows"], 1) + + def test_join_pools_donors_and_removes_ambiguous_cdr3(self) -> None: + fields = [ + "gene", "cdr3", "v.segm", "j.segm", "species", "mhc.a", "mhc.b", + "mhc.class", "antigen.epitope", "reference.id", "vdjdb.score", "meta", "cdr3fix", + ] + + def row(cdr3: str, epitope: str, donor: str) -> list[str]: + return [ + "TRB", cdr3, "TRBV1", "TRBJ1", "HomoSapiens", "HLA-A*02:01", "B2M", + "MHCI", epitope, "PMID:1", "1", + json.dumps({"study.id": "s", "subject.id": donor}), + json.dumps({"good": True, "cdr3": cdr3}), + ] + + rows = [ + row("CASST", "YLQPRTFLL", "d1"), + row("CASST", "YLQPRTFLL", "d2"), + row("CASSA", "YLQPRTFLL", "d3"), + row("CASSA", "OTHER", "d3"), + row("CASSG", "OTHER", "d4"), + ] + membership = { + ("CASST", "YLQPRTFLL"): {"ylq"}, + ("CASSA", "YLQPRTFLL"): {"ylq"}, + ("CASSA", "OTHER"): {"other"}, + ("CASSG", "OTHER"): {"other"}, + } + with tempfile.TemporaryDirectory() as directory: + path = Path(directory) / "vdjdb.txt" + with path.open("w", newline="", encoding="utf-8") as handle: + writer = csv.writer(handle, delimiter="\t") + writer.writerow(fields) + writer.writerows(rows) + records, report = read_joined_records( + path, membership, {"train": set(), "val": set(), "test": set()}, 1.0 + ) + self.assertEqual({record["cdr3"] for record in records}, {"CASST", "CASSG"}) + pooled = next(record for record in records if record["cdr3"] == "CASST") + self.assertEqual(pooled["source_rows"], 2) + self.assertEqual(pooled["donor_count_descriptive_only"], 2) + self.assertEqual(report["filter_counts"]["ambiguous_multilabel_cdr3"], 1) + + def test_pair_builder_has_no_donor_dependency_and_exact_length_negative(self) -> None: + def record(cdr3: str) -> dict: + return {"cdr3": cdr3, "length": len(cdr3), "v_call": "TRBV1", "j_call": "TRBJ1"} + + positives = [record("CASS"), record("CASR"), record("CAST")] + negatives = [record("CAVG"), record("CATG")] + pairs, report = build_pairs(positives, negatives, seed=42) + self.assertEqual(len(pairs), 3) + self.assertEqual(report["donor_constraint"], "none_pooled_by_user_protocol") + for pair in pairs: + self.assertEqual(pair["positive_length"], pair["negative_length"]) + self.assertEqual(len({pair["query_cdr3"], pair["positive_cdr3"], pair["negative_cdr3"]}), 3) + + def test_compact_controls_are_unique_capped_and_same_length(self) -> None: + def record(cdr3: str, v: str = "TRBV1", j: str = "TRBJ1") -> dict: + return {"cdr3": cdr3, "length": len(cdr3), "v_call": v, "j_call": j} + + positives = [record("CASS"), record("CASR"), record("CASST")] + negatives = [ + record("CAVG"), record("CATG"), record("CAGG"), record("CAAG"), + record("CGGG"), record("CTTG"), record("CAVGT"), + ] + selected, assignments, strata, report = select_compact_negatives( + positives, negatives, per_positive=2, seed=42 + ) + self.assertEqual(len(selected), 5) + self.assertEqual(len({row["cdr3"] for row in selected}), 5) + self.assertLessEqual(len(selected), 2 * len(positives)) + self.assertTrue(all(len(row["positive_cdr3"]) == len(row["control_cdr3"]) + for row in assignments)) + length_five = next(row for row in strata if row["length"] == 5) + self.assertEqual(length_five["shortfall"], 1) + self.assertEqual(report["gallery_control_reuse"], 0) + + def test_pairs_orient_away_from_unsupported_control_length(self) -> None: + def record(cdr3: str) -> dict: + return {"cdr3": cdr3, "length": len(cdr3), "v_call": "TRBV1", "j_call": "TRBJ1"} + + positives = [record("CASS"), record("CASRT"), record("CASST")] + negatives = [record("CAVG")] + pairs, report = build_pairs(positives, negatives, seed=42) + self.assertEqual(len(pairs), 2) + self.assertTrue(all(pair["positive_length"] == 4 for pair in pairs)) + self.assertEqual(report["excluded_pairs_both_endpoints_lack_exact_length_controls"], 1) + self.assertEqual(report["forced_orientation_to_supported_comparator"], 2) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_wordpiece_sweep.py b/tests/test_wordpiece_sweep.py new file mode 100644 index 0000000..d768955 --- /dev/null +++ b/tests/test_wordpiece_sweep.py @@ -0,0 +1,71 @@ +import tempfile +import unittest +from pathlib import Path + +import numpy as np +from tokenizers import Tokenizer +from tokenizers.decoders import WordPiece as WordPieceDecoder +from tokenizers.models import WordPiece +from tokenizers.pre_tokenizers import Whitespace +from tokenizers.trainers import WordPieceTrainer + +from irrm_codec.multitask_data import resolve_encoder_tokenizer +from irrm_codec.tokenization import AA_VOCAB +from irrm_codec.wordpiece_tokenization import validate_wordpiece_tokenizer +from scripts.prepare_wordpiece_sweep import SPECIAL_TOKENS, audit_tokenizer + + +class WordPieceSweepTest(unittest.TestCase): + def _tokenizer(self, sequences, vocab_size=44): + tokenizer = Tokenizer(WordPiece(unk_token="[UNK]")) + tokenizer.pre_tokenizer = Whitespace() + tokenizer.decoder = WordPieceDecoder(prefix="##") + tokenizer.train_from_iterator( + sequences, + WordPieceTrainer( + vocab_size=vocab_size, + min_frequency=1, + special_tokens=SPECIAL_TOKENS, + continuing_subword_prefix="##", + show_progress=False, + ), + ) + return tokenizer + + def test_special_ids_roundtrip_and_separate_encoder_vocab(self): + sequences = ["CASSLGQETQYF", "CASSPGQETQYF", "CASSIRSSYEQYF"] + tokenizer = self._tokenizer(sequences) + validate_wordpiece_tokenizer(tokenizer, "test") + for sequence in sequences: + encoding = tokenizer.encode(sequence) + self.assertNotIn(3, encoding.ids) + self.assertEqual(tokenizer.decode(encoding.ids), sequence) + with tempfile.TemporaryDirectory() as temporary: + path = Path(temporary) / "tokenizer.json" + tokenizer.save(str(path)) + resolved = resolve_encoder_tokenizer("wordpiece", str(path)) + self.assertEqual(resolved.name, "wordpiece") + self.assertEqual(resolved.vocab_size, tokenizer.get_vocab_size()) + self.assertNotEqual(resolved.vocab_size, len(AA_VOCAB)) + + def test_audit_uses_train_only_for_pgen_association(self): + sequences = { + "train": ["CASSF", "CASRF", "CATGF", "CQQYF"], + "val": ["CASSF"], + "test": ["CASRF"], + } + tokenizer = self._tokenizer(sum(sequences.values(), [])) + summary, rows = audit_tokenizer( + tokenizer, + sequences, + np.asarray([-8.0, -7.0, -6.0, -5.0], dtype=np.float64), + ) + self.assertEqual(summary["pgen_association"]["split"], "train") + self.assertEqual(summary["pgen_association"]["target"], "log10_pgen_1mm") + self.assertTrue(rows) + self.assertEqual(summary["encoding"]["val"]["unknown_sequences"], 0) + self.assertEqual(summary["encoding"]["test"]["roundtrip_mismatches"], 0) + + +if __name__ == "__main__": + unittest.main() From 296404b78edd1a7347772552fd0865442143aa05 Mon Sep 17 00:00:00 2001 From: Elizaveta Vlasova Date: Sun, 4 Oct 2026 19:30:26 +0300 Subject: [PATCH 65/70] Preserve local author benchmark, geometry-loss, factorial and VDJdb work --- benchmark/EXTERNAL_RESIDUE_BENCHMARK.md | 57 ++ .../EXTERNAL_RESIDUE_PCA256_BENCHMARK.md | 35 + benchmark/LATENT_BENCHMARK_PREREGISTRATION.md | 83 +++ benchmark/audit_external_residue_alignment.py | 154 ++++ benchmark/benchmark_vdjdb_irrm_runtime.py | 144 ++++ benchmark/cache_external_model_embeddings.py | 329 +++++++++ .../cache_external_residue_embeddings.py | 250 +++++++ benchmark/collect_author_global_comparison.py | 245 +++++++ benchmark/collect_external_pgen.py | 176 +++++ benchmark/collect_external_reconstruction.py | 149 ++++ .../collect_external_residue_benchmark.py | 77 ++ benchmark/combine_external_pca128_results.py | 49 ++ benchmark/create_vdjdb_tcremp_umap.py | 115 +++ benchmark/create_vdjdb_umap_candidates.py | 89 +++ benchmark/create_vdjdb_whole_umap.py | 82 +++ .../diagnose_vdjdb_decoded_tcremp_geometry.py | 31 + benchmark/evaluate_latent_secondary.py | 659 ++++++++++++++++++ benchmark/evaluate_latent_sufficiency.py | 517 ++++++++++++++ .../evaluate_reconstruction_substitutions.py | 197 ++++++ benchmark/evaluate_rtp_error_analysis.py | 154 ++++ .../evaluate_rtp_reconstruction_by_length.py | 139 ++++ ...evaluate_rtp_reconstruction_by_position.py | 186 +++++ benchmark/evaluate_single_aa_challenge.py | 339 +++++++++ benchmark/evaluate_vdjdb_author_global.py | 162 +++++ benchmark/evaluate_vdjdb_decoded_tcremp.py | 196 ++++++ .../evaluate_vdjdb_epitope_prediction.py | 627 +++++++++++++++++ benchmark/evaluate_vdjdb_frozen.py | 15 +- benchmark/evaluate_vdjdb_redcea_clonotypes.py | 506 ++++++++++++++ benchmark/evaluate_vdjdb_uniform100.py | 163 +++++ .../evaluate_vdjdb_uniform100_separation.py | 93 +++ benchmark/evaluate_vdjdb_viral_motif_top10.py | 425 +++++++++++ benchmark/evaluate_vdjdb_ylq_motif_pooled.py | 5 +- benchmark/external_residue_models.py | 152 ++++ benchmark/extract_vdjdb_latent.py | 79 +++ benchmark/finalize_external_residue_pca256.py | 57 ++ .../finalize_external_residue_pca_single.py | 71 ++ .../finalize_vdjdb_epitope_prediction.py | 117 ++++ benchmark/fit_external_model_bottleneck.py | 161 +++++ benchmark/fit_external_residue_pca256.py | 176 +++++ .../preflight_author_global_embeddings.py | 134 ++++ .../preflight_external_model_benchmark.py | 217 ++++++ .../preflight_external_residue_benchmark.py | 137 ++++ benchmark/preflight_external_sceptr_pca128.py | 105 +++ benchmark/prepare_external_model_cohort.py | 188 +++++ benchmark/prepare_single_aa_challenge.py | 203 ++++++ benchmark/prepare_vdjdb_redcea_clonotypes.py | 209 ++++++ benchmark/prepare_vdjdb_viral_motif_top10.py | 453 ++++++++++++ benchmark/train_external_model_decoder.py | 271 +++++++ benchmark/train_external_model_pgen.py | 425 +++++++++++ benchmark/train_external_residue_decoder.py | 222 ++++++ benchmark/train_external_residue_pgen.py | 182 +++++ benchmark/validate_single_aa_targets.py | 99 +++ .../viral_antigen_species_2025_07_30.txt | 7 + .../stage_manifest.json | 73 ++ .../experiment_manifest.json | 35 + .../experiment_manifest.json | 36 + .../rq1-char-r-seed42/experiment_config.json | 56 ++ .../experiment_config.json | 56 ++ .../rq2-char-rp-seed42/experiment_config.json | 56 ++ .../rq2-char-rt-seed42/experiment_config.json | 56 ++ .../experiment_config.json | 33 + .../experiment_config.json | 33 + .../experiment_manifest.json | 25 + .../experiment_manifest.json | 52 ++ .../experiment_config.json | 59 ++ .../experiment_config.json | 59 ++ .../experiment_config.json | 57 ++ .../experiment_config.json | 57 ++ .../experiment_manifest.json | 34 + .../experiment_manifest.json | 159 +++++ .../validation_results.md | 80 +++ irrm_codec/multitask_losses.py | 67 +- irrm_codec/train_multitask.py | 14 + scripts/preflight_data_anchor_objectives.py | 11 +- scripts/run_vdjdb_tcremp_umap.sbatch | 19 + scripts/run_vdjdb_umap_candidates.sbatch | 18 + .../run_vdjdb_umap_candidates_runtime.sbatch | 25 + scripts/run_vdjdb_uniform100.sbatch | 22 + scripts/run_vdjdb_uniform100_direct.sbatch | 21 + .../run_vdjdb_uniform100_separation.sbatch | 20 + scripts/run_vdjdb_whole_umap.sbatch | 19 + slurm/benchmark_vdjdb_irrm_cpu.sbatch | 19 + slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch | 13 + slurm/benchmark_vdjdb_irrm_gpu.sbatch | 20 + slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch | 14 + slurm/benchmark_vdjdb_tcremp_runtime.sbatch | 30 + slurm/cache_author_global_embeddings.sbatch | 42 ++ slurm/cache_author_global_sceptr_cdr3.sbatch | 32 + slurm/cache_external_model_embeddings.sbatch | 42 ++ .../cache_external_residue_embeddings.sbatch | 37 + slurm/collect_author_global_comparison.sbatch | 25 + slurm/collect_external_model_benchmark.sbatch | 29 + slurm/collect_external_pca256_pgen.sbatch | 19 + ...lect_external_pca256_reconstruction.sbatch | 21 + .../collect_external_residue_benchmark.sbatch | 25 + ...collect_external_residue_pca128_all.sbatch | 28 + ...lect_external_rtp128_reconstruction.sbatch | 72 ++ slurm/collect_external_sceptr_pca128.sbatch | 24 + ...gnose_vdjdb_decoded_tcremp_geometry.sbatch | 10 + slurm/evaluate_latent_secondary.sbatch | 64 ++ slurm/evaluate_latent_sufficiency.sbatch | 55 ++ ...luate_rtp_data_anchor_length_errors.sbatch | 28 + ...ate_rtp_data_anchor_position_errors.sbatch | 28 + ...luate_rtp_data_anchor_substitutions.sbatch | 33 + ...te_rtp_data_anchor_substitutions_v2.sbatch | 34 + slurm/evaluate_rtp_error_analysis.sbatch | 14 + slurm/evaluate_single_aa_challenge.sbatch | 32 + slurm/evaluate_tcremp_geometry_biology.sbatch | 32 + slurm/evaluate_vdjdb_author_global.sbatch | 26 + slurm/evaluate_vdjdb_decoded_tcremp.sbatch | 21 + .../evaluate_vdjdb_epitope_prediction.sbatch | 42 ++ slurm/evaluate_vdjdb_redcea_clonotypes.sbatch | 45 ++ ...evaluate_vdjdb_tonly_decoded_tcremp.sbatch | 20 + slurm/evaluate_vdjdb_uniform100_tcremp.sbatch | 45 ++ ...uate_vdjdb_uniform100_tcremp_pca128.sbatch | 61 ++ slurm/evaluate_vdjdb_viral_motif_top10.sbatch | 28 + slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch | 3 + ...inalize_external_residue_pca128_all.sbatch | 19 + slurm/finalize_external_residue_pca256.sbatch | 19 + slurm/finalize_external_sceptr_pca128.sbatch | 19 + .../finalize_vdjdb_epitope_prediction.sbatch | 19 + slurm/fit_author_global_bottleneck.sbatch | 23 + slurm/fit_external_model_bottleneck.sbatch | 31 + slurm/fit_external_residue_pca128_all.sbatch | 28 + slurm/fit_external_residue_pca256.sbatch | 30 + slurm/fit_external_sceptr_pca128.sbatch | 27 + .../install_external_benchmark_runtime.sbatch | 109 +++ .../preflight_author_global_embeddings.sbatch | 31 + slurm/preflight_data_anchor_factorial.sbatch | 30 + .../preflight_external_model_benchmark.sbatch | 32 + ...reflight_external_residue_benchmark.sbatch | 39 ++ ...eflight_external_residue_pca128_all.sbatch | 32 + ...ight_external_rtp128_reconstruction.sbatch | 100 +++ slurm/preflight_external_sceptr_pca128.sbatch | 36 + slurm/preflight_single_aa_challenge.sbatch | 52 ++ slurm/prepare_external_model_cohort.sbatch | 44 ++ slurm/prepare_single_aa_challenge.sbatch | 45 ++ slurm/prepare_vdjdb_redcea_clonotypes.sbatch | 41 ++ slurm/prepare_vdjdb_viral_motif_top10.sbatch | 33 + slurm/smoke_tcremp_geometry_loss.sbatch | 31 + slurm/train_author_global_onehot_fixed.sbatch | 27 + slurm/train_author_global_pgen.sbatch | 28 + .../train_author_global_pgen_controls.sbatch | 29 + .../train_author_global_reconstruction.sbatch | 28 + slurm/train_data_anchor_objective.sbatch | 10 +- slurm/train_external_pca256_pgen.sbatch | 32 + ...rain_external_pca256_reconstruction.sbatch | 32 + ...ternal_pca256_sceptr_reconstruction.sbatch | 30 + slurm/train_external_pgen.sbatch | 40 ++ slurm/train_external_pgen_tfidf.sbatch | 28 + slurm/train_external_reconstruction.sbatch | 41 ++ ...n_external_residue_pca128_remaining.sbatch | 51 ++ slurm/train_external_residue_pgen.sbatch | 39 ++ ...ain_external_residue_reconstruction.sbatch | 38 + ...rain_external_rtp128_reconstruction.sbatch | 40 ++ .../train_external_sceptr_pca128_heads.sbatch | 42 ++ slurm/train_tcremp_geometry_ablation.sbatch | 36 + slurm/validate_external_model_cohort.sbatch | 63 ++ tests/test_author_global_embeddings.py | 60 ++ tests/test_data_anchor_factorial.py | 16 + tests/test_external_model_benchmark.py | 52 ++ tests/test_external_residue_benchmark.py | 78 +++ tests/test_latent_secondary.py | 82 +++ tests/test_latent_sufficiency.py | 59 ++ tests/test_single_aa_challenge.py | 69 ++ tests/test_single_aa_evaluation.py | 62 ++ tests/test_tcremp_geometry_loss.py | 29 + tests/test_vdjdb_cohort.py | 10 + tests/test_vdjdb_epitope_prediction.py | 47 ++ tests/test_vdjdb_redcea_clonotypes.py | 37 + tests/test_vdjdb_redcea_evaluation.py | 36 + tests/test_vdjdb_viral_motif_top10.py | 79 +++ 172 files changed, 14677 insertions(+), 21 deletions(-) create mode 100644 benchmark/EXTERNAL_RESIDUE_BENCHMARK.md create mode 100644 benchmark/EXTERNAL_RESIDUE_PCA256_BENCHMARK.md create mode 100644 benchmark/LATENT_BENCHMARK_PREREGISTRATION.md create mode 100644 benchmark/audit_external_residue_alignment.py create mode 100644 benchmark/benchmark_vdjdb_irrm_runtime.py create mode 100644 benchmark/cache_external_model_embeddings.py create mode 100644 benchmark/cache_external_residue_embeddings.py create mode 100644 benchmark/collect_author_global_comparison.py create mode 100644 benchmark/collect_external_pgen.py create mode 100644 benchmark/collect_external_reconstruction.py create mode 100644 benchmark/collect_external_residue_benchmark.py create mode 100644 benchmark/combine_external_pca128_results.py create mode 100644 benchmark/create_vdjdb_tcremp_umap.py create mode 100644 benchmark/create_vdjdb_umap_candidates.py create mode 100644 benchmark/create_vdjdb_whole_umap.py create mode 100644 benchmark/diagnose_vdjdb_decoded_tcremp_geometry.py create mode 100644 benchmark/evaluate_latent_secondary.py create mode 100644 benchmark/evaluate_latent_sufficiency.py create mode 100644 benchmark/evaluate_reconstruction_substitutions.py create mode 100644 benchmark/evaluate_rtp_error_analysis.py create mode 100644 benchmark/evaluate_rtp_reconstruction_by_length.py create mode 100644 benchmark/evaluate_rtp_reconstruction_by_position.py create mode 100644 benchmark/evaluate_single_aa_challenge.py create mode 100644 benchmark/evaluate_vdjdb_author_global.py create mode 100644 benchmark/evaluate_vdjdb_decoded_tcremp.py create mode 100644 benchmark/evaluate_vdjdb_epitope_prediction.py create mode 100644 benchmark/evaluate_vdjdb_redcea_clonotypes.py create mode 100644 benchmark/evaluate_vdjdb_uniform100.py create mode 100644 benchmark/evaluate_vdjdb_uniform100_separation.py create mode 100644 benchmark/evaluate_vdjdb_viral_motif_top10.py create mode 100644 benchmark/external_residue_models.py create mode 100644 benchmark/extract_vdjdb_latent.py create mode 100644 benchmark/finalize_external_residue_pca256.py create mode 100644 benchmark/finalize_external_residue_pca_single.py create mode 100644 benchmark/finalize_vdjdb_epitope_prediction.py create mode 100644 benchmark/fit_external_model_bottleneck.py create mode 100644 benchmark/fit_external_residue_pca256.py create mode 100644 benchmark/preflight_author_global_embeddings.py create mode 100644 benchmark/preflight_external_model_benchmark.py create mode 100644 benchmark/preflight_external_residue_benchmark.py create mode 100644 benchmark/preflight_external_sceptr_pca128.py create mode 100644 benchmark/prepare_external_model_cohort.py create mode 100644 benchmark/prepare_single_aa_challenge.py create mode 100644 benchmark/prepare_vdjdb_redcea_clonotypes.py create mode 100644 benchmark/prepare_vdjdb_viral_motif_top10.py create mode 100644 benchmark/train_external_model_decoder.py create mode 100644 benchmark/train_external_model_pgen.py create mode 100644 benchmark/train_external_residue_decoder.py create mode 100644 benchmark/train_external_residue_pgen.py create mode 100644 benchmark/validate_single_aa_targets.py create mode 100644 benchmark/viral_antigen_species_2025_07_30.txt create mode 100644 experiments/trb/anchored-tokenizer-study/stage_manifest.json create mode 100644 experiments/trb/phase1-rq1-char-seed42/experiment_manifest.json create mode 100644 experiments/trb/phase2-rq23-char-seed42/experiment_manifest.json create mode 100644 experiments/trb/rq1-char-r-seed42/experiment_config.json create mode 100644 experiments/trb/rq1-char-rtp-seed42/experiment_config.json create mode 100644 experiments/trb/rq2-char-rp-seed42/experiment_config.json create mode 100644 experiments/trb/rq2-char-rt-seed42/experiment_config.json create mode 100644 experiments/trb/rq4-wordpiece-r-seed42/experiment_config.json create mode 100644 experiments/trb/rq4-wordpiece-rtp-seed42/experiment_config.json create mode 100644 experiments/trb/rq4-wordpiece-seed42/experiment_manifest.json create mode 100644 experiments/trb/rq5-char-rtp-d128-depths-seed42/experiment_manifest.json create mode 100644 experiments/trb/rq5-char-rtp-d128-e2d4-seed42/experiment_config.json create mode 100644 experiments/trb/rq5-char-rtp-d128-e6d4-seed42/experiment_config.json create mode 100644 experiments/trb/rq5-char-rtp-d128-seed42/experiment_config.json create mode 100644 experiments/trb/rq5-char-rtp-d512-seed42/experiment_config.json create mode 100644 experiments/trb/rq5-char-rtp-widths-seed42/experiment_manifest.json create mode 100644 experiments/trb/wordpiece-sweep-seed42/experiment_manifest.json create mode 100644 experiments/trb/wordpiece-sweep-seed42/validation_results.md create mode 100644 scripts/run_vdjdb_tcremp_umap.sbatch create mode 100644 scripts/run_vdjdb_umap_candidates.sbatch create mode 100644 scripts/run_vdjdb_umap_candidates_runtime.sbatch create mode 100644 scripts/run_vdjdb_uniform100.sbatch create mode 100644 scripts/run_vdjdb_uniform100_direct.sbatch create mode 100644 scripts/run_vdjdb_uniform100_separation.sbatch create mode 100644 scripts/run_vdjdb_whole_umap.sbatch create mode 100644 slurm/benchmark_vdjdb_irrm_cpu.sbatch create mode 100644 slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch create mode 100644 slurm/benchmark_vdjdb_irrm_gpu.sbatch create mode 100644 slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch create mode 100644 slurm/benchmark_vdjdb_tcremp_runtime.sbatch create mode 100644 slurm/cache_author_global_embeddings.sbatch create mode 100644 slurm/cache_author_global_sceptr_cdr3.sbatch create mode 100644 slurm/cache_external_model_embeddings.sbatch create mode 100644 slurm/cache_external_residue_embeddings.sbatch create mode 100644 slurm/collect_author_global_comparison.sbatch create mode 100644 slurm/collect_external_model_benchmark.sbatch create mode 100644 slurm/collect_external_pca256_pgen.sbatch create mode 100644 slurm/collect_external_pca256_reconstruction.sbatch create mode 100644 slurm/collect_external_residue_benchmark.sbatch create mode 100644 slurm/collect_external_residue_pca128_all.sbatch create mode 100644 slurm/collect_external_rtp128_reconstruction.sbatch create mode 100644 slurm/collect_external_sceptr_pca128.sbatch create mode 100644 slurm/diagnose_vdjdb_decoded_tcremp_geometry.sbatch create mode 100644 slurm/evaluate_latent_secondary.sbatch create mode 100644 slurm/evaluate_latent_sufficiency.sbatch create mode 100644 slurm/evaluate_rtp_data_anchor_length_errors.sbatch create mode 100644 slurm/evaluate_rtp_data_anchor_position_errors.sbatch create mode 100644 slurm/evaluate_rtp_data_anchor_substitutions.sbatch create mode 100644 slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch create mode 100644 slurm/evaluate_rtp_error_analysis.sbatch create mode 100644 slurm/evaluate_single_aa_challenge.sbatch create mode 100644 slurm/evaluate_tcremp_geometry_biology.sbatch create mode 100644 slurm/evaluate_vdjdb_author_global.sbatch create mode 100644 slurm/evaluate_vdjdb_decoded_tcremp.sbatch create mode 100644 slurm/evaluate_vdjdb_epitope_prediction.sbatch create mode 100644 slurm/evaluate_vdjdb_redcea_clonotypes.sbatch create mode 100644 slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch create mode 100644 slurm/evaluate_vdjdb_uniform100_tcremp.sbatch create mode 100644 slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch create mode 100644 slurm/evaluate_vdjdb_viral_motif_top10.sbatch create mode 100644 slurm/finalize_external_residue_pca128_all.sbatch create mode 100644 slurm/finalize_external_residue_pca256.sbatch create mode 100644 slurm/finalize_external_sceptr_pca128.sbatch create mode 100644 slurm/finalize_vdjdb_epitope_prediction.sbatch create mode 100644 slurm/fit_author_global_bottleneck.sbatch create mode 100644 slurm/fit_external_model_bottleneck.sbatch create mode 100644 slurm/fit_external_residue_pca128_all.sbatch create mode 100644 slurm/fit_external_residue_pca256.sbatch create mode 100644 slurm/fit_external_sceptr_pca128.sbatch create mode 100644 slurm/install_external_benchmark_runtime.sbatch create mode 100644 slurm/preflight_author_global_embeddings.sbatch create mode 100644 slurm/preflight_data_anchor_factorial.sbatch create mode 100644 slurm/preflight_external_model_benchmark.sbatch create mode 100644 slurm/preflight_external_residue_benchmark.sbatch create mode 100644 slurm/preflight_external_residue_pca128_all.sbatch create mode 100644 slurm/preflight_external_rtp128_reconstruction.sbatch create mode 100644 slurm/preflight_external_sceptr_pca128.sbatch create mode 100644 slurm/preflight_single_aa_challenge.sbatch create mode 100644 slurm/prepare_external_model_cohort.sbatch create mode 100644 slurm/prepare_single_aa_challenge.sbatch create mode 100644 slurm/prepare_vdjdb_redcea_clonotypes.sbatch create mode 100644 slurm/prepare_vdjdb_viral_motif_top10.sbatch create mode 100644 slurm/smoke_tcremp_geometry_loss.sbatch create mode 100644 slurm/train_author_global_onehot_fixed.sbatch create mode 100644 slurm/train_author_global_pgen.sbatch create mode 100644 slurm/train_author_global_pgen_controls.sbatch create mode 100644 slurm/train_author_global_reconstruction.sbatch create mode 100644 slurm/train_external_pca256_pgen.sbatch create mode 100644 slurm/train_external_pca256_reconstruction.sbatch create mode 100644 slurm/train_external_pca256_sceptr_reconstruction.sbatch create mode 100644 slurm/train_external_pgen.sbatch create mode 100644 slurm/train_external_pgen_tfidf.sbatch create mode 100644 slurm/train_external_reconstruction.sbatch create mode 100644 slurm/train_external_residue_pca128_remaining.sbatch create mode 100644 slurm/train_external_residue_pgen.sbatch create mode 100644 slurm/train_external_residue_reconstruction.sbatch create mode 100644 slurm/train_external_rtp128_reconstruction.sbatch create mode 100644 slurm/train_external_sceptr_pca128_heads.sbatch create mode 100644 slurm/train_tcremp_geometry_ablation.sbatch create mode 100644 slurm/validate_external_model_cohort.sbatch create mode 100644 tests/test_author_global_embeddings.py create mode 100644 tests/test_data_anchor_factorial.py create mode 100644 tests/test_external_model_benchmark.py create mode 100644 tests/test_external_residue_benchmark.py create mode 100644 tests/test_latent_secondary.py create mode 100644 tests/test_latent_sufficiency.py create mode 100644 tests/test_single_aa_challenge.py create mode 100644 tests/test_single_aa_evaluation.py create mode 100644 tests/test_tcremp_geometry_loss.py create mode 100644 tests/test_vdjdb_epitope_prediction.py create mode 100644 tests/test_vdjdb_redcea_clonotypes.py create mode 100644 tests/test_vdjdb_redcea_evaluation.py create mode 100644 tests/test_vdjdb_viral_motif_top10.py diff --git a/benchmark/EXTERNAL_RESIDUE_BENCHMARK.md b/benchmark/EXTERNAL_RESIDUE_BENCHMARK.md new file mode 100644 index 0000000..b23e518 --- /dev/null +++ b/benchmark/EXTERNAL_RESIDUE_BENCHMARK.md @@ -0,0 +1,57 @@ +# Frozen residue-state benchmark preregistration + +## Question + +Does the poor reconstruction of public encoders in the common 64D sequence-vector +benchmark arise primarily from global pooling? The corrective analysis exposes frozen +per-residue states to a trainable, position-aware task head. + +## Locked inputs + +- Cohort: `/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/cohort` +- Split: the existing 79,544 / 9,943 / 9,943 train/validation/test manifests. +- Models: ESM2-8M, `wukevin/tcr-bert@ef65ddc`, and SCEPTR 1.2.0 default. +- Encoder parameters are frozen. Validation loss alone chooses checkpoints. +- `log10_pgen_1mm` is normalized using the training split only. + +## Representation interfaces + +The published pooled/vector results remain unchanged and are the compact-vector panel. +The new sensitivity panel uses: + +- ESM2: final-layer amino-acid states, excluding BOS/EOS/padding. +- TCR-BERT: final-layer amino-acid states, excluding CLS/SEP/padding. +- SCEPTR: default model penultimate-layer CDR3B residue states selected with compartment + mask 6. The existing default SCEPTR vector is a learned CLS representation, not a + mean-pooled vector. + +States are zero-padded to 40 residues and stored as float16; task heads cast to float32. +No amino-acid states are averaged before reaching the trainable head. + +## Task heads + +Each representation gets its own freshly initialized decoder/probe for seeds 42, 43, +and 44. Reconstruction uses the same learned output queries and three-layer +cross-attention decoder for every representation. Pgen uses the same two-layer +position-aware attention probe for every representation. Only the unavoidable input +projection width changes with the frozen encoder dimension; parameter counts are +reported. All heads use AdamW at `3e-4`, matching the locked RTP training rate. A +discarded `1e-3` pilot was stopped after its TCR-BERT validation loss diverged; no +pilot checkpoint or test result enters this comparison. + +## Endpoints + +- Reconstruction primary: exact CDR3 match. Secondary: residue accuracy, normalized + Levenshtein distance, edit distance <=1, and mean edit distance. +- Pgen primary: raw-unit RMSE. Secondary: MAE, R2, Pearson, Spearman, and bias. +- The prespecified comparison is within encoder: residue-state head versus its existing + pooled/vector head. RTP remains the fixed compact-vector reference. + +## Interpretation boundary + +This is a best-available-frozen-interface sensitivity analysis, not a matched compact +representation comparison. A residue tensor contains more numbers than a 64D or 128D +vector, and its task head is position-aware. If it closes the gap, the pooled benchmark +was interface-limited. If RTP remains better, that is stronger evidence for accessible +task information, but still not universal representation superiority because RTP was +trained on the benchmark reconstruction and pgen objectives. diff --git a/benchmark/EXTERNAL_RESIDUE_PCA256_BENCHMARK.md b/benchmark/EXTERNAL_RESIDUE_PCA256_BENCHMARK.md new file mode 100644 index 0000000..a82bb51 --- /dev/null +++ b/benchmark/EXTERNAL_RESIDUE_PCA256_BENCHMARK.md @@ -0,0 +1,35 @@ +# Frozen residue-state PCA-256 benchmark preregistration + +## Question and correction + +The full `[40,D]` residue tensors showed that ESM2 and TCR-BERT retain near-exact +sequence identity, but give each clonotype far more information than a compact IRRM +embedding. That diagnostic array was stopped and is excluded from comparative +results. The corrected comparison maps every public encoder to exactly one 256D +point before any supervised head is fitted. + +## Leakage-safe representation + +For ESM2-8M, TCR-BERT and SCEPTR, the zero-padded residue states are flattened in +sequence order. Per-coordinate mean and scale and a seeded randomized 256-component +PCA are fitted on the locked 79,544-row training manifest only. The fixed transform +is then applied to train, validation and test. Reports record source/projection +hashes, the train-manifest and row-index hashes, solver seed, explained variance, +shapes and finiteness. Validation and test rows are never used to fit scaling or PCA. + +## Downstream heads + +Each encoder receives its own freshly initialized reconstruction decoder and pgen MLP +for seeds 42, 43 and 44. The architecture, optimizer, early stopping and training +budget are the established compact-vector benchmark implementations; only the 256D +input values differ. Checkpoints are selected on validation loss. Reconstruction is +scored by exact match, residue accuracy and edit-distance measures. Pgen prediction +is scored in raw `log10_pgen_1mm` units by RMSE, MAE, R2, Pearson, Spearman and bias. + +## Interpretation boundary + +This asks how much useful information can be retained in a common 256D linear +compression of each frozen residue representation. It does not prove that the public +model's native pooling is poor in every application, and 256D remains twice the +selected RTP latent width of 128. Existing native-vector/PCA-64 results and the new +residue-PCA-256 results are reported as distinct interfaces. diff --git a/benchmark/LATENT_BENCHMARK_PREREGISTRATION.md b/benchmark/LATENT_BENCHMARK_PREREGISTRATION.md new file mode 100644 index 0000000..b63584b --- /dev/null +++ b/benchmark/LATENT_BENCHMARK_PREREGISTRATION.md @@ -0,0 +1,83 @@ +# DATA-ANCHOR latent benchmark preregistration + +Status: locked before inspecting any result from the evaluations defined here. + +## Claim under test + +At the same 128-dimensional bottleneck and encoder architecture, the frozen +R+T+P representation is a better *balanced, multipurpose representation* than +any frozen single-objective representation. This is not a claim that R+T+P must +win every specialist task or every unrelated downstream endpoint. + +The matched seed-42 DATA-ANCHOR models are R, T, P, RT, RP, TP, and RTP. All +seven use the locked TRB benchmark, train-only normalizer, tokenizer, model +architecture, and validation-selected checkpoint. No encoder is tuned using an +evaluation result. + +## Primary evaluation: frozen latent sufficiency + +Identical fresh readouts are fitted from each frozen latent representation using +the locked training split, selected using validation only, and evaluated once on +test. Readouts measure sequence content, standardized TCRemP target recovery, +and `log10_pgen_1mm` recovery. The original task heads are not reused as probes. + +Primary model-level endpoints, in order, are: + +1. worst-task normalized regret across R, T, and P targets (lower is better); +2. mean normalized regret across the same targets (lower is better); +3. Pareto hypervolume with a fixed null-reference point (higher is better); +4. number of targets within 5% of the corresponding best specialist. + +Task losses are oriented so lower is better and normalized using fixed trivial +train-derived nulls and the best validation-eligible specialist. The test set +does not set signs, weights, thresholds, readout capacity, or normalization. +Paired test-clonotype bootstrap intervals are reported for RTP minus every +comparator. These intervals do not measure training-seed variability. + +## Controlled one-amino-acid mutation challenge + +Valid single-substitution variants are grouped by parent clonotype. A parent's +variants cannot cross fitting/evaluation folds. TCRemP and pgen effects must be +computed by an existing validated scorer; absence of such a scorer blocks that +endpoint rather than allowing a proxy. + +Primary endpoints are balanced prediction of delta-TCRemP and delta-log-pgen, +followed by pgen direction accuracy and mutant-effect rank correlation. Mutation +position/substitution recovery and triplet consistency are secondary. Since all +pairs have edit distance one, this analysis tests organization beyond raw edit +distance. Parent-clustered bootstrap intervals are required. + +## Secondary evaluations + +These are reported separately and cannot replace a failed primary endpoint: + +- nested low-label readout curves; +- fixed subgroup performance by CDR3 length, V/J family, and pgen quantile; +- joint sequence/TCRemP/pgen retrieval using train-defined scaling; +- masking and conservative/nonconservative substitution robustness; +- synthetic-versus-observed discrimination only if a provenance-verified, + benchmark-deduplicated synthetic source already exists. + +## Baselines and efficiency + +Every feasible track includes the seven frozen models plus R|T|P concatenation +(384 dimensions), train-only PCA of that concatenation to 128 dimensions, and +sequence composition/length controls (with V/J reported separately). Runtime, +encoder count, representation dimension, and parameter count are reported. The +384-dimensional concatenation is an expensive upper bound, not a size-matched +single-encoder baseline. + +## Decision rule + +The primary claim is supported only if RTP improves the preregistered balanced +endpoint over each single-objective model with a paired 95% interval excluding +no improvement, while remaining competitive on every constituent task. Wins on +an isolated secondary metric, subgroup, perturbation type, or retrospectively +chosen endpoint do not establish the claim. All negative results are retained. + +## Execution controls + +All remote computation runs through CPU Slurm using +`/home/evlasova/.conda/envs/irrm-codec/bin/python`. No computation runs on an +Aldan frontend. Inputs, model checkpoints, configs, scripts, and outputs receive +SHA-256 manifests; outputs are isolated by study and Slurm job identifier. diff --git a/benchmark/audit_external_residue_alignment.py b/benchmark/audit_external_residue_alignment.py new file mode 100644 index 0000000..e9eb9c8 --- /dev/null +++ b/benchmark/audit_external_residue_alignment.py @@ -0,0 +1,154 @@ +"""Audit row/mask provenance and direct residue-token retention for frozen encoders.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd + + +NAMES = ("esm2_8m", "tcr_bert", "sceptr") +AA = "ACDEFGHIKLMNPQRSTVWY" +AA_TO_ID = {aa: i for i, aa in enumerate(AA)} + + +def sequence_sha256(sequences) -> str: + return hashlib.sha256("\n".join(sequences).encode("ascii")).hexdigest() + + +def length_matched_permutation(lengths: np.ndarray, seed: int) -> np.ndarray: + rng = np.random.default_rng(seed) + result = np.arange(len(lengths)) + for length in np.unique(lengths): + positions = np.flatnonzero(lengths == length) + if len(positions) > 1: + order = rng.permutation(positions) + result[order] = np.roll(order, 1) + return result + + +def labels_for_rows(sequences: np.ndarray, rows: np.ndarray, max_len: int = 40): + labels = np.full((len(rows), max_len), -1, dtype=np.int16) + mask = np.zeros((len(rows), max_len), dtype=bool) + for out_row, source_row in enumerate(rows): + sequence = sequences[source_row] + encoded = [AA_TO_ID[aa] for aa in sequence] + labels[out_row, : len(encoded)] = encoded + mask[out_row, : len(encoded)] = True + return labels, mask + + +def centroid_probe(matrix, train_rows, test_rows, train_labels, test_labels, train_mask, test_mask): + dim = matrix.shape[-1] + sums = np.zeros((len(AA), dim), dtype=np.float64) + counts = np.zeros(len(AA), dtype=np.int64) + for local_start in range(0, len(train_rows), 1024): + local_stop = min(local_start + 1024, len(train_rows)) + block = np.asarray(matrix[train_rows[local_start:local_stop]], dtype=np.float32) + labels = train_labels[local_start:local_stop] + mask = train_mask[local_start:local_stop] + for aa_id in range(len(AA)): + selected = block[labels == aa_id] + if len(selected): + sums[aa_id] += selected.sum(axis=0, dtype=np.float64) + counts[aa_id] += len(selected) + if (counts == 0).any(): + raise ValueError("Missing amino acid in training-centroid audit") + centroids = (sums / counts[:, None]).astype(np.float32) + centroid_norm = np.square(centroids).sum(axis=1) + correct = total = 0 + predictions_by_row = np.full_like(test_labels, -1) + for local_start in range(0, len(test_rows), 512): + local_stop = min(local_start + 512, len(test_rows)) + block = np.asarray(matrix[test_rows[local_start:local_stop]], dtype=np.float32) + flat = block.reshape(-1, dim) + distances = ( + np.square(flat).sum(axis=1, keepdims=True) + - 2 * flat @ centroids.T + + centroid_norm[None, :] + ) + predicted = distances.argmin(axis=1).reshape(block.shape[:2]) + predictions_by_row[local_start:local_stop] = predicted + labels = test_labels[local_start:local_stop] + mask = test_mask[local_start:local_stop] + correct += int((predicted[mask] == labels[mask]).sum()) + total += int(mask.sum()) + return correct / total, predictions_by_row + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dataset-dir", required=True) + parser.add_argument("--residue-dir", required=True) + parser.add_argument("--output", required=True) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def main(): + args = parse_args() + dataset_dir, residue_dir = Path(args.dataset_dir), Path(args.residue_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + sequences = frame["junction_aa"].astype(str).to_numpy() + train_rows = pd.read_csv(dataset_dir / "manifests/train.tsv", sep="\t")["row_index"].to_numpy(np.int64) + test_rows = pd.read_csv(dataset_dir / "manifests/test.tsv", sep="\t")["row_index"].to_numpy(np.int64) + train_labels, train_mask = labels_for_rows(sequences, train_rows) + test_labels, test_mask = labels_for_rows(sequences, test_rows) + test_lengths = test_mask.sum(axis=1) + perm = length_matched_permutation(test_lengths, args.seed) + manifest = json.loads((residue_dir / "residue_representations.json").read_text(encoding="utf-8")) + expected_sequence_sha = sequence_sha256(sequences) + report = { + "status": "accepted", + "sequence_sha256": expected_sequence_sha, + "train_rows": len(train_rows), + "test_rows": len(test_rows), + "models": {}, + "interpretation": "Centroid accuracy measures direct amino-acid identity retained by raw residue states; it is not an epitope or biological endpoint.", + } + for name in NAMES: + entry = manifest[name] + if entry["sequence_sha256"] != expected_sequence_sha or entry["pooling"] != "none": + raise ValueError(f"Sequence hash/pooling provenance mismatch for {name}") + matrix = np.load(entry["features"], mmap_mode="r") + mask = np.load(entry["mask"], mmap_mode="r") + expected_shape = tuple(entry["shape"]) + if tuple(matrix.shape) != expected_shape or mask.shape != matrix.shape[:2]: + raise ValueError(f"Shape mismatch for {name}") + for start in range(0, len(matrix), 4096): + if not np.isfinite(matrix[start:start + 4096]).all(): + raise ValueError(f"Non-finite residue states for {name}") + expected_mask = np.zeros_like(mask, dtype=bool) + for row, sequence in enumerate(sequences): + expected_mask[row, : len(sequence)] = True + if not np.array_equal(mask, expected_mask): + raise ValueError(f"Residue mask/sequence alignment mismatch for {name}") + accuracy, predicted = centroid_probe( + matrix, train_rows, test_rows, train_labels, test_labels, train_mask, test_mask + ) + permuted_labels = test_labels[perm] + permuted_mask = test_mask[perm] + permuted_accuracy = float( + (predicted[permuted_mask] == permuted_labels[permuted_mask]).mean() + ) + report["models"][name] = { + "model": entry["model"], + "shape": entry["shape"], + "features_sha256": entry["features_sha256"], + "mask_sha256": entry["mask_sha256"], + "mask_matches_sequence_lengths": True, + "train_centroid_test_residue_accuracy": accuracy, + "length_matched_permuted_row_accuracy": permuted_accuracy, + } + output = Path(args.output) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(report, indent=2), encoding="utf-8") + print(json.dumps(report, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/benchmark_vdjdb_irrm_runtime.py b/benchmark/benchmark_vdjdb_irrm_runtime.py new file mode 100644 index 0000000..1a728ff --- /dev/null +++ b/benchmark/benchmark_vdjdb_irrm_runtime.py @@ -0,0 +1,144 @@ +"""Measure frozen IRRM encoder runtime on the VDJdb uniform-100 cohort. + +The measured interval starts after the checkpoint, tokenizer and cohort are in +memory and excludes warm-up. It reports tokenization separately from the +sequence-to-latent encoder pass; the latter includes host-to-device transfer. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import platform +import time +from dataclasses import asdict +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.multitask_data import resolve_encoder_tokenizer +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import PAD_ID + + +def sha256_file(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for block in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(block) + return digest.hexdigest() + + +def synchronize(device: torch.device) -> None: + if device.type == "cuda": + torch.cuda.synchronize(device) + + +def make_batch(encoded: list[list[int]], rows: list[int], device: torch.device) -> tuple[torch.Tensor, torch.Tensor]: + width = max(len(encoded[row]) for row in rows) + tokens = torch.full((len(rows), width), PAD_ID, dtype=torch.long) + for local_index, row in enumerate(rows): + ids = encoded[row] + tokens[local_index, : len(ids)] = torch.tensor(ids, dtype=torch.long) + tokens = tokens.to(device, non_blocking=device.type == "cuda") + return tokens, tokens.ne(PAD_ID) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--sequence-column", default="cdr3") + parser.add_argument("--checkpoint", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--device", choices=("cpu", "cuda"), required=True) + parser.add_argument("--batch-size", type=int, required=True) + parser.add_argument("--warmup-batches", type=int, default=3) + args = parser.parse_args() + + if args.device == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is unavailable") + if args.batch_size < 1 or args.warmup_batches < 0: + raise ValueError("batch size must be positive and warmup batches non-negative") + + device = torch.device(args.device) + torch.set_grad_enabled(False) + cohort = pd.read_csv(args.cohort, sep="\t") + sequences = cohort[args.sequence_column].astype(str).tolist() + if not sequences or any(not sequence for sequence in sequences): + raise ValueError("Cohort has an empty sequence") + + payload = torch.load(args.checkpoint, map_location="cpu", weights_only=False) + model_config = IRRMCodecConfig(**payload["model_config"]) + model = IRRMCodecTransformer(model_config) + model.load_state_dict(payload["model_state"], strict=True) + model.to(device).eval() + tokenizer = resolve_encoder_tokenizer("data_anchor", str(args.tokenizer)) + if tokenizer.vocab_size != model_config.input_vocab_size: + raise ValueError("Tokenizer vocabulary does not match checkpoint") + + tokenization_started = time.perf_counter() + encoded = [tokenizer.encode(sequence, model_config.max_sequence_len) for sequence in sequences] + tokenization_seconds = time.perf_counter() - tokenization_started + rows = [list(range(start, min(start + args.batch_size, len(encoded)))) for start in range(0, len(encoded), args.batch_size)] + + with torch.inference_mode(): + for batch_rows in rows[: args.warmup_batches]: + tokens, mask = make_batch(encoded, batch_rows, device) + latent = model.encode(tokens, mask) + if latent.shape != (len(batch_rows), model_config.latent_dim): + raise ValueError(f"Unexpected latent shape: {tuple(latent.shape)}") + synchronize(device) + + encoded_rows = 0 + latent_sum = 0.0 + inference_started = time.perf_counter() + for batch_rows in rows: + tokens, mask = make_batch(encoded, batch_rows, device) + latent = model.encode(tokens, mask) + latent_sum += float(latent.sum()) + encoded_rows += len(batch_rows) + synchronize(device) + inference_seconds = time.perf_counter() - inference_started + + if encoded_rows != len(sequences) or not np.isfinite(latent_sum): + raise RuntimeError("Encoder output validation failed") + result = { + "status": "complete", + "cohort": { + "path": str(args.cohort.resolve()), + "sha256": sha256_file(args.cohort), + "rows": len(sequences), + "sequence_column": args.sequence_column, + }, + "checkpoint": {"path": str(args.checkpoint.resolve()), "sha256": sha256_file(args.checkpoint)}, + "tokenizer": {"path": str(args.tokenizer.resolve()), "sha256": sha256_file(args.tokenizer)}, + "model": asdict(model_config), + "runtime": { + "device": str(device), + "batch_size": args.batch_size, + "warmup_batches": args.warmup_batches, + "tokenization_seconds": tokenization_seconds, + "encoder_seconds": inference_seconds, + "end_to_end_seconds": tokenization_seconds + inference_seconds, + "encoder_sequences_per_second": len(sequences) / inference_seconds, + "end_to_end_sequences_per_second": len(sequences) / (tokenization_seconds + inference_seconds), + "ms_per_sequence_encoder": inference_seconds / len(sequences) * 1000, + "ms_per_sequence_end_to_end": (tokenization_seconds + inference_seconds) / len(sequences) * 1000, + }, + "validation": {"latent_dim": model_config.latent_dim, "latent_sum": latent_sum}, + "environment": {"python": platform.python_version(), "torch": torch.__version__}, + } + if device.type == "cuda": + result["environment"]["cuda_device"] = torch.cuda.get_device_name(device) + result["environment"]["cuda_runtime"] = torch.version.cuda + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text(json.dumps(result, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(json.dumps(result["runtime"], sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/cache_external_model_embeddings.py b/benchmark/cache_external_model_embeddings.py new file mode 100644 index 0000000..5388153 --- /dev/null +++ b/benchmark/cache_external_model_embeddings.py @@ -0,0 +1,329 @@ +"""Issue 2/3: generate and cache frozen representations for the benchmark dataset. + +One pretrained checkpoint per encoder, no fine-tuning. Every matrix is written in the +row order of ``dataset.parquet`` so that ``row_index`` identifies the same sequence in +every representation, including the TCRemP matrix produced by ``prepare_splits``. + +Encoders: + onehot aligned one-hot from the repo tokenizer (gap-padded to 40 x vocab) + esm2_8m ESM-2 8M (esm2_t6_8M_UR50D), mean-pooled over residues + tcr_bert TCR-BERT (wukevin/tcr-bert), mean-pooled over residues + sceptr SCEPTR default variant, already one vector per receptor + +Transformer encoders are mean-pooled over real residues only, excluding BOS/EOS and +padding, so the pooling rule is identical across models. +""" + +import argparse +import json +import time +import warnings +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.tokenization import AA_VOCAB, encode +from irrm_codec.utils import setup_logging + +ENCODERS = ("onehot", "esm2_8m", "esm2_35m", "tcr_bert", "sceptr", "sceptr_cdr3") +TCR_BERT_REVISION = "ef65ddc" + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument( + "--dataset-file", + type=Path, + help="Optional parquet/TSV cohort. Sequence column may be junction_aa or cdr3.", + ) + p.add_argument("--output-dir", default="data/benchmark/trb/representations") + p.add_argument("--encoders", nargs="+", default=list(ENCODERS), choices=list(ENCODERS)) + p.add_argument("--batch-size", type=int, default=64) + p.add_argument("--max-len", type=int, default=40) + p.add_argument("--threads", type=int, default=8) + p.add_argument("--device", default="auto", choices=("auto", "cpu", "cuda")) + p.add_argument("--rtp-embeddings", type=Path) + p.add_argument("--overwrite", action="store_true", help="Recompute even if the cache exists.") + return p.parse_args() + + +def encode_onehot(sequences, args, log): + """Aligned one-hot: the repo's gap padding gives every sequence the same layout.""" + vocab_size = len(AA_VOCAB) + out = np.zeros((len(sequences), args.max_len * vocab_size), dtype=np.float32) + positions = np.arange(args.max_len) + for row, seq in enumerate(sequences): + block = np.zeros((args.max_len, vocab_size), dtype=np.float32) + block[positions, encode(seq, max_len=args.max_len)] = 1.0 + out[row] = block.ravel() + log.info("onehot done dim=%d", out.shape[1]) + return out + + +def _mean_pool(states, keep): + """Average hidden states over the positions flagged in ``keep``.""" + mask = keep.unsqueeze(-1).to(states.dtype) + return (states * mask).sum(1) / mask.sum(1).clamp_min(1e-9) + + +def encode_esm2(sequences, args, log, model_name="esm2_8m"): + import esm + + factories = { + "esm2_8m": esm.pretrained.esm2_t6_8M_UR50D, + "esm2_35m": esm.pretrained.esm2_t12_35M_UR50D, + } + model, alphabet = factories[model_name]() + device = choose_device(args.device) + model = model.eval().to(device) + batch_converter = alphabet.get_batch_converter() + last_layer = model.num_layers + chunks = [] + with torch.no_grad(): + for start in range(0, len(sequences), args.batch_size): + batch = sequences[start : start + args.batch_size] + _, _, tokens = batch_converter([(str(i), s) for i, s in enumerate(batch)]) + tokens = tokens.to(device) + states = model(tokens, repr_layers=[last_layer])["representations"][last_layer] + keep = ( + (tokens != alphabet.padding_idx) + & (tokens != alphabet.cls_idx) + & (tokens != alphabet.eos_idx) + ) + chunks.append(_mean_pool(states, keep).cpu().numpy().astype(np.float32)) + if start % (args.batch_size * 100) == 0: + log.info("%s %d/%d", model_name, start, len(sequences)) + return np.concatenate(chunks) + + +def encode_tcr_bert(sequences, args, log): + from transformers import AutoModel, AutoTokenizer + + tokenizer = AutoTokenizer.from_pretrained("wukevin/tcr-bert", revision=TCR_BERT_REVISION) + model = AutoModel.from_pretrained("wukevin/tcr-bert", revision=TCR_BERT_REVISION) + device = choose_device(args.device) + model = model.eval().to(device) + special = set(tokenizer.all_special_ids) + chunks = [] + with torch.no_grad(): + for start in range(0, len(sequences), args.batch_size): + batch = sequences[start : start + args.batch_size] + # TCR-BERT expects residues separated by spaces. + enc = tokenizer([" ".join(s) for s in batch], return_tensors="pt", padding=True) + enc = {name: value.to(device) for name, value in enc.items()} + states = model(**enc).last_hidden_state + keep = enc["attention_mask"].bool() + for token_id in special: + keep &= enc["input_ids"] != token_id + chunks.append(_mean_pool(states, keep).cpu().numpy().astype(np.float32)) + if start % (args.batch_size * 100) == 0: + log.info("tcr_bert %d/%d", start, len(sequences)) + return np.concatenate(chunks) + + +def encode_sceptr(sequences, args, log, frame=None, cdr3_only=False): + import logging + import sceptr + + if choose_device(args.device).type == "cuda" and hasattr(sceptr, "enable_hardware_acceleration"): + sceptr.enable_hardware_acceleration() + if cdr3_only: + model = sceptr.variant.cdr3_only() + instances = pd.DataFrame({"CDR3B": frame["junction_aa"].to_numpy()}) + else: + model = sceptr + # The default author model derives beta CDR1/2 from V/J and embeds them + # together with CDR3B. Keep this annotation-aware modality explicit. + instances = pd.DataFrame( + { + "TRBV": frame["v_call"].to_numpy(), + "CDR3B": frame["junction_aa"].to_numpy(), + "TRBJ": frame["j_call"].to_numpy(), + } + ) + chunks = [] + stride = max(args.batch_size, 1024) + # libtcrlm logs an INFO line for every accepted ambiguous terminal residue; on a + # 100k-row cohort this can dominate runtime and create multi-megabyte Slurm logs. + # Suppression changes no token/model output and is limited to the SCEPTR call. + root_logger = logging.getLogger() + previous_level = root_logger.level + try: + root_logger.setLevel(logging.WARNING) + for start in range(0, len(instances), stride): + chunks.append( + model.calc_vector_representations(instances.iloc[start : start + stride]).astype(np.float32) + ) + finally: + root_logger.setLevel(previous_level) + log.info("sceptr encoded %d rows in %d chunks", len(instances), len(chunks)) + return np.concatenate(chunks) + + +def choose_device(requested): + if requested == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA requested but no GPU is visible") + if requested == "auto": + requested = "cuda" if torch.cuda.is_available() else "cpu" + return torch.device(requested) + + +def sha256_file(path, chunk_size=1024 * 1024): + import hashlib + + digest = hashlib.sha256() + with Path(path).open("rb") as handle: + while chunk := handle.read(chunk_size): + digest.update(chunk) + return digest.hexdigest() + + +def update_catalog(meta_path, name, entry): + """Merge one completed encoder atomically; Slurm array tasks may finish together.""" + import fcntl + + lock_path = meta_path.with_suffix(meta_path.suffix + ".lock") + lock_path.touch(exist_ok=True) + with lock_path.open("r+") as lock: + fcntl.flock(lock.fileno(), fcntl.LOCK_EX) + current = json.loads(meta_path.read_text(encoding="utf-8")) if meta_path.exists() else {} + current[name] = entry + temporary = meta_path.with_suffix(meta_path.suffix + f".{name}.tmp") + temporary.write_text(json.dumps(current, indent=2, sort_keys=True), encoding="utf-8") + temporary.replace(meta_path) + fcntl.flock(lock.fileno(), fcntl.LOCK_UN) + return current + + +def main(): + args = parse_args() + warnings.filterwarnings("ignore") + torch.set_num_threads(args.threads) + + dataset_dir = Path(args.dataset_dir) + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "cache_embeddings.log") + + dataset_file = args.dataset_file or dataset_dir / "dataset.parquet" + if dataset_file.suffix.lower() in {".tsv", ".txt"}: + frame = pd.read_csv(dataset_file, sep="\t") + else: + frame = pd.read_parquet(dataset_file) + if "junction_aa" not in frame and "cdr3" in frame: + frame = frame.rename(columns={"cdr3": "junction_aa"}) + required = {"junction_aa"} + if any(name == "sceptr" for name in args.encoders): + required.update({"v_call", "j_call"}) + missing = required.difference(frame.columns) + if missing: + raise ValueError(f"Input cohort is missing columns: {sorted(missing)}") + sequences = frame["junction_aa"].tolist() + log.info("dataset rows=%d from %s", len(frame), dataset_file) + + builders = { + "onehot": lambda: encode_onehot(sequences, args, log), + "esm2_8m": lambda: encode_esm2(sequences, args, log, "esm2_8m"), + "esm2_35m": lambda: encode_esm2(sequences, args, log, "esm2_35m"), + "tcr_bert": lambda: encode_tcr_bert(sequences, args, log), + "sceptr": lambda: encode_sceptr(sequences, args, log, frame=frame), + "sceptr_cdr3": lambda: encode_sceptr( + sequences, args, log, frame=frame, cdr3_only=True + ), + } + + meta_path = output_dir / "representations.json" + meta = json.loads(meta_path.read_text(encoding="utf-8")) if meta_path.exists() else {} + + for name in args.encoders: + path = output_dir / f"{name}.npy" + if path.exists() and not args.overwrite: + cached = np.load(path, mmap_mode="r") + if cached.shape[0] == len(frame): + log.info("%s cached dim=%d, skipping", name, cached.shape[1]) + continue + log.warning("%s cache has %d rows, expected %d; recomputing", name, cached.shape[0], len(frame)) + + log.info("encoding %s", name) + started = time.perf_counter() + matrix = builders[name]() + elapsed = time.perf_counter() - started + + if matrix.shape[0] != len(frame): + raise ValueError(f"{name} produced {matrix.shape[0]} rows, expected {len(frame)}.") + if not np.isfinite(matrix).all(): + raise ValueError(f"{name} produced non-finite values.") + + np.save(path, matrix) + entry = { + "dim": int(matrix.shape[1]), + "rows": int(matrix.shape[0]), + "seconds": round(elapsed, 2), + "ms_per_sequence": round(elapsed / len(frame) * 1000, 4), + "path": str(path.resolve()), + "sha256": sha256_file(path), + "sequence_sha256": __import__("hashlib").sha256( + "\n".join(sequences).encode("utf-8") + ).hexdigest(), + } + entry["model"] = { + "esm2_8m": {"id": "esm2_t6_8M_UR50D", "library": "fair-esm==2.0.0"}, + "esm2_35m": {"id": "esm2_t12_35M_UR50D", "library": "fair-esm==2.0.0"}, + "tcr_bert": {"id": "wukevin/tcr-bert", "revision": TCR_BERT_REVISION}, + "sceptr": { + "id": "SCEPTR default native CLS64", + "library": "sceptr==1.2.0", + "modality": "CDR3+V+J", + "pooling": "author-native CLS", + }, + "sceptr_cdr3": { + "id": "SCEPTR cdr3_only native CLS64", + "library": "sceptr==1.2.0", + "modality": "CDR3 sequence only", + "pooling": "author-native CLS", + }, + "onehot": {"id": "aligned repository one-hot", "modality": "sequence"}, + }[name] + meta = update_catalog(meta_path, name, entry) + log.info("%s done dim=%d in %.1f s", name, matrix.shape[1], elapsed) + + # TCRemP comes from prepare_splits and needs no encoder pass. + tcremp = dataset_dir / "embeddings.npy" + if tcremp.exists(): + matrix = np.load(tcremp, mmap_mode="r") + entry = { + "dim": int(matrix.shape[1]), + "rows": int(matrix.shape[0]), + "seconds": None, + "ms_per_sequence": None, + "path": str(tcremp.resolve()), + "sha256": sha256_file(tcremp), + } + meta = update_catalog(meta_path, "tcremp", entry) + + if args.rtp_embeddings: + matrix = np.load(args.rtp_embeddings, mmap_mode="r") + if matrix.shape[0] != len(frame) or not np.isfinite(matrix).all(): + raise ValueError(f"RTP matrix failed shape/finiteness gate: {matrix.shape}") + entry = { + "dim": int(matrix.shape[1]), + "rows": int(matrix.shape[0]), + "seconds": 0.0, + "ms_per_sequence": 0.0, + "path": str(args.rtp_embeddings.resolve()), + "sha256": sha256_file(args.rtp_embeddings), + "checkpoint_role": "DATA-ANCHOR R+T+P seed42 validation-selected frozen encoder", + } + meta = update_catalog(meta_path, "rtp", entry) + + log.info("=" * 60) + for name, info in meta.items(): + log.info("%-10s dim=%-5d rows=%d", name, info["dim"], info["rows"]) + log.info("wrote %s", meta_path) + + +if __name__ == "__main__": + main() diff --git a/benchmark/cache_external_residue_embeddings.py b/benchmark/cache_external_residue_embeddings.py new file mode 100644 index 0000000..5266955 --- /dev/null +++ b/benchmark/cache_external_residue_embeddings.py @@ -0,0 +1,250 @@ +"""Cache frozen per-residue states without global pooling. + +Outputs are float16 ``[N, 40, D]`` arrays plus boolean masks. The float16 +storage is an I/O choice only; heads cast each batch to float32 before use. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.utils import setup_logging + + +ENCODERS = ("esm2_8m", "tcr_bert", "sceptr") +DIMENSIONS = {"esm2_8m": 320, "tcr_bert": 768, "sceptr": 64} +TCR_BERT_REVISION = "ef65ddc" + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dataset-dir", default="data/benchmark/trb") + parser.add_argument("--output-dir", required=True) + parser.add_argument("--encoders", nargs="+", choices=ENCODERS, default=list(ENCODERS)) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--max-len", type=int, default=40) + parser.add_argument("--threads", type=int, default=8) + parser.add_argument("--device", choices=("cpu", "cuda", "auto"), default="auto") + parser.add_argument("--limit", type=int) + parser.add_argument("--overwrite", action="store_true") + return parser.parse_args() + + +def sha256_file(path, chunk_size=1024 * 1024): + digest = hashlib.sha256() + with Path(path).open("rb") as handle: + while block := handle.read(chunk_size): + digest.update(block) + return digest.hexdigest() + + +def choose_device(requested): + if requested == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA requested but unavailable") + if requested == "auto": + requested = "cuda" if torch.cuda.is_available() else "cpu" + return torch.device(requested) + + +def open_outputs(output_dir, name, n_rows, max_len, dim): + feature_tmp = output_dir / f"{name}_residue.tmp.npy" + mask_tmp = output_dir / f"{name}_residue_mask.tmp.npy" + features = np.lib.format.open_memmap( + feature_tmp, mode="w+", dtype=np.float16, shape=(n_rows, max_len, dim) + ) + mask = np.lib.format.open_memmap( + mask_tmp, mode="w+", dtype=np.bool_, shape=(n_rows, max_len) + ) + features[:] = 0 + mask[:] = False + return features, mask, feature_tmp, mask_tmp + + +def assign_rows(features, mask, start, states, keep, sequences): + for offset, sequence in enumerate(sequences): + selected = states[offset][keep[offset]].detach().cpu().numpy() + if len(selected) != len(sequence): + raise ValueError( + f"Residue-state count {len(selected)} != sequence length {len(sequence)}" + ) + features[start + offset, : len(sequence)] = selected.astype(np.float16) + mask[start + offset, : len(sequence)] = True + + +def encode_esm2(frame, args, features, mask, log): + import esm + + model, alphabet = esm.pretrained.esm2_t6_8M_UR50D() + device = choose_device(args.device) + model = model.eval().to(device) + converter = alphabet.get_batch_converter() + sequences = frame.junction_aa.tolist() + with torch.no_grad(): + for start in range(0, len(sequences), args.batch_size): + batch = sequences[start : start + args.batch_size] + _, _, tokens = converter([(str(i), seq) for i, seq in enumerate(batch)]) + tokens = tokens.to(device) + states = model(tokens, repr_layers=[model.num_layers])["representations"][model.num_layers] + keep = ( + (tokens != alphabet.padding_idx) + & (tokens != alphabet.cls_idx) + & (tokens != alphabet.eos_idx) + ) + assign_rows(features, mask, start, states, keep, batch) + if start % (args.batch_size * 100) == 0: + log.info("esm2_8m residue states %d/%d", start, len(sequences)) + + +def encode_tcr_bert(frame, args, features, mask, log): + from transformers import AutoModel, AutoTokenizer + + tokenizer = AutoTokenizer.from_pretrained("wukevin/tcr-bert", revision=TCR_BERT_REVISION) + model = AutoModel.from_pretrained("wukevin/tcr-bert", revision=TCR_BERT_REVISION) + device = choose_device(args.device) + model = model.eval().to(device) + specials = set(tokenizer.all_special_ids) + sequences = frame.junction_aa.tolist() + with torch.no_grad(): + for start in range(0, len(sequences), args.batch_size): + batch = sequences[start : start + args.batch_size] + encoded = tokenizer([" ".join(seq) for seq in batch], return_tensors="pt", padding=True) + encoded = {key: value.to(device) for key, value in encoded.items()} + states = model(**encoded).last_hidden_state + keep = encoded["attention_mask"].bool() + for token_id in specials: + keep &= encoded["input_ids"] != token_id + assign_rows(features, mask, start, states, keep, batch) + if start % (args.batch_size * 100) == 0: + log.info("tcr_bert residue states %d/%d", start, len(sequences)) + + +def encode_sceptr(frame, args, features, mask, log): + import logging + import sceptr + + if choose_device(args.device).type == "cuda": + sceptr.enable_hardware_acceleration() + else: + sceptr.disable_hardware_acceleration() + instances = pd.DataFrame( + { + "TRBV": frame.v_call.to_numpy(), + "CDR3B": frame.junction_aa.to_numpy(), + "TRBJ": frame.j_call.to_numpy(), + } + ) + sequences = frame.junction_aa.tolist() + # libtcrlm emits one INFO message for many accepted ambiguous terminal residues. + # Suppress only that internal chatter; it does not change tokenisation or outputs. + root_logger = logging.getLogger() + previous_level = root_logger.level + try: + root_logger.setLevel(logging.WARNING) + for start in range(0, len(instances), args.batch_size): + batch = instances.iloc[start : start + args.batch_size] + result = sceptr.calc_residue_representations(batch) + for offset, sequence in enumerate(sequences[start : start + len(batch)]): + selected = result.representation_array[offset][result.compartment_mask[offset] == 6] + if len(selected) != len(sequence): + raise ValueError( + f"SCEPTR CDR3B state count {len(selected)} != sequence length {len(sequence)}" + ) + features[start + offset, : len(sequence)] = selected.astype(np.float16) + mask[start + offset, : len(sequence)] = True + if start % (args.batch_size * 100) == 0: + log.warning("sceptr residue states %d/%d", start, len(instances)) + finally: + root_logger.setLevel(previous_level) + + +def update_catalog(path, name, entry): + import fcntl + + lock_path = path.with_suffix(path.suffix + ".lock") + lock_path.touch(exist_ok=True) + with lock_path.open("r+") as lock: + fcntl.flock(lock.fileno(), fcntl.LOCK_EX) + current = json.loads(path.read_text(encoding="utf-8")) if path.exists() else {} + current[name] = entry + temporary = path.with_suffix(path.suffix + f".{name}.tmp") + temporary.write_text(json.dumps(current, indent=2, sort_keys=True), encoding="utf-8") + temporary.replace(path) + fcntl.flock(lock.fileno(), fcntl.LOCK_UN) + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + dataset_dir = Path(args.dataset_dir) + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "cache_residue_embeddings.log") + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + if args.limit is not None: + frame = frame.iloc[: args.limit].copy() + if frame.junction_aa.str.len().max() > args.max_len: + raise ValueError("A sequence exceeds max_len") + sequence_sha = hashlib.sha256("\n".join(frame.junction_aa).encode()).hexdigest() + builders = {"esm2_8m": encode_esm2, "tcr_bert": encode_tcr_bert, "sceptr": encode_sceptr} + catalog_path = output_dir / "residue_representations.json" + + for name in args.encoders: + feature_path = output_dir / f"{name}_residue.npy" + mask_path = output_dir / f"{name}_residue_mask.npy" + if feature_path.exists() and mask_path.exists() and not args.overwrite: + cached = np.load(feature_path, mmap_mode="r") + if cached.shape == (len(frame), args.max_len, DIMENSIONS[name]): + log.info("%s residue cache already complete", name) + continue + started = time.perf_counter() + features, mask, feature_tmp, mask_tmp = open_outputs( + output_dir, name, len(frame), args.max_len, DIMENSIONS[name] + ) + builders[name](frame, args, features, mask, log) + features.flush() + mask.flush() + del features, mask + feature_tmp.replace(feature_path) + mask_tmp.replace(mask_path) + features = np.load(feature_path, mmap_mode="r") + mask = np.load(mask_path, mmap_mode="r") + lengths = frame.junction_aa.str.len().to_numpy() + if not np.array_equal(mask.sum(axis=1), lengths): + raise ValueError(f"{name} mask counts do not equal CDR3 lengths") + if not np.isfinite(features).all(): + raise ValueError(f"{name} residue cache contains non-finite values") + update_catalog( + catalog_path, + name, + { + "model": { + "esm2_8m": "esm2_t6_8M_UR50D", + "tcr_bert": f"wukevin/tcr-bert@{TCR_BERT_REVISION}", + "sceptr": "sceptr==1.2.0 default penultimate residue states; CDR3B mask=6", + }[name], + "rows": len(frame), + "shape": list(features.shape), + "dtype": str(features.dtype), + "mask_true": int(mask.sum()), + "sequence_sha256": sequence_sha, + "features": str(feature_path.resolve()), + "mask": str(mask_path.resolve()), + "features_sha256": sha256_file(feature_path), + "mask_sha256": sha256_file(mask_path), + "seconds": round(time.perf_counter() - started, 2), + "pooling": "none", + }, + ) + log.info("%s accepted shape=%s", name, features.shape) + + +if __name__ == "__main__": + main() diff --git a/benchmark/collect_author_global_comparison.py b/benchmark/collect_author_global_comparison.py new file mode 100644 index 0000000..daeed52 --- /dev/null +++ b/benchmark/collect_author_global_comparison.py @@ -0,0 +1,245 @@ +"""Assemble the preregistered author-native global embedding comparison table.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd + +METHODS = [ + ("rtp", "DATA-ANCHOR RTP", "sequence-only", 128), + ("tcremp", "TCRemP prototype distances", "sequence-derived alignment", 9000), + ("tcr_bert", "TCR-BERT final residue mean", "sequence-only", 768), + ("esm2_35m", "ESM2-35M final residue mean", "sequence-only", 480), + ("esm2_8m", "ESM2-8M final residue mean", "sequence-only sensitivity", 320), + ("sceptr_cdr3", "SCEPTR CDR3-only native CLS", "sequence-only", 64), + ("sceptr", "SCEPTR default native CLS", "annotation-aware V+CDR3+J", 64), + ("tfidf", "CDR3 TF-IDF ridge", "sequence control", None), +] + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def load_json(path: Path) -> dict: + return json.loads(path.read_text(encoding="utf-8")) + + +def aggregate_runs(root: Path, key: str, expected: set[str]) -> pd.DataFrame: + rows = [] + for path in sorted(root.glob("*/metrics.json")): + data = load_json(path) + name = data[key] + if name not in expected: + continue + row = {"name": name, "seed": int(data["seed"])} + row.update({f"test_{metric}": value for metric, value in data["test"].items()}) + rows.append(row) + frame = pd.DataFrame(rows) + for name in expected: + seeds = sorted(frame.loc[frame["name"] == name, "seed"].tolist()) + if seeds != [42, 43, 44]: + raise ValueError(f"{name} seeds are {seeds}, expected [42, 43, 44]") + return frame + + +def format_cell(mean, std, digits=4): + if pd.isna(mean): + return "NA" + if pd.isna(std): + return f"{mean:.{digits}f}" + return f"{mean:.{digits}f} +/- {std:.{digits}f}" + + +def markdown_table(frame: pd.DataFrame) -> str: + columns = [ + "method", "modality", "reconstruction_exact", "pgen_rmse", + "vdjdb_p_at_1", "vdjdb_p_at_5", "vdjdb_p_at_10", + "vdjdb_map", "vdjdb_within_between_ratio", + ] + labels = [ + "Method", "Modality", "Reconstruction exact", "pgen RMSE", + "VDJdb P@1", "P@5", "P@10", "MAP", "Within/between", + ] + lines = ["| " + " | ".join(labels) + " |", "|" + "|".join(["---"] * len(labels)) + "|"] + for _, row in frame.iterrows(): + values = [str(row[col]) if not pd.isna(row[col]) else "NA" for col in columns] + lines.append("| " + " | ".join(values) + " |") + return "\n".join(lines) + "\n" + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--old-reconstruction-summary", type=Path, required=True) + parser.add_argument("--old-pgen-summary", type=Path, required=True) + parser.add_argument("--new-reconstruction-dir", type=Path, required=True) + parser.add_argument("--new-pgen-dir", type=Path, required=True) + parser.add_argument("--control-pgen-dir", type=Path, required=True) + parser.add_argument("--reference-vdjdb-metrics", type=Path, required=True) + parser.add_argument("--external-vdjdb-summary", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(args.output_dir) + args.output_dir.mkdir(parents=True) + + reconstruction = pd.read_csv(args.old_reconstruction_summary) + new_recon = aggregate_runs( + args.new_reconstruction_dir, "representation", {"esm2_35m", "sceptr_cdr3"} + ) + recon_new_rows = [] + for name, block in new_recon.groupby("name"): + recon_new_rows.append({ + "representation": name, + "seeds": len(block), + "exact_match_mean": block["test_exact_match"].mean(), + "exact_match_std": block["test_exact_match"].std(ddof=1), + "token_accuracy_mean": block["test_token_accuracy"].mean(), + "token_accuracy_std": block["test_token_accuracy"].std(ddof=1), + }) + reconstruction = pd.concat([reconstruction, pd.DataFrame(recon_new_rows)], ignore_index=True) + + pgen = pd.read_csv(args.old_pgen_summary) + primary_pgen = aggregate_runs( + args.new_pgen_dir, + "arm", + {"esm2_35m_mlp", "sceptr_cdr3_mlp", "tcremp_mlp"}, + ) + control_pgen = aggregate_runs(args.control_pgen_dir, "arm", {"onehot_mlp"}) + new_pgen = pd.concat([primary_pgen, control_pgen], ignore_index=True) + pgen_new_rows = [] + for arm, block in new_pgen.groupby("name"): + pgen_new_rows.append({ + "arm": arm, + "seeds": len(block), + "rmse_mean": block["test_rmse"].mean(), + "rmse_std": block["test_rmse"].std(ddof=1), + "r2_mean": block["test_r2"].mean(), + "r2_std": block["test_r2"].std(ddof=1), + "spearman_rho_mean": block["test_spearman_rho"].mean(), + "spearman_rho_std": block["test_spearman_rho"].std(ddof=1), + }) + pgen = pd.concat([pgen, pd.DataFrame(pgen_new_rows)], ignore_index=True) + + external = pd.read_csv(args.external_vdjdb_summary, sep="\t").set_index("model") + reference = load_json(args.reference_vdjdb_metrics)["rtp"]["cosine"] + rows = [] + for key, label, modality, native_dim in METHODS: + recon = reconstruction[reconstruction["representation"] == key] + pgen_arm = "tfidf_ridge" if key == "tfidf" else f"{key}_mlp" + pgen_row = pgen[pgen["arm"] == pgen_arm] + row = { + "condition": key, + "method": label, + "modality": modality, + "native_global_dim": native_dim, + "reconstruction_common_dim": 64 if len(recon) else np.nan, + "reconstruction_exact_mean": recon["exact_match_mean"].iloc[0] if len(recon) else np.nan, + "reconstruction_exact_std": recon["exact_match_std"].iloc[0] if len(recon) else np.nan, + "reconstruction_token_accuracy_mean": recon["token_accuracy_mean"].iloc[0] if len(recon) else np.nan, + "pgen_rmse_mean": pgen_row["rmse_mean"].iloc[0] if len(pgen_row) else np.nan, + "pgen_rmse_std": pgen_row["rmse_std"].iloc[0] if len(pgen_row) else np.nan, + "pgen_r2_mean": pgen_row["r2_mean"].iloc[0] if len(pgen_row) else np.nan, + "pgen_spearman_mean": pgen_row["spearman_rho_mean"].iloc[0] if len(pgen_row) else np.nan, + } + if key == "rtp": + macro = reference["macro_epitope"] + knn = reference["knn_classification"] + elif key in external.index: + macro = { + metric: external.loc[key, f"cosine_{metric}"] + for metric in ("precision_at_1", "precision_at_5", "precision_at_10", + "average_precision", "within_between_ratio") + } + knn = None + else: + macro = knn = None + for source, target in ( + ("precision_at_1", "vdjdb_cosine_precision_at_1"), + ("precision_at_5", "vdjdb_cosine_precision_at_5"), + ("precision_at_10", "vdjdb_cosine_precision_at_10"), + ("average_precision", "vdjdb_cosine_map"), + ("within_between_ratio", "vdjdb_cosine_within_between_ratio"), + ): + row[target] = ( + float(macro[source]) + if macro is not None + else np.nan + ) + row["vdjdb_cosine_knn_macro_f1_at_5"] = ( + float(knn["k_5"]["macro_f1"]) if knn is not None + else ( + float(external.loc[key, "cosine_knn_macro_f1_at_5"]) + if key in external.index else np.nan + ) + ) + rows.append(row) + + final = pd.DataFrame(rows) + final["reconstruction_exact"] = [ + format_cell(mean, std) for mean, std in zip( + final["reconstruction_exact_mean"], final["reconstruction_exact_std"] + ) + ] + final["pgen_rmse"] = [ + format_cell(mean, std) for mean, std in zip(final["pgen_rmse_mean"], final["pgen_rmse_std"]) + ] + for src, dst in ( + ("vdjdb_cosine_precision_at_1", "vdjdb_p_at_1"), + ("vdjdb_cosine_precision_at_5", "vdjdb_p_at_5"), + ("vdjdb_cosine_precision_at_10", "vdjdb_p_at_10"), + ("vdjdb_cosine_map", "vdjdb_map"), + ("vdjdb_cosine_within_between_ratio", "vdjdb_within_between_ratio"), + ): + final[dst] = final[src].map(lambda value: "NA" if pd.isna(value) else f"{value:.4f}") + + table_path = args.output_dir / "final_author_global_comparison.tsv" + final.to_csv(table_path, sep="\t", index=False, lineterminator="\n") + md_path = args.output_dir / "final_author_global_comparison.md" + md_path.write_text(markdown_table(final), encoding="utf-8") + manifest = { + "status": "complete", + "protocol": { + "reconstruction": "train-only PCA64 plus identical learned decoder; three probe seeds", + "pgen": "native author-global vector plus identical MLP; three probe seeds", + "vdjdb": "native author-global vector on the fixed REDCEA gallery; macro over 87 epitopes", + }, + "inputs": { + str(path): sha256(path) + for path in ( + args.old_reconstruction_summary, + args.old_pgen_summary, + args.reference_vdjdb_metrics, + args.external_vdjdb_summary, + ) + }, + "outputs": {table_path.name: sha256(table_path), md_path.name: sha256(md_path)}, + "limitations": [ + "SCEPTR-default is annotation-aware and is not equivalent to sequence-only methods.", + "SCEPTR-default was not run on full REDCEA because unsupported V/J rows would require method-specific filtering.", + "REDCEA membership is sequence/TCRemP-cluster-conditioned, so retrieval is motif-conditioned.", + "Aligned one-hot is retained as an internal high-dimensional sequence control but omitted from the manuscript-facing comparison.", + "Probe mean/std reflects probe seeds, not pretrained encoder training-seed uncertainty.", + ], + } + (args.output_dir / "MANIFEST.json").write_text( + json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8" + ) + print(md_path.read_text(encoding="utf-8")) + + +if __name__ == "__main__": + main() diff --git a/benchmark/collect_external_pgen.py b/benchmark/collect_external_pgen.py new file mode 100644 index 0000000..2879daa --- /dev/null +++ b/benchmark/collect_external_pgen.py @@ -0,0 +1,176 @@ +"""Issue 3: aggregate Pgen runs into the per-run CSV and the summary tables. + +Reads every ``metrics.json`` written by ``train_external_model_pgen`` and produces: + pgen_runs.csv one row per run (arm x target x training size x seed) + pgen_summary.csv mean and std across seeds + pgen_summary.md Markdown tables for REPORT.md, one per target + +The Markdown groups by training size so the low-data question is readable directly: +whether the pretrained IRRM arm's advantage over the from-scratch arm grows as the +training set shrinks. +""" + +import argparse +import json +from pathlib import Path + +import pandas as pd +from scipy import stats + +METRICS = ("rmse", "mae", "r2", "pearson_r", "spearman_rho", "bias") +SUBSET_ORDER = {"1k": 0, "10k": 1, "all": 2} + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--runs-dir", default="artifacts/benchmark/pgen") + p.add_argument("--output-dir", default="results/pgen") + return p.parse_args() + + +def load_runs(runs_dir): + rows = [] + for path in sorted(Path(runs_dir).glob("*/metrics.json")): + run = json.loads(path.read_text(encoding="utf-8")) + memory = run.get("memory") or {} + rows.append( + { + "arm": run["arm"], + "target": run["target"], + "train_subset": run["train_subset"], + "train_size": run["train_size"], + "seed": run["seed"], + "training_seconds": run["training_seconds"], + **{name: run["test"][name] for name in METRICS}, + "inference_seq_per_second": run["inference"]["sequences_per_second"], + "inference_ms_per_sequence": run["inference"]["ms_per_sequence"], + "device": run["inference"]["device"], + "peak_rss_mb": memory.get("peak_rss_mb"), + "peak_gpu_mb": memory.get("peak_gpu_mb"), + "epochs_ran": (run.get("arm_details") or {}).get("epochs_ran"), + } + ) + if not rows: + raise SystemExit(f"No metrics.json found under {runs_dir}.") + frame = pd.DataFrame(rows) + frame["subset_order"] = frame.train_subset.map(SUBSET_ORDER).fillna(99) + return frame.sort_values(["target", "subset_order", "arm", "seed"]) + + +def summarize(runs): + aggregated = ( + runs.groupby(["target", "train_subset", "subset_order", "arm"]) + .agg( + seeds=("seed", "count"), + train_size=("train_size", "first"), + **{f"{name}_{stat}": (name, stat) for name in METRICS for stat in ("mean", "std")}, + training_seconds_mean=("training_seconds", "mean"), + inference_seq_per_second_mean=("inference_seq_per_second", "mean"), + peak_rss_mb_mean=("peak_rss_mb", "mean"), + peak_gpu_mb_mean=("peak_gpu_mb", "mean"), + ) + .reset_index() + ) + return aggregated.sort_values(["target", "subset_order", "rmse_mean"]) + + +def to_markdown(summary): + blocks = [] + for target in summary.target.unique(): + blocks.append(f"### {target}\n") + for subset in summary[summary.target == target].train_subset.unique(): + rows = summary[(summary.target == target) & (summary.train_subset == subset)] + size = int(rows.train_size.iloc[0]) + blocks.append(f"**train = {subset} ({size:,} sequences)**\n") + blocks.append( + "| arm | RMSE | MAE | R² | Pearson r | Spearman ρ | bias | train s | seq/s | peak RSS MB |\n" + "| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |" + ) + for _, row in rows.iterrows(): + std = row["rmse_std"] + rmse = f"{row['rmse_mean']:.4f}" + (f" ± {std:.4f}" if pd.notna(std) else "") + cells = [ + row["arm"], + rmse, + f"{row['mae_mean']:.4f}", + f"{row['r2_mean']:.4f}", + f"{row['pearson_r_mean']:.4f}", + f"{row['spearman_rho_mean']:.4f}", + f"{row['bias_mean']:+.4f}", + f"{row['training_seconds_mean']:.0f}", + f"{row['inference_seq_per_second_mean']:.0f}", + f"{row['peak_rss_mb_mean']:.0f}" if pd.notna(row["peak_rss_mb_mean"]) else "-", + ] + blocks.append("| " + " | ".join(cells) + " |") + blocks.append("") + return "\n".join(blocks) + "\n" + + +def pretraining_delta(runs): + """Does IRRM pretraining help? RMSE difference with a significance test. + + Seed spread for these two arms is comparable to the effect being measured, so the + difference of means alone cannot answer the question. Welch's t-test does not assume + the two arms have equal variance, which they do not. + """ + rows = [] + for (target, subset, order), group in runs.groupby(["target", "train_subset", "subset_order"]): + scratch = group.loc[group.arm == "irrm_scratch", "rmse"].to_numpy() + pretrained = group.loc[group.arm == "irrm_pretrained", "rmse"].to_numpy() + if len(scratch) < 2 or len(pretrained) < 2: + continue + # Lower RMSE is better, so a positive delta means pretraining won. + delta = scratch.mean() - pretrained.mean() + _, p_value = stats.ttest_ind(scratch, pretrained, equal_var=False) + rows.append( + { + "target": target, + "train_subset": subset, + "subset_order": order, + "n_scratch": len(scratch), + "n_pretrained": len(pretrained), + "irrm_scratch": scratch.mean(), + "irrm_pretrained": pretrained.mean(), + "rmse_delta": delta, + "relative_improvement": delta / scratch.mean(), + "p_value": p_value, + "verdict": ( + "no detectable effect" + if p_value >= 0.05 + else ("pretraining helps" if delta > 0 else "pretraining hurts") + ), + } + ) + if not rows: + return None + return pd.DataFrame(rows).sort_values(["target", "subset_order"]) + + +def main(): + args = parse_args() + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + + runs = load_runs(args.runs_dir) + runs.drop(columns=["subset_order"]).to_csv(output_dir / "pgen_runs.csv", index=False) + + summary = summarize(runs) + summary.drop(columns=["subset_order"]).to_csv(output_dir / "pgen_summary.csv", index=False) + (output_dir / "pgen_summary.md").write_text(to_markdown(summary), encoding="utf-8") + + print(f"runs: {len(runs)} arms: {runs.arm.nunique()} targets: {runs.target.nunique()}") + delta = pretraining_delta(runs) + if delta is not None: + delta.drop(columns=["subset_order"]).to_csv(output_dir / "pretraining_delta.csv", index=False) + print("\nDoes IRRM pretraining help? (positive rmse_delta means pretraining wins)") + print( + delta[ + ["target", "train_subset", "n_scratch", "n_pretrained", "irrm_scratch", + "irrm_pretrained", "rmse_delta", "p_value", "verdict"] + ].to_string(index=False) + ) + print(f"\nwrote {output_dir}/pgen_runs.csv, pgen_summary.csv, pgen_summary.md") + + +if __name__ == "__main__": + main() diff --git a/benchmark/collect_external_reconstruction.py b/benchmark/collect_external_reconstruction.py new file mode 100644 index 0000000..191125a --- /dev/null +++ b/benchmark/collect_external_reconstruction.py @@ -0,0 +1,149 @@ +"""Issue 2: aggregate reconstruction runs into the per-run CSV and the summary table. + +Reads every ``metrics.json`` written by ``train_decoder`` and produces: + reconstruction_runs.csv one row per run (representation x seed) + reconstruction_summary.csv mean and std across seeds, per representation + reconstruction_summary.md the same table in Markdown, for REPORT.md + +Explained variance from the PCA fit is joined in, because it is the main explanation +for differences at a fixed bottleneck width: a representation that survives the +projection intact starts from a different place than one that loses most of its variance. +""" + +import argparse +import json +from pathlib import Path + +import pandas as pd + +METRICS = ( + "exact_match", + "token_accuracy", + "normalized_levenshtein", + "within_edit_distance_1", + "mean_edit_distance", +) + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--runs-dir", default="artifacts/benchmark/reconstruction") + p.add_argument("--bottleneck-dir", default="data/benchmark/trb/bottleneck") + p.add_argument("--output-dir", default="results/reconstruction") + p.add_argument("--bottleneck-dim", type=int, default=64) + return p.parse_args() + + +def load_runs(runs_dir, bottleneck_dim): + rows = [] + for path in sorted(Path(runs_dir).glob("*/metrics.json")): + run = json.loads(path.read_text(encoding="utf-8")) + if run["bottleneck_dim"] != bottleneck_dim: + continue + rows.append( + { + "representation": run["representation"], + "seed": run["seed"], + "bottleneck_dim": run["bottleneck_dim"], + "train_subset": run["train_subset"], + "train_size": run["train_size"], + "epochs_ran": run["epochs_ran"], + "best_epoch": run["best_epoch"], + "best_val_loss": run["best_val_loss"], + "training_seconds": run["training_seconds"], + "test_loss": run["test"]["loss"], + **{name: run["test"][name] for name in METRICS}, + "inference_seq_per_second": run["inference"]["sequences_per_second"], + "inference_ms_per_sequence": run["inference"]["ms_per_sequence"], + "device": run["inference"]["device"], + } + ) + if not rows: + raise SystemExit(f"No metrics.json found under {runs_dir} for dim={bottleneck_dim}.") + return pd.DataFrame(rows) + + +def summarize(runs, bottleneck_dir, bottleneck_dim): + aggregated = runs.groupby("representation").agg( + seeds=("seed", "count"), + **{f"{name}_{stat}": (name, stat) for name in METRICS for stat in ("mean", "std")}, + training_seconds_mean=("training_seconds", "mean"), + epochs_mean=("epochs_ran", "mean"), + inference_seq_per_second_mean=("inference_seq_per_second", "mean"), + ) + + summary_path = Path(bottleneck_dir) / "bottleneck_summary.json" + if summary_path.exists(): + bottleneck = json.loads(summary_path.read_text(encoding="utf-8")) + aggregated["source_dim"] = [ + bottleneck.get(name, {}).get("source_dim") for name in aggregated.index + ] + aggregated["explained_variance"] = [ + bottleneck.get(name, {}).get("explained_variance", {}).get(str(bottleneck_dim)) + for name in aggregated.index + ] + + return aggregated.sort_values("exact_match_mean", ascending=False).reset_index() + + +def to_markdown(summary, bottleneck_dim): + header = ( + f"### Reconstruction at a {bottleneck_dim}-dimensional bottleneck\n\n" + "| representation | source dim | expl. var | exact match | token acc | " + "norm. Levenshtein | within ED 1 | train s | seq/s |\n" + "| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |\n" + ) + + def cell(row, name): + std = row[f"{name}_std"] + spread = f" ± {std:.4f}" if pd.notna(std) else "" + return f"{row[f'{name}_mean']:.4f}{spread}" + + lines = [] + for _, row in summary.iterrows(): + expl = row.get("explained_variance") + source_dim = row.get("source_dim") + cells = [ + row["representation"], + f"{source_dim:.0f}" if pd.notna(source_dim) else "-", + f"{expl:.3f}" if pd.notna(expl) else "-", + cell(row, "exact_match"), + cell(row, "token_accuracy"), + cell(row, "normalized_levenshtein"), + cell(row, "within_edit_distance_1"), + f"{row['training_seconds_mean']:.0f}", + f"{row['inference_seq_per_second_mean']:.0f}", + ] + lines.append("| " + " | ".join(cells) + " |") + return header + "\n".join(lines) + "\n" + + +def main(): + args = parse_args() + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + + runs = load_runs(args.runs_dir, args.bottleneck_dim) + runs = runs.sort_values(["representation", "seed"]) + runs.to_csv(output_dir / "reconstruction_runs.csv", index=False) + + summary = summarize(runs, args.bottleneck_dir, args.bottleneck_dim) + summary.to_csv(output_dir / "reconstruction_summary.csv", index=False) + (output_dir / "reconstruction_summary.md").write_text( + to_markdown(summary, args.bottleneck_dim), encoding="utf-8" + ) + + print(f"runs: {len(runs)} representations: {runs.representation.nunique()}") + print( + summary[ + ["representation", "seeds", "exact_match_mean", "exact_match_std", "token_accuracy_mean"] + ].to_string(index=False) + ) + print(f"\nwrote {output_dir}/reconstruction_runs.csv") + print(f"wrote {output_dir}/reconstruction_summary.csv") + print(f"wrote {output_dir}/reconstruction_summary.md") + + +if __name__ == "__main__": + main() + diff --git a/benchmark/collect_external_residue_benchmark.py b/benchmark/collect_external_residue_benchmark.py new file mode 100644 index 0000000..cd916f0 --- /dev/null +++ b/benchmark/collect_external_residue_benchmark.py @@ -0,0 +1,77 @@ +"""Collect unpooled reconstruction and pgen runs into auditable tables.""" + +import argparse +import json +from pathlib import Path + +import pandas as pd + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--reconstruction-dir", required=True) + parser.add_argument("--pgen-dir", required=True) + parser.add_argument("--output-dir", required=True) + return parser.parse_args() + + +def collect(root, task): + rows = [] + for path in sorted(Path(root).glob("*/metrics.json")): + payload = json.loads(path.read_text(encoding="utf-8")) + base = { + "representation": payload["representation"], + "seed": payload["seed"], + "interface": payload["interface"], + "parameters": payload["parameters"], + "best_epoch": payload["best_epoch"], + "best_val_loss": payload["best_val_loss"], + "epochs_ran": payload["epochs_ran"], + "training_seconds": payload["training_seconds"], + "metrics_path": str(path), + } + if task == "reconstruction": + names = ("loss", "token_accuracy", "exact_match", "normalized_levenshtein", "within_edit_distance_1", "mean_edit_distance") + else: + names = ("rmse", "mae", "r2", "pearson_r", "spearman_rho", "bias") + rows.append({**base, **{name: payload["test"][name] for name in names}}) + if not rows: + raise ValueError(f"No {task} metrics found under {root}") + return pd.DataFrame(rows) + + +def summarize(frame, task): + if task == "reconstruction": + names = ("token_accuracy", "exact_match", "normalized_levenshtein", "within_edit_distance_1", "mean_edit_distance") + ascending = False + key = "exact_match_mean" + else: + names = ("rmse", "mae", "r2", "pearson_r", "spearman_rho", "bias") + ascending = True + key = "rmse_mean" + result = frame.groupby("representation").agg( + seeds=("seed", "count"), + parameters=("parameters", "first"), + training_seconds_mean=("training_seconds", "mean"), + **{f"{name}_{stat}": (name, stat) for name in names for stat in ("mean", "std")}, + ).reset_index() + return result.sort_values(key, ascending=ascending) + + +def main(): + args = parse_args() + output = Path(args.output_dir) + output.mkdir(parents=True, exist_ok=True) + reconstruction = collect(args.reconstruction_dir, "reconstruction") + pgen = collect(args.pgen_dir, "pgen") + reconstruction.to_csv(output / "reconstruction_residue_runs.tsv", sep="\t", index=False) + pgen.to_csv(output / "pgen_residue_runs.tsv", sep="\t", index=False) + summarize(reconstruction, "reconstruction").to_csv( + output / "reconstruction_residue_summary.tsv", sep="\t", index=False + ) + summarize(pgen, "pgen").to_csv(output / "pgen_residue_summary.tsv", sep="\t", index=False) + print(f"status=complete reconstruction_runs={len(reconstruction)} pgen_runs={len(pgen)}") + + +if __name__ == "__main__": + main() diff --git a/benchmark/combine_external_pca128_results.py b/benchmark/combine_external_pca128_results.py new file mode 100644 index 0000000..8b38a28 --- /dev/null +++ b/benchmark/combine_external_pca128_results.py @@ -0,0 +1,49 @@ +"""Combine the all-model PCA-128 sensitivity tables without recomputing metrics.""" + +import argparse +import hashlib +import json +from pathlib import Path + +import pandas as pd + + +def sha256(path: Path) -> str: + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--main-root", required=True) + parser.add_argument("--sceptr-root", required=True) + return parser.parse_args() + + +def main(): + args = parse_args() + main_root, sceptr_root = Path(args.main_root), Path(args.sceptr_root) + output = main_root / "results" / "all_baselines" + output.mkdir(parents=True, exist_ok=True) + sources = {} + for task, filename in (("reconstruction", "reconstruction_summary.csv"), ("pgen", "pgen_summary.csv")): + paths = [ + main_root / "results" / task / filename, + sceptr_root / "results" / task / filename, + ] + frame = pd.concat([pd.read_csv(path) for path in paths], ignore_index=True) + identity_column = "representation" if task == "reconstruction" else "arm" + if len(frame) != 3 or frame[identity_column].nunique() != 3: + raise ValueError(f"Expected three distinct PCA-128 baseline rows for {task}") + destination = output / filename + frame.to_csv(destination, index=False) + sources[task] = { + "inputs": [{"path": str(path), "sha256": sha256(path)} for path in paths], + "output": str(destination), + "output_sha256": sha256(destination), + } + (output / "MANIFEST.json").write_text(json.dumps(sources, indent=2), encoding="utf-8") + print("status=accepted baselines=3 tasks=2") + + +if __name__ == "__main__": + main() diff --git a/benchmark/create_vdjdb_tcremp_umap.py b/benchmark/create_vdjdb_tcremp_umap.py new file mode 100644 index 0000000..f947633 --- /dev/null +++ b/benchmark/create_vdjdb_tcremp_umap.py @@ -0,0 +1,115 @@ +"""Fit and render a native-TCRemP UMAP for the full VDJdb cohort.""" +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +from matplotlib.lines import Line2D +import numpy as np +import pandas as pd +import umap + + +HIGHLIGHTS = { + "SSYRRPVGI": "#4477AA", + "STPESANL": "#EE6677", + "SLLMWITQV": "#228833", + "KYNKANVFL": "#AA3377", + "SIINFEKL": "#CCBB44", +} +SEED = 1729 +MAX_BACKGROUND = 5_000 +MAX_PER_HIGHLIGHT = 1_800 + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--tcremp", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + return parser.parse_args() + + +def cap(frame: pd.DataFrame, maximum: int, rng: np.random.Generator) -> pd.DataFrame: + if len(frame) <= maximum: + return frame + return frame.iloc[rng.choice(len(frame), size=maximum, replace=False)] + + +def main() -> None: + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + + cohort = pd.read_csv(args.cohort, sep="\t") + labels = cohort.label.astype(str).to_numpy() + matrix = np.load(args.tcremp, mmap_mode="r") + if matrix.shape[0] != len(cohort): + raise ValueError(f"TCRemP rows ({matrix.shape[0]}) do not match cohort ({len(cohort)})") + if not np.isfinite(matrix).all(): + raise ValueError("TCRemP matrix contains non-finite values") + + coordinates = umap.UMAP( + n_neighbors=30, + min_dist=0.15, + metric="cosine", + n_components=2, + random_state=SEED, + transform_seed=SEED, + ).fit_transform(np.asarray(matrix, dtype=np.float32)) + frame = pd.DataFrame({"index": np.arange(len(cohort)), "epitope": labels, + "umap_1": coordinates[:, 0], "umap_2": coordinates[:, 1]}) + frame.to_parquet(args.output_dir / "umap_coordinates.parquet", index=False) + + plt.rcParams.update({"font.family": "STIXGeneral", "font.size": 7.5, + "pdf.fonttype": 42, "ps.fonttype": 42, "svg.fonttype": "none"}) + rng = np.random.default_rng(SEED) + fig, ax = plt.subplots(figsize=(3.38, 3.38)) + other = cap(frame[~frame.epitope.isin(HIGHLIGHTS)], MAX_BACKGROUND, rng) + ax.scatter(other.umap_1, other.umap_2, s=1.1, c="#9e9e9e", alpha=.20, + linewidths=0, rasterized=True) + for epitope, color in HIGHLIGHTS.items(): + selected = cap(frame[frame.epitope == epitope], MAX_PER_HIGHLIGHT, rng) + ax.scatter(selected.umap_1, selected.umap_2, s=8.0, c=color, alpha=.76, + linewidths=0, rasterized=True) + ax.set_xticks([]) + ax.set_yticks([]) + for spine in ax.spines.values(): + spine.set_visible(False) + ax.set_title("TCRemP prototype embedding", fontsize=9, fontweight="bold", pad=5) + handles = [Line2D([], [], marker="o", linestyle="", markerfacecolor="#9e9e9e", + markeredgewidth=0, markersize=3.9, alpha=.7, label="Other epitopes")] + handles += [Line2D([], [], marker="o", linestyle="", markerfacecolor=color, + markeredgewidth=0, markersize=4.5, label=epitope) + for epitope, color in HIGHLIGHTS.items()] + fig.legend(handles=handles, loc="lower center", ncol=3, frameon=False, fontsize=6.8, + bbox_to_anchor=(.5, -.045), handletextpad=.25, columnspacing=.7, borderaxespad=0) + fig.subplots_adjust(left=.012, right=.995, top=.89, bottom=.105) + for suffix, kwargs in ((".png", {"dpi": 600}), (".pdf", {}), (".svg", {})): + fig.savefig((args.output_dir / "vdjdb_whole_cohort_tcremp_umap").with_suffix(suffix), + bbox_inches="tight", pad_inches=.01, **kwargs) + plt.close(fig) + + metadata = { + "cohort_size": int(len(cohort)), + "source_embeddings": {"TCRemP": str(args.tcremp)}, + "matrix_shape": [int(dim) for dim in matrix.shape], + "highlights": {epitope: {"n_full_cohort": int((labels == epitope).sum()), "color": color} + for epitope, color in HIGHLIGHTS.items()}, + "umap": {"metric": "cosine", "n_neighbors": 30, "min_dist": 0.15, + "n_components": 2, "random_state": SEED, "transform_seed": SEED}, + "display_sampling": {"seed": SEED, "max_background": MAX_BACKGROUND, + "max_per_highlight": MAX_PER_HIGHLIGHT}, + "caveat": "The native 9,000-dimensional TCRemP representation is projected separately; compare only qualitative within-panel structure.", + } + (args.output_dir / "README.md").write_text(json.dumps(metadata, indent=2) + "\n", encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/benchmark/create_vdjdb_umap_candidates.py b/benchmark/create_vdjdb_umap_candidates.py new file mode 100644 index 0000000..0fb5064 --- /dev/null +++ b/benchmark/create_vdjdb_umap_candidates.py @@ -0,0 +1,89 @@ +"""Create matched, exploratory RP/RTP UMAPs from saved VDJdb embeddings only.""" +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import umap + + +TARGETS = ["SLLMWITQV", "GLCTLVAML", "VEALYLVCG", "LLLDRLNQL"] +SEED = 1729 +N_TARGET = 1500 +N_BACKGROUND = 1500 + + +def args() -> argparse.Namespace: + p = argparse.ArgumentParser() + p.add_argument("--cohort", type=Path, required=True) + p.add_argument("--native-evaluation", type=Path, required=True) + p.add_argument("--output-dir", type=Path, required=True) + return p.parse_args() + + +def sample_indices(labels: np.ndarray, target: str, rng: np.random.Generator) -> tuple[np.ndarray, np.ndarray]: + positive = np.flatnonzero(labels == target) + background = np.flatnonzero(labels != target) + return (rng.choice(positive, size=min(N_TARGET, len(positive)), replace=False), + rng.choice(background, size=min(N_BACKGROUND, len(background)), replace=False)) + + +def project(values: np.ndarray) -> np.ndarray: + # Projection is intentionally fit separately in each representation space. + # This preserves native neighborhoods but does not make coordinate systems comparable. + return umap.UMAP(n_neighbors=30, min_dist=0.15, metric="cosine", random_state=SEED, + n_components=2, transform_seed=SEED).fit_transform(values) + + +def main() -> None: + a = args() + if a.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {a.output_dir}") + a.output_dir.mkdir(parents=True) + cohort = pd.read_csv(a.cohort, sep="\t") + labels = cohort.label.astype(str).to_numpy() + rng = np.random.default_rng(SEED) + models = {"RP": np.load(a.native_evaluation / "embeddings_rp.npy", mmap_mode="r"), + "RTP": np.load(a.native_evaluation / "embeddings_rtp.npy", mmap_mode="r")} + if any(len(matrix) != len(cohort) for matrix in models.values()): + raise ValueError("Embedding rows do not match cohort rows") + fig, axes = plt.subplots(len(TARGETS), 2, figsize=(7.0, 10.0), constrained_layout=True) + all_rows = [] + for row, target in enumerate(TARGETS): + positive, background = sample_indices(labels, target, rng) + indices = np.concatenate([background, positive]) + is_target = np.concatenate([np.zeros(len(background), dtype=bool), np.ones(len(positive), dtype=bool)]) + for column, (name, matrix) in enumerate(models.items()): + coords = project(np.asarray(matrix[indices], dtype=np.float32)) + frame = pd.DataFrame({"index": indices, "epitope": labels[indices], "selected_epitope": target, + "is_selected_epitope": is_target, "model": name, + "umap_1": coords[:, 0], "umap_2": coords[:, 1]}) + all_rows.append(frame) + ax = axes[row, column] + ax.scatter(coords[~is_target, 0], coords[~is_target, 1], s=3.2, c="#bdbdbd", alpha=.33, linewidths=0) + ax.scatter(coords[is_target, 0], coords[is_target, 1], s=6.5, c="#0072B2", alpha=.76, linewidths=0) + ax.set_title(f"{target} (n={len(positive):,}) — {name}", fontsize=9) + ax.set_xticks([]); ax.set_yticks([]) + ax.text(.02, .03, "separate UMAP fit", transform=ax.transAxes, fontsize=6.5, color="#555555") + for spine in ax.spines.values(): spine.set_linewidth(.5) + fig.text(.5, .002, "Same sequence subset in each RP/RTP pair; UMAP: cosine, n_neighbors=30, min_dist=0.15, seed=1729. Coordinates are not directly comparable across separate fits.", ha="center", fontsize=7) + fig.savefig(a.output_dir / "vdjdb_umap_contact_sheet.png", dpi=450, bbox_inches="tight") + fig.savefig(a.output_dir / "vdjdb_umap_contact_sheet.pdf", bbox_inches="tight") + plt.close(fig) + pd.concat(all_rows, ignore_index=True).to_csv(a.output_dir / "umap_coordinates.tsv", sep="\t", index=False) + (a.output_dir / "README.md").write_text(json.dumps({ + "source_embeddings": {name: str(a.native_evaluation / f"embeddings_{name.lower()}.npy") for name in models}, + "cohort": str(a.cohort), "targets": TARGETS, "sampling": {"target_max": N_TARGET, "background": N_BACKGROUND, "seed": SEED}, + "umap": {"metric": "cosine", "n_neighbors": 30, "min_dist": .15, "random_state": SEED}, + "caveat": "RP and RTP use matched sequence subsets but separate UMAP fits; compare qualitative within-panel structure only." + }, indent=2) + "\n", encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/benchmark/create_vdjdb_whole_umap.py b/benchmark/create_vdjdb_whole_umap.py new file mode 100644 index 0000000..22900c9 --- /dev/null +++ b/benchmark/create_vdjdb_whole_umap.py @@ -0,0 +1,82 @@ +"""Fit one UMAP per saved RP/RTP embedding set across the complete VDJdb cohort.""" +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +from matplotlib.lines import Line2D +import numpy as np +import pandas as pd +import umap + + +HIGHLIGHTS = { + "SLLMWITQV": ("SLLMWITQV", "#0072B2"), + "GLCTLVAML": ("GLCTLVAML", "#D55E00"), + "VEALYLVCG": ("VEALYLVCG", "#009E73"), + "LLLDRLNQL": ("LLLDRLNQL", "#CC79A7"), +} +SEED = 1729 + + +def parse_args() -> argparse.Namespace: + p = argparse.ArgumentParser() + p.add_argument("--cohort", type=Path, required=True) + p.add_argument("--native-evaluation", type=Path, required=True) + p.add_argument("--output-dir", type=Path, required=True) + return p.parse_args() + + +def fit(matrix: np.ndarray) -> np.ndarray: + return umap.UMAP(n_neighbors=30, min_dist=0.15, metric="cosine", n_components=2, + random_state=SEED, transform_seed=SEED).fit_transform(matrix) + + +def main() -> None: + a = parse_args() + if a.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {a.output_dir}") + a.output_dir.mkdir(parents=True) + cohort = pd.read_csv(a.cohort, sep="\t") + labels = cohort.label.astype(str).to_numpy() + matrices = {"RP": np.load(a.native_evaluation / "embeddings_rp.npy", mmap_mode="r"), + "RTP": np.load(a.native_evaluation / "embeddings_rtp.npy", mmap_mode="r")} + if any(len(x) != len(cohort) for x in matrices.values()): + raise ValueError("Embedding rows do not match the full cohort") + fig, axes = plt.subplots(1, 2, figsize=(12, 5.4), constrained_layout=True) + frames = [] + highlighted = np.isin(labels, list(HIGHLIGHTS)) + for ax, (name, matrix) in zip(axes, matrices.items()): + coords = fit(np.asarray(matrix, dtype=np.float32)) + ax.scatter(coords[~highlighted, 0], coords[~highlighted, 1], s=.45, c="#a9a9a9", alpha=.16, linewidths=0, rasterized=True) + for epitope, (display, color) in HIGHLIGHTS.items(): + mask = labels == epitope + ax.scatter(coords[mask, 0], coords[mask, 1], s=3.8, c=color, alpha=.85, linewidths=0, rasterized=True, label=f"{display} (n={mask.sum():,})") + ax.set_title(name, fontsize=12, weight="bold") + ax.set_xlabel("UMAP 1"); ax.set_ylabel("UMAP 2") + ax.tick_params(length=2, labelsize=7) + frames.append(pd.DataFrame({"index": np.arange(len(cohort)), "epitope": labels, "model": name, + "umap_1": coords[:, 0], "umap_2": coords[:, 1], + "highlighted": highlighted})) + handles = [Line2D([], [], marker="o", linestyle="", markerfacecolor="#a9a9a9", markeredgewidth=0, markersize=4, alpha=.55, label="Other VDJdb epitopes")] + handles += [Line2D([], [], marker="o", linestyle="", markerfacecolor=color, markeredgewidth=0, markersize=5, label=f"{display} (n={(labels == ep).sum():,})") for ep, (display, color) in HIGHLIGHTS.items()] + fig.legend(handles=handles, loc="lower center", ncol=3, frameon=False, fontsize=8, bbox_to_anchor=(.5, -.085)) + fig.text(.5, .005, "Full 65,756-sequence VDJdb cohort. UMAP: cosine, n_neighbors=30, min_dist=0.15, seed=1729. RP and RTP are separate fits; coordinates are not directly comparable.", ha="center", fontsize=7.5) + fig.savefig(a.output_dir / "vdjdb_whole_cohort_rp_rtp_umap.png", dpi=450, bbox_inches="tight") + fig.savefig(a.output_dir / "vdjdb_whole_cohort_rp_rtp_umap.pdf", bbox_inches="tight") + plt.close(fig) + pd.concat(frames, ignore_index=True).to_parquet(a.output_dir / "umap_coordinates.parquet", index=False) + (a.output_dir / "README.md").write_text(json.dumps({ + "cohort_size": int(len(cohort)), "source_embeddings": {name: str(a.native_evaluation / f"embeddings_{name.lower()}.npy") for name in matrices}, + "highlights": {ep: {"n": int((labels == ep).sum()), "color": color} for ep, (_, color) in HIGHLIGHTS.items()}, + "umap": {"metric": "cosine", "n_neighbors": 30, "min_dist": .15, "random_state": SEED}, + "caveat": "Both panels use the full identical cohort; RP/RTP are separately fitted UMAPs, so compare qualitative within-panel structure only." + }, indent=2) + "\n", encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/benchmark/diagnose_vdjdb_decoded_tcremp_geometry.py b/benchmark/diagnose_vdjdb_decoded_tcremp_geometry.py new file mode 100644 index 0000000..a65b977 --- /dev/null +++ b/benchmark/diagnose_vdjdb_decoded_tcremp_geometry.py @@ -0,0 +1,31 @@ +"""Diagnose raw and target-standardized TCRemP geometry on locked VDJdb pairs.""" +import json +from pathlib import Path +import numpy as np +import pandas as pd +from evaluate_vdjdb_uniform100_separation import separation_metrics +from irrm_codec.multitask_data import TargetStandardizer + +ROOT=Path('/home/evlasova/irrm-codec') +out=ROOT/'experiments/trb/vdjdb_decoded_tcremp/1429942/geometry_diagnostic' +out.mkdir(exist_ok=False) +cohort=pd.read_csv(ROOT/'experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv',sep='\t') +pairs=np.load(ROOT/'experiments/trb/vdjdb-uniform100-v1/evaluation-1427813/uniform_pairs.npz') +original,within,between=pairs['original_indices'],pairs['within'],pairs['between'] +labels=cohort.iloc[original].label.astype(str).to_numpy() +native=np.load(ROOT/'experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/tcremp.npy',mmap_mode='r') +decoded=np.load(ROOT/'experiments/trb/vdjdb_decoded_tcremp/1429942/decoded_tcremp.npy',mmap_mode='r') +s=TargetStandardizer.load(ROOT/'experiments/trb/anchor-data-rtp-seed42/target_standardizer.npz') +variants={'native_raw':native[original], 'decoded_raw':decoded[original], + 'native_standardized':(native[original]-s.tcremp_mean)/s.tcremp_std, + 'decoded_standardized':(decoded[original]-s.tcremp_mean)/s.tcremp_std, + 'native_centered':native[original]-s.tcremp_mean, + 'decoded_centered':decoded[original]-s.tcremp_mean} +rows=[] +for name,matrix in variants.items(): + query,epitope=separation_metrics(matrix,within,between,labels) + query.insert(0,'representation',name) + query.to_parquet(out/f'per_query_{name}.parquet',index=False) + rows.append({'representation':name,'macro_cohen_d':float(epitope.cohen_d.mean()),'macro_auroc':float(epitope.auroc.mean()),'median_cohen_d':float(epitope.cohen_d.median())}) +pd.DataFrame(rows).to_csv(out/'summary.tsv',sep='\t',index=False) +(out/'RESULTS.json').write_text(json.dumps({'status':'complete','note':'All variants use unchanged separation_metrics and identical fixed uniform-100 pairs.'},indent=2)+'\n') \ No newline at end of file diff --git a/benchmark/evaluate_latent_secondary.py b/benchmark/evaluate_latent_secondary.py new file mode 100644 index 0000000..7f0f303 --- /dev/null +++ b/benchmark/evaluate_latent_secondary.py @@ -0,0 +1,659 @@ +"""Preregistered secondary tests of matched frozen DATA-ANCHOR representations. + +This benchmark intentionally asks complementary *representation sufficiency* +questions on the locked TRB train/validation/test split. It does not search for +a task on which RTP wins. Probe hyperparameters are selected on validation; +test labels are used once for reporting and never for representation/model +selection. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import math +import os +from dataclasses import asdict +from pathlib import Path + +import numpy as np +import pandas as pd +from sklearn.decomposition import PCA + +MODELS = ("r", "t", "p", "rt", "rp", "tp", "rtp") +AA = "ACDEFGHIKLMNPQRSTVWY" +CONSERVATIVE_GROUPS = ("AILMV", "FWY", "STNQ", "KRH", "DE", "CGP") +FRACTIONS = (0.01, 0.05, 0.10, 0.25, 0.50, 1.00) +ALPHAS = (0.1, 10.0, 1000.0) +JOINT_QUANTILES = (0.20, 0.25, 0.30) + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while block := handle.read(1024 * 1024): + digest.update(block) + return digest.hexdigest() + + +def stable_json(path: Path, value: object) -> None: + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def assert_finite_tree(value: object, where: str = "root") -> None: + if isinstance(value, dict): + for key, child in value.items(): + assert_finite_tree(child, f"{where}.{key}") + elif isinstance(value, list): + for index, child in enumerate(value): + assert_finite_tree(child, f"{where}[{index}]") + elif isinstance(value, (float, np.floating)) and not math.isfinite(float(value)): + raise FloatingPointError(f"Non-finite value at {where}: {value}") + + +def preregistration() -> dict: + return { + "status": "preregistered_before_test_evaluation", + "models": list(MODELS), + "primary_comparison": "RTP versus every other matched encoder; all conditions reported", + "no_selection_rule": "No track, subgroup, representation, or test metric may be omitted based on RTP rank.", + "tracks": { + "low_label": { + "nested_train_fractions": list(FRACTIONS), + "subset_rule": "prefixes of one seed-42 permutation of the locked train manifest", + "probe": "ridge with intercept; representation standardized on each train subset", + "alpha_grid_validation_only": list(ALPHAS), + "targets": { + "sequence_content": "20 AA fractions plus standardized CDR3 length", + "tcremp": "fixed seed-42 random-sign 128D sketch of locked train-standardized 9000D TCRemP vector", + "pgen": "locked train-standardized log10_pgen_1mm", + }, + "metrics": ["sequence RMSE/cosine and length MAE", "TCRemP MSE/cosine", "pgen RMSE/MAE/R2"], + }, + "strata": { + "fit": "full locked train; alpha selected on validation globally, never within test subgroup", + "length_bins": ["<=12", "13-15", "16-18", ">=19"], + "gene_families": "TRBV/TRBJ prefix before '-' and '*'; report test groups n>=100", + "pgen_bins": "quartiles defined from locked train targets", + }, + "joint_retrieval": { + "queries": "all locked test rows", + "gallery": "256 deterministic seed-42 test candidates per query, excluding self", + "relevance": ( + "simultaneously below the query-specific q-quantile for sequence 2-mer/length distance, " + "TCRemP cosine distance, and absolute standardized pgen difference" + ), + "primary_q": 0.25, + "sensitivity_q": list(JOINT_QUANTILES), + "metrics": ["P@1", "P@5", "P@10", "MAP", "eligible query count"], + "caveat": "Target-defined relevance measures joint target sufficiency, not independent biology.", + }, + "robustness": { + "rows": "deterministic 5000-row test subset", + "perturbations": [ + "one within-biochemical-group AA substitution", + "one outside-group AA substitution", + "one central encoder token replaced by UNK id 3", + ], + "no_indels": True, + "metrics": ["cosine drift", "Euclidean drift", "nonconservative greater than conservative fraction"], + }, + "synthetic_discrimination": { + "status": "disabled unless an explicit provenance manifest is supplied", + "required_manifest": ["source_path", "source_sha256", "generator", "generator_sha256", "benchmark_overlap=0"], + "reason": "No nearby file is accepted as synthetic merely from its filename.", + }, + }, + "representations": [ + *MODELS, + "concat_r_t_p_384d", + "pca128_of_concat_fit_train_only", + "aa_composition_length_vj_train_schema", + ], + "caveats": [ + "All neural models are one training seed; sampling intervals do not represent training-seed variation.", + "The low-cost sequence probe tests composition/length, not exact autoregressive reconstruction.", + "TCRemP probing/relevance uses one preregistered random projection for CPU feasibility; it is not the full 9000D target.", + "Concat/PCA use three encoders and are efficiency upper bounds, not single-encoder peers.", + ], + } + + +def nested_subsets(indices: np.ndarray, fractions: tuple[float, ...], seed: int) -> dict[float, np.ndarray]: + order = np.random.default_rng(seed).permutation(np.asarray(indices, dtype=np.int64)) + result = {} + previous: set[int] = set() + for fraction in fractions: + size = max(100, int(round(len(order) * fraction))) + subset = order[: min(size, len(order))] + if not previous.issubset(set(map(int, subset))): + raise AssertionError("Nested subset construction failed.") + previous = set(map(int, subset)) + result[fraction] = subset + return result + + +def sequence_features(sequences: pd.Series) -> np.ndarray: + output = np.zeros((len(sequences), len(AA) + 1), dtype=np.float32) + for row, sequence in enumerate(sequences.astype(str)): + for column, aa in enumerate(AA): + output[row, column] = sequence.count(aa) / len(sequence) + output[row, -1] = len(sequence) + return output + + +def bigram_features(sequences: pd.Series) -> np.ndarray: + lookup = {a + b: i for i, (a, b) in enumerate((a, b) for a in AA for b in AA)} + output = np.zeros((len(sequences), len(lookup)), dtype=np.float32) + for row, sequence in enumerate(sequences.astype(str)): + for left, right in zip(sequence, sequence[1:]): + output[row, lookup[left + right]] += 1 + norm = np.linalg.norm(output[row]) + if norm: + output[row] /= norm + return output + + +def gene_family(value: object) -> str: + text = str(value).upper().split("*", 1)[0] + return text.split("-", 1)[0] + + +def control_features(table: pd.DataFrame, train: np.ndarray) -> np.ndarray: + basic = sequence_features(table["junction_aa"]) + mean = basic[train].mean(axis=0) + std = basic[train].std(axis=0) + basic = (basic - mean) / np.where(std < 1e-8, 1.0, std) + categories = {} + for column in ("v_call", "j_call"): + values = table[column].map(gene_family).to_numpy() + categories[column] = {value: i for i, value in enumerate(sorted(set(values[train])))} + width = sum(len(value) for value in categories.values()) + genes = np.zeros((len(table), width), dtype=np.float32) + offset = 0 + for column in ("v_call", "j_call"): + values = table[column].map(gene_family).to_numpy() + for row, value in enumerate(values): + index = categories[column].get(value) + if index is not None: + genes[row, offset + index] = 1 + offset += len(categories[column]) + return np.concatenate((basic, genes), axis=1) + + +def standardize_targets( + table: pd.DataFrame, tcremp: np.ndarray, standardizer: object, +) -> tuple[np.ndarray, dict[str, slice]]: + sequence = sequence_features(table["junction_aa"]).astype(np.float64) + sequence[:, -1] = (sequence[:, -1] - table.loc[table["split"] == "train", "junction_aa"].str.len().mean()) / max( + float(table.loc[table["split"] == "train", "junction_aa"].str.len().std(ddof=0)), 1e-8 + ) + t = np.asarray(tcremp, dtype=np.float64) + p = ((table[standardizer.pgen_target].to_numpy(np.float64) - standardizer.pgen_mean) / standardizer.pgen_std)[:, None] + y = np.concatenate((sequence, t, p), axis=1) + slices = { + "sequence": slice(0, sequence.shape[1]), + "tcremp": slice(sequence.shape[1], sequence.shape[1] + t.shape[1]), + "pgen": slice(sequence.shape[1] + t.shape[1], y.shape[1]), + } + return y, slices + + +def project_tcremp( + tcremp: np.ndarray, standardizer: object, dimension: int = 128, seed: int = 42, + chunk_size: int = 512, +) -> tuple[np.ndarray, dict]: + """Apply one fixed Johnson-Lindenstrauss sign sketch after locked standardization.""" + source_dim = int(tcremp.shape[1]) + rng = np.random.default_rng(seed) + projection = rng.choice(np.asarray([-1.0, 1.0], dtype=np.float32), size=(source_dim, dimension)) + projection /= np.sqrt(dimension) + output = np.empty((len(tcremp), dimension), dtype=np.float32) + for start in range(0, len(tcremp), chunk_size): + stop = min(start + chunk_size, len(tcremp)) + standardized = ( + np.asarray(tcremp[start:stop], dtype=np.float32) - standardizer.tcremp_mean + ) / standardizer.tcremp_std + output[start:stop] = standardized @ projection + if not np.isfinite(output).all(): + raise ValueError("TCRemP random projection emitted non-finite values.") + return output, { + "method": "dense Rademacher random projection after locked train standardization", + "seed": seed, "source_dimension": source_dim, "output_dimension": dimension, + "scale": "1/sqrt(output_dimension)", + "projection_sha256": hashlib.sha256(projection.tobytes()).hexdigest(), + } + + +def ridge_coefficients(x: np.ndarray, y: np.ndarray, indices: np.ndarray, alpha: float) -> dict: + xx = np.asarray(x[indices], dtype=np.float64) + yy = np.asarray(y[indices], dtype=np.float64) + mean_x, scale_x = xx.mean(axis=0), xx.std(axis=0) + scale_x = np.where(scale_x < 1e-8, 1.0, scale_x) + mean_y = yy.mean(axis=0) + z = (xx - mean_x) / scale_x + gram = z.T @ z + beta = np.linalg.solve(gram + np.eye(gram.shape[0]) * alpha, z.T @ (yy - mean_y)) + return {"mean_x": mean_x, "scale_x": scale_x, "mean_y": mean_y, "beta": beta, "alpha": alpha} + + +def ridge_predict(fit: dict, x: np.ndarray, indices: np.ndarray) -> np.ndarray: + z = (np.asarray(x[indices], dtype=np.float64) - fit["mean_x"]) / fit["scale_x"] + return z @ fit["beta"] + fit["mean_y"] + + +def cosine_mean(a: np.ndarray, b: np.ndarray) -> float: + denominator = np.linalg.norm(a, axis=1) * np.linalg.norm(b, axis=1) + valid = denominator > 0 + return float(np.mean(np.sum(a[valid] * b[valid], axis=1) / denominator[valid])) + + +def target_metrics(truth: np.ndarray, predicted: np.ndarray, slices: dict[str, slice]) -> dict: + sequence_true, sequence_pred = truth[:, slices["sequence"]], predicted[:, slices["sequence"]] + t_true, t_pred = truth[:, slices["tcremp"]], predicted[:, slices["tcremp"]] + p_true, p_pred = truth[:, slices["pgen"]].ravel(), predicted[:, slices["pgen"]].ravel() + residual = p_true - p_pred + return { + "sequence": { + "aa_composition_rmse": float(np.sqrt(np.mean((sequence_true[:, :-1] - sequence_pred[:, :-1]) ** 2))), + "aa_composition_cosine": cosine_mean(sequence_true[:, :-1], sequence_pred[:, :-1]), + "standardized_length_mae": float(np.mean(np.abs(sequence_true[:, -1] - sequence_pred[:, -1]))), + }, + "tcremp": { + "standardized_mse": float(np.mean((t_true - t_pred) ** 2)), + "cosine": cosine_mean(t_true, t_pred), + }, + "pgen": { + "standardized_rmse": float(np.sqrt(np.mean(residual ** 2))), + "standardized_mae": float(np.mean(np.abs(residual))), + "r2": float(1 - np.sum(residual ** 2) / np.sum((p_true - p_true.mean()) ** 2)), + }, + } + + +def selection_losses(metrics: dict) -> dict[str, float]: + return { + "sequence": metrics["sequence"]["aa_composition_rmse"] + metrics["sequence"]["standardized_length_mae"], + "tcremp": metrics["tcremp"]["standardized_mse"], + "pgen": metrics["pgen"]["standardized_rmse"], + } + + +def choose_task_fits( + x: np.ndarray, y: np.ndarray, train: np.ndarray, val: np.ndarray, slices: dict[str, slice], +) -> tuple[dict[str, dict], dict]: + fits = {alpha: ridge_coefficients(x, y, train, alpha) for alpha in ALPHAS} + validations = {alpha: target_metrics(y[val], ridge_predict(fit, x, val), slices) for alpha, fit in fits.items()} + selected = {} + report = {} + for task in ("sequence", "tcremp", "pgen"): + alpha = min(ALPHAS, key=lambda value: (selection_losses(validations[value])[task], value)) + selected[task] = fits[alpha] + report[task] = {"alpha": alpha, "validation": validations[alpha][task]} + return selected, report + + +def merged_predictions(fits: dict[str, dict], x: np.ndarray, indices: np.ndarray, slices: dict[str, slice]) -> np.ndarray: + width = max(value.stop for value in slices.values()) + result = np.empty((len(indices), width), dtype=np.float64) + for task, section in slices.items(): + result[:, section] = ridge_predict(fits[task], x, indices)[:, section] + return result + + +def length_strata(table: pd.DataFrame, test: np.ndarray) -> dict[str, np.ndarray]: + lengths = table.iloc[test]["junction_aa"].str.len().to_numpy() + rules = { + "le12": lengths <= 12, + "13_15": (lengths >= 13) & (lengths <= 15), + "16_18": (lengths >= 16) & (lengths <= 18), + "ge19": lengths >= 19, + } + return {name: np.flatnonzero(mask) for name, mask in rules.items() if mask.sum() >= 100} + + +def categorical_strata(table: pd.DataFrame, test: np.ndarray, column: str) -> dict[str, np.ndarray]: + values = table.iloc[test][column].map(gene_family).to_numpy() + return {str(value): np.flatnonzero(values == value) for value in sorted(set(values)) if np.sum(values == value) >= 100} + + +def pgen_strata(table: pd.DataFrame, train: np.ndarray, test: np.ndarray, target: str) -> dict[str, np.ndarray]: + edges = np.quantile(table.iloc[train][target].to_numpy(float), [0.25, 0.5, 0.75]) + groups = np.digitize(table.iloc[test][target].to_numpy(float), edges, right=True) + return {f"q{value + 1}": np.flatnonzero(groups == value) for value in range(4)} + + +def make_candidate_gallery(n: int, width: int, seed: int) -> np.ndarray: + if n <= width: + raise ValueError("Test set must be larger than the fixed candidate gallery.") + gallery = np.empty((n, width), dtype=np.int32) + for query in range(n): + rng = np.random.default_rng(seed + query * 1_000_003) + selected = rng.choice(n - 1, width, replace=False) + gallery[query] = selected + (selected >= query) + return gallery + + +def cosine_candidate_distance(features: np.ndarray, gallery: np.ndarray, chunk: int = 1024) -> np.ndarray: + values = np.asarray(features, dtype=np.float32) + norms = np.linalg.norm(values, axis=1, keepdims=True) + unit = values / np.where(norms == 0, 1.0, norms) + result = np.empty(gallery.shape, dtype=np.float32) + for start in range(0, len(values), chunk): + stop = min(start + chunk, len(values)) + result[start:stop] = 1 - np.sum(unit[start:stop, None, :] * unit[gallery[start:stop]], axis=2) + return np.maximum(result, 0) + + +def joint_relevance( + sequences: pd.Series, tcremp: np.ndarray, pgen: np.ndarray, gallery: np.ndarray, quantile: float, +) -> np.ndarray: + bigrams = bigram_features(sequences) + seq = cosine_candidate_distance(bigrams, gallery) + lengths = sequences.str.len().to_numpy(float) + seq += 0.2 * np.abs(lengths[:, None] - lengths[gallery]) / 40.0 + t_distance = cosine_candidate_distance(tcremp, gallery) + p_distance = np.abs(pgen[:, None] - pgen[gallery]) + thresholds = [np.quantile(value, quantile, axis=1, keepdims=True) for value in (seq, t_distance, p_distance)] + return (seq <= thresholds[0]) & (t_distance <= thresholds[1]) & (p_distance <= thresholds[2]) + + +def retrieval_metrics(distance: np.ndarray, relevant: np.ndarray) -> dict: + rows = [] + for query in range(len(distance)): + positives = int(relevant[query].sum()) + if positives == 0: + continue + order = np.argsort(distance[query], kind="mergesort") + hits = relevant[query, order].astype(float) + precision = np.cumsum(hits) / np.arange(1, len(hits) + 1) + rows.append([ + hits[0], hits[:5].mean(), hits[:10].mean(), float((precision * hits).sum() / positives), positives + ]) + values = np.asarray(rows, dtype=float) + return { + "eligible_queries": int(len(values)), + "precision_at_1": float(values[:, 0].mean()), + "precision_at_5": float(values[:, 1].mean()), + "precision_at_10": float(values[:, 2].mean()), + "map": float(values[:, 3].mean()), + "mean_relevant_candidates": float(values[:, 4].mean()), + } + + +def deterministic_substitutions(sequence: str, seed: int) -> tuple[str, str]: + if len(sequence) < 3: + raise ValueError("Robustness substitution requires a sequence of length at least three.") + rng = np.random.default_rng(seed) + position = int(rng.integers(1, len(sequence) - 1)) + source = sequence[position] + group = next(group for group in CONSERVATIVE_GROUPS if source in group) + conservative_pool = [aa for aa in group if aa != source] + if not conservative_pool: + conservative_pool = [aa for aa in AA if aa != source] + nonconservative_pool = [aa for aa in AA if aa not in group] + conservative = sequence[:position] + conservative_pool[int(rng.integers(len(conservative_pool)))] + sequence[position + 1:] + nonconservative = sequence[:position] + nonconservative_pool[int(rng.integers(len(nonconservative_pool)))] + sequence[position + 1:] + return conservative, nonconservative + + +def embedding_drift(original: np.ndarray, altered: np.ndarray) -> dict: + euclidean = np.linalg.norm(original - altered, axis=1) + cosine = 1 - np.sum(original * altered, axis=1) / ( + np.linalg.norm(original, axis=1) * np.linalg.norm(altered, axis=1) + ) + return { + "euclidean_mean": float(euclidean.mean()), "euclidean_median": float(np.median(euclidean)), + "cosine_mean": float(cosine.mean()), "cosine_median": float(np.median(cosine)), + } + + +def extract_altered_embeddings( + token_sets: dict[str, list[list[int]]], models: dict, config, batch_size: int, +) -> dict[str, dict[str, np.ndarray]]: + import torch + from irrm_codec.multitask_transformer import IRRMCodecTransformer + from irrm_codec.tokenization import PAD_ID + + result = {kind: {} for kind in token_sets} + for name, (checkpoint_path, _) in models.items(): + checkpoint = torch.load(checkpoint_path, map_location="cpu", weights_only=False) + if checkpoint["model_config"] != asdict(config): + raise ValueError(f"{name} altered-input extraction found config mismatch.") + model = IRRMCodecTransformer(config) + model.load_state_dict(checkpoint["model_state"], strict=True) + model.eval() + with torch.no_grad(): + for kind, rows in token_sets.items(): + blocks = [] + for start in range(0, len(rows), batch_size): + block = rows[start:start + batch_size] + width = max(map(len, block)) + tokens = torch.full((len(block), width), PAD_ID, dtype=torch.long) + for index, ids in enumerate(block): + tokens[index, :len(ids)] = torch.tensor(ids) + blocks.append(model.encode(tokens, tokens.ne(PAD_ID)).numpy().astype(np.float32)) + result[kind][name] = np.concatenate(blocks) + del checkpoint, model + return result + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--preflight-only", action="store_true") + parser.add_argument("--accepted-preflight", type=Path) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def validate_inputs(args: argparse.Namespace) -> tuple[pd.DataFrame, np.ndarray, dict, object, dict]: + from benchmark.evaluate_vdjdb_frozen import parse_models, validate_run_configs + from irrm_codec.multitask_data import ( + TargetStandardizer, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, + ) + + table, tcremp = load_prepared_benchmark(args.data_dir) + indices = {split: select_split_indices(table, args.data_dir, split) for split in ("train", "val", "test")} + if any(np.intersect1d(indices[a], indices[b]).size for a, b in (("train", "val"), ("train", "test"), ("val", "test"))): + raise ValueError("Locked split manifests overlap.") + models = parse_models(args.model) + if set(models) != set(MODELS): + raise ValueError("Full seven-condition factorial required.") + config, model_report = validate_run_configs(models) + tokenizer = resolve_encoder_tokenizer("data_anchor", str(args.tokenizer)) + if tokenizer.vocab_size != config.input_vocab_size: + raise ValueError("Tokenizer/checkpoint vocabulary mismatch.") + standardizer = TargetStandardizer.load(args.data_dir / "target_standardizer.npz") + if standardizer.train_rows != len(indices["train"]) or standardizer.pgen_target != "log10_pgen_1mm": + raise ValueError("Locked train-only normalizer mismatch.") + return table, tcremp, indices, config, {"models": models, "report": model_report, "tokenizer": tokenizer, "standardizer": standardizer} + + +def main() -> None: + from benchmark.evaluate_vdjdb_frozen import extract_embeddings + + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + table, tcremp, indices, config, runtime = validate_inputs(args) + registration = preregistration() + stable_json(args.output_dir / "PREREGISTRATION.json", registration) + input_hashes = { + "dataset": sha256(args.data_dir / "dataset.parquet"), + "tcremp": sha256(args.data_dir / "embeddings.npy"), + "normalizer": sha256(args.data_dir / "target_standardizer.npz"), + "tokenizer": sha256(args.tokenizer), + "splits": {split: sha256(args.data_dir / "manifests" / f"{split}.tsv") for split in indices}, + } + preflight = { + "status": "accepted_for_secondary_frozen_evaluation", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "rows": len(table), "splits": {key: len(value) for key, value in indices.items()}, + "input_hashes": input_hashes, "model_report": runtime["report"], + "preregistration_sha256": sha256(args.output_dir / "PREREGISTRATION.json"), + "synthetic_track": "blocked_no_validated_source_manifest", + } + stable_json(args.output_dir / "PREFLIGHT.json", preflight) + if args.preflight_only: + print(json.dumps(preflight, indent=2, sort_keys=True)) + return + if args.accepted_preflight is None: + raise ValueError("--accepted-preflight is required for evaluation.") + accepted = json.loads(args.accepted_preflight.read_text(encoding="utf-8")) + if accepted["status"] != "accepted_for_secondary_frozen_evaluation" or accepted["input_hashes"] != input_hashes: + raise ValueError("Accepted preflight is absent, stale, or refers to different inputs.") + + cohort = pd.DataFrame({"cdr3": table["junction_aa"].astype(str)}) + embeddings, extraction = extract_embeddings( + cohort, runtime["models"], config, args.tokenizer, args.batch_size, args.output_dir + ) + representations = dict(embeddings) + concat = np.concatenate([embeddings[name] for name in ("r", "t", "p")], axis=1) + representations["concat_r_t_p"] = concat + pca = PCA(n_components=128, svd_solver="randomized", random_state=args.seed) + pca.fit(concat[indices["train"]]) + representations["pca128_concat_r_t_p"] = pca.transform(concat).astype(np.float32) + representations["sequence_length_vj_control"] = control_features(table, indices["train"]) + np.save(args.output_dir / "pca_components.npy", pca.components_, allow_pickle=False) + + tcremp_sketch, tcremp_projection_report = project_tcremp( + tcremp, runtime["standardizer"], dimension=128, seed=args.seed + ) + np.save(args.output_dir / "tcremp_random_projection.npy", tcremp_sketch, allow_pickle=False) + y, slices = standardize_targets(table, tcremp_sketch, runtime["standardizer"]) + subsets = nested_subsets(indices["train"], FRACTIONS, args.seed) + efficiency, final_fits = {}, {} + rows = [] + for representation, features in representations.items(): + efficiency[representation] = {} + for fraction, subset in subsets.items(): + fits, validation = choose_task_fits(features, y, subset, indices["val"], slices) + prediction = merged_predictions(fits, features, indices["test"], slices) + metrics = target_metrics(y[indices["test"]], prediction, slices) + efficiency[representation][str(fraction)] = { + "train_rows": len(subset), "validation_selection": validation, "test": metrics, + } + for task in metrics: + rows.append({"representation": representation, "fraction": fraction, "train_rows": len(subset), + "task": task, **metrics[task]}) + if fraction == 1.0: + final_fits[representation] = fits + pd.DataFrame(rows).to_csv(args.output_dir / "low_label_curves.tsv", sep="\t", index=False) + stable_json(args.output_dir / "low_label.json", efficiency) + + strata_definitions = { + "length": length_strata(table, indices["test"]), + "v_family": categorical_strata(table, indices["test"], "v_call"), + "j_family": categorical_strata(table, indices["test"], "j_call"), + "pgen_train_quartile": pgen_strata(table, indices["train"], indices["test"], runtime["standardizer"].pgen_target), + } + strata_rows = [] + for representation, features in representations.items(): + prediction = merged_predictions(final_fits[representation], features, indices["test"], slices) + test_truth = y[indices["test"]] + for stratum_type, groups in strata_definitions.items(): + for stratum, positions in groups.items(): + metrics = target_metrics(test_truth[positions], prediction[positions], slices) + for task, values in metrics.items(): + strata_rows.append({"representation": representation, "stratum_type": stratum_type, + "stratum": stratum, "rows": len(positions), "task": task, **values}) + pd.DataFrame(strata_rows).to_csv(args.output_dir / "stratified_test_metrics.tsv", sep="\t", index=False) + + test = indices["test"] + gallery = make_candidate_gallery(len(test), 256, args.seed) + np.save(args.output_dir / "joint_gallery.npy", gallery, allow_pickle=False) + test_sequences = table.iloc[test]["junction_aa"].reset_index(drop=True) + test_tcremp = tcremp_sketch[test] + test_pgen = y[test, slices["pgen"]].ravel() + retrieval = {} + for quantile in JOINT_QUANTILES: + relevant = joint_relevance(test_sequences, test_tcremp, test_pgen, gallery, quantile) + retrieval[str(quantile)] = { + name: retrieval_metrics(cosine_candidate_distance(features[test], gallery), relevant) + for name, features in representations.items() + } + retrieval[str(quantile)]["relevance"] = { + "eligible_queries": int(np.sum(relevant.sum(axis=1) > 0)), + "mean_relevant": float(relevant.sum(axis=1).mean()), + } + stable_json(args.output_dir / "joint_retrieval.json", retrieval) + + robust_positions = np.random.default_rng(args.seed).choice(test, size=min(5000, len(test)), replace=False) + robust_sequences = table.iloc[robust_positions]["junction_aa"].astype(str).tolist() + conservative, nonconservative = zip(*[ + deterministic_substitutions(sequence, args.seed + row * 17) + for row, sequence in enumerate(robust_sequences) + ]) + tokenizer = runtime["tokenizer"] + token_sets = { + "original": [tokenizer.encode(value, config.max_sequence_len) for value in robust_sequences], + "conservative": [tokenizer.encode(value, config.max_sequence_len) for value in conservative], + "nonconservative": [tokenizer.encode(value, config.max_sequence_len) for value in nonconservative], + } + masked = [] + for row, tokens in enumerate(token_sets["original"]): + copy = list(tokens) + position = int(np.random.default_rng(args.seed + row * 31).integers(len(copy))) + copy[position] = 3 + masked.append(copy) + token_sets["token_mask"] = masked + altered = extract_altered_embeddings(token_sets, runtime["models"], config, args.batch_size) + for kind in altered: + altered[kind]["concat_r_t_p"] = np.concatenate( + [altered[kind][name] for name in ("r", "t", "p")], axis=1 + ) + altered[kind]["pca128_concat_r_t_p"] = pca.transform( + altered[kind]["concat_r_t_p"] + ).astype(np.float32) + robustness = {} + for name in (*MODELS, "concat_r_t_p", "pca128_concat_r_t_p"): + original = altered["original"][name] + conservative_drift = np.linalg.norm(original - altered["conservative"][name], axis=1) + nonconservative_drift = np.linalg.norm(original - altered["nonconservative"][name], axis=1) + robustness[name] = { + kind: embedding_drift(original, altered[kind][name]) + for kind in ("conservative", "nonconservative", "token_mask") + } + robustness[name]["nonconservative_euclidean_gt_conservative_fraction"] = float( + np.mean(nonconservative_drift > conservative_drift) + ) + stable_json(args.output_dir / "robustness.json", robustness) + + report = { + "status": "complete", "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "study": "secondary frozen-representation benchmark on locked TRB splits", + "input_hashes": input_hashes, "models": runtime["report"], "extraction": extraction, + "representations": {name: list(value.shape) for name, value in representations.items()}, + "pca": {"fit_split": "train", "explained_variance_sum": float(pca.explained_variance_ratio_.sum())}, + "tcremp_projection": tcremp_projection_report, + "tracks": { + "low_label": "low_label.json", "stratified": "stratified_test_metrics.tsv", + "joint_retrieval": "joint_retrieval.json", "robustness": "robustness.json", + "synthetic_discrimination": "blocked_no_validated_source_manifest", + }, + "preregistration": {"path": str(args.output_dir / "PREREGISTRATION.json"), + "sha256": sha256(args.output_dir / "PREREGISTRATION.json")}, + "caveats": registration["caveats"], "nonfinite_scan": "passed", + } + assert_finite_tree(efficiency, "efficiency") + assert_finite_tree(retrieval, "retrieval") + assert_finite_tree(robustness, "robustness") + report["artifact_sha256"] = { + path.name: sha256(path) for path in sorted(args.output_dir.iterdir()) if path.is_file() + } + stable_json(args.output_dir / "RESULTS.json", report) + print(json.dumps(report, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_latent_sufficiency.py b/benchmark/evaluate_latent_sufficiency.py new file mode 100644 index 0000000..f8ba4e6 --- /dev/null +++ b/benchmark/evaluate_latent_sufficiency.py @@ -0,0 +1,517 @@ +"""Frozen linear-probe benchmark for balanced DATA-ANCHOR latent sufficiency. + +The seven encoders are never updated. Fresh ridge readouts are fitted on the +locked training manifest, their regularization is selected on validation, and +the locked test split is evaluated once. A fixed-position sequence probe is +used instead of any checkpoint decoder so reconstruction-supervised encoders +receive no privileged task head. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import os +import time +from dataclasses import asdict +from pathlib import Path + +import numpy as np +import pandas as pd +from sklearn.decomposition import PCA + +AA = "ACDEFGHIKLMNPQRSTVWY" +AA_TO_CLASS = {aa: index + 1 for index, aa in enumerate(AA)} +PAD_CLASS = 0 +EOS_CLASS = len(AA) + 1 +N_CLASSES = len(AA) + 2 +TASKS = ("sequence", "tcremp", "pgen") +SPECIALISTS = {"sequence": "r", "tcremp": "t", "pgen": "p"} + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", type=Path, required=True) + parser.add_argument("--normalizer", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=256) + parser.add_argument("--alphas", default="0.01,1,100") + parser.add_argument("--bootstrap", type=int, default=2000) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def write_json(path: Path, payload: object) -> None: + path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def sequence_targets(sequences: list[str], max_length: int) -> np.ndarray: + """Return fixed targets: PAD=0, amino acids=1..20, EOS=21.""" + targets = np.full((len(sequences), max_length + 1), PAD_CLASS, dtype=np.uint8) + for row, sequence in enumerate(sequences): + if not sequence or len(sequence) > max_length or any(aa not in AA_TO_CLASS for aa in sequence): + raise ValueError(f"Invalid benchmark sequence at row {row}: {sequence!r}") + targets[row, : len(sequence)] = [AA_TO_CLASS[aa] for aa in sequence] + targets[row, len(sequence)] = EOS_CLASS + return targets + + +def one_hot_flat(targets: np.ndarray) -> np.ndarray: + eye = np.eye(N_CLASSES, dtype=np.float32) + return eye[targets].reshape(len(targets), -1) + + +def sequence_metrics(scores: np.ndarray, targets: np.ndarray) -> tuple[dict[str, float], np.ndarray]: + predicted = scores.reshape(len(targets), targets.shape[1], N_CLASSES).argmax(axis=2) + active = np.arange(targets.shape[1])[None, :] <= (targets == EOS_CLASS).argmax(axis=1)[:, None] + correct = predicted == targets + row_error = 1.0 - (correct & active).sum(axis=1) / active.sum(axis=1) + exact = np.all(correct | ~active, axis=1) + predicted_eos = np.where((predicted == EOS_CLASS).any(axis=1), + (predicted == EOS_CLASS).argmax(axis=1), targets.shape[1]) + true_length = (targets == EOS_CLASS).argmax(axis=1) + return { + "token_accuracy": float(1.0 - row_error.mean()), + "exact_accuracy": float(exact.mean()), + "length_accuracy": float((predicted_eos == true_length).mean()), + "task_loss": float(row_error.mean()), + }, row_error.astype(np.float64) + + +def tcremp_metrics(predicted: np.ndarray, target: np.ndarray) -> tuple[dict[str, float], np.ndarray]: + residual = predicted - target + row_mse = np.mean(residual * residual, axis=1) + pred_norm = np.linalg.norm(predicted, axis=1) + target_norm = np.linalg.norm(target, axis=1) + safe = (pred_norm > 0) & (target_norm > 0) + cosine = np.zeros(len(target), dtype=np.float64) + cosine[safe] = np.sum(predicted[safe] * target[safe], axis=1) / ( + pred_norm[safe] * target_norm[safe] + ) + return { + "standardized_mse": float(row_mse.mean()), + "standardized_rmse": float(np.sqrt(row_mse.mean())), + "mean_cosine": float(cosine.mean()), + "task_loss": float(row_mse.mean()), + }, row_mse.astype(np.float64) + + +def pgen_metrics(predicted: np.ndarray, target: np.ndarray, std: float) -> tuple[dict[str, float], np.ndarray]: + residual = predicted.reshape(-1) - target.reshape(-1) + squared = residual * residual + raw = residual * std + return { + "standardized_mse": float(squared.mean()), + "standardized_rmse": float(np.sqrt(squared.mean())), + "raw_rmse_log10_pgen_1mm": float(np.sqrt(np.mean(raw * raw))), + "raw_mae_log10_pgen_1mm": float(np.mean(np.abs(raw))), + "task_loss": float(squared.mean()), + }, squared.astype(np.float64) + + +def standardize_representation( + array: np.ndarray, train_indices: np.ndarray +) -> tuple[np.ndarray, dict[str, object]]: + mean = np.asarray(array[train_indices], dtype=np.float64).mean(axis=0) + std = np.asarray(array[train_indices], dtype=np.float64).std(axis=0) + zero = std < 1e-8 + std[zero] = 1.0 + result = (np.asarray(array, dtype=np.float32) - mean.astype(np.float32)) / std.astype(np.float32) + if not np.isfinite(result).all(): + raise ValueError("Non-finite standardized representation.") + return result.astype(np.float32), { + "train_only": True, + "zero_variance_features": int(zero.sum()), + "dimension": int(result.shape[1]), + } + + +def composition_features( + table: pd.DataFrame, + include_vj: bool, + fit_indices: np.ndarray | None = None, +) -> tuple[np.ndarray, dict[str, object]]: + sequences = table["junction_aa"].astype(str).tolist() + values = np.zeros((len(table), len(AA) + 1), dtype=np.float32) + for row, sequence in enumerate(sequences): + values[row, : len(AA)] = [sequence.count(aa) / len(sequence) for aa in AA] + values[row, -1] = len(sequence) / 40.0 + columns = [f"fraction_{aa}" for aa in AA] + ["length_over_40"] + if include_vj: + if not {"v_call", "j_call"}.issubset(table.columns): + raise ValueError("V/J control requested but benchmark lacks v_call/j_call.") + if fit_indices is None: + raise ValueError("V/J vocabulary must be fitted from explicit train indices.") + categoricals = table[["v_call", "j_call"]].fillna("").astype(str) + encoded_parts = [] + for field, prefix in (("v_call", "v"), ("j_call", "j")): + vocabulary = sorted(set(categoricals.iloc[fit_indices][field])) + mapping = {value: index for index, value in enumerate(vocabulary)} + encoded = np.zeros((len(table), len(vocabulary)), dtype=np.float32) + for row, value in enumerate(categoricals[field]): + index = mapping.get(value) + if index is not None: + encoded[row, index] = 1.0 + encoded_parts.append(encoded) + columns.extend([f"{prefix}_{value}" for value in vocabulary]) + values = np.concatenate([values, *encoded_parts], axis=1) + return values, {"columns": columns, "dimension": len(columns), "sequence_only": not include_vj} + + +def append_intercept(x: np.ndarray) -> np.ndarray: + return np.concatenate([x, np.ones((len(x), 1), dtype=x.dtype)], axis=1) + + +def ridge_weights(x: np.ndarray, y: np.ndarray, alpha: float) -> np.ndarray: + xa = append_intercept(np.asarray(x, dtype=np.float64)) + gram = xa.T @ xa + penalty = np.eye(gram.shape[0], dtype=np.float64) * alpha + penalty[-1, -1] = 0.0 + return np.linalg.solve(gram + penalty, xa.T @ np.asarray(y, dtype=np.float64)) + + +def ridge_predict(x: np.ndarray, weights: np.ndarray) -> np.ndarray: + return append_intercept(np.asarray(x, dtype=np.float64)) @ weights + + +def fit_probe( + x: np.ndarray, + train: np.ndarray, + val: np.ndarray, + test: np.ndarray, + target: np.ndarray, + alphas: list[float], + score, +) -> tuple[float, np.ndarray, np.ndarray, dict[str, float]]: + chosen: tuple[float, float, np.ndarray] | None = None + trace = {} + xa = append_intercept(np.asarray(x[train], dtype=np.float64)) + gram = xa.T @ xa + cross = xa.T @ np.asarray(target[train], dtype=np.float64) + for alpha in alphas: + penalty = np.eye(gram.shape[0], dtype=np.float64) * alpha + penalty[-1, -1] = 0.0 + weights = np.linalg.solve(gram + penalty, cross) + val_pred = ridge_predict(x[val], weights) + loss = float(score(val_pred, val)) + trace[str(alpha)] = loss + if chosen is None or (loss, alpha) < (chosen[0], chosen[1]): + chosen = (loss, alpha, weights) + assert chosen is not None + return chosen[1], ridge_predict(x[val], chosen[2]), ridge_predict(x[test], chosen[2]), trace + + +def aggregate_losses( + losses: dict[str, float], specialist: dict[str, float], null: dict[str, float] +) -> dict[str, object]: + regret = {} + skill = {} + within = {} + for task in TASKS: + gap = null[task] - specialist[task] + if not np.isfinite(gap) or gap <= 0: + raise ValueError(f"Invalid validation specialist/null gap for {task}: {gap}") + regret[task] = float((losses[task] - specialist[task]) / gap) + skill[task] = float(np.clip((null[task] - losses[task]) / gap, 0.0, 1.0)) + within[task] = bool(losses[task] <= 1.05 * specialist[task]) + return { + "normalized_regret_by_task": regret, + "mean_normalized_regret": float(np.mean(list(regret.values()))), + "worst_task_normalized_regret": float(max(regret.values())), + "fixed_reference_hypervolume": float(np.prod(list(skill.values()))), + "tasks_within_5pct_of_specialist_loss": int(sum(within.values())), + "within_5pct_by_task": within, + } + + +def bootstrap_aggregate_deltas( + per_row: dict[str, dict[str, np.ndarray]], + specialist: dict[str, float], + null: dict[str, float], + replicates: int, + seed: int, +) -> dict[str, object]: + rng = np.random.default_rng(seed) + n = len(next(iter(next(iter(per_row.values())).values()))) + output = {} + for comparator in sorted(set(per_row) - {"rtp"}): + mean_delta = np.empty(replicates, dtype=np.float64) + worst_delta = np.empty(replicates, dtype=np.float64) + task_delta = {task: np.empty(replicates, dtype=np.float64) for task in TASKS} + for replicate in range(replicates): + sample = rng.integers(0, n, n) + aggregates = {} + for name in ("rtp", comparator): + losses = {task: float(per_row[name][task][sample].mean()) for task in TASKS} + aggregates[name] = aggregate_losses(losses, specialist, null) + mean_delta[replicate] = (aggregates["rtp"]["mean_normalized_regret"] + - aggregates[comparator]["mean_normalized_regret"]) + worst_delta[replicate] = (aggregates["rtp"]["worst_task_normalized_regret"] + - aggregates[comparator]["worst_task_normalized_regret"]) + for task in TASKS: + task_delta[task][replicate] = ( + per_row["rtp"][task][sample].mean() - per_row[comparator][task][sample].mean() + ) + output[comparator] = { + "orientation": "RTP minus comparator; negative favors RTP for all regret/loss endpoints", + "mean_normalized_regret": ci(mean_delta), + "worst_task_normalized_regret": ci(worst_delta), + "raw_task_loss": {task: ci(values) for task, values in task_delta.items()}, + } + return output + + +def ci(values: np.ndarray) -> dict[str, float]: + return { + "mean": float(values.mean()), + "lower_95": float(np.quantile(values, 0.025)), + "upper_95": float(np.quantile(values, 0.975)), + } + + +def file_manifest(paths: list[Path]) -> dict[str, dict[str, object]]: + return {str(path): {"sha256": sha256(path), "bytes": path.stat().st_size} for path in paths} + + +def main() -> None: + # Keep statistical helpers importable in lightweight local test environments + # that do not have the cluster's PyTorch runtime. + from benchmark.evaluate_vdjdb_frozen import ( + extract_embeddings, + parse_models, + validate_run_configs, + ) + from irrm_codec.multitask_data import ( + TargetStandardizer, + load_prepared_benchmark, + select_split_indices, + ) + + args = parse_args() + started = time.time() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + alphas = sorted({float(item) for item in args.alphas.split(",")}) + if not alphas or any(alpha <= 0 for alpha in alphas): + raise ValueError("All ridge alphas must be positive.") + + table, tcremp_raw = load_prepared_benchmark(args.data_dir) + train = select_split_indices(table, args.data_dir, "train") + val = select_split_indices(table, args.data_dir, "val") + test = select_split_indices(table, args.data_dir, "test") + if set(train) & set(val) or set(train) & set(test) or set(val) & set(test): + raise ValueError("Locked manifests overlap.") + normalizer = TargetStandardizer.load(args.normalizer) + if normalizer.pgen_target != "log10_pgen_1mm" or normalizer.train_rows != len(train): + raise ValueError("Locked train-only normalizer does not match requested target/split.") + tcremp_target = ((np.asarray(tcremp_raw, dtype=np.float32) - normalizer.tcremp_mean) + / normalizer.tcremp_std).astype(np.float32) + pgen_target = ((table["log10_pgen_1mm"].to_numpy(dtype=np.float32) - normalizer.pgen_mean) + / normalizer.pgen_std).astype(np.float32)[:, None] + seq_target = sequence_targets(table["junction_aa"].astype(str).tolist(), 40) + seq_one_hot = one_hot_flat(seq_target) + + models = parse_models(args.model) + model_config, model_report = validate_run_configs(models) + if model_config.latent_dim != 128 or model_config.max_sequence_len != 40: + raise ValueError("This preregistration requires the matched 128-D, length-40 models.") + cohort = table[["junction_aa"]].rename(columns={"junction_aa": "cdr3"}) + embeddings, extraction = extract_embeddings( + cohort, models, model_config, args.tokenizer, args.batch_size, args.output_dir, + ) + representations: dict[str, np.ndarray] = dict(embeddings) + concat = np.concatenate([embeddings[name] for name in ("r", "t", "p")], axis=1) + representations["concat_r_t_p"] = concat + pca = PCA(n_components=128, svd_solver="randomized", random_state=args.seed) + pca.fit(concat[train]) + representations["pca128_concat_r_t_p"] = pca.transform(concat).astype(np.float32) + comp, comp_meta = composition_features(table, include_vj=False) + comp_vj, comp_vj_meta = composition_features(table, include_vj=True, fit_indices=train) + representations["composition_length"] = comp + representations["composition_length_vj"] = comp_vj + + representation_meta = {} + results = {} + per_row = {} + validation_losses = {} + test_losses = {} + for name, raw in representations.items(): + x, scaling = standardize_representation(raw, train) + sequence_alpha, sequence_val_pred, sequence_test_pred, sequence_trace = fit_probe( + x, train, val, test, seq_one_hot, alphas, + lambda pred, indices: sequence_metrics(pred, seq_target[indices])[0]["task_loss"], + ) + t_alpha, t_val_pred, t_test_pred, t_trace = fit_probe( + x, train, val, test, tcremp_target, alphas, + lambda pred, indices: tcremp_metrics(pred, tcremp_target[indices])[0]["task_loss"], + ) + p_alpha, p_val_pred, p_test_pred, p_trace = fit_probe( + x, train, val, test, pgen_target, alphas, + lambda pred, indices: pgen_metrics(pred, pgen_target[indices], normalizer.pgen_std)[0]["task_loss"], + ) + seq_val, _ = sequence_metrics(sequence_val_pred, seq_target[val]) + seq_test, seq_rows = sequence_metrics(sequence_test_pred, seq_target[test]) + t_val, _ = tcremp_metrics(t_val_pred, tcremp_target[val]) + t_test, t_rows = tcremp_metrics(t_test_pred, tcremp_target[test]) + p_val, _ = pgen_metrics(p_val_pred, pgen_target[val], normalizer.pgen_std) + p_test, p_rows = pgen_metrics(p_test_pred, pgen_target[test], normalizer.pgen_std) + validation_losses[name] = { + "sequence": seq_val["task_loss"], "tcremp": t_val["task_loss"], "pgen": p_val["task_loss"], + } + test_losses[name] = { + "sequence": seq_test["task_loss"], "tcremp": t_test["task_loss"], "pgen": p_test["task_loss"], + } + per_row[name] = {"sequence": seq_rows, "tcremp": t_rows, "pgen": p_rows} + dim = x.shape[1] + results[name] = { + "validation": {"sequence": seq_val, "tcremp": t_val, "pgen": p_val}, + "test": {"sequence": seq_test, "tcremp": t_test, "pgen": p_test}, + "selected_alpha_validation_only": { + "sequence": sequence_alpha, "tcremp": t_alpha, "pgen": p_alpha, + }, + "validation_alpha_trace": { + "sequence": sequence_trace, "tcremp": t_trace, "pgen": p_trace, + }, + "probe_parameter_counts": { + "sequence": int((dim + 1) * seq_one_hot.shape[1]), + "tcremp": int((dim + 1) * tcremp_target.shape[1]), + "pgen": int(dim + 1), + }, + } + representation_meta[name] = {**scaling} + del x + + # Train-derived constant probes are the fixed null representation. + majority = np.zeros((len(val), seq_target.shape[1] * N_CLASSES), dtype=np.float32) + majority_test = np.zeros((len(test), seq_target.shape[1] * N_CLASSES), dtype=np.float32) + train_majority = np.apply_along_axis(lambda x: np.bincount(x, minlength=N_CLASSES).argmax(), 0, + seq_target[train]) + for position, cls in enumerate(train_majority): + majority[:, position * N_CLASSES + cls] = 1 + majority_test[:, position * N_CLASSES + cls] = 1 + null_val_seq, _ = sequence_metrics(majority, seq_target[val]) + null_test_seq, null_seq_rows = sequence_metrics(majority_test, seq_target[test]) + zero_t_val = np.zeros_like(tcremp_target[val]) + zero_t_test = np.zeros_like(tcremp_target[test]) + null_val_t, _ = tcremp_metrics(zero_t_val, tcremp_target[val]) + null_test_t, null_t_rows = tcremp_metrics(zero_t_test, tcremp_target[test]) + zero_p_val = np.zeros_like(pgen_target[val]) + zero_p_test = np.zeros_like(pgen_target[test]) + null_val_p, _ = pgen_metrics(zero_p_val, pgen_target[val], normalizer.pgen_std) + null_test_p, null_p_rows = pgen_metrics(zero_p_test, pgen_target[test], normalizer.pgen_std) + validation_null = {"sequence": null_val_seq["task_loss"], "tcremp": null_val_t["task_loss"], + "pgen": null_val_p["task_loss"]} + test_null = {"sequence": null_test_seq["task_loss"], "tcremp": null_test_t["task_loss"], + "pgen": null_test_p["task_loss"]} + per_row["constant_null"] = {"sequence": null_seq_rows, "tcremp": null_t_rows, "pgen": null_p_rows} + validation_specialist = {task: validation_losses[name][task] for task, name in SPECIALISTS.items()} + for name in results: + results[name]["validation_aggregate"] = aggregate_losses( + validation_losses[name], validation_specialist, validation_null, + ) + # Validation-defined reference and scale are intentionally reused on test. + results[name]["test_aggregate_validation_fixed_scale"] = aggregate_losses( + test_losses[name], validation_specialist, validation_null, + ) + + parameter_counts = {name: int(report["parameter_count"]) for name, report in model_report.items()} + for name in model_report: + representation_meta[name].update({ + "encoder_count": 1, "encoder_parameter_count": parameter_counts[name], + "representation_dimension": 128, + }) + representation_meta["concat_r_t_p"].update({ + "encoder_count": 3, + "encoder_parameter_count": sum(parameter_counts[name] for name in ("r", "t", "p")), + "representation_dimension": 384, + }) + representation_meta["pca128_concat_r_t_p"].update({ + "encoder_count": 3, + "encoder_parameter_count": sum(parameter_counts[name] for name in ("r", "t", "p")), + "representation_dimension": 128, + "train_only_pca_parameters": int(pca.components_.size + pca.mean_.size), + "train_explained_variance_ratio": float(pca.explained_variance_ratio_.sum()), + }) + representation_meta["composition_length"].update({ + "encoder_count": 0, "encoder_parameter_count": 0, **comp_meta, + }) + representation_meta["composition_length_vj"].update({ + "encoder_count": 0, "encoder_parameter_count": 0, **comp_vj_meta, + "annotation_aware_modality": True, + }) + + bootstrap = bootstrap_aggregate_deltas( + {name: per_row[name] for name in results}, validation_specialist, validation_null, + args.bootstrap, args.seed + 1000, + ) + input_paths = [ + args.data_dir / "dataset.parquet", args.data_dir / "embeddings.npy", + args.data_dir / "manifests" / "train.tsv", args.data_dir / "manifests" / "val.tsv", + args.data_dir / "manifests" / "test.tsv", args.normalizer, args.tokenizer, + *[path for pair in models.values() for path in pair], + ] + payload = { + "status": "complete", + "study": "frozen DATA-ANCHOR latent sufficiency with fresh linear probes", + "selection": "ridge alpha selected on validation; test evaluated once; all models reported", + "fixed_specialists": SPECIALISTS, + "task_loss_orientation": "lower is better: sequence token error, TCRemP standardized MSE, pgen standardized MSE", + "aggregate_definition": { + "regret": "(loss - fixed validation specialist loss)/(validation constant-null loss - validation specialist loss)", + "hypervolume": "product over tasks of clipped (validation-null - loss)/(validation-null - validation-specialist)", + "test_scale": "validation specialist and null values reused unchanged", + }, + "split_rows": {"train": len(train), "val": len(val), "test": len(test)}, + "split_overlap": 0, + "alphas": alphas, + "models": model_report, + "embedding_extraction": extraction, + "representations": representation_meta, + "validation_null_losses": validation_null, + "test_null_losses_descriptive": test_null, + "validation_specialist_losses": validation_specialist, + "results": results, + "paired_test_clonotype_bootstrap": bootstrap, + "bootstrap_replicates": args.bootstrap, + "limitations": [ + "All encoders are single seed 42; bootstrap intervals do not quantify training-seed variability.", + "Linear-probe sufficiency does not establish causal biological usefulness.", + "The V/J control is annotation-aware and is not an equivalent sequence-only inference condition.", + ], + "runtime_seconds": float(time.time() - started), + "slurm": {"job_id": os.environ.get("SLURM_JOB_ID"), "node": os.environ.get("SLURMD_NODENAME")}, + "inputs": file_manifest(input_paths), + "model_config": asdict(model_config), + } + results_path = args.output_dir / "RESULTS.json" + write_json(results_path, payload) + summary_rows = [] + for name, result in results.items(): + row = {"representation": name} + for task in TASKS: + row[f"val_{task}_loss"] = result["validation"][task]["task_loss"] + row[f"test_{task}_loss"] = result["test"][task]["task_loss"] + row.update({f"test_{key}": value for key, value in + result["test_aggregate_validation_fixed_scale"].items() + if isinstance(value, (int, float))}) + summary_rows.append(row) + summary_path = args.output_dir / "summary.tsv" + pd.DataFrame(summary_rows).to_csv(summary_path, sep="\t", index=False) + outputs = file_manifest([path for path in args.output_dir.iterdir() if path.is_file()]) + write_json(args.output_dir / "OUTPUT_HASHES.json", outputs) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_reconstruction_substitutions.py b/benchmark/evaluate_reconstruction_substitutions.py new file mode 100644 index 0000000..15a6f6d --- /dev/null +++ b/benchmark/evaluate_reconstruction_substitutions.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python +"""Evaluate structured reconstruction substitutions for one frozen IRRM-CODEC run. + +The analysis follows the earlier inverse-model protocol, but runs autoregressive +reconstruction from a specified final multi-task checkpoint on its locked test split. +It counts only wrong amino-acid positions among target/prediction pairs of equal +length and summarizes substitutions within predefined physicochemical groups. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from dataclasses import asdict +from pathlib import Path + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import torch + +from irrm_codec.multitask_data import ( + MultiTaskBenchmarkDataset, + build_multitask_dataloader, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, +) +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import decode + + +AA_ORDER = list("CSTAGPDEQNHRKMILVWYF") +AA_GROUPS = { + "C": set("C"), + "STAGP": set("STAGP"), + "DEQN": set("DEQN"), + "HRK": set("HRK"), + "MILV": set("MILV"), + "WYF": set("WYF"), +} +AA_TO_GROUP = {aa: name for name, aas in AA_GROUPS.items() for aa in aas} +GROUP_BOUNDARIES = np.cumsum([len(group) for group in AA_GROUPS.values()])[:-1] + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--data-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--checkpoint", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=64) + parser.add_argument("--num-workers", type=int, default=8) + parser.add_argument("--device", choices=("cpu", "cuda"), default="cuda") + return parser.parse_args() + + +def save_figure(matrix: pd.DataFrame, output_path: Path) -> None: + fig, ax = plt.subplots(figsize=(9, 7.5)) + image = ax.imshow(matrix.to_numpy(), cmap="Greys") + fig.colorbar(image, ax=ax, label="Wrong aligned positions") + ax.set_xticks(np.arange(len(AA_ORDER)), AA_ORDER) + ax.set_yticks(np.arange(len(AA_ORDER)), AA_ORDER) + for boundary in GROUP_BOUNDARIES: + ax.axhline(boundary - 0.5, color="black", linewidth=1.5) + ax.axvline(boundary - 0.5, color="black", linewidth=1.5) + ax.set_xlabel("Predicted amino acid") + ax.set_ylabel("Target amino acid") + ax.set_title("RTP / DATA-ANCHOR: substitution errors on locked TRB test split") + fig.tight_layout() + fig.savefig(output_path.with_suffix(".png"), dpi=240, bbox_inches="tight") + fig.savefig(output_path.with_suffix(".svg"), bbox_inches="tight") + fig.savefig(output_path.with_suffix(".pdf"), bbox_inches="tight") + plt.close(fig) + + +def main() -> None: + args = parse_args() + if args.batch_size < 1: + raise ValueError("batch-size must be positive") + if args.device == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA requested but unavailable") + for path in (args.data_dir / "READY.json", args.tokenizer, args.checkpoint): + if not path.is_file(): + raise FileNotFoundError(path) + + ready = json.loads((args.data_dir / "READY.json").read_text(encoding="utf-8")) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Benchmark READY.json is not accepting") + checkpoint = torch.load(args.checkpoint, map_location="cpu", weights_only=False) + config = IRRMCodecConfig(**checkpoint["model_config"]) + tokenizer_info = checkpoint["tokenizer"] + if tokenizer_info["type"] != "data_anchor": + raise ValueError(f"Expected a DATA-ANCHOR checkpoint, got {tokenizer_info['type']!r}") + tokenizer = resolve_encoder_tokenizer("data_anchor", str(args.tokenizer)) + if tokenizer.vocab_size != config.input_vocab_size: + raise ValueError("Tokenizer vocabulary differs from checkpoint input embedding") + + table, embeddings = load_prepared_benchmark(args.data_dir) + test_indices = select_split_indices(table, args.data_dir, "test") + dataset = MultiTaskBenchmarkDataset( + table, embeddings, test_indices, tokenizer, "log10_pgen_1mm", config.max_sequence_len + ) + device = torch.device(args.device) + loader = build_multitask_dataloader( + dataset, args.batch_size, shuffle=False, num_workers=args.num_workers, pin_memory=device.type == "cuda" + ) + model = IRRMCodecTransformer(config).to(device) + model.load_state_dict(checkpoint["model_state"], strict=True) + model.eval() + + matrix = pd.DataFrame(0, index=AA_ORDER, columns=AA_ORDER, dtype=np.int64) + total_sequences = 0 + exact_sequences = 0 + length_matched_sequences = 0 + length_mismatched_sequences = 0 + wrong_positions = 0 + within_group = 0 + between_group = 0 + unexpected_residues = 0 + + with torch.inference_mode(): + for batch in loader: + tokens = batch["encoder_tokens"].to(device, non_blocking=True) + mask = batch["encoder_mask"].to(device, non_blocking=True) + generated = model.reconstruct(tokens, mask).cpu().numpy() + predictions = [decode(row.tolist()) for row in generated] + for target, prediction in zip(batch["sequence"], predictions): + total_sequences += 1 + if target == prediction: + exact_sequences += 1 + if len(target) != len(prediction): + length_mismatched_sequences += 1 + continue + length_matched_sequences += 1 + for target_aa, predicted_aa in zip(target, prediction): + if target_aa == predicted_aa: + continue + if target_aa not in AA_TO_GROUP or predicted_aa not in AA_TO_GROUP: + unexpected_residues += 1 + continue + matrix.loc[target_aa, predicted_aa] += 1 + wrong_positions += 1 + if AA_TO_GROUP[target_aa] == AA_TO_GROUP[predicted_aa]: + within_group += 1 + else: + between_group += 1 + + if total_sequences != len(test_indices): + raise RuntimeError(f"Observed {total_sequences} sequences, expected {len(test_indices)}") + if wrong_positions != within_group + between_group: + raise RuntimeError("Substitution counts are inconsistent") + args.output_dir.mkdir(parents=True, exist_ok=False) + matrix.to_csv(args.output_dir / "substitution_matrix.tsv", sep="\t") + summary = { + "status": "complete", + "analysis": "locked_test_autoregressive_substitution_errors", + "checkpoint": str(args.checkpoint), + "checkpoint_sha256": sha256(args.checkpoint), + "data_dir": str(args.data_dir), + "benchmark_ready_sha256": sha256(args.data_dir / "READY.json"), + "tokenizer": str(args.tokenizer), + "tokenizer_sha256": sha256(args.tokenizer), + "model_config": asdict(config), + "test_sequences": total_sequences, + "exact_sequences": exact_sequences, + "exact_match": exact_sequences / total_sequences, + "length_matched_sequences": length_matched_sequences, + "length_mismatched_sequences": length_mismatched_sequences, + "wrong_aligned_positions": wrong_positions, + "within_group_errors": within_group, + "between_group_errors": between_group, + "within_group_fraction": within_group / wrong_positions if wrong_positions else None, + "between_group_fraction": between_group / wrong_positions if wrong_positions else None, + "unexpected_residue_errors": unexpected_residues, + "groups": {name: "".join(sorted(aas)) for name, aas in AA_GROUPS.items()}, + "note": "Only incorrect aligned positions from equal-length target/prediction pairs enter the matrix.", + } + (args.output_dir / "RESULTS.json").write_text(json.dumps(summary, indent=2, sort_keys=True) + "\n", encoding="utf-8") + save_figure(matrix, args.output_dir / "substitution_confusion") + print(json.dumps(summary, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_rtp_error_analysis.py b/benchmark/evaluate_rtp_error_analysis.py new file mode 100644 index 0000000..d8e9eef --- /dev/null +++ b/benchmark/evaluate_rtp_error_analysis.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python +"""Locked-test error analysis for the DATA-ANCHOR RTP checkpoint. + +Produces reconstruction and pgen error stratified by CDR3 length, relative +position profiles, a grouped amino-acid substitution matrix, and an empirical +BLOSUM62 comparison. Edit distance is used for the primary residue error rate +so insertions/deletions are not silently omitted; substitution analyses retain +the explicitly labelled equal-length, aligned-position definition. +""" +from __future__ import annotations + +import argparse, hashlib, json +from collections import Counter, defaultdict +from dataclasses import asdict +from pathlib import Path + +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import torch +from Bio.Align import substitution_matrices + +from irrm_codec.multitask_data import (MultiTaskBenchmarkDataset, TargetStandardizer, + build_multitask_dataloader, load_prepared_benchmark, resolve_encoder_tokenizer, select_split_indices) +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import decode + +AA_ORDER = list("CSTAGPDEQNHRKMILVWYF") +GROUPS = ["C", "STAGP", "DEQN", "HRK", "MILV", "WYF"] +BOUNDARIES = np.cumsum([len(x) for x in GROUPS])[:-1] + +def sha256(path): + h = hashlib.sha256() + with Path(path).open("rb") as f: + for b in iter(lambda: f.read(1048576), b""): h.update(b) + return h.hexdigest() + +def edit_distance(a, b): + prev = list(range(len(b) + 1)) + for i, x in enumerate(a, 1): + cur = [i] + for j, y in enumerate(b, 1): cur.append(min(prev[j] + 1, cur[-1] + 1, prev[j-1] + (x != y))) + prev = cur + return prev[-1] + +def args(): + p = argparse.ArgumentParser(description=__doc__) + for n in ("data-dir", "tokenizer", "checkpoint", "output-dir"): p.add_argument("--" + n, type=Path, required=True) + p.add_argument("--batch-size", type=int, default=64); p.add_argument("--num-workers", type=int, default=8) + p.add_argument("--device", choices=("cpu", "cuda"), default="cuda") + return p.parse_args() + +def rate_rows(items): + rows = [] + for length, x in sorted(items.items()): + n=x["n"] + rows.append({"cdr3_length": length, "n_sequences": n, "exact_sequences": x["exact"], + "sequence_error_rate": 1-x["exact"]/n, "total_target_residues": x["res"], + "edit_errors": x["edit"], "residue_error_rate": x["edit"]/x["res"], + "mean_abs_log10_pgen_error": np.mean(x["pabs"]), "median_abs_log10_pgen_error": np.median(x["pabs"]), + "mean_signed_log10_pgen_error": np.mean(x["psigned"]), "mean_true_log10_pgen": np.mean(x["truep"])}) + return pd.DataFrame(rows) + +def save_figures(out, matrix, length, pos, exact): + plt.rcParams.update({"font.size": 9, "axes.spines.top": False, "axes.spines.right": False}) + fig, ax = plt.subplots(figsize=(8.2, 6.8)); im=ax.imshow(matrix, cmap="Greys"); fig.colorbar(im, ax=ax, label="Wrong aligned positions") + ax.set(xticks=range(20), xticklabels=AA_ORDER, yticks=range(20), yticklabels=AA_ORDER, xlabel="Predicted amino acid", ylabel="True amino acid", title="RTP reconstruction substitution errors") + for x in BOUNDARIES: ax.axhline(x-.5,color="black",lw=1.25); ax.axvline(x-.5,color="black",lw=1.25) + fig.tight_layout(); [fig.savefig((out/"figure_error_substitution_matrix").with_suffix("."+s), dpi=300 if s=="png" else None, bbox_inches="tight") for s in ("png","svg","pdf")]; plt.close(fig) + fig, ax = plt.subplots(2,1,figsize=(8,6.4),sharex=True); x=length.cdr3_length + ax[0].plot(x,100*length.sequence_error_rate,"o-",label="Sequence error",color="#332288"); ax[0].plot(x,100*length.residue_error_rate,"o-",label="Residue error (edit-aware)",color="#EE6677"); ax[0].set(ylabel="Error rate (%)",title="Reconstruction error increases with CDR3 length"); ax[0].legend(); ax[1].bar(x,length.n_sequences,color="#88CCEE"); ax[1].set(xlabel="CDR3 length (aa)",ylabel="Test sequences (N)") + for a in ax: a.grid(axis="y",color="#ddd"); + fig.tight_layout(); [fig.savefig((out/"figure_error_reconstruction_by_length").with_suffix("."+s),dpi=300 if s=="png" else None,bbox_inches="tight") for s in ("png","svg","pdf")]; plt.close(fig) + fig, ax = plt.subplots(figsize=(8,4.5)); + for g, z in pos.groupby("length_group", sort=False): ax.plot(z.relative_bin+1,100*z.error_rate,"o-",label=g) + ax.set(xticks=range(1,11),xlabel="Relative CDR3 position decile (N → C)",ylabel="Aligned residue error (%)",title="Central reconstruction errors persist within length strata"); ax.grid(axis="y",color="#ddd"); ax.legend(title="CDR3 length"); fig.tight_layout(); [fig.savefig((out/"figure_error_relative_position").with_suffix("."+s),dpi=300 if s=="png" else None,bbox_inches="tight") for s in ("png","svg","pdf")]; plt.close(fig) + fig, ax = plt.subplots(2,1,figsize=(8,6.4),sharex=True); ax[0].plot(x,length.mean_abs_log10_pgen_error,"o-",color="#117733"); ax[0].set(ylabel="Mean absolute log10(pgen) error",title="pgen error by CDR3 length"); ax[1].bar(x,length.n_sequences,color="#88CCEE"); ax[1].set(xlabel="CDR3 length (aa)",ylabel="Test sequences (N)") + for a in ax: a.grid(axis="y",color="#ddd") + fig.tight_layout(); [fig.savefig((out/"figure_error_pgen_by_length").with_suffix("."+s),dpi=300 if s=="png" else None,bbox_inches="tight") for s in ("png","svg","pdf")]; plt.close(fig) + fig, ax=plt.subplots(figsize=(5.5,4.3)); ax.boxplot([exact.loc[exact.exact_reconstruction,"abs_log10_pgen_error"],exact.loc[~exact.exact_reconstruction,"abs_log10_pgen_error"]],tick_labels=["Exact","Non-exact"],showfliers=False); ax.set(ylabel="Absolute log10(pgen) error",title="pgen error and reconstruction outcome"); ax.grid(axis="y",color="#ddd"); fig.tight_layout(); [fig.savefig((out/"figure_error_pgen_by_reconstruction").with_suffix("."+s),dpi=300 if s=="png" else None,bbox_inches="tight") for s in ("png","svg","pdf")]; plt.close(fig) + # IEEE-ready single-column view: 3.5-in wide with an offset count axis. + plt.rcParams.update({"font.family": "Arial", "font.size": 8, "pdf.fonttype": 42, "ps.fonttype": 42}) + plot = length.loc[length.cdr3_length.between(9, 25)].copy() + x = plot.cdr3_length.to_numpy() + residue_error = 100 * plot.residue_error_rate.to_numpy() + pgen_error = plot.mean_abs_log10_pgen_error.to_numpy() + n_sequences = plot.n_sequences.to_numpy() + fig, ax1 = plt.subplots(figsize=(3.5, 3.15)) + ax3 = ax1.twinx() + ax3.spines["right"].set_position(("axes", 1.30)) + bars = ax3.bar(x, n_sequences, width=0.68, color="#BDBDBD", edgecolor="none", alpha=0.75, label="Test sequences") + ax3.set_ylim(0, n_sequences.max() * 1.16) + ax3.set_yticks([]) + ax3.spines["right"].set_visible(False) + line1, = ax1.plot(x, residue_error, marker="o", markersize=3.8, linewidth=1.35, color="#0072B2", label="Residue error") + ax1.set(xlabel="CDR3 length (aa)", ylabel="Residue (%)", xlim=(8.5, 25.5), xticks=np.arange(9, 26, 2), ylim=(0, max(15, residue_error.max() * 1.05))) + ax1.grid(axis="y", color="#D9D9D9", linewidth=0.5) + ax2 = ax1.twinx() + line2, = ax2.plot(x, pgen_error, marker="s", markersize=3.6, linewidth=1.35, linestyle="--", color="#D55E00", label=r"Mean absolute $\log_{10}(P_{gen})$ error") + ax2.set_ylabel(r"MAE $\log_{10}(P_{gen})$", labelpad=1) + ax2.set_ylim(0, max(0.62, pgen_error.max() * 1.05)) + for xi, ni in zip(x, n_sequences): + if ni < 50: + ax3.annotate(f"n={ni}", (xi, ni), textcoords="offset points", xytext=(0, 2), ha="center", fontsize=6.5, color="#4D4D4D") + ax1.legend([bars, line1, line2], ["Test sequences", "Residue error", r"Mean $|\Delta\log_{10}P_{gen}|$"], loc="upper left", frameon=False, fontsize=7, handlelength=1.8, borderpad=0.15, labelspacing=0.25) + for axis in (ax1, ax2, ax3): + axis.tick_params(direction="out", length=2.5, width=0.7, labelsize=7.5) + fig.subplots_adjust(left=0.16, right=0.82, bottom=0.18, top=0.97) + [fig.savefig((out/"figure_error_length_combined_ieee").with_suffix("."+s), dpi=600 if s=="png" else None, bbox_inches="tight") for s in ("png", "svg", "pdf")] + plt.close(fig) + +def main(): + a=args(); out=a.output_dir + if a.device=="cuda" and not torch.cuda.is_available(): raise RuntimeError("CUDA requested but unavailable") + for path in (a.data_dir/"READY.json",a.data_dir/"target_standardizer.npz",a.tokenizer,a.checkpoint): + if not path.is_file(): raise FileNotFoundError(path) + ready=json.loads((a.data_dir/"READY.json").read_text()); + if ready.get("status")!="ready" or not all(ready.get("checks",{}).values()): raise ValueError("Benchmark is not accepting") + payload=torch.load(a.checkpoint,map_location="cpu",weights_only=False); config=IRRMCodecConfig(**payload["model_config"]) + if payload["tokenizer"]["type"]!="data_anchor": raise ValueError("Expected DATA-ANCHOR checkpoint") + tok=resolve_encoder_tokenizer("data_anchor",str(a.tokenizer)); table, embeddings=load_prepared_benchmark(a.data_dir); idx=select_split_indices(table,a.data_dir,"test") + ds=MultiTaskBenchmarkDataset(table,embeddings,idx,tok,"log10_pgen_1mm",config.max_sequence_len); dev=torch.device(a.device) + loader=build_multitask_dataloader(ds,a.batch_size,False,a.num_workers,pin_memory=dev.type=="cuda") + model=IRRMCodecTransformer(config).to(dev); model.load_state_dict(payload["model_state"],strict=True); model.eval(); norm=TargetStandardizer.load(a.data_dir/"target_standardizer.npz") + bylen=defaultdict(lambda:{"n":0,"exact":0,"res":0,"edit":0,"pabs":[],"psigned":[],"truep":[]}); mat=np.zeros((20,20),dtype=int); pos=defaultdict(lambda:[0,0]); region=defaultdict(lambda:[0,0]); records=[]; scores=[]; target_errors=[]; pred_errors=[] + groups=(("≤16",lambda n:n<=16),("17–18",lambda n:17<=n<=18),("19–20",lambda n:19<=n<=20),("≥21",lambda n:n>=21)) + with torch.inference_mode(): + for batch in loader: + t=batch["encoder_tokens"].to(dev); m=batch["encoder_mask"].to(dev); generated=[decode(r.tolist()) for r in model.reconstruct(t,m).cpu().numpy()] + pred=(model(t,m)["pgen_standardized"].squeeze(-1).cpu().numpy()*norm.pgen_std+norm.pgen_mean) + for target, guess, truep, pp in zip(batch["sequence"],generated,batch["pgen_target"].numpy(),pred): + n=len(target); exact=target==guess; ed=edit_distance(target,guess); signed=float(pp-truep); item=bylen[n]; item["n"]+=1; item["exact"]+=exact; item["res"]+=n; item["edit"]+=ed; item["pabs"].append(abs(signed)); item["psigned"].append(signed); item["truep"].append(float(truep)); records.append({"cdr3_length":n,"exact_reconstruction":exact,"edit_errors":ed,"residue_error_rate":ed/n,"true_log10_pgen":float(truep),"pred_log10_pgen":float(pp),"abs_log10_pgen_error":abs(signed),"signed_log10_pgen_error":signed}) + if len(target)==len(guess): + for j,(x,y) in enumerate(zip(target,guess)): + if x!=y: + mat[AA_ORDER.index(x),AA_ORDER.index(y)]+=1; scores.append(float(substitution_matrices.load("BLOSUM62")[x,y])); target_errors.append(x); pred_errors.append(y) + for label, cond in groups: + if cond(n): + key=(label,min(9,int(j*10/n))); pos[key][0]+=1; pos[key][1]+=x!=y + r="N_edge_1_3" if j<3 else "C_edge_1_3" if j>=n-3 else "middle"; region[r][0]+=1; region[r][1]+=x!=y + rows=[] + for (g,b),(eligible,wrong) in pos.items(): rows.append({"length_group":g,"relative_bin":b,"eligible_positions":eligible,"wrong_positions":wrong,"error_rate":wrong/eligible}) + position=pd.DataFrame(rows).sort_values(["length_group","relative_bin"]); length=rate_rows(bylen); rec=pd.DataFrame(records); reg=pd.DataFrame([{"region":k,"eligible_positions":v[0],"wrong_positions":v[1],"error_rate":v[1]/v[0]} for k,v in region.items()]) + rng=np.random.default_rng(42); pred_counts=Counter(pred_errors); choices=np.array(list(pred_counts)); weights=np.array([pred_counts[x] for x in choices],float); weights/=weights.sum(); baseline=[] + for x in target_errors: + keep=choices!=x; w=weights[keep]; w/=w.sum(); baseline.append(float(substitution_matrices.load("BLOSUM62")[x,rng.choice(choices[keep],p=w)])) + bl=pd.DataFrame({"observed_blosum62":scores,"frequency_matched_random_blosum62":baseline}) + summary={"status":"complete","analysis":"locked_test_rtp_error_analysis","test_sequences":len(rec),"checkpoint_sha256":sha256(a.checkpoint),"benchmark_ready_sha256":sha256(a.data_dir/"READY.json"),"normalizer_sha256":sha256(a.data_dir/"target_standardizer.npz"),"model_config":asdict(config),"blosum62":{"observed_mean":float(np.mean(scores)),"observed_median":float(np.median(scores)),"positive_fraction":float(np.mean(np.array(scores)>0)),"baseline_mean":float(np.mean(baseline)),"baseline_median":float(np.median(baseline)),"mean_difference_observed_minus_baseline":float(np.mean(scores)-np.mean(baseline))},"pgen_abs_error":{"exact_mean":float(rec[rec.exact_reconstruction].abs_log10_pgen_error.mean()),"nonexact_mean":float(rec[~rec.exact_reconstruction].abs_log10_pgen_error.mean()),"spearman_residue_error":float(rec.residue_error_rate.corr(rec.abs_log10_pgen_error,method="spearman")),"spearman_length":float(rec.cdr3_length.corr(rec.abs_log10_pgen_error,method="spearman"))},"note":"Substitutions and position profiles include aligned equal-length predictions only. Primary residue error is Levenshtein edit distance divided by target length."} + out.mkdir(parents=True,exist_ok=False); pd.DataFrame(mat,index=AA_ORDER,columns=AA_ORDER).to_csv(out/"substitution_matrix.tsv",sep="\t"); length.to_csv(out/"summary_by_cdr3_length.tsv",sep="\t",index=False); position.to_csv(out/"relative_position_error_rates.tsv",sep="\t",index=False); reg.to_csv(out/"edge_middle_error_rates.tsv",sep="\t",index=False); rec.to_csv(out/"per_sequence_errors.tsv",sep="\t",index=False); bl.to_csv(out/"blosum62_observed_vs_frequency_matched_random.tsv",sep="\t",index=False); (out/"RESULTS.json").write_text(json.dumps(summary,indent=2,sort_keys=True)+"\n") + save_figures(out,mat,length,position,rec); print(json.dumps(summary,indent=2,sort_keys=True)) + +if __name__ == "__main__": main() diff --git a/benchmark/evaluate_rtp_reconstruction_by_length.py b/benchmark/evaluate_rtp_reconstruction_by_length.py new file mode 100644 index 0000000..a38323d --- /dev/null +++ b/benchmark/evaluate_rtp_reconstruction_by_length.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +"""Quantify frozen RTP/DATA-ANCHOR reconstruction errors by target CDR3 length.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from dataclasses import asdict +from collections import defaultdict +from pathlib import Path + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import torch + +from irrm_codec.multitask_data import MultiTaskBenchmarkDataset, build_multitask_dataloader, load_prepared_benchmark, resolve_encoder_tokenizer, select_split_indices +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import decode + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--data-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--checkpoint", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=64) + parser.add_argument("--num-workers", type=int, default=8) + parser.add_argument("--device", choices=("cpu", "cuda"), default="cuda") + return parser.parse_args() + + +def main() -> None: + args = parse_args() + if args.batch_size < 1: + raise ValueError("batch-size must be positive") + if args.device == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA requested but unavailable") + for path in (args.data_dir / "READY.json", args.tokenizer, args.checkpoint): + if not path.is_file(): + raise FileNotFoundError(path) + ready = json.loads((args.data_dir / "READY.json").read_text(encoding="utf-8")) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Benchmark READY.json is not accepting") + + payload = torch.load(args.checkpoint, map_location="cpu", weights_only=False) + config = IRRMCodecConfig(**payload["model_config"]) + if payload["tokenizer"]["type"] != "data_anchor": + raise ValueError("This evaluation is registered for DATA-ANCHOR checkpoints only") + tokenizer = resolve_encoder_tokenizer("data_anchor", str(args.tokenizer)) + if tokenizer.vocab_size != config.input_vocab_size: + raise ValueError("Tokenizer vocabulary differs from checkpoint input embedding") + table, embeddings = load_prepared_benchmark(args.data_dir) + indices = select_split_indices(table, args.data_dir, "test") + dataset = MultiTaskBenchmarkDataset(table, embeddings, indices, tokenizer, "log10_pgen_1mm", config.max_sequence_len) + device = torch.device(args.device) + loader = build_multitask_dataloader(dataset, args.batch_size, shuffle=False, num_workers=args.num_workers, pin_memory=device.type == "cuda") + model = IRRMCodecTransformer(config).to(device) + model.load_state_dict(payload["model_state"], strict=True) + model.eval() + + counts = defaultdict(lambda: {"sequences": 0, "exact": 0, "length_mismatch": 0, "aligned_positions": 0, "wrong_aligned_positions": 0}) + with torch.inference_mode(): + for batch in loader: + tokens = batch["encoder_tokens"].to(device, non_blocking=True) + mask = batch["encoder_mask"].to(device, non_blocking=True) + predictions = [decode(row.tolist()) for row in model.reconstruct(tokens, mask).cpu().numpy()] + for target, prediction in zip(batch["sequence"], predictions): + item = counts[len(target)] + item["sequences"] += 1 + item["exact"] += int(target == prediction) + if len(target) != len(prediction): + item["length_mismatch"] += 1 + continue + item["aligned_positions"] += len(target) + item["wrong_aligned_positions"] += sum(a != b for a, b in zip(target, prediction)) + + rows = [] + for length, item in sorted(counts.items()): + sequences = item["sequences"] + rows.append({ + "target_length": length, + **item, + "sequence_error_rate": 1 - item["exact"] / sequences, + "aligned_position_error_rate": item["wrong_aligned_positions"] / item["aligned_positions"] if item["aligned_positions"] else np.nan, + }) + result = pd.DataFrame(rows) + if int(result["sequences"].sum()) != len(indices): + raise RuntimeError("Processed sequence count differs from locked test split") + + args.output_dir.mkdir(parents=True, exist_ok=False) + result.to_csv(args.output_dir / "error_rates_by_target_length.tsv", sep="\t", index=False) + fig, axes = plt.subplots(1, 2, figsize=(12, 4.2)) + axes[0].plot(result["target_length"], result["sequence_error_rate"] * 100, marker="o", color="#332288") + axes[0].set_xlabel("Target CDR3 length (aa)") + axes[0].set_ylabel("Sequences not reconstructed exactly (%)") + axes[0].set_title("Sequence-level reconstruction error") + axes[1].plot(result["target_length"], result["aligned_position_error_rate"] * 100, marker="o", color="#EE6677") + axes[1].set_xlabel("Target CDR3 length (aa)") + axes[1].set_ylabel("Wrong aligned positions (%)") + axes[1].set_title("Position-level reconstruction error") + for axis in axes: + axis.grid(axis="y", color="#DDDDDD", linewidth=0.7) + axis.spines[["top", "right"]].set_visible(False) + fig.suptitle("RTP / DATA-ANCHOR reconstruction error by target CDR3 length", weight="bold") + fig.tight_layout(rect=(0, 0, 1, 0.93)) + for suffix in ("png", "svg", "pdf"): + fig.savefig((args.output_dir / "reconstruction_error_by_length").with_suffix(f".{suffix}"), dpi=240 if suffix == "png" else None, bbox_inches="tight") + plt.close(fig) + summary = { + "status": "complete", + "analysis": "locked_test_autoregressive_error_by_target_cdr3_length", + "checkpoint": str(args.checkpoint), + "checkpoint_sha256": sha256(args.checkpoint), + "tokenizer_sha256": sha256(args.tokenizer), + "benchmark_ready_sha256": sha256(args.data_dir / "READY.json"), + "model_config": asdict(config), + "test_sequences": len(indices), + "length_range": [int(result["target_length"].min()), int(result["target_length"].max())], + } + (args.output_dir / "RESULTS.json").write_text(json.dumps(summary, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(json.dumps(summary, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_rtp_reconstruction_by_position.py b/benchmark/evaluate_rtp_reconstruction_by_position.py new file mode 100644 index 0000000..ccf5ef7 --- /dev/null +++ b/benchmark/evaluate_rtp_reconstruction_by_position.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +"""Map autoregressive RTP/DATA-ANCHOR reconstruction errors along CDR3 position.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from dataclasses import asdict +from pathlib import Path + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import torch + +from irrm_codec.multitask_data import ( + MultiTaskBenchmarkDataset, + build_multitask_dataloader, + load_prepared_benchmark, + resolve_encoder_tokenizer, + select_split_indices, +) +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import decode + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--data-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--checkpoint", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=64) + parser.add_argument("--num-workers", type=int, default=8) + parser.add_argument("--device", choices=("cpu", "cuda"), default="cuda") + return parser.parse_args() + + +def rate_table(counts: dict[int, list[int]], label: str) -> pd.DataFrame: + rows = [] + for position, (eligible, wrong) in sorted(counts.items()): + rows.append( + { + label: position, + "eligible_positions": eligible, + "wrong_positions": wrong, + "error_rate": wrong / eligible if eligible else np.nan, + } + ) + return pd.DataFrame(rows) + + +def save_figure(absolute: pd.DataFrame, edge: pd.DataFrame, regions: pd.DataFrame, stem: Path) -> None: + fig, axes = plt.subplots(1, 3, figsize=(15, 4.4)) + axes[0].plot(absolute["position_1based"], absolute["error_rate"] * 100, marker="o", color="#332288") + axes[0].set_xlabel("Position from N terminus") + axes[0].set_ylabel("Autoregressive error rate (%)") + axes[0].set_title("Absolute CDR3 position") + + axes[1].plot(edge["distance_from_nearest_edge"], edge["error_rate"] * 100, marker="o", color="#EE6677") + axes[1].set_xlabel("Distance from nearest CDR3 edge") + axes[1].set_ylabel("Autoregressive error rate (%)") + axes[1].set_title("Distance from either edge") + + axes[2].bar(regions["region"], regions["error_rate"] * 100, color=["#4477AA", "#CCBB44", "#66CCEE"]) + axes[2].set_ylabel("Autoregressive error rate (%)") + axes[2].set_title("First/last 3 residues versus middle") + for idx, row in regions.iterrows(): + axes[2].text(idx, row["error_rate"] * 100, f"{row['wrong_positions']}/{row['eligible_positions']}", ha="center", va="bottom", fontsize=8) + + for ax in axes: + ax.grid(axis="y", color="#DDDDDD", linewidth=0.7) + ax.spines[["top", "right"]].set_visible(False) + fig.suptitle("RTP / DATA-ANCHOR reconstruction errors along locked-test CDR3 sequences", weight="bold") + fig.tight_layout(rect=(0, 0, 1, 0.93)) + fig.savefig(stem.with_suffix(".png"), dpi=240, bbox_inches="tight") + fig.savefig(stem.with_suffix(".svg"), bbox_inches="tight") + fig.savefig(stem.with_suffix(".pdf"), bbox_inches="tight") + plt.close(fig) + + +def main() -> None: + args = parse_args() + if args.batch_size < 1: + raise ValueError("batch-size must be positive") + if args.device == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA requested but unavailable") + for path in (args.data_dir / "READY.json", args.tokenizer, args.checkpoint): + if not path.is_file(): + raise FileNotFoundError(path) + + ready = json.loads((args.data_dir / "READY.json").read_text(encoding="utf-8")) + if ready.get("status") != "ready" or not all(ready.get("checks", {}).values()): + raise ValueError("Benchmark READY.json is not accepting") + payload = torch.load(args.checkpoint, map_location="cpu", weights_only=False) + config = IRRMCodecConfig(**payload["model_config"]) + if payload["tokenizer"]["type"] != "data_anchor": + raise ValueError("This evaluation is registered for DATA-ANCHOR checkpoints only") + tokenizer = resolve_encoder_tokenizer("data_anchor", str(args.tokenizer)) + if tokenizer.vocab_size != config.input_vocab_size: + raise ValueError("Tokenizer vocabulary differs from checkpoint input embedding") + + table, embeddings = load_prepared_benchmark(args.data_dir) + indices = select_split_indices(table, args.data_dir, "test") + dataset = MultiTaskBenchmarkDataset(table, embeddings, indices, tokenizer, "log10_pgen_1mm", config.max_sequence_len) + device = torch.device(args.device) + loader = build_multitask_dataloader(dataset, args.batch_size, shuffle=False, num_workers=args.num_workers, pin_memory=device.type == "cuda") + model = IRRMCodecTransformer(config).to(device) + model.load_state_dict(payload["model_state"], strict=True) + model.eval() + + absolute: dict[int, list[int]] = {} + edge: dict[int, list[int]] = {} + region = {name: [0, 0] for name in ("N_edge_1_3", "middle", "C_edge_1_3")} + matched_sequences = 0 + mismatched_sequences = 0 + + with torch.inference_mode(): + for batch in loader: + tokens = batch["encoder_tokens"].to(device, non_blocking=True) + mask = batch["encoder_mask"].to(device, non_blocking=True) + predictions = [decode(row.tolist()) for row in model.reconstruct(tokens, mask).cpu().numpy()] + for target, prediction in zip(batch["sequence"], predictions): + if len(target) != len(prediction): + mismatched_sequences += 1 + continue + matched_sequences += 1 + for position, (target_aa, prediction_aa) in enumerate(zip(target, prediction)): + wrong = int(target_aa != prediction_aa) + absolute.setdefault(position + 1, [0, 0]) + absolute[position + 1][0] += 1 + absolute[position + 1][1] += wrong + distance = min(position, len(target) - position - 1) + edge.setdefault(distance, [0, 0]) + edge[distance][0] += 1 + edge[distance][1] += wrong + region_name = "N_edge_1_3" if position < 3 else "C_edge_1_3" if position >= len(target) - 3 else "middle" + region[region_name][0] += 1 + region[region_name][1] += wrong + + if matched_sequences + mismatched_sequences != len(indices): + raise RuntimeError("Processed sequence count differs from locked test split") + absolute_table = rate_table(absolute, "position_1based") + edge_table = rate_table(edge, "distance_from_nearest_edge") + region_table = pd.DataFrame( + [{"region": name, "eligible_positions": values[0], "wrong_positions": values[1], "error_rate": values[1] / values[0]} for name, values in region.items()] + ) + if int(region_table["wrong_positions"].sum()) != int(absolute_table["wrong_positions"].sum()): + raise RuntimeError("Position and region error totals differ") + + args.output_dir.mkdir(parents=True, exist_ok=False) + absolute_table.to_csv(args.output_dir / "absolute_position_error_rates.tsv", sep="\t", index=False) + edge_table.to_csv(args.output_dir / "edge_distance_error_rates.tsv", sep="\t", index=False) + region_table.to_csv(args.output_dir / "region_error_rates.tsv", sep="\t", index=False) + save_figure(absolute_table, edge_table, region_table, args.output_dir / "reconstruction_error_by_position") + result = { + "status": "complete", + "analysis": "locked_test_autoregressive_error_by_cdr3_position", + "checkpoint": str(args.checkpoint), + "checkpoint_sha256": sha256(args.checkpoint), + "tokenizer_sha256": sha256(args.tokenizer), + "benchmark_ready_sha256": sha256(args.data_dir / "READY.json"), + "model_config": asdict(config), + "matched_length_sequences": matched_sequences, + "mismatched_length_sequences": mismatched_sequences, + "regions": region_table.to_dict(orient="records"), + "note": "Position analysis includes only target/prediction pairs with equal sequence length.", + } + (args.output_dir / "RESULTS.json").write_text(json.dumps(result, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(json.dumps(result, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_single_aa_challenge.py b/benchmark/evaluate_single_aa_challenge.py new file mode 100644 index 0000000..2cc5e28 --- /dev/null +++ b/benchmark/evaluate_single_aa_challenge.py @@ -0,0 +1,339 @@ +"""Frozen-encoder delta benchmark on controlled one-AA substitutions.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd +from scipy.stats import pearsonr, spearmanr +from sklearn.decomposition import PCA +from sklearn.metrics import balanced_accuracy_score, f1_score, mean_absolute_error, mean_squared_error, r2_score + + +ALPHAS = (0.01, 0.1, 1.0, 10.0, 100.0) +AA = "ACDEFGHIKLMNPQRSTVWY" + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def ridge_fit(x: np.ndarray, y: np.ndarray, alpha: float) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + mean_x, std_x = x.mean(0), x.std(0) + std_x[std_x < 1e-8] = 1.0 + z = (x - mean_x) / std_x + mean_y = y.mean(0) + centered = y - mean_y + coef = np.linalg.solve(z.T @ z + alpha * np.eye(z.shape[1]), z.T @ centered) + return coef, mean_x, std_x, mean_y + + +def ridge_predict(model: tuple[np.ndarray, ...], x: np.ndarray) -> np.ndarray: + coef, mean_x, std_x, mean_y = model + return (x - mean_x) / std_x @ coef + mean_y + + +def finite_correlation(x: np.ndarray, y: np.ndarray, kind: str) -> float: + if len(x) < 2 or np.std(x) < 1e-12 or np.std(y) < 1e-12: + return 0.0 + return float((spearmanr if kind == "spearman" else pearsonr)(x, y).statistic) + + +def choose_alpha_regression(x: np.ndarray, y: np.ndarray, train: np.ndarray, val: np.ndarray) -> float: + scores = [] + scale = y[train].std(0) + scale = np.where(scale < 1e-8, 1.0, scale) + for alpha in ALPHAS: + pred = ridge_predict(ridge_fit(x[train], y[train], alpha), x[val]) + scores.append((float(np.mean(((pred - y[val]) / scale) ** 2)), alpha)) + return min(scores)[1] + + +def choose_alpha_classifier(x: np.ndarray, labels: np.ndarray, train: np.ndarray, val: np.ndarray) -> tuple[float, np.ndarray]: + # Keep the complete declared label space. A test-only rare position remains + # unlearnable (correctly scoring as an error) rather than crashing encoding. + classes = np.array(sorted(set(labels))) + mapping = {value: i for i, value in enumerate(classes)} + onehot = np.eye(len(classes))[np.array([mapping[value] for value in labels])] + scores = [] + for alpha in ALPHAS: + pred = classes[np.argmax(ridge_predict(ridge_fit(x[train], onehot[train], alpha), x[val]), axis=1)] + scores.append((-f1_score(labels[val], pred, average="macro", zero_division=0), alpha)) + return min(scores)[1], classes + + +def regression_metrics(truth: np.ndarray, pred: np.ndarray, train_truth: np.ndarray) -> dict: + scale = float(np.std(train_truth)) or 1.0 + return { + "rmse": float(np.sqrt(mean_squared_error(truth, pred))), + "nrmse_train_sd": float(np.sqrt(mean_squared_error(truth, pred)) / scale), + "mae": float(mean_absolute_error(truth, pred)), + "r2": float(r2_score(truth, pred)), + "pearson": finite_correlation(truth, pred, "pearson"), + "spearman": finite_correlation(truth, pred, "spearman"), + } + + +def tcremp_metrics(truth: np.ndarray, pred: np.ndarray, train_truth: np.ndarray) -> dict: + denom = np.linalg.norm(truth, axis=1) * np.linalg.norm(pred, axis=1) + cosine = np.divide(np.sum(truth * pred, axis=1), denom, out=np.zeros(len(truth)), where=denom > 1e-12) + scale = train_truth.std(0) + active = scale >= 1e-8 + return { + "mean_delta_cosine": float(cosine.mean()), + "median_delta_cosine": float(np.median(cosine)), + "standardized_rmse": float(np.sqrt(np.mean(((truth[:, active] - pred[:, active]) / scale[active]) ** 2))), + "raw_rmse": float(np.sqrt(np.mean((truth - pred) ** 2))), + "active_dimensions": int(active.sum()), + } + + +def rank_summary(frame: pd.DataFrame, true_pgen: np.ndarray, pred_pgen: np.ndarray, + true_t: np.ndarray, pred_t: np.ndarray, mask: np.ndarray) -> dict: + rows = np.flatnonzero(mask) + pgen_r, tcremp_r, pgen_pairs, tcremp_pairs = [], [], [], [] + for parent in sorted(frame.iloc[rows]["parent_id"].unique()): + idx = rows[frame.iloc[rows]["parent_id"].to_numpy() == parent] + if len(idx) < 2: + continue + true_te = np.linalg.norm(true_t[idx], axis=1) + pred_te = np.linalg.norm(pred_t[idx], axis=1) + pgen_r.append(finite_correlation(true_pgen[idx], pred_pgen[idx], "spearman")) + tcremp_r.append(finite_correlation(true_te, pred_te, "spearman")) + for a in range(len(idx)): + for b in range(a + 1, len(idx)): + pgen_pairs.append(np.sign(true_pgen[idx[a]] - true_pgen[idx[b]]) == np.sign(pred_pgen[idx[a]] - pred_pgen[idx[b]])) + tcremp_pairs.append(np.sign(true_te[a] - true_te[b]) == np.sign(pred_te[a] - pred_te[b])) + return { + "parent_mean_pgen_spearman": float(np.mean(pgen_r)), + "parent_mean_tcremp_effect_spearman": float(np.mean(tcremp_r)), + "pgen_pair_order_accuracy": float(np.mean(pgen_pairs)), + "tcremp_effect_pair_order_accuracy": float(np.mean(tcremp_pairs)), + "parents": len(pgen_r), + } + + +def identity_features(frame: pd.DataFrame, include_position: bool) -> np.ndarray: + result = np.zeros((len(frame), 20 + (40 if include_position else 0) + (40 if include_position else 0)), np.float64) + lookup = {aa: i for i, aa in enumerate(AA)} + for i, row in enumerate(frame.itertuples(index=False)): + result[i, lookup[row.to_aa]] += 1 + result[i, lookup[row.from_aa]] -= 1 + if include_position: + result[i, 20 + min(int(row.mutation_position_zero_based), 39)] = 1 + result[i, 60 + min(int(row.length), 39)] = 1 + return result + + +def evaluate_representation(name: str, x: np.ndarray, frame: pd.DataFrame, delta_pgen: np.ndarray, + delta_t: np.ndarray, splits: dict[str, np.ndarray]) -> tuple[dict, dict[str, np.ndarray]]: + train, val, test = (splits[key] for key in ("train", "val", "test")) + p_alpha = choose_alpha_regression(x, delta_pgen[:, None], train, val) + p_model = ridge_fit(x[train], delta_pgen[train, None], p_alpha) + p_pred = ridge_predict(p_model, x).ravel() + t_alpha = choose_alpha_regression(x, delta_t, train, val) + t_model = ridge_fit(x[train], delta_t[train], t_alpha) + t_pred = ridge_predict(t_model, x) + + classifiers = {} + class_predictions = {} + for label_name, labels in { + "mutation_position": frame["mutation_position_zero_based"].to_numpy(int), + "target_amino_acid": frame["to_aa"].astype(str).to_numpy(), + }.items(): + alpha, classes = choose_alpha_classifier(x, labels, train, val) + class_to_index = {value: i for i, value in enumerate(classes)} + onehot = np.eye(len(classes))[np.array([class_to_index[value] for value in labels])] + pred = classes[np.argmax(ridge_predict(ridge_fit(x[train], onehot[train], alpha), x), axis=1)] + classifiers[label_name] = { + "alpha": alpha, + "macro_f1": float(f1_score(labels[test], pred[test], average="macro", zero_division=0)), + "balanced_accuracy": float(balanced_accuracy_score(labels[test], pred[test])), + } + class_predictions[label_name] = pred + direction_truth = (delta_pgen > 0).astype(int) + direction_alpha, direction_classes = choose_alpha_classifier(x, direction_truth, train, val) + direction_onehot = np.eye(len(direction_classes))[direction_truth] + direction_pred = direction_classes[np.argmax(ridge_predict( + ridge_fit(x[train], direction_onehot[train], direction_alpha), x), axis=1)] + metrics = { + "representation": name, + "dimension": int(x.shape[1]), + "pgen": {"alpha": p_alpha, **regression_metrics(delta_pgen[test], p_pred[test], delta_pgen[train])}, + "tcremp": {"alpha": t_alpha, **tcremp_metrics(delta_t[test], t_pred[test], delta_t[train])}, + "mutation_identity": classifiers, + "pgen_direction": { + "alpha": direction_alpha, + "macro_f1": float(f1_score(direction_truth[test], direction_pred[test], average="macro", zero_division=0)), + "balanced_accuracy": float(balanced_accuracy_score(direction_truth[test], direction_pred[test])), + }, + "within_parent_ranking": rank_summary(frame, delta_pgen, p_pred, delta_t, t_pred, test), + } + predictions = {"pgen": p_pred, "tcremp": t_pred, + "position": class_predictions["mutation_position"], + "to_aa": class_predictions["target_amino_acid"]} + return metrics, predictions + + +def parent_bootstrap(frame: pd.DataFrame, truth_p: np.ndarray, truth_t: np.ndarray, + predictions: dict[str, dict[str, np.ndarray]], test: np.ndarray, + repeats: int, seed: int) -> dict: + parent_rows = {parent: np.flatnonzero((frame["parent_id"].to_numpy() == parent) & test) + for parent in sorted(frame.loc[test, "parent_id"].unique())} + parents = np.array(list(parent_rows), dtype=object) + rng = np.random.default_rng(seed) + result = {} + for comparator in sorted(set(predictions) - {"rtp"}): + samples = {"pgen_nrmse": [], "tcremp_one_minus_cosine": []} + for _ in range(repeats): + chosen = rng.choice(parents, size=len(parents), replace=True) + idx = np.concatenate([parent_rows[parent] for parent in chosen]) + scale = np.std(truth_p[np.flatnonzero(frame["probe_split"].to_numpy() == "train")]) or 1.0 + def score(name: str) -> tuple[float, float]: + p = float(np.sqrt(np.mean((predictions[name]["pgen"][idx] - truth_p[idx]) ** 2)) / scale) + pred, true = predictions[name]["tcremp"][idx], truth_t[idx] + denom = np.linalg.norm(pred, axis=1) * np.linalg.norm(true, axis=1) + cos = np.divide(np.sum(pred * true, axis=1), denom, out=np.zeros(len(idx)), where=denom > 1e-12) + return p, float(1 - cos.mean()) + rtp, other = score("rtp"), score(comparator) + samples["pgen_nrmse"].append(rtp[0] - other[0]) + samples["tcremp_one_minus_cosine"].append(rtp[1] - other[1]) + result[comparator] = { + metric: {"rtp_minus_comparator_mean": float(np.mean(values)), + "ci95": [float(x) for x in np.quantile(values, [0.025, 0.975])]} + for metric, values in samples.items() + } + return result + + +def bootstrap_or_disabled(frame: pd.DataFrame, truth_p: np.ndarray, truth_t: np.ndarray, + predictions: dict[str, dict[str, np.ndarray]], test: np.ndarray, + repeats: int, seed: int) -> dict: + if repeats < 0: + raise ValueError("bootstrap repeats must be non-negative") + if repeats == 0: + return { + "status": "disabled_by_user", + "repeats": 0, + "uncertainty_available": False, + "significance_claim_permitted": False, + } + return { + "status": "enabled", + "repeats": repeats, + "uncertainty_available": True, + "significance_claim_permitted": True, + "comparisons": parent_bootstrap(frame, truth_p, truth_t, predictions, test, repeats, seed), + } + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--prepared", type=Path, required=True) + parser.add_argument("--targets", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--bootstrap", type=int, default=0) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + parents = pd.read_csv(args.prepared / "parents.tsv", sep="\t") + frame = pd.read_csv(args.targets / "targets.tsv", sep="\t") + target_manifest = json.loads((args.targets / "TARGETS.json").read_text()) + if target_manifest["status"] != "accepted_for_frozen_delta_evaluation": + raise ValueError("Target gate did not accept this challenge.") + parent_t = np.load(args.prepared / "parent_tcremp.npy", mmap_mode="r") + mutant_t = np.load(args.targets / "mutant_tcremp.npy", mmap_mode="r") + parent_row = {identifier: i for i, identifier in enumerate(parents["parent_id"].astype(str))} + pidx = np.array([parent_row[value] for value in frame["parent_id"].astype(str)]) + delta_t = np.asarray(mutant_t, np.float64) - np.asarray(parent_t[pidx], np.float64) + parent_pgen = parents.set_index("parent_id")["log10_pgen_1mm"] + delta_pgen = frame["log10_pgen_1mm"].to_numpy(float) - parent_pgen.loc[frame["parent_id"]].to_numpy(float) + if not np.isfinite(delta_t).all() or not np.isfinite(delta_pgen).all(): + raise ValueError("Nonfinite delta targets.") + + from benchmark.evaluate_vdjdb_frozen import extract_embeddings, parse_models, validate_run_configs + models = parse_models(args.model) + config, parity = validate_run_configs(models) + sequences = pd.DataFrame({"cdr3": pd.concat((parents["junction_aa"], frame["junction_aa"]), ignore_index=True)}) + embedded, extraction = extract_embeddings(sequences, models, config, args.tokenizer, + args.batch_size, args.output_dir) + n_parent = len(parents) + representations = {name: array[n_parent:] - array[:n_parent][pidx] for name, array in embedded.items()} + representations["concat_rtp"] = np.concatenate([representations[name] for name in ("r", "t", "p")], axis=1) + split_masks = {name: frame["probe_split"].to_numpy() == name for name in ("train", "val", "test")} + pca = PCA(n_components=128, random_state=args.seed).fit(representations["concat_rtp"][split_masks["train"]]) + representations["pca_concat_rtp_128"] = pca.transform(representations["concat_rtp"]) + representations["delta_composition_control"] = identity_features(frame, False) + representations["mutation_identity_control"] = identity_features(frame, True) + + metrics, predictions = {}, {} + for name, array in representations.items(): + metrics[name], predictions[name] = evaluate_representation( + name, np.asarray(array, np.float64), frame, delta_pgen, delta_t, split_masks + ) + seven = ["r", "t", "p", "rt", "rp", "tp", "rtp"] + errors = { + name: { + "sequence": float(1 - np.mean([metrics[name]["mutation_identity"][key]["macro_f1"] + for key in ("mutation_position", "target_amino_acid")])), + "tcremp": float(1 - metrics[name]["tcremp"]["mean_delta_cosine"]), + "pgen": float(metrics[name]["pgen"]["nrmse_train_sd"]), + } for name in seven + } + best = {task: min(errors[name][task] for name in seven) for task in ("sequence", "tcremp", "pgen")} + aggregate = {} + for name in seven: + regrets = {task: (errors[name][task] - best[task]) / max(best[task], 1e-8) for task in best} + aggregate[name] = {"task_errors": errors[name], "relative_regrets": regrets, + "mean_relative_regret": float(np.mean(list(regrets.values()))), + "worst_task_relative_regret": float(max(regrets.values()))} + bootstrap = bootstrap_or_disabled(frame, delta_pgen, delta_t, predictions, split_masks["test"], + args.bootstrap, args.seed) + payload = { + "status": "complete", + "study": "parent-disjoint controlled one-amino-acid frozen-delta benchmark", + "all_pairs_edit_distance": 1, + "probe_split_unit": "parent clonotype", + "rows": len(frame), + "parents": int(frame["parent_id"].nunique()), + "split_parent_counts": { + str(key): int(value) + for key, value in frame.groupby("probe_split")["parent_id"].nunique().items() + }, + "model_parity": parity, + "extraction": extraction, + "metrics": metrics, + "preregistered_aggregate": {"definition": "relative error regret against best of seven per task; lower is better", + "best_task_errors": best, "models": aggregate}, + "parent_clustered_bootstrap": bootstrap, + "controls": ["delta_composition_control", "mutation_identity_control"], + "ensemble_baselines": ["concat_rtp", "pca_concat_rtp_128"], + "limitations": [ + "fixed seed42 encoders", + "linear probes only", + "mutants are in-silico and are not observed repertoire clonotypes", + "bootstrap uncertainty was disabled by user direction; point estimates only and no significance claim", + ], + } + result_path = args.output_dir / "RESULTS.json" + result_path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n") + hashes = {path.name: sha256(path) for path in args.output_dir.iterdir() if path.is_file()} + (args.output_dir / "HASHES.json").write_text(json.dumps(hashes, indent=2, sort_keys=True) + "\n") + print(json.dumps({"status": "complete", "results": str(result_path)}, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_author_global.py b/benchmark/evaluate_vdjdb_author_global.py new file mode 100644 index 0000000..326c85a --- /dev/null +++ b/benchmark/evaluate_vdjdb_author_global.py @@ -0,0 +1,162 @@ +"""Evaluate author-native frozen global embeddings on the fixed REDCEA gallery.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd + +from benchmark.evaluate_vdjdb_redcea_clonotypes import ( + METRIC_COLUMNS, + candidate_distances, + summarize_candidates, +) + +EXTERNAL = ("esm2_35m", "tcr_bert", "sceptr_cdr3") +MODALITY = { + "esm2_35m": "sequence-only", + "tcr_bert": "sequence-only", + "sceptr_cdr3": "sequence-only", + "sceptr": "annotation-aware V+CDR3+J", +} + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--preflight", type=Path, required=True) + parser.add_argument("--representations-dir", type=Path, required=True) + parser.add_argument("--reference-evaluation", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(args.output_dir) + args.output_dir.mkdir(parents=True) + gate = json.loads(args.preflight.read_text(encoding="utf-8")) + if gate["status"] != "accepted": + raise ValueError("Author-global preflight did not accept.") + + cohort = pd.read_csv(args.cohort, sep="\t") + if sha256(args.cohort) != gate["input_hashes"]["redcea_cohort"]: + raise ValueError("Cohort hash differs from accepted preflight.") + gallery_file = args.reference_evaluation / "candidate_gallery.npz" + gallery = np.load(gallery_file) + candidates = gallery["candidates"] + relevant = gallery["relevant"] + if candidates.shape[0] != len(cohort): + raise ValueError("Candidate gallery row count mismatch.") + + labels_text = cohort["label"].astype(str) + label_names = sorted(labels_text.unique()) + label_to_id = {label: index for index, label in enumerate(label_names)} + label_ids = np.array([label_to_id[value] for value in labels_text], dtype=np.int32) + sequence_sha = hashlib.sha256( + "\n".join(cohort["cdr3"].astype(str)).encode("utf-8") + ).hexdigest() + catalog = json.loads( + (args.representations_dir / "representations.json").read_text(encoding="utf-8") + ) + + summaries = {} + per_epitope = [] + rows = [] + for name in EXTERNAL: + entry = catalog[name] + if entry["rows"] != len(cohort) or entry["sequence_sha256"] != sequence_sha: + raise ValueError(f"{name} catalog provenance mismatch") + source = Path(entry["path"]) + if sha256(source) != entry["sha256"]: + raise ValueError(f"{name} representation hash mismatch") + matrix = np.load(source, mmap_mode="r") + if matrix.shape != (len(cohort), entry["dim"]) or not np.isfinite(matrix).all(): + raise ValueError(f"{name} shape/finiteness mismatch: {matrix.shape}") + summaries[name] = {} + row = {"model": name, "modality": MODALITY[name], "native_dim": int(matrix.shape[1])} + for distance in ("cosine", "euclidean"): + distances, norms = candidate_distances(matrix, candidates, distance) + summary, _, per_label = summarize_candidates( + distances, candidates, relevant, label_ids, label_names + ) + summary["embedding_norms"] = norms + summaries[name][distance] = summary + per_label.insert(0, "model", name) + per_label.insert(1, "modality", MODALITY[name]) + per_label.insert(2, "distance", distance) + per_epitope.append(per_label) + for metric in METRIC_COLUMNS: + row[f"{distance}_{metric}"] = summary["macro_epitope"][metric] + for k in (1, 5, 10): + row[f"{distance}_knn_macro_f1_at_{k}"] = ( + summary["knn_classification"][f"k_{k}"]["macro_f1"] + ) + rows.append(row) + + pd.DataFrame(rows).to_csv( + args.output_dir / "external_retrieval_summary.tsv", + sep="\t", index=False, lineterminator="\n", + ) + pd.concat(per_epitope, ignore_index=True).to_csv( + args.output_dir / "external_per_epitope.tsv", + sep="\t", index=False, lineterminator="\n", + ) + (args.output_dir / "external_metrics.json").write_text( + json.dumps(summaries, indent=2, sort_keys=True) + "\n", encoding="utf-8" + ) + result = { + "status": "complete", + "cohort": { + "sha256": sha256(args.cohort), + "clonotypes": len(cohort), + "epitopes": len(label_names), + }, + "candidate_gallery": { + "path": str(gallery_file), + "sha256": sha256(gallery_file), + "shape": list(candidates.shape), + }, + "representations": { + name: { + "sha256": catalog[name]["sha256"], + "dim": catalog[name]["dim"], + "modality": MODALITY[name], + "model": catalog[name]["model"], + } + for name in EXTERNAL + }, + "selection": "No VDJdb labels were used to fit, pool, tune, or select an encoder.", + "unavailable": { + "sceptr": ( + "Annotation-aware SCEPTR-default rejects unsupported/nonfunctional " + "VDJdb V/J alleles; the fixed cohort was not filtered per method." + ) + }, + "uncertainty": "Per-epitope distributions retained; no bootstrap requested.", + "circularity_caveat": ( + "REDCEA membership is sequence/TCRemP-cluster-conditioned; this is " + "motif-conditioned retrieval geometry, not independent binding evidence." + ), + } + (args.output_dir / "RESULTS.json").write_text( + json.dumps(result, indent=2, sort_keys=True) + "\n", encoding="utf-8" + ) + print(json.dumps(result, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_decoded_tcremp.py b/benchmark/evaluate_vdjdb_decoded_tcremp.py new file mode 100644 index 0000000..8191388 --- /dev/null +++ b/benchmark/evaluate_vdjdb_decoded_tcremp.py @@ -0,0 +1,196 @@ +"""Decode saved VDJdb RTP latents through the frozen TCRemP head. + +This intentionally reuses the frozen uniform-100 VDJdb cohort, candidate pairs, +and ``separation_metrics`` implementation. It does not encode sequences or +train a model: its sole intervention is ``saved RTP -> frozen T head``. +""" +from __future__ import annotations + +import argparse +import hashlib +import json +from dataclasses import asdict +from pathlib import Path + +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import torch +import umap + +from evaluate_vdjdb_uniform100_separation import separation_metrics +from irrm_codec.multitask_data import TargetStandardizer +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer + + +SEED = 1729 +HIGHLIGHTS = { + "SSYRRPVGI": "#4477AA", "STPESANL": "#EE6677", "SLLMWITQV": "#228833", + "KYNKANVFL": "#AA3377", "SIINFEKL": "#CCBB44", +} + + +def parse_args() -> argparse.Namespace: + p = argparse.ArgumentParser(description=__doc__) + p.add_argument("--cohort", type=Path, required=True) + p.add_argument("--rtp", type=Path, required=True, + help="Existing full-cohort RTP matrix used by the VDJdb analysis.") + p.add_argument("--checkpoint", type=Path, required=True) + p.add_argument("--standardizer", type=Path, required=True) + p.add_argument("--uniform-evaluation", type=Path, required=True, + help="Directory containing the locked uniform_pairs.npz.") + p.add_argument("--existing-separation", type=Path, required=True, + help="Completed RP/RTP separation directory; values are reused, not recomputed.") + p.add_argument("--native-tcremp", type=Path, + help="Optional existing aligned native TCRemP matrix for reconstruction diagnostics.") + p.add_argument("--output-dir", type=Path, required=True) + p.add_argument("--batch-size", type=int, default=256) + p.add_argument("--device", choices=("cpu", "cuda"), default="cpu") + return p.parse_args() + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for block in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(block) + return digest.hexdigest() + + +def decode(a: argparse.Namespace, rtp: np.ndarray, out: Path) -> tuple[Path, dict]: + payload = torch.load(a.checkpoint, map_location="cpu", weights_only=False) + config = IRRMCodecConfig(**payload["model_config"]) + if rtp.ndim != 2 or rtp.shape[1] != config.latent_dim: + raise ValueError(f"RTP shape {rtp.shape} is incompatible with latent_dim={config.latent_dim}") + standardizer = TargetStandardizer.load(a.standardizer) + if len(standardizer.tcremp_mean) != config.tcremp_dim: + raise ValueError("TCRemP standardizer and checkpoint output dimensions differ") + device = torch.device(a.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("--device cuda requested but CUDA is unavailable") + model = IRRMCodecTransformer(config).to(device) + model.load_state_dict(payload["model_state"], strict=True) + model.eval() + mean = torch.from_numpy(standardizer.tcremp_mean).to(device) + std = torch.from_numpy(standardizer.tcremp_std).to(device) + decoded_path = out / "decoded_tcremp.npy" + decoded = np.lib.format.open_memmap(decoded_path, mode="w+", dtype=np.float32, + shape=(len(rtp), config.tcremp_dim)) + with torch.inference_mode(): + for start in range(0, len(rtp), a.batch_size): + stop = min(start + a.batch_size, len(rtp)) + z = torch.from_numpy(np.asarray(rtp[start:stop], dtype=np.float32)).to(device) + decoded[start:stop] = (model.tcremp_head(z) * std + mean).cpu().numpy() + decoded.flush() + return decoded_path, { + "checkpoint_epoch_zero_based": int(payload["epoch"]), + "checkpoint_best_validation_loss": float(payload["best_val_loss"]), + "model_config": asdict(config), "standardizer_train_rows": standardizer.train_rows, + } + + +def diagnostics(decoded: np.ndarray, native: np.ndarray | None) -> dict: + result = {"decoded": {"shape": [int(x) for x in decoded.shape], + "nan_count": int(np.isnan(decoded).sum()), "inf_count": int(np.isinf(decoded).sum()), + "min": float(np.min(decoded)), "max": float(np.max(decoded)), + "mean": float(np.mean(decoded)), "std": float(np.std(decoded))}} + if native is not None: + if native.shape != decoded.shape: + raise ValueError(f"Native TCRemP shape {native.shape} does not match decoded {decoded.shape}") + # Chunked global sums avoid a second multi-GB temporary array. + cosine, squared, dot, sx, sy, sxx, syy, n = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0 + for start in range(0, len(decoded), 128): + x, y = np.asarray(decoded[start:start+128], np.float64), np.asarray(native[start:start+128], np.float64) + cosine += float(np.sum(np.sum(x*y, axis=1) / (np.linalg.norm(x, axis=1)*np.linalg.norm(y, axis=1)))) + squared += float(np.square(x-y).sum()); dot += float((x*y).sum()); sx += float(x.sum()); sy += float(y.sum()) + sxx += float(np.square(x).sum()); syy += float(np.square(y).sum()); n += x.size + pearson = (n*dot-sx*sy) / np.sqrt((n*sxx-sx*sx)*(n*syy-sy*sy)) + result["native_tcremp"] = {"available": True, "global_mean_cosine": cosine / len(decoded), + "global_pearson": float(pearson), "global_mse": squared / n} + else: + result["native_tcremp"] = {"available": False} + return result + + +def plot_umap(matrix: np.ndarray, labels: np.ndarray, out: Path) -> None: + coords = umap.UMAP(n_neighbors=30, min_dist=.15, metric="cosine", n_components=2, + random_state=SEED, transform_seed=SEED).fit_transform(np.asarray(matrix, np.float32)) + frame = pd.DataFrame({"index": np.arange(len(labels)), "epitope": labels, + "umap_1": coords[:, 0], "umap_2": coords[:, 1]}) + frame.to_parquet(out / "umap_coordinates.parquet", index=False) + plt.rcParams.update({"font.family": "STIXGeneral", "font.size": 7.5, "pdf.fonttype": 42, "svg.fonttype": "none"}) + fig, ax = plt.subplots(figsize=(3.38, 3.38)) + other = ~np.isin(labels, list(HIGHLIGHTS)) + ax.scatter(coords[other, 0], coords[other, 1], s=1.1, c="#9e9e9e", alpha=.20, linewidths=0, rasterized=True) + for epitope, color in HIGHLIGHTS.items(): + keep = labels == epitope + ax.scatter(coords[keep, 0], coords[keep, 1], s=8, c=color, alpha=.76, linewidths=0, rasterized=True, label=epitope) + ax.set(xticks=[], yticks=[], title="Decoded TCRemP-like representation") + for spine in ax.spines.values(): spine.set_visible(False) + ax.legend(loc="lower center", bbox_to_anchor=(.5, -.16), ncol=3, frameon=False, fontsize=6.8) + fig.subplots_adjust(left=.012, right=.995, top=.89, bottom=.14) + for suffix, kwargs in ((".png", {"dpi": 600}), (".pdf", {}), (".svg", {})): + fig.savefig((out / "vdjdb_decoded_tcremp_umap").with_suffix(suffix), bbox_inches="tight", pad_inches=.01, **kwargs) + plt.close(fig) + + +def plot_effects(table: pd.DataFrame, out: Path) -> None: + long = table.melt(id_vars=["epitope", "N"], value_vars=["d_RP", "d_RTP", "d_decoded_TCRemP"], + var_name="representation", value_name="cohen_d") + order = table.sort_values("d_RTP", ascending=False).epitope + wide = long.pivot(index="representation", columns="epitope", values="cohen_d")[order] + fig, ax = plt.subplots(figsize=(11, 2.2)) + image = ax.imshow(wide, aspect="auto", cmap="viridis") + ax.set(yticks=range(len(wide.index)), yticklabels=wide.index, xticks=range(len(order)), xticklabels=order) + ax.tick_params(axis="x", labelrotation=90, labelsize=5); ax.tick_params(axis="y", labelsize=7) + fig.colorbar(image, ax=ax, label="Cohen's d", shrink=.8) + fig.tight_layout() + for suffix in (".png", ".pdf", ".svg"): fig.savefig((out / "cohen_d_comparison").with_suffix(suffix), dpi=600 if suffix==".png" else None) + plt.close(fig) + + +def main() -> None: + a = parse_args() + if a.output_dir.exists(): raise FileExistsError(f"Refusing to overwrite {a.output_dir}") + a.output_dir.mkdir(parents=True) + cohort = pd.read_csv(a.cohort, sep="\t") + rtp = np.load(a.rtp, mmap_mode="r") + if len(rtp) != len(cohort): raise ValueError("Saved RTP row count does not match cohort") + cohort.insert(0, "cohort_index", np.arange(len(cohort))) + cohort.to_csv(a.output_dir / "receptor_metadata.tsv", sep="\t", index=False) + decoded_path, decoder_meta = decode(a, rtp, a.output_dir) + decoded = np.load(decoded_path, mmap_mode="r") + native = np.load(a.native_tcremp, mmap_mode="r") if a.native_tcremp else None + check = diagnostics(decoded, native) + check["ordering"] = {"cohort_rows": len(cohort), "rtp_rows": len(rtp), "decoded_rows": len(decoded), + "exact_row_order_preserved": True, "identifier_columns": [c for c in ("cid", "cdr3") if c in cohort]} + (a.output_dir / "sanity_checks.json").write_text(json.dumps(check, indent=2, sort_keys=True)+"\n") + pairs = np.load(a.uniform_evaluation / "uniform_pairs.npz") + original, within, between = pairs["original_indices"], pairs["within"], pairs["between"] + labels = cohort.iloc[original].label.astype(str).to_numpy() + query, decoded_epitope = separation_metrics(decoded[original], within, between, labels) + query.insert(0, "model", "decoded_TCRemP") + query.to_parquet(a.output_dir / "per_query_decoded_tcremp.parquet", index=False) + old = pd.read_csv(a.existing_separation / "per_epitope.tsv", sep="\t") + old = old[old.model.isin(["RP", "RTP"])].pivot(index=["epitope", "queries"], columns="model", values="cohen_d").reset_index() + result = old.merge(decoded_epitope, left_on=["epitope", "queries"], right_on=["epitope", "queries"], validate="one_to_one") + result = result.rename(columns={"queries": "N", "RP": "d_RP", "RTP": "d_RTP", "cohen_d": "d_decoded_TCRemP"}) + result["decoded_minus_RP"] = result.d_decoded_TCRemP-result.d_RP + result["decoded_minus_RTP"] = result.d_decoded_TCRemP-result.d_RTP + result.sort_values("epitope").to_csv(a.output_dir / "per_epitope_cohen_d.tsv", sep="\t", index=False) + summary = {"median_cohen_d": {k: float(result[k].median()) for k in ("d_RP", "d_RTP", "d_decoded_TCRemP")}, + "fraction_decoded_gt_RP": float((result.d_decoded_TCRemP > result.d_RP).mean()), + "fraction_decoded_gt_RTP": float((result.d_decoded_TCRemP > result.d_RTP).mean()), + "pearson_d_RTP_vs_decoded": float(result.d_RTP.corr(result.d_decoded_TCRemP)), + "top_decoded": result.nlargest(10, "d_decoded_TCRemP")[["epitope", "N", "d_decoded_TCRemP"]].to_dict("records"), + "top_gains_vs_RP": result.nlargest(10, "decoded_minus_RP")[["epitope", "decoded_minus_RP"]].to_dict("records"), + "largest_losses_vs_RTP": result.nsmallest(10, "decoded_minus_RTP")[["epitope", "decoded_minus_RTP"]].to_dict("records")} + (a.output_dir / "aggregate_statistics.json").write_text(json.dumps(summary, indent=2, sort_keys=True)+"\n") + plot_effects(result, a.output_dir); plot_umap(decoded, cohort.label.astype(str).to_numpy(), a.output_dir) + manifest = {"status": "complete", "decoder": decoder_meta, "inputs": {name: {"path": str(path), "sha256": sha256(path)} for name, path in {"cohort":a.cohort,"rtp":a.rtp,"checkpoint":a.checkpoint,"standardizer":a.standardizer,"pairs":a.uniform_evaluation/"uniform_pairs.npz"}.items()}, "protocol": "Saved RTP latents decoded only through frozen TCRemP head; Cohen's d is imported from evaluate_vdjdb_uniform100_separation.separation_metrics without modification."} + (a.output_dir / "RESULTS.json").write_text(json.dumps(manifest, indent=2, sort_keys=True)+"\n") + + +if __name__ == "__main__": main() diff --git a/benchmark/evaluate_vdjdb_epitope_prediction.py b/benchmark/evaluate_vdjdb_epitope_prediction.py new file mode 100644 index 0000000..bea57b4 --- /dev/null +++ b/benchmark/evaluate_vdjdb_epitope_prediction.py @@ -0,0 +1,627 @@ +"""Frozen-embedding multiclass epitope prediction on the manuscript VDJdb cohort. + +The selected rows are exactly ``original_indices`` from the published uniform-100 +separation evaluation. No encoder is loaded or fine-tuned here. Every dense +representation uses the same cached folds, training-only scaling, and the same +small, training-only C selection procedure. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import os +import warnings +from dataclasses import dataclass +from pathlib import Path + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +from joblib import Parallel, delayed +from scipy import sparse +from scipy.stats import wilcoxon +from sklearn.exceptions import ConvergenceWarning +from sklearn.feature_extraction.text import TfidfVectorizer +from sklearn.linear_model import LogisticRegression +from sklearn.metrics import ( + accuracy_score, + balanced_accuracy_score, + f1_score, + roc_auc_score, + top_k_accuracy_score, +) +from sklearn.model_selection import StratifiedGroupKFold, StratifiedKFold, StratifiedShuffleSplit +from sklearn.preprocessing import StandardScaler + + +NATIVE_NAMES = ("r", "t", "p", "rt", "rp", "tp", "rtp") +EXTERNAL_FILES = { + "esm2_35m": "esm2_35m.npy", + "tcr_bert": "tcr_bert.npy", + "sceptr_cdr3": "sceptr_cdr3.npy", +} +DISPLAY = { + "r": "R", "t": "T", "p": "P", "rt": "RT", "rp": "RP", "tp": "TP", + "rtp": "RTP", "esm2_35m": "ESM2-35M", "tcr_bert": "TCR-BERT", + "sceptr_cdr3": "SCEPTR (CDR3-only)", "kmer_tfidf": "3-mer TF-IDF", +} +PRIMARY_ORDER = ( + "rtp", "rp", "r", "t", "p", "rt", "tp", "tcr_bert", "sceptr_cdr3", + "esm2_35m", "kmer_tfidf", +) + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def stable_json(path: Path, value: object) -> None: + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--uniform-evaluation", type=Path, required=True) + parser.add_argument("--native-evaluation", type=Path, required=True) + parser.add_argument("--external-representations", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--seeds", type=int, nargs="+", default=[42, 43, 44]) + parser.add_argument("--folds", type=int, default=5) + parser.add_argument("--c-grid", type=float, nargs="+", default=[0.1, 1.0]) + parser.add_argument("--max-iter", type=int, default=400) + parser.add_argument("--jobs", type=int, default=1) + parser.add_argument("--representations", nargs="+", default=list(PRIMARY_ORDER)) + parser.add_argument("--skip-similarity-grouped", action="store_true") + return parser.parse_args() + + +def selected_cohort(cohort_path: Path, uniform_dir: Path) -> tuple[pd.DataFrame, np.ndarray]: + cohort = pd.read_csv(cohort_path, sep="\t") + pairs = np.load(uniform_dir / "uniform_pairs.npz") + original = np.asarray(pairs["original_indices"], dtype=np.int64) + if len(original) != 65_756 or len(np.unique(original)) != len(original): + raise ValueError("Uniform evaluation does not contain the locked 65,756 unique rows.") + selected = cohort.iloc[original].copy().reset_index(drop=True) + selected.insert(0, "prediction_row_index", np.arange(len(selected), dtype=np.int64)) + selected.insert(1, "source_cohort_row_index", original) + if selected["label"].nunique() != 40 or selected.groupby("label").size().min() < 101: + raise ValueError("Selected cohort differs from the locked 40-epitope support gate.") + return selected, original + + +def audit_dataset(frame: pd.DataFrame) -> tuple[dict, pd.DataFrame]: + class_sizes = frame.groupby("label", sort=True).size().rename("sequences").reset_index() + duplicate_rows = int(frame["cdr3"].duplicated(keep=False).sum()) + labels_per_sequence = frame.groupby("cdr3")["label"].nunique() + conflicting = int((labels_per_sequence > 1).sum()) + sizes = class_sizes["sequences"].to_numpy() + report = { + "sequences": int(len(frame)), + "epitopes": int(len(class_sizes)), + "class_size_min": int(sizes.min()), + "class_size_median": float(np.median(sizes)), + "class_size_max": int(sizes.max()), + "duplicate_cdr3_rows": duplicate_rows, + "duplicate_cdr3_sequences_exist": bool(duplicate_rows), + "identical_cdr3_with_different_labels": conflicting, + } + return report, class_sizes + + +class UnionFind: + def __init__(self, n: int): + self.parent = np.arange(n, dtype=np.int64) + + def find(self, value: int) -> int: + while self.parent[value] != value: + self.parent[value] = self.parent[self.parent[value]] + value = int(self.parent[value]) + return value + + def union(self, left: int, right: int) -> None: + a, b = self.find(left), self.find(right) + if a != b: + self.parent[max(a, b)] = min(a, b) + + +def redcea_component_groups(frame: pd.DataFrame) -> np.ndarray: + """Connect rows sharing any retained REDCEA cluster identifier.""" + union = UnionFind(len(frame)) + owner: dict[str, int] = {} + for index, raw in enumerate(frame["source_cids"].astype(str)): + identifiers = [value for value in raw.split("|") if value] + if not identifiers: + identifiers = [str(frame.iloc[index]["cid"])] + for identifier in identifiers: + if identifier in owner: + union.union(index, owner[identifier]) + else: + owner[identifier] = index + roots = np.array([union.find(i) for i in range(len(frame))], dtype=np.int64) + _, groups = np.unique(roots, return_inverse=True) + return groups.astype(np.int64) + + +def _valid_folds(folds: list[tuple[np.ndarray, np.ndarray]], y: np.ndarray) -> bool: + expected = set(np.unique(y).tolist()) + return all(set(np.unique(y[train])) == expected and set(np.unique(y[test])) == expected + for train, test in folds) + + +def make_splits( + y: np.ndarray, exact_groups: np.ndarray, similarity_groups: np.ndarray, + seeds: list[int], requested_folds: int, include_similarity: bool, +) -> tuple[dict[str, list[tuple[int, int, np.ndarray, np.ndarray]]], dict]: + protocols: dict[str, list[tuple[int, int, np.ndarray, np.ndarray]]] = { + "sequence_stratified": [], "exact_cdr3_grouped": [] + } + report: dict[str, object] = {} + for repeat, seed in enumerate(seeds): + splitter = StratifiedKFold(requested_folds, shuffle=True, random_state=seed) + folds = list(splitter.split(np.zeros(len(y)), y)) + for fold, (train, test) in enumerate(folds): + item = (repeat, fold, train.astype(np.int64), test.astype(np.int64)) + protocols["sequence_stratified"].append(item) + protocols["exact_cdr3_grouped"].append(item) + if len(np.unique(exact_groups)) == len(exact_groups): + report["exact_cdr3_grouped"] = { + "alias_of": "sequence_stratified", + "reason": "the locked cohort has one row per unique exact CDR3", + } + else: + raise ValueError("Unexpected duplicate exact CDR3s in the locked deduplicated cohort.") + + if include_similarity: + per_label_groups = pd.DataFrame({"y": y, "group": similarity_groups}).groupby("y")[ + "group" + ].nunique() + maximum = min(requested_folds, int(per_label_groups.min())) + chosen: tuple[int, list[list[tuple[np.ndarray, np.ndarray]]]] | None = None + for n_splits in range(maximum, 1, -1): + repeated = [] + for seed in seeds: + splitter = StratifiedGroupKFold(n_splits, shuffle=True, random_state=seed) + folds = list(splitter.split(np.zeros(len(y)), y, similarity_groups)) + repeated.append(folds) + if all(_valid_folds(folds, y) for folds in repeated): + chosen = n_splits, repeated + break + if chosen is None: + raise ValueError("Could not construct class-complete REDCEA-grouped folds.") + n_splits, repeated = chosen + protocols["redcea_similarity_grouped"] = [] + for repeat, folds in enumerate(repeated): + for fold, (train, test) in enumerate(folds): + if np.intersect1d(similarity_groups[train], similarity_groups[test]).size: + raise AssertionError("REDCEA group leakage detected.") + protocols["redcea_similarity_grouped"].append( + (repeat, fold, train.astype(np.int64), test.astype(np.int64)) + ) + report["redcea_similarity_grouped"] = { + "folds": n_splits, + "groups": int(len(np.unique(similarity_groups))), + "minimum_groups_per_epitope": int(per_label_groups.min()), + "definition": "connected components of rows sharing any retained REDCEA source_cid", + } + return protocols, report + + +def write_split_assignments( + path: Path, protocols: dict[str, list[tuple[int, int, np.ndarray, np.ndarray]]], + frame: pd.DataFrame, +) -> None: + blocks = [] + for protocol, folds in protocols.items(): + by_repeat: dict[int, np.ndarray] = {} + for repeat, fold, _, test in folds: + by_repeat.setdefault(repeat, np.full(len(frame), -1, dtype=np.int16))[test] = fold + for repeat, assignments in by_repeat.items(): + if np.any(assignments < 0): + raise AssertionError(f"Incomplete assignments for {protocol} repeat {repeat}") + blocks.append(pd.DataFrame({ + "protocol": protocol, + "repeat": repeat, + "prediction_row_index": frame["prediction_row_index"], + "source_cohort_row_index": frame["source_cohort_row_index"], + "cdr3": frame["cdr3"], + "label": frame["label"], + "test_fold": assignments, + })) + pd.concat(blocks, ignore_index=True).to_csv(path, index=False, lineterminator="\n") + + +def load_dense_matrix( + name: str, original: np.ndarray, native_dir: Path, external_dir: Path, source_rows: int, +) -> np.ndarray: + path = (native_dir / f"embeddings_{name}.npy") if name in NATIVE_NAMES else ( + external_dir / EXTERNAL_FILES[name] + ) + matrix = np.load(path, mmap_mode="r") + if matrix.ndim != 2 or matrix.shape[0] != source_rows: + raise ValueError(f"{name} shape {matrix.shape} does not align to {source_rows} source rows") + selected = np.asarray(matrix[original], dtype=np.float32) + if not np.isfinite(selected).all(): + raise ValueError(f"{name} contains non-finite values") + return selected + + +def inner_split( + train: np.ndarray, y: np.ndarray, groups: np.ndarray | None, seed: int +) -> tuple[np.ndarray, np.ndarray]: + if groups is None: + split = StratifiedShuffleSplit(n_splits=1, test_size=0.15, random_state=seed) + inner_train, inner_val = next(split.split(np.zeros(len(train)), y[train])) + else: + sub_y, sub_groups = y[train], groups[train] + per_label = pd.DataFrame({"y": sub_y, "g": sub_groups}).groupby("y")["g"].nunique() + n_splits = min(3, int(per_label.min())) + if n_splits < 2: + raise ValueError("Outer training data cannot support group-aware C selection.") + split = StratifiedGroupKFold(n_splits, shuffle=True, random_state=seed) + candidates = list(split.split(np.zeros(len(train)), sub_y, sub_groups)) + valid = [item for item in candidates if _valid_folds([item], sub_y)] + if not valid: + raise ValueError("No class-complete group-aware inner split.") + inner_train, inner_val = valid[0] + return train[inner_train], train[inner_val] + + +def classifier(c_value: float, max_iter: int, seed: int) -> LogisticRegression: + return LogisticRegression( + C=c_value, + penalty="l2", + solver="lbfgs", + class_weight="balanced", + max_iter=max_iter, + tol=1e-4, + random_state=seed, + ) + + +def transform_dense( + matrix: np.ndarray, fit_rows: np.ndarray, *row_sets: np.ndarray +) -> tuple[list[np.ndarray], StandardScaler]: + scaler = StandardScaler().fit(matrix[fit_rows]) + return [scaler.transform(matrix[rows]) for rows in row_sets], scaler + + +@dataclass(frozen=True) +class FoldSpec: + protocol: str + repeat: int + fold: int + train: np.ndarray + test: np.ndarray + seed: int + + +def score_predictions(y_true: np.ndarray, probabilities: np.ndarray, classes: np.ndarray) -> dict: + predicted = classes[np.argmax(probabilities, axis=1)] + return { + "macro_f1": float(f1_score(y_true, predicted, average="macro")), + "balanced_accuracy": float(balanced_accuracy_score(y_true, predicted)), + "accuracy": float(accuracy_score(y_true, predicted)), + "macro_auroc": float(roc_auc_score( + y_true, probabilities, labels=classes, multi_class="ovr", average="macro" + )), + "top3_accuracy": float(top_k_accuracy_score( + y_true, probabilities, k=3, labels=classes + )), + } + + +def evaluate_fold( + spec: FoldSpec, name: str, matrix: np.ndarray | None, sequences: np.ndarray, + y: np.ndarray, classes: np.ndarray, groups: np.ndarray | None, + c_grid: tuple[float, ...], max_iter: int, +) -> tuple[dict, pd.DataFrame]: + tune_train, tune_val = inner_split(spec.train, y, groups, spec.seed + spec.fold * 1009) + best: tuple[float, float] | None = None + if name == "kmer_tfidf": + vectorizer = TfidfVectorizer(analyzer="char", ngram_range=(3, 3), lowercase=False) + inner_train_x = vectorizer.fit_transform(sequences[tune_train]) + inner_val_x = vectorizer.transform(sequences[tune_val]) + else: + (inner_train_x, inner_val_x), _ = transform_dense( + matrix, tune_train, tune_train, tune_val + ) + for c_value in c_grid: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", ConvergenceWarning) + model = classifier(c_value, max_iter, spec.seed).fit(inner_train_x, y[tune_train]) + value = float(f1_score(y[tune_val], model.predict(inner_val_x), average="macro")) + candidate = (value, -c_value) + if best is None or candidate > best: + best = candidate + chosen_c = -best[1] + + if name == "kmer_tfidf": + vectorizer = TfidfVectorizer(analyzer="char", ngram_range=(3, 3), lowercase=False) + train_x = vectorizer.fit_transform(sequences[spec.train]) + test_x = vectorizer.transform(sequences[spec.test]) + dimension = int(train_x.shape[1]) + else: + (train_x, test_x), _ = transform_dense(matrix, spec.train, spec.train, spec.test) + dimension = int(matrix.shape[1]) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", ConvergenceWarning) + model = classifier(chosen_c, max_iter, spec.seed).fit(train_x, y[spec.train]) + probabilities = model.predict_proba(test_x) + if not np.array_equal(model.classes_, classes): + raise ValueError("A fold lacks one or more classes despite split validation.") + metrics = score_predictions(y[spec.test], probabilities, classes) + row = { + "protocol": spec.protocol, "repeat": spec.repeat, "fold": spec.fold, + "seed": spec.seed, "representation": name, "display_name": DISPLAY[name], + "dim": dimension, "train_rows": len(spec.train), "test_rows": len(spec.test), + "selected_c": chosen_c, **metrics, + } + predicted = classes[np.argmax(probabilities, axis=1)] + top3 = classes[np.argpartition(probabilities, -3, axis=1)[:, -3:]] + prediction = pd.DataFrame({ + "protocol": spec.protocol, + "repeat": spec.repeat, + "fold": spec.fold, + "representation": name, + "prediction_row_index": spec.test, + "true_label": y[spec.test], + "predicted_label": predicted, + "correct": predicted == y[spec.test], + "top3_labels": ["|".join(map(str, sorted(values))) for values in top3], + "true_label_probability": probabilities[ + np.arange(len(spec.test)), np.searchsorted(classes, y[spec.test]) + ], + }) + return row, prediction + + +def aggregate_metrics(raw: pd.DataFrame) -> pd.DataFrame: + metrics = ["macro_f1", "balanced_accuracy", "accuracy", "macro_auroc", "top3_accuracy"] + grouped = raw.groupby(["protocol", "representation", "display_name"], sort=False) + rows = [] + for keys, frame in grouped: + row = dict(zip(("protocol", "representation", "display_name"), keys)) + row["dim"] = int(round(float(frame["dim"].median()))) + row["dim_min"] = int(frame["dim"].min()) + row["dim_max"] = int(frame["dim"].max()) + row["observations"] = len(frame) + for metric in metrics: + row[f"{metric}_mean"] = float(frame[metric].mean()) + row[f"{metric}_std"] = float(frame[metric].std(ddof=1)) + rows.append(row) + return pd.DataFrame(rows) + + +def paired_statistics(raw: pd.DataFrame) -> tuple[pd.DataFrame, pd.DataFrame]: + comparisons = ("rp", "tcr_bert", "sceptr_cdr3", "esm2_35m") + differences, tests = [], [] + for protocol in raw["protocol"].unique(): + subset = raw[raw.protocol == protocol] + wide = subset.pivot(index=["repeat", "fold", "seed"], columns="representation", + values="macro_f1") + if "rtp" not in wide: + continue + for comparator in comparisons: + if comparator not in wide: + continue + paired = wide[["rtp", comparator]].dropna().copy() + paired["difference"] = paired["rtp"] - paired[comparator] + for index, values in paired.iterrows(): + differences.append({ + "protocol": protocol, "repeat": index[0], "fold": index[1], + "seed": index[2], "comparison": f"rtp_minus_{comparator}", + "rtp_macro_f1": values["rtp"], "comparator_macro_f1": values[comparator], + "difference": values["difference"], + }) + delta = paired["difference"].to_numpy() + try: + statistic, p_value = wilcoxon(delta, alternative="two-sided", method="auto") + except ValueError: + statistic, p_value = 0.0, 1.0 + tests.append({ + "protocol": protocol, "comparison": f"rtp_vs_{comparator}", + "observations": len(delta), "mean_paired_difference": float(delta.mean()), + "median_paired_difference": float(np.median(delta)), + "wins": int((delta > 0).sum()), "ties": int((delta == 0).sum()), + "losses": int((delta < 0).sum()), "wilcoxon_statistic": float(statistic), + "wilcoxon_two_sided_p": float(p_value), + }) + return pd.DataFrame(differences), pd.DataFrame(tests) + + +def latex_table(aggregate: pd.DataFrame, protocol: str) -> str: + data = aggregate[aggregate.protocol == protocol].set_index("representation") + lines = [ + r"\begin{tabular}{lrrrrr}", r"\toprule", + r"Representation & Dim & Macro F1 & Balanced accuracy & Accuracy & Macro AUROC \\", + r"\midrule", + ] + for name in PRIMARY_ORDER: + if name not in data.index: + continue + row = data.loc[name] + cell = lambda metric: f"{row[f'{metric}_mean']:.3f} $\\pm$ {row[f'{metric}_std']:.3f}" + lines.append( + f"{DISPLAY[name]} & {int(row['dim'])} & {cell('macro_f1')} & " + f"{cell('balanced_accuracy')} & {cell('accuracy')} & {cell('macro_auroc')} \\\\" + ) + lines.extend([r"\bottomrule", r"\end{tabular}", ""]) + return "\n".join(lines) + + +def create_figure(raw: pd.DataFrame, aggregate: pd.DataFrame, output: Path) -> None: + standard = aggregate[aggregate.protocol == "sequence_stratified"].set_index("representation") + order = [name for name in PRIMARY_ORDER if name in standard.index] + fig, axes = plt.subplots(1, 3, figsize=(11.2, 3.65), gridspec_kw={"width_ratios": [1.55, 1, 1]}) + ax = axes[0] + positions = np.arange(len(order)) + means = standard.loc[order, "macro_f1_mean"].to_numpy() + errors = standard.loc[order, "macro_f1_std"].to_numpy() + colors = ["#d55e00" if name == "rtp" else "#4477aa" if name in NATIVE_NAMES else "#228833" + for name in order] + ax.errorbar(positions, means, yerr=errors, fmt="none", ecolor="#333333", capsize=2, lw=.9) + ax.scatter(positions, means, c=colors, s=34, edgecolor="white", linewidth=.5, zorder=3) + ax.set_xticks(positions, [DISPLAY[name] for name in order], rotation=50, ha="right") + ax.set_ylabel("Macro F1") + ax.set_title("A Sequence-stratified performance", loc="left", fontweight="bold") + ax.grid(axis="y", color="#dddddd", linewidth=.6) + + def paired_panel(panel, protocol: str, title: str) -> None: + subset = raw[(raw.protocol == protocol) & raw.representation.isin(["rp", "rtp"])] + wide = subset.pivot(index=["repeat", "fold"], columns="representation", values="macro_f1").dropna() + for _, row in wide.iterrows(): + panel.plot([0, 1], [row.rp, row.rtp], color="#999999", alpha=.65, lw=.7) + panel.scatter([0, 1], [row.rp, row.rtp], c=["#4477aa", "#d55e00"], s=18, zorder=3) + delta = (wide.rtp - wide.rp).mean() + panel.set_xticks([0, 1], ["RP", "RTP"]) + panel.set_ylabel("Macro F1") + panel.set_title(title, loc="left", fontweight="bold") + panel.text(.5, .02, f"mean Δ={delta:+.3f}", transform=panel.transAxes, + ha="center", va="bottom", fontsize=8) + panel.grid(axis="y", color="#dddddd", linewidth=.6) + + paired_panel(axes[1], "sequence_stratified", "B TCRemP effect") + if "redcea_similarity_grouped" in set(raw.protocol): + paired_panel(axes[2], "redcea_similarity_grouped", "C Cluster-grouped") + else: + axes[2].axis("off") + fig.suptitle("Frozen TCR representations for multiclass epitope prediction", y=1.01, fontsize=12) + fig.tight_layout() + fig.savefig(output / "epitope_prediction.png", dpi=600, bbox_inches="tight") + fig.savefig(output / "epitope_prediction.pdf", bbox_inches="tight") + plt.close(fig) + + +def main() -> None: + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + if len(set(args.seeds)) != len(args.seeds) or args.folds < 2: + raise ValueError("Seeds must be unique and at least two folds are required.") + if any(value <= 0 for value in args.c_grid): + raise ValueError("Every C value must be positive.") + unknown = set(args.representations).difference(PRIMARY_ORDER) + if unknown: + raise ValueError(f"Unknown representations: {sorted(unknown)}") + + frame, original = selected_cohort(args.cohort, args.uniform_evaluation) + audit, class_sizes = audit_dataset(frame) + frame.to_csv(args.output_dir / "samples.tsv", sep="\t", index=False, lineterminator="\n") + class_sizes.to_csv(args.output_dir / "class_sizes.csv", index=False, lineterminator="\n") + exact_groups = pd.factorize(frame["cdr3"], sort=True)[0] + similarity_groups = redcea_component_groups(frame) + label_names = np.array(sorted(frame["label"].astype(str).unique())) + label_to_id = {label: index for index, label in enumerate(label_names)} + y_id = np.array([label_to_id[label] for label in frame["label"].astype(str)], dtype=np.int32) + protocols, split_report = make_splits( + y_id, exact_groups, similarity_groups, args.seeds, args.folds, + not args.skip_similarity_grouped, + ) + write_split_assignments(args.output_dir / "split_assignments.csv", protocols, frame) + + specs = [] + for protocol, folds in protocols.items(): + if protocol == "exact_cdr3_grouped": + continue # exact groups are singletons; metrics are copied below with an explicit flag + group_values = similarity_groups if protocol == "redcea_similarity_grouped" else None + for repeat, fold, train, test in folds: + specs.append((FoldSpec(protocol, repeat, fold, train, test, args.seeds[repeat]), group_values)) + + all_metrics, all_predictions, rep_manifest = [], [], {} + sequences = frame["cdr3"].astype(str).to_numpy() + source_rows = int(pd.read_csv(args.cohort, sep="\t", usecols=["cdr3"]).shape[0]) + for name in args.representations: + matrix = None if name == "kmer_tfidf" else load_dense_matrix( + name, original, args.native_evaluation, args.external_representations, source_rows + ) + rep_manifest[name] = { + "display_name": DISPLAY[name], + "dim": "fold-specific vocabulary" if matrix is None else int(matrix.shape[1]), + } + tasks = Parallel(n_jobs=args.jobs, verbose=10)( + delayed(evaluate_fold)( + spec, name, matrix, sequences, y_id, np.arange(len(label_names)), group_values, + tuple(sorted(set(args.c_grid))), args.max_iter, + ) + for spec, group_values in specs + ) + for metrics, predictions in tasks: + predictions["true_label"] = predictions["true_label"].map(dict(enumerate(label_names))) + predictions["predicted_label"] = predictions["predicted_label"].map(dict(enumerate(label_names))) + # top3 values are encoded class IDs; preserve IDs compactly and map is in label_classes.tsv. + all_metrics.append(metrics) + all_predictions.append(predictions) + + raw = pd.DataFrame(all_metrics) + exact = raw[raw.protocol == "sequence_stratified"].copy() + exact["protocol"] = "exact_cdr3_grouped" + exact["evaluation_reused"] = True + raw["evaluation_reused"] = False + raw = pd.concat([raw, exact], ignore_index=True) + raw.to_csv(args.output_dir / "fold_metrics.csv", index=False, lineterminator="\n") + pd.concat(all_predictions, ignore_index=True).to_parquet( + args.output_dir / "predictions.parquet", index=False, compression="zstd" + ) + pd.DataFrame({"class_id": np.arange(len(label_names)), "label": label_names}).to_csv( + args.output_dir / "label_classes.tsv", sep="\t", index=False, lineterminator="\n" + ) + aggregate = aggregate_metrics(raw) + aggregate.to_csv(args.output_dir / "aggregated_metrics.csv", index=False, lineterminator="\n") + differences, tests = paired_statistics(raw) + differences.to_csv(args.output_dir / "paired_macro_f1_differences.csv", index=False, + lineterminator="\n") + tests.to_csv(args.output_dir / "paired_tests.csv", index=False, lineterminator="\n") + for protocol in aggregate.protocol.unique(): + (args.output_dir / f"table_{protocol}.tex").write_text( + latex_table(aggregate, protocol), encoding="utf-8" + ) + create_figure(raw, aggregate, args.output_dir) + + input_files = { + "cohort": args.cohort, + "uniform_pairs": args.uniform_evaluation / "uniform_pairs.npz", + } + manifest = { + "status": "complete", + "dataset": audit, + "protocols": { + "outer": { + "requested_folds": args.folds, "seeds": args.seeds, + "standard": "repeated shuffled StratifiedKFold", + "exact_cdr3_grouped": split_report["exact_cdr3_grouped"], + "similarity_grouped": split_report.get("redcea_similarity_grouped"), + }, + "classifier": "L2 multinomial logistic regression; balanced class weights", + "standardization": "training-fold statistics only", + "hyperparameter_selection": { + "c_grid": sorted(set(args.c_grid)), + "criterion": "inner-training macro F1; smaller C wins ties", + "inner_split": "stratified 15% validation; group-aware for grouped protocol", + }, + "tfidf": "character 3-mer TF-IDF fit on training rows only", + "exact_group_evaluation_reused": True, + }, + "representations": rep_manifest, + "inputs": {name: {"path": str(path), "sha256": sha256(path)} + for name, path in input_files.items()}, + "outputs": {name: sha256(args.output_dir / name) for name in ( + "samples.tsv", "class_sizes.csv", "split_assignments.csv", "fold_metrics.csv", + "aggregated_metrics.csv", "paired_macro_f1_differences.csv", "paired_tests.csv", + "predictions.parquet", "epitope_prediction.png", "epitope_prediction.pdf", + )}, + "software": {"python": os.sys.version, "slurm_job_id": os.environ.get("SLURM_JOB_ID")}, + } + stable_json(args.output_dir / "RESULTS.json", manifest) + print(json.dumps({"status": "complete", "output": str(args.output_dir), **audit}, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_frozen.py b/benchmark/evaluate_vdjdb_frozen.py index fe2cbd0..bbccf54 100644 --- a/benchmark/evaluate_vdjdb_frozen.py +++ b/benchmark/evaluate_vdjdb_frozen.py @@ -30,8 +30,10 @@ def parse_args() -> argparse.Namespace: parser.add_argument("--cohort", type=Path, required=True) parser.add_argument("--cohort-preflight", type=Path, required=True) parser.add_argument("--tokenizer", type=Path, required=True) - parser.add_argument("--model", action="append", required=True, - help="NAME:CHECKPOINT:RUN_CONFIG; repeat for r,p,rp,rtp") + parser.add_argument( + "--model", action="append", required=True, + help="NAME:CHECKPOINT:RUN_CONFIG; legacy R/P/RP/RTP or the full seven-condition factorial", + ) parser.add_argument("--output-dir", type=Path, required=True) parser.add_argument("--batch-size", type=int, default=128) parser.add_argument("--max-pairs-per-label", type=int, default=2000) @@ -63,16 +65,21 @@ def parse_models(values: list[str]) -> dict[str, tuple[Path, Path]]: if name in result: raise ValueError(f"Duplicate model name: {name}") result[name] = (Path(checkpoint), Path(config)) - if set(result) != {"r", "p", "rp", "rtp"}: - raise ValueError("Exact required model names are r, p, rp, and rtp.") + legacy = {"r", "p", "rp", "rtp"} + factorial = {"r", "t", "p", "rt", "rp", "tp", "rtp"} + if set(result) not in (legacy, factorial): + raise ValueError("Models must be legacy r/p/rp/rtp or the full seven-condition factorial.") return result def validate_run_configs(models: dict[str, tuple[Path, Path]]) -> tuple[IRRMCodecConfig, dict]: expected_weights = { "r": (1.0, 0.0, 0.0), + "t": (0.0, 1.0, 0.0), "p": (0.0, 0.0, 1.0), + "rt": (1.0, 1.0, 0.0), "rp": (1.0, 0.0, 1.0), + "tp": (0.0, 1.0, 1.0), "rtp": (1.0, 1.0, 1.0), } configs = {name: json.loads(path.read_text(encoding="utf-8")) for name, (_, path) in models.items()} diff --git a/benchmark/evaluate_vdjdb_redcea_clonotypes.py b/benchmark/evaluate_vdjdb_redcea_clonotypes.py new file mode 100644 index 0000000..df9d78b --- /dev/null +++ b/benchmark/evaluate_vdjdb_redcea_clonotypes.py @@ -0,0 +1,506 @@ +"""Evaluate frozen DATA-ANCHOR latents on REDCEA motif-member clonotypes. + +Every retained clonotype is a query. Its deterministic candidate gallery has +up to 20 same-epitope clonotypes and four times as many other-epitope controls, +selected without model embeddings. This keeps the all-clonotype evaluation +tractable while fixing positive prevalence and using identical comparisons for +all seven frozen encoders. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import math +import os +from pathlib import Path + +import numpy as np +import pandas as pd +from sklearn.cluster import MiniBatchKMeans +from sklearn.metrics import ( + adjusted_mutual_info_score, + adjusted_rand_score, + balanced_accuracy_score, + calinski_harabasz_score, + completeness_score, + davies_bouldin_score, + f1_score, + homogeneity_score, + precision_recall_fscore_support, + silhouette_score, + v_measure_score, +) + +PRIMARY_MODELS = ("r", "t", "p", "rt", "rp", "tp", "rtp") +METRIC_COLUMNS = ( + "precision_at_1", "precision_at_5", "precision_at_10", "average_precision", + "within_between_ratio", "between_minus_within", "nearest_margin", +) + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def stable_json(path: Path, value: object) -> None: + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def assert_finite_tree(value: object, path: str = "root") -> None: + if isinstance(value, dict): + for key, child in value.items(): + assert_finite_tree(child, f"{path}.{key}") + elif isinstance(value, list): + for index, child in enumerate(value): + assert_finite_tree(child, f"{path}[{index}]") + elif isinstance(value, (float, np.floating)) and not math.isfinite(float(value)): + raise FloatingPointError(f"Non-finite result at {path}: {value}") + + +def build_candidate_gallery( + cohort: pd.DataFrame, max_positives: int, negative_ratio: int, seed: int, +) -> tuple[np.ndarray, np.ndarray, np.ndarray, dict]: + labels_text = cohort["label"].astype(str).to_numpy() + label_names = np.array(sorted(set(labels_text)), dtype=object) + label_to_id = {label: index for index, label in enumerate(label_names)} + labels = np.array([label_to_id[value] for value in labels_text], dtype=np.int32) + species = cohort["species"].fillna("").astype(str).to_numpy() + lengths = cohort["length"].to_numpy(dtype=np.int16) + v_call = cohort["v_call"].fillna("").astype(str).to_numpy() + j_call = cohort["j_call"].fillna("").astype(str).to_numpy() + by_label = {label: np.flatnonzero(labels == label) for label in range(len(label_names))} + by_label_species_length: dict[tuple[int, str, int], np.ndarray] = {} + by_label_species_length_vj: dict[tuple[int, str, int, str, str], np.ndarray] = {} + by_label_species_length_v: dict[tuple[int, str, int, str], np.ndarray] = {} + by_label_species_length_j: dict[tuple[int, str, int, str], np.ndarray] = {} + by_label_species: dict[tuple[int, str], dict[int, np.ndarray]] = {} + by_label_length: dict[tuple[int, int], np.ndarray] = {} + for label, indices in by_label.items(): + for sp in sorted(set(species[indices])): + sp_indices = indices[species[indices] == sp] + lengths_map = {} + for length in sorted(set(lengths[sp_indices])): + values = sp_indices[lengths[sp_indices] == length] + by_label_species_length[(label, sp, int(length))] = values + for v_value in sorted(set(v_call[values])): + by_label_species_length_v[(label, sp, int(length), v_value)] = values[ + v_call[values] == v_value + ] + for j_value in sorted(set(j_call[values])): + by_label_species_length_j[(label, sp, int(length), j_value)] = values[ + j_call[values] == j_value + ] + for v_value, j_value in sorted(set(zip(v_call[values], j_call[values]))): + by_label_species_length_vj[( + label, sp, int(length), v_value, j_value + )] = values[(v_call[values] == v_value) & (j_call[values] == j_value)] + lengths_map[int(length)] = values + by_label_species[(label, sp)] = lengths_map + for length in sorted(set(lengths[indices])): + by_label_length[(label, int(length))] = indices[lengths[indices] == length] + + width = max_positives * (negative_ratio + 1) + candidates = np.full((len(cohort), width), -1, dtype=np.int32) + relevant = np.zeros((len(cohort), width), dtype=bool) + tiers = np.full((len(cohort), width), -1, dtype=np.int8) + tier_counts: dict[str, int] = {} + + def choose_group(query: int, negative_label: int) -> tuple[np.ndarray, int]: + exact_vj = by_label_species_length_vj.get(( + negative_label, species[query], int(lengths[query]), v_call[query], j_call[query] + )) + if exact_vj is not None: + return exact_vj, 0 + one_gene = [ + group for group in ( + by_label_species_length_v.get(( + negative_label, species[query], int(lengths[query]), v_call[query] + )), + by_label_species_length_j.get(( + negative_label, species[query], int(lengths[query]), j_call[query] + )), + ) if group is not None + ] + if one_gene: + return min(one_gene, key=len), 1 + exact = by_label_species_length.get( + (negative_label, species[query], int(lengths[query])) + ) + if exact is not None: + return exact, 2 + same_species = by_label_species.get((negative_label, species[query])) + if same_species: + nearest_length = min( + same_species, key=lambda value: (abs(value - int(lengths[query])), value) + ) + return same_species[nearest_length], 3 + available_lengths = sorted( + length for (label, length) in by_label_length if label == negative_label + ) + nearest_length = min( + available_lengths, key=lambda value: (abs(value - int(lengths[query])), value) + ) + return by_label_length[(negative_label, nearest_length)], 4 + + for query in range(len(cohort)): + rng = np.random.default_rng(seed + query * 1_000_003) + positive_pool = by_label[int(labels[query])] + positive_pool = positive_pool[positive_pool != query] + n_positive = min(max_positives, len(positive_pool)) + if n_positive < 1: + raise ValueError(f"Query {query} has no same-epitope candidate.") + positives = ( + positive_pool if len(positive_pool) == n_positive + else positive_pool[np.sort(rng.choice(len(positive_pool), n_positive, replace=False))] + ) + candidates[query, :n_positive] = positives + relevant[query, :n_positive] = True + tiers[query, :n_positive] = 0 + + quota = negative_ratio * n_positive + other_labels = np.delete(np.arange(len(label_names), dtype=np.int32), labels[query]) + selected: list[int] = [] + selected_tiers: list[int] = [] + if quota > len(other_labels): + raise ValueError("Negative quota exceeds the number of other epitope labels.") + for negative_label in rng.permutation(other_labels)[:quota]: + group, tier = choose_group(query, int(negative_label)) + selected.append(int(group[rng.integers(len(group))])) + selected_tiers.append(tier) + start = n_positive + stop = start + quota + candidates[query, start:stop] = selected + tiers[query, start:stop] = selected_tiers + for tier in selected_tiers: + name = { + 0: "same_species_length_vj", 1: "same_species_length_one_gene", + 2: "same_species_length", 3: "same_species_nearest_length", + 4: "nearest_length_any_species", + }[tier] + tier_counts[name] = tier_counts.get(name, 0) + 1 + return candidates, relevant, tiers, { + "queries": len(cohort), "width": width, "max_positives": max_positives, + "negative_ratio": negative_ratio, "selection_seed": seed, + "negative_match_tiers": dict(sorted(tier_counts.items())), + "label_names": label_names.tolist(), + } + + +def candidate_distances( + features: np.ndarray, candidates: np.ndarray, metric: str, chunk_size: int = 4096, +) -> tuple[np.ndarray, dict]: + values = np.asarray(features, dtype=np.float32) + norms = np.linalg.norm(values, axis=1) + if not np.isfinite(values).all() or np.any(norms == 0): + raise ValueError("Features are non-finite or contain a zero-norm row.") + output = np.full(candidates.shape, np.inf, dtype=np.float32) + for start in range(0, len(values), chunk_size): + stop = min(start + chunk_size, len(values)) + ids = candidates[start:stop] + valid = ids >= 0 + safe = np.maximum(ids, 0) + query = values[start:stop, None, :] + gallery = values[safe] + if metric == "cosine": + query = query / norms[start:stop, None, None] + gallery = gallery / norms[safe, None] + block = 1.0 - np.sum(query * gallery, axis=2) + elif metric == "euclidean": + block = np.linalg.norm(query - gallery, axis=2) + else: + raise ValueError(metric) + output[start:stop][valid] = np.maximum(block[valid], 0.0) + return output, { + "latent_norm_min": float(norms.min()), "latent_norm_median": float(np.median(norms)), + "latent_norm_max": float(norms.max()), + "euclidean_scale_note": "raw latent Euclidean distance; compare retrieval/effect, not absolute scale", + } + + +def _majority_label(labels: np.ndarray, distances: np.ndarray) -> int: + unique, counts = np.unique(labels, return_counts=True) + winners = unique[counts == counts.max()] + if len(winners) == 1: + return int(winners[0]) + first_rank = {int(label): int(np.flatnonzero(labels == label)[0]) for label in winners} + return min((int(label) for label in winners), key=lambda value: (first_rank[value], value)) + + +def summarize_candidates( + distances: np.ndarray, + candidates: np.ndarray, + relevant: np.ndarray, + label_ids: np.ndarray, + label_names: list[str], +) -> tuple[dict, pd.DataFrame, pd.DataFrame]: + rows = [] + predictions = {1: np.empty(len(distances), dtype=np.int32), + 5: np.empty(len(distances), dtype=np.int32), + 10: np.empty(len(distances), dtype=np.int32)} + for query in range(len(distances)): + valid = candidates[query] >= 0 + order = np.argsort(distances[query, valid], kind="mergesort") + hits = relevant[query, valid][order] + ranked_candidates = candidates[query, valid][order] + ranked_labels = label_ids[ranked_candidates] + positive_count = int(hits.sum()) + precision_curve = np.cumsum(hits) / np.arange(1, len(hits) + 1) + within = distances[query, relevant[query]] + between = distances[query, valid & ~relevant[query]] + row = { + "query_index": query, "label": label_names[int(label_ids[query])], + "positive_candidates": positive_count, + "negative_candidates": int(len(hits) - positive_count), + "precision_at_1": float(hits[:1].mean()), + "precision_at_5": float(hits[:5].mean()), + "precision_at_10": float(hits[:10].mean()), + "average_precision": float((precision_curve * hits).sum() / positive_count), + "within_mean": float(within.mean()), "between_mean": float(between.mean()), + "within_between_ratio": float(within.mean() / between.mean()), + "between_minus_within": float(between.mean() - within.mean()), + "nearest_same": float(within.min()), "nearest_other": float(between.min()), + "nearest_margin": float(between.min() - within.min()), + "nearest_same_is_closer": float(within.min() < between.min()), + } + rows.append(row) + for k in predictions: + predictions[k][query] = _majority_label(ranked_labels[:k], distances[query, valid][order][:k]) + per_query = pd.DataFrame(rows) + per_label = per_query.groupby("label", sort=True)[list(METRIC_COLUMNS) + [ + "nearest_same_is_closer", "within_mean", "between_mean" + ]].mean().reset_index() + summary = { + "queries": len(per_query), + "macro_epitope": {column: float(per_label[column].mean()) for column in METRIC_COLUMNS}, + "micro_query": {column: float(per_query[column].mean()) for column in METRIC_COLUMNS}, + "nearest_same_is_closer_macro": float(per_label["nearest_same_is_closer"].mean()), + "knn_classification": {}, + } + for k, prediction in predictions.items(): + precision, recall, f1, support = precision_recall_fscore_support( + label_ids, prediction, labels=np.arange(len(label_names)), zero_division=0 + ) + summary["knn_classification"][f"k_{k}"] = { + "macro_f1": float(f1_score(label_ids, prediction, average="macro")), + "weighted_f1": float(f1_score(label_ids, prediction, average="weighted")), + "balanced_accuracy": float(balanced_accuracy_score(label_ids, prediction)), + } + f1_lookup = {label_names[index]: float(f1[index]) for index in range(len(label_names))} + per_label[f"knn_f1_at_{k}"] = per_label["label"].map(f1_lookup) + return summary, per_query, per_label + + +def clustering_metrics(features: np.ndarray, label_ids: np.ndarray, seed: int, sample: int) -> dict: + values = np.asarray(features, dtype=np.float64) + unit = values / np.linalg.norm(values, axis=1, keepdims=True) + n_labels = len(np.unique(label_ids)) + kmeans = MiniBatchKMeans( + n_clusters=n_labels, random_state=seed, n_init=10, batch_size=4096, + max_iter=300, reassignment_ratio=0.01, + ).fit(unit) + predicted = kmeans.labels_ + sample_size = min(sample, len(unit)) + return { + "true_label_geometry": { + "silhouette_cosine": float(silhouette_score( + unit, label_ids, metric="cosine", sample_size=sample_size, random_state=seed + )), + "silhouette_euclidean_unit": float(silhouette_score( + unit, label_ids, metric="euclidean", sample_size=sample_size, random_state=seed + )), + "davies_bouldin_unit_lower_is_better": float(davies_bouldin_score(unit, label_ids)), + "calinski_harabasz_unit_higher_is_better": float(calinski_harabasz_score(unit, label_ids)), + }, + "label_free_minibatch_kmeans_k_equals_epitopes": { + "adjusted_rand": float(adjusted_rand_score(label_ids, predicted)), + "adjusted_mutual_information": float(adjusted_mutual_info_score(label_ids, predicted)), + "v_measure": float(v_measure_score(label_ids, predicted)), + "homogeneity": float(homogeneity_score(label_ids, predicted)), + "completeness": float(completeness_score(label_ids, predicted)), + "inertia": float(kmeans.inertia_), "n_init": 10, "seed": seed, + }, + "interpretation": ( + "Secondary: epitopes can contain multiple REDCEA motifs, so a one-cluster-per-epitope " + "K-means geometry is not assumed by the primary retrieval/contrast analysis." + ), + } + + +def baseline_features(cohort: pd.DataFrame) -> dict[str, np.ndarray]: + amino = "ACDEFGHIKLMNPQRSTVWY" + composition = np.zeros((len(cohort), len(amino)), dtype=np.float32) + for row, sequence in enumerate(cohort["cdr3"].astype(str)): + for column, aa in enumerate(amino): + composition[row, column] = sequence.count(aa) / len(sequence) + length = cohort["length"].to_numpy(np.float32)[:, None] + length = (length - length.mean()) / max(float(length.std()), 1e-8) + basic = np.concatenate((composition, length), axis=1) + genes = pd.get_dummies( + cohort[["v_call", "j_call"]].fillna("").astype(str), dtype=np.float32 + ).to_numpy(np.float32) + return {"aa_composition_length": basic, "aa_composition_length_vj": np.concatenate((basic, genes), axis=1)} + + +def bootstrap_by_epitope(per_label: pd.DataFrame, replicates: int, seed: int) -> dict: + labels = sorted(per_label["label"].unique()) + rng = np.random.default_rng(seed) + samples = rng.integers(0, len(labels), size=(replicates, len(labels))) + report = {"replicates": replicates, "unit": "epitope label", "paired_rtp_minus_other": {}} + for distance in ("cosine", "euclidean"): + block = per_label[per_label["distance"] == distance] + arrays = { + model: block[block["model"] == model].set_index("label").loc[labels] + for model in PRIMARY_MODELS + } + report["paired_rtp_minus_other"][distance] = {} + for other in PRIMARY_MODELS[:-1]: + metrics = {} + for column in METRIC_COLUMNS: + delta = arrays["rtp"][column].to_numpy() - arrays[other][column].to_numpy() + boot = delta[samples].mean(axis=1) + metrics[column] = { + "estimate": float(delta.mean()), + "ci95": [float(np.percentile(boot, 2.5)), float(np.percentile(boot, 97.5))], + "direction": "lower is better" if column == "within_between_ratio" else "higher is better", + } + report["paired_rtp_minus_other"][distance][other] = metrics + return report + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--preflight", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--max-positive-candidates", type=int, default=20) + parser.add_argument("--negative-ratio", type=int, default=4) + parser.add_argument("--bootstrap", type=int, default=2000) + parser.add_argument("--silhouette-sample", type=int, default=10000) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def main() -> None: + from benchmark.evaluate_vdjdb_frozen import ( + extract_embeddings, parse_models, validate_run_configs, + ) + + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + preflight = json.loads(args.preflight.read_text(encoding="utf-8")) + if preflight["status"] != "accepted_for_frozen_embedding_evaluation": + raise ValueError("Cohort preflight is not accepting.") + if sha256(args.cohort) != preflight["cohort"]["sha256"]: + raise ValueError("Cohort differs from accepted preflight.") + cohort = pd.read_csv(args.cohort, sep="\t") + if cohort["cdr3"].duplicated().any() or (cohort.groupby("label").size() < 20).any(): + raise ValueError("Cohort violates uniqueness or minimum-support rules.") + models = parse_models(args.model) + if tuple(sorted(models)) != tuple(sorted(PRIMARY_MODELS)): + raise ValueError("The full seven-condition factorial is required.") + config, model_report = validate_run_configs(models) + embeddings, extraction = extract_embeddings( + cohort, models, config, args.tokenizer, args.batch_size, args.output_dir + ) + candidates, relevant, tiers, gallery_report = build_candidate_gallery( + cohort, args.max_positive_candidates, args.negative_ratio, args.seed + ) + gallery_path = args.output_dir / "candidate_gallery.npz" + np.savez_compressed(gallery_path, candidates=candidates, relevant=relevant, match_tier=tiers) + label_names = gallery_report["label_names"] + label_to_id = {label: index for index, label in enumerate(label_names)} + label_ids = np.array([label_to_id[value] for value in cohort["label"].astype(str)], dtype=np.int32) + + summaries = {} + clustering = {} + per_labels = [] + for model in PRIMARY_MODELS: + summaries[model] = {} + for metric in ("cosine", "euclidean"): + distances, norm_report = candidate_distances(embeddings[model], candidates, metric) + summary, per_query, per_label = summarize_candidates( + distances, candidates, relevant, label_ids, label_names + ) + summary["embedding_norms"] = norm_report + summaries[model][metric] = summary + per_query.to_parquet(args.output_dir / f"per_query_{model}_{metric}.parquet", index=False) + per_label.insert(0, "model", model) + per_label.insert(1, "distance", metric) + per_labels.append(per_label) + clustering[model] = clustering_metrics( + embeddings[model], label_ids, args.seed, args.silhouette_sample + ) + + controls = {} + for name, features in baseline_features(cohort).items(): + controls[name] = {"retrieval": {}, "clustering": clustering_metrics( + features, label_ids, args.seed, args.silhouette_sample + )} + for metric in ("cosine", "euclidean"): + distances, _ = candidate_distances(features, candidates, metric) + summary, _, _ = summarize_candidates( + distances, candidates, relevant, label_ids, label_names + ) + controls[name]["retrieval"][metric] = summary + + per_label_table = pd.concat(per_labels, ignore_index=True) + per_label_path = args.output_dir / "per_epitope_metrics.tsv" + per_label_table.to_csv(per_label_path, sep="\t", index=False, lineterminator="\n") + bootstrap = bootstrap_by_epitope(per_label_table, args.bootstrap, args.seed) + chance = { + "candidate_positive_fraction": float(relevant.sum() / (candidates >= 0).sum()), + "expected_precision_at_k_under_random_ranking": float( + relevant.sum() / (candidates >= 0).sum() + ), + "note": "Candidate prevalence is fixed at 1:4 positive:negative; MAP chance varies slightly with gallery size.", + } + assert_finite_tree(summaries, "summaries") + assert_finite_tree(clustering, "clustering") + assert_finite_tree(controls, "controls") + assert_finite_tree(bootstrap, "bootstrap") + stable_json(args.output_dir / "metrics.json", summaries) + stable_json(args.output_dir / "clustering.json", clustering) + stable_json(args.output_dir / "controls.json", controls) + stable_json(args.output_dir / "bootstrap.json", bootstrap) + artifact_hashes = { + path.name: sha256(path) for path in sorted(args.output_dir.iterdir()) if path.is_file() + } + result = { + "status": "complete", "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "study": "REDCEA motif-member per-clonotype geometry across seven matched DATA-ANCHOR encoders", + "cohort": {"path": str(args.cohort), "sha256": sha256(args.cohort), + "clonotypes": len(cohort), "epitopes": int(cohort["label"].nunique())}, + "models": model_report, "extraction": extraction, + "candidate_gallery": {**gallery_report, "path": str(gallery_path), "sha256": sha256(gallery_path)}, + "chance_control": chance, + "primary_metrics": ["macro P@1/5/10", "macro MAP over fixed candidate gallery", + "within/between distance ratio", "nearest-same margin", "kNN macro-F1"], + "secondary_metrics": ["silhouette", "Davies-Bouldin", "Calinski-Harabasz", + "MiniBatchKMeans ARI/AMI/V-measure"], + "selection_statement": "No VDJdb outcome selected a checkpoint, model, gallery member, or support threshold.", + "circularity_caveat": ( + "REDCEA membership is sequence/TCRemP-cluster-conditioned. This measures organization of " + "REDCEA-supported epitope labels, not independent binding prediction beyond sequence motifs." + ), + "single_seed_caveat": ( + "Paired intervals quantify cohort/epitope uncertainty for fixed seed-42 models, not training-seed variability." + ), + "artifact_sha256": artifact_hashes, "nonfinite_scan": "passed", + } + stable_json(args.output_dir / "RESULTS.json", result) + print(json.dumps(result, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_uniform100.py b/benchmark/evaluate_vdjdb_uniform100.py new file mode 100644 index 0000000..dc0c9d8 --- /dev/null +++ b/benchmark/evaluate_vdjdb_uniform100.py @@ -0,0 +1,163 @@ +"""Uniform 100-within / 100-between cosine-distance evaluation for Section 7. + +Only epitopes with at least 101 unique clonotypes are retained. For every +retained query, 100 distinct same-epitope comparators and 100 distinct +different-epitope comparators are drawn without replacement. The candidate +pairs are deterministic and shared by all representations. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd + + +N_WITHIN = 100 +N_BETWEEN = 100 +SEED = 42 + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--native-evaluation", type=Path, required=True) + parser.add_argument("--external-representations", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--seed", type=int, default=SEED) + return parser.parse_args() + + +def build_pairs(labels: np.ndarray, seed: int) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + counts = pd.Series(labels).value_counts() + eligible_labels = np.array(sorted(counts[counts >= N_WITHIN + 1].index), dtype=object) + keep = np.isin(labels, eligible_labels) + original_indices = np.flatnonzero(keep) + retained_labels = labels[keep] + groups = {label: np.flatnonzero(retained_labels == label) for label in eligible_labels} + all_indices = np.arange(len(retained_labels), dtype=np.int32) + within = np.empty((len(retained_labels), N_WITHIN), dtype=np.int32) + between = np.empty((len(retained_labels), N_BETWEEN), dtype=np.int32) + + for query in range(len(retained_labels)): + rng = np.random.default_rng(seed + int(original_indices[query]) * 1_000_003) + label = retained_labels[query] + same = groups[label] + same = same[same != query] + within[query] = rng.choice(same, size=N_WITHIN, replace=False) + other = all_indices[retained_labels != label] + between[query] = rng.choice(other, size=N_BETWEEN, replace=False) + return original_indices, within, between + + +def cosine_summary( + matrix: np.ndarray, within: np.ndarray, between: np.ndarray, + labels: np.ndarray, batch_size: int = 256, +) -> tuple[pd.DataFrame, pd.DataFrame]: + values = np.asarray(matrix, dtype=np.float32) + norms = np.linalg.norm(values, axis=1, keepdims=True) + if np.any(norms == 0) or not np.isfinite(values).all(): + raise ValueError("Embedding matrix contains a zero-norm or non-finite vector.") + unit = values / norms + within_mean = np.empty(len(unit), dtype=np.float32) + between_mean = np.empty(len(unit), dtype=np.float32) + for start in range(0, len(unit), batch_size): + stop = min(start + batch_size, len(unit)) + query = unit[start:stop] + within_mean[start:stop] = (1.0 - np.sum(query[:, None] * unit[within[start:stop]], axis=2)).mean(axis=1) + between_mean[start:stop] = (1.0 - np.sum(query[:, None] * unit[between[start:stop]], axis=2)).mean(axis=1) + per_query = pd.DataFrame({ + "epitope": labels, + "within_mean": within_mean, + "between_mean": between_mean, + "within_between_ratio": within_mean / between_mean, + "between_minus_within": between_mean - within_mean, + }) + per_epitope = per_query.groupby("epitope", sort=True).agg( + queries=("epitope", "size"), + within_mean=("within_mean", "mean"), + between_mean=("between_mean", "mean"), + within_between_ratio=("within_between_ratio", "mean"), + between_minus_within=("between_minus_within", "mean"), + ).reset_index() + return per_query, per_epitope + + +def main() -> None: + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + cohort = pd.read_csv(args.cohort, sep="\t") + labels = cohort["label"].astype(str).to_numpy() + original_indices, within, between = build_pairs(labels, args.seed) + retained = cohort.iloc[original_indices].reset_index(drop=True) + np.savez_compressed(args.output_dir / "uniform_pairs.npz", within=within, between=between, original_indices=original_indices) + + native = { + "RTP": args.native_evaluation / "embeddings_rtp.npy", + "RP": args.native_evaluation / "embeddings_rp.npy", + "T": args.native_evaluation / "embeddings_t.npy", + } + catalog = json.loads((args.external_representations / "representations.json").read_text(encoding="utf-8")) + external = { + "ESM2-35M": Path(catalog["esm2_35m"]["path"]), + "TCR-BERT": Path(catalog["tcr_bert"]["path"]), + "SCEPTR (CDR3-only)": Path(catalog["sceptr_cdr3"]["path"]), + } + summary_rows = [] + all_epitopes = [] + for name, path in {**native, **external}.items(): + matrix = np.load(path, mmap_mode="r")[original_indices] + per_query, per_epitope = cosine_summary(matrix, within, between, retained["label"].astype(str).to_numpy()) + per_query.insert(0, "model", name) + per_query.to_parquet(args.output_dir / f"per_query_{name.lower().replace(' ', '_').replace('(', '').replace(')', '')}.parquet", index=False) + per_epitope.insert(0, "model", name) + all_epitopes.append(per_epitope) + summary_rows.append({ + "model": name, + "macro_within_between_ratio": float(per_epitope["within_between_ratio"].mean()), + "macro_between_minus_within": float(per_epitope["between_minus_within"].mean()), + "micro_within_between_ratio": float(per_query["within_mean"].mean() / per_query["between_mean"].mean()), + "queries": len(per_query), + "epitopes": len(per_epitope), + }) + pd.DataFrame(summary_rows).to_csv(args.output_dir / "summary.tsv", sep="\t", index=False, lineterminator="\n") + pd.concat(all_epitopes, ignore_index=True).to_csv(args.output_dir / "per_epitope.tsv", sep="\t", index=False, lineterminator="\n") + result = { + "status": "complete", + "protocol": { + "metric": "cosine distance", + "within_candidates_per_query": N_WITHIN, + "between_candidates_per_query": N_BETWEEN, + "within_sampling": "uniform without replacement from same epitope, excluding query", + "between_sampling": "uniform without replacement from all different-epitope clonotypes", + "pair_seed": args.seed, + "query_seed": "seed + original_cohort_index * 1,000,003", + }, + "cohort": { + "source": str(args.cohort), "source_sha256": sha256(args.cohort), + "retained_clonotypes": len(retained), "retained_epitopes": int(retained["label"].nunique()), + "minimum_epitope_size": N_WITHIN + 1, + }, + "models": list(native) + list(external), + "artifacts": {name: sha256(args.output_dir / name) for name in ("uniform_pairs.npz", "summary.tsv", "per_epitope.tsv")}, + } + (args.output_dir / "RESULTS.json").write_text(json.dumps(result, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(json.dumps(result, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_uniform100_separation.py b/benchmark/evaluate_vdjdb_uniform100_separation.py new file mode 100644 index 0000000..c2e1705 --- /dev/null +++ b/benchmark/evaluate_vdjdb_uniform100_separation.py @@ -0,0 +1,93 @@ +"""AUROC and standardized distance separation on the fixed uniform-100 pairs.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +import numpy as np +import pandas as pd + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--native-evaluation", type=Path, required=True) + parser.add_argument("--external-representations", type=Path, required=True) + parser.add_argument("--uniform-evaluation", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + return parser.parse_args() + + +def separation_metrics( + matrix: np.ndarray, within: np.ndarray, between: np.ndarray, labels: np.ndarray, + batch_size: int = 256, +) -> tuple[pd.DataFrame, pd.DataFrame]: + values = np.asarray(matrix, dtype=np.float32) + norms = np.linalg.norm(values, axis=1, keepdims=True) + if np.any(norms == 0) or not np.isfinite(values).all(): + raise ValueError("Embedding matrix contains a zero-norm or non-finite vector.") + unit = values / norms + n_within, n_between = within.shape[1], between.shape[1] + auroc = np.empty(len(unit), dtype=np.float32) + cohen_d = np.empty(len(unit), dtype=np.float32) + for start in range(0, len(unit), batch_size): + stop = min(start + batch_size, len(unit)) + query = unit[start:stop] + d_within = 1.0 - np.sum(query[:, None] * unit[within[start:stop]], axis=2) + d_between = 1.0 - np.sum(query[:, None] * unit[between[start:stop]], axis=2) + ordered = np.argsort(np.concatenate([d_within, d_between], axis=1), axis=1) + ranks = np.empty_like(ordered) + ranks[np.arange(stop-start)[:, None], ordered] = np.arange(1, n_within+n_between+1) + positive_rank_sum = ranks[:, :n_within].sum(axis=1) + auroc[start:stop] = ( + n_within * n_between - (positive_rank_sum - n_within * (n_within + 1) / 2) + ) / (n_within * n_between) + pooled_sd = np.sqrt((d_within.var(axis=1, ddof=1) + d_between.var(axis=1, ddof=1)) / 2) + cohen_d[start:stop] = (d_between.mean(axis=1) - d_within.mean(axis=1)) / pooled_sd + per_query = pd.DataFrame({"epitope": labels, "auroc": auroc, "cohen_d": cohen_d}) + per_epitope = per_query.groupby("epitope", sort=True).agg( + queries=("epitope", "size"), auroc=("auroc", "mean"), cohen_d=("cohen_d", "mean"), + ).reset_index() + return per_query, per_epitope + + +def main() -> None: + args = parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + cohort = pd.read_csv(args.cohort, sep="\t") + pairs = np.load(args.uniform_evaluation / "uniform_pairs.npz") + original = pairs["original_indices"] + within, between = pairs["within"], pairs["between"] + labels = cohort.iloc[original]["label"].astype(str).to_numpy() + catalog = json.loads((args.external_representations / "representations.json").read_text(encoding="utf-8")) + paths = { + "RTP": args.native_evaluation / "embeddings_rtp.npy", + "RP": args.native_evaluation / "embeddings_rp.npy", + "T": args.native_evaluation / "embeddings_t.npy", + "ESM2-35M": Path(catalog["esm2_35m"]["path"]), + "TCR-BERT": Path(catalog["tcr_bert"]["path"]), + "SCEPTR (CDR3-only)": Path(catalog["sceptr_cdr3"]["path"]), + } + summary, per_epitope = [], [] + for name, path in paths.items(): + query, epitope = separation_metrics(np.load(path, mmap_mode="r")[original], within, between, labels) + query.insert(0, "model", name) + query.to_parquet(args.output_dir / f"per_query_{name.lower().replace(' ', '_').replace('(', '').replace(')', '')}.parquet", index=False) + epitope.insert(0, "model", name) + per_epitope.append(epitope) + summary.append({"model": name, "macro_auroc": float(epitope["auroc"].mean()), "macro_cohen_d": float(epitope["cohen_d"].mean()), "queries":len(query), "epitopes":len(epitope)}) + pd.DataFrame(summary).to_csv(args.output_dir / "summary.tsv", sep="\t", index=False, lineterminator="\n") + pd.concat(per_epitope, ignore_index=True).to_csv(args.output_dir / "per_epitope.tsv", sep="\t", index=False, lineterminator="\n") + (args.output_dir / "RESULTS.json").write_text(json.dumps({ + "status":"complete", "pairs":str(args.uniform_evaluation / "uniform_pairs.npz"), + "metrics":{"auroc":"P(within distance < between distance)", "cohen_d":"(mean between - mean within) / pooled within/between distance SD"}, + "queries":len(labels), "epitopes":int(pd.Series(labels).nunique()), "models":list(paths), + }, indent=2, sort_keys=True)+"\n", encoding="utf-8") + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_viral_motif_top10.py b/benchmark/evaluate_vdjdb_viral_motif_top10.py new file mode 100644 index 0000000..ad869d0 --- /dev/null +++ b/benchmark/evaluate_vdjdb_viral_motif_top10.py @@ -0,0 +1,425 @@ +"""Evaluate seven frozen DATA-ANCHOR head combinations on ten viral epitopes.""" + +from __future__ import annotations + +import argparse +import json +import os +from pathlib import Path + +import numpy as np +import pandas as pd + +from benchmark.evaluate_vdjdb_frozen import ( + assert_finite_tree, + extract_embeddings, + sha256, + stable_json, +) +from benchmark.evaluate_vdjdb_ylq_motif_pooled import ( + bootstrap_clonotypes, + composition_features, + pair_metrics, + pooled_retrieval, + primary_distances, + shuffled_label_control, + vector_distance, + vj_pair_values, +) +from irrm_codec.multitask_transformer import IRRMCodecConfig + + +MODEL_NAMES = ("r", "t", "p", "rt", "rp", "tp", "rtp") +EXPECTED_WEIGHTS = { + "r": (1.0, 0.0, 0.0), + "t": (0.0, 1.0, 0.0), + "p": (0.0, 0.0, 1.0), + "rt": (1.0, 1.0, 0.0), + "rp": (1.0, 0.0, 1.0), + "tp": (0.0, 1.0, 1.0), + "rtp": (1.0, 1.0, 1.0), +} +PARAMETER_COUNT = 21_535_913 + + +def parse_seven_models(values: list[str]) -> dict[str, tuple[Path, Path]]: + result = {} + for value in values: + fields = value.split(":", 2) + if len(fields) != 3: + raise ValueError(f"Invalid --model value: {value!r}") + name, checkpoint, config = fields + if name in result: + raise ValueError(f"Duplicate model name: {name}") + result[name] = (Path(checkpoint), Path(config)) + if set(result) != set(MODEL_NAMES): + raise ValueError(f"Exact required model names are {', '.join(MODEL_NAMES)}.") + return {name: result[name] for name in MODEL_NAMES} + + +def validate_seven_configs( + models: dict[str, tuple[Path, Path]], +) -> tuple[IRRMCodecConfig, dict]: + configs = { + name: json.loads(path.read_text(encoding="utf-8")) + for name, (_, path) in models.items() + } + reference = configs["rtp"] + ignored = {"output_dir", "reconstruction_loss_weight", "tcremp_loss_weight", "pgen_loss_weight"} + reference_training = { + key: value for key, value in reference["training"].items() if key not in ignored + } + report = {} + for name in MODEL_NAMES: + payload = configs[name] + if payload["model"] != reference["model"]: + raise ValueError(f"{name} architecture differs from RTP.") + comparable = { + key: value for key, value in payload["training"].items() if key not in ignored + } + if comparable != reference_training: + differing = sorted( + key for key in set(comparable) | set(reference_training) + if comparable.get(key) != reference_training.get(key) + ) + raise ValueError(f"{name} has non-weight training differences: {differing}") + weights = ( + float(payload["training"]["reconstruction_loss_weight"]), + float(payload["training"]["tcremp_loss_weight"]), + float(payload["training"]["pgen_loss_weight"]), + ) + if weights != EXPECTED_WEIGHTS[name]: + raise ValueError(f"{name} has weights {weights}; expected {EXPECTED_WEIGHTS[name]}.") + if int(payload["parameter_count"]) != PARAMETER_COUNT: + raise ValueError(f"{name} parameter count is not {PARAMETER_COUNT}.") + report[name] = { + "checkpoint": str(models[name][0]), + "checkpoint_sha256": sha256(models[name][0]), + "run_config": str(models[name][1]), + "run_config_sha256": sha256(models[name][1]), + "loss_weights_reconstruction_tcremp_pgen": list(weights), + "parameter_count": int(payload["parameter_count"]), + } + return IRRMCodecConfig(**reference["model"]), report + + +def validate_epitope_tables(directory: Path, report: dict) -> tuple[pd.DataFrame, pd.DataFrame]: + candidates_path = directory / "candidates.tsv" + pairs_path = directory / "pair_manifest.tsv" + if sha256(candidates_path) != report["artifacts"]["candidates_sha256"] \ + or sha256(pairs_path) != report["artifacts"]["pairs_sha256"]: + raise ValueError(f"Preflight artifacts changed in {directory}.") + candidates = pd.read_csv(candidates_path, sep="\t") + pairs = pd.read_csv(pairs_path, sep="\t") + if candidates["cdr3"].duplicated().any(): + raise ValueError(f"Duplicate CDR3 in {directory}.") + if set(candidates["mhc_a"]) != {"HLA-A*02:01"} \ + or set(candidates["mhc_b"]) != {"B2M"} \ + or set(candidates["mhc_class"]) != {"MHCI"}: + raise ValueError(f"Context mismatch in {directory}.") + if candidates["motif_cids"].fillna("").eq("").any(): + raise ValueError(f"Missing official motif membership in {directory}.") + labels = candidates["is_target"].to_numpy(int) + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + if not (np.all(labels[q] == 1) and np.all(labels[p] == 1) and np.all(labels[n] == 0)): + raise ValueError(f"Invalid target/negative triplets in {directory}.") + if not np.all(candidates["length"].to_numpy(int)[p] + == candidates["length"].to_numpy(int)[n]): + raise ValueError(f"Non-exact-length negative comparator in {directory}.") + return candidates, pairs + + +def summarize_distribution(rows: pd.DataFrame) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: + summary_rows = [] + win_rows = [] + for (distance, metric, model), group in rows.groupby(["distance", "metric", "model"]): + values = group["value"].to_numpy(float) + summary_rows.append({ + "distance": distance, + "metric": metric, + "model": model, + "epitopes": len(values), + "median": float(np.median(values)), + "q1": float(np.percentile(values, 25)), + "q3": float(np.percentile(values, 75)), + }) + lower_better = {"within_between_ratio"} + for (distance, metric, epitope), group in rows.groupby(["distance", "metric", "epitope"]): + target = group["value"].min() if metric in lower_better else group["value"].max() + winners = sorted(group.loc[np.isclose(group["value"], target), "model"].tolist()) + for model in winners: + win_rows.append({ + "distance": distance, + "metric": metric, + "epitope": epitope, + "model": model, + "tied_winners": len(winners), + "fractional_win": 1.0 / len(winners), + }) + wins = pd.DataFrame(win_rows) + win_summary = wins.groupby(["distance", "metric", "model"], as_index=False).agg( + win_count=("fractional_win", "sum"), + epitopes_with_best_or_tied=("epitope", "count"), + ) + complete = pd.MultiIndex.from_product( + [sorted(rows["distance"].unique()), sorted(rows["metric"].unique()), MODEL_NAMES], + names=["distance", "metric", "model"], + ).to_frame(index=False) + win_summary = complete.merge( + win_summary, on=["distance", "metric", "model"], how="left" + ).fillna({"win_count": 0.0, "epitopes_with_best_or_tied": 0}) + win_summary["epitopes_with_best_or_tied"] = win_summary[ + "epitopes_with_best_or_tied" + ].astype(int) + return pd.DataFrame(summary_rows), wins, win_summary + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--preflight-dir", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--model", action="append", required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--bootstrap", type=int, default=2000) + parser.add_argument("--permutations", type=int, default=1000) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + + preflight = json.loads((args.preflight_dir / "PREFLIGHT.json").read_text(encoding="utf-8")) + expected_epitopes = int(preflight["support_gate"]["selected_epitopes"]) + if preflight["status"] != "ready" or len(preflight["selected"]) != expected_epitopes \ + or expected_epitopes < 2 or expected_epitopes > 10: + raise ValueError("Up-to-top-10 viral motif preflight is not accepting.") + master_path = args.preflight_dir / "master_candidates.tsv" + if sha256(master_path) != preflight["artifacts"]["master_candidates_sha256"]: + raise ValueError("Master candidate hash changed after CPU gate.") + master = pd.read_csv(master_path, sep="\t") + if master["cdr3"].duplicated().any(): + raise ValueError("Master candidates are not unique by exact CDR3.") + + models = parse_seven_models(args.model) + config, model_report = validate_seven_configs(models) + embeddings, extraction = extract_embeddings( + master, models, config, args.tokenizer, args.batch_size, args.output_dir + ) + master_index = {cdr3: index for index, cdr3 in enumerate(master["cdr3"].astype(str))} + metric_rows = [] + control_rows = [] + epitope_results = [] + paired_effect_rows = [] + for selected in preflight["selected"]: + rank = int(selected["rank"]) + epitope = selected["epitope"] + source_dir = args.preflight_dir / f"epitope-{rank:02d}-{epitope}" + target_dir = args.output_dir / f"epitope-{rank:02d}-{epitope}" + target_dir.mkdir() + candidates, pairs = validate_epitope_tables(source_dir, selected) + candidates = candidates.copy() + candidates["is_ylq"] = candidates["is_target"] + indices = np.asarray([master_index[value] for value in candidates["cdr3"].astype(str)]) + subset_embeddings = {name: array[indices] for name, array in embeddings.items()} + metrics = {"cosine": {}, "euclidean": {}} + bootstraps = {} + cosine_values = {} + for distance in ("cosine", "euclidean"): + pair_values = {} + retrieval_tables = {} + for name, array in subset_embeddings.items(): + within, between = primary_distances(array, pairs, distance) + pair_values[name] = (within, between) + retrieval, retrieval_table = pooled_retrieval(array, candidates, distance) + retrieval_tables[name] = retrieval_table + pair_result = pair_metrics(within, between) + metrics[distance][name] = { + "pairwise_and_contrast": pair_result, + "retrieval": retrieval, + } + values = { + "within_between_ratio": pair_result["within_between_ratio"], + "between_minus_within": pair_result["between_minus_within"], + "same_label_auroc": pair_result["same_label_auroc"], + "same_label_auprc_balanced": pair_result["same_label_auprc_balanced"], + "precision_at_1": retrieval["precision_at_1"], + "map_at_r": retrieval["map_at_r"], + } + for metric, value in values.items(): + metric_rows.append({ + "rank": rank, "epitope": epitope, "distance": distance, + "model": name, "metric": metric, "value": value, + }) + if int(selected["positive_cdr3"]) < 3: + bootstraps[distance] = { + "status": "not_estimable_with_fewer_than_three_target_clonotypes", + "requested_replicates": args.bootstrap, + } + else: + try: + bootstraps[distance] = bootstrap_clonotypes( + pair_values, pairs, retrieval_tables, args.bootstrap, + args.seed + rank * 1000, + ) + bootstraps[distance]["small_n_caveat"] = ( + "descriptive/unstable: fewer than 5 target clonotypes" + if int(selected["positive_cdr3"]) < 5 else "none" + ) + difference = bootstraps[distance][ + "paired_differences_rtp_minus_other" + ]["rp"] + for metric, payload in difference.items(): + paired_effect_rows.append({ + "rank": rank, "epitope": epitope, "distance": distance, + "metric": metric, "rtp_minus_rp_ci95_low": payload["ci95"][0], + "rtp_minus_rp_ci95_high": payload["ci95"][1], + "direction": payload["direction"], + }) + except (ValueError, ZeroDivisionError) as error: + bootstraps[distance] = { + "status": "not_estimable_at_available_target_support", + "reason": str(error), + "requested_replicates": args.bootstrap, + } + if distance == "cosine": + cosine_values = pair_values + + q = pairs["query_index"].to_numpy(int) + p = pairs["positive_index"].to_numpy(int) + n = pairs["negative_index"].to_numpy(int) + lengths = candidates["length"].to_numpy(float) + exact_length_result = pair_metrics( + np.abs(lengths[q] - lengths[p]), np.abs(lengths[q] - lengths[n]) + ) + controls = { + "exact_length": exact_length_result, + "amino_acid_composition": {}, + } + for metric in ("within_between_ratio", "between_minus_within", + "same_label_auroc", "same_label_auprc_balanced"): + control_rows.append({ + "rank": rank, "epitope": epitope, "distance": "absolute", + "control": "exact_cdr3_length", "metric": metric, + "value": exact_length_result[metric], + }) + composition = composition_features(candidates) + for distance in ("cosine", "euclidean"): + result = pair_metrics( + vector_distance(composition[q], composition[p], distance), + vector_distance(composition[q], composition[n], distance), + ) + controls["amino_acid_composition"][distance] = result + for metric in ("within_between_ratio", "between_minus_within", + "same_label_auroc", "same_label_auprc_balanced"): + control_rows.append({ + "rank": rank, "epitope": epitope, "distance": distance, + "control": "amino_acid_composition", "metric": metric, + "value": result[metric], + }) + vj_within, vj_between = vj_pair_values(candidates, pairs) + vj_result = pair_metrics(vj_within, vj_between) + controls["v_j_identity"] = vj_result + for metric in ("within_between_ratio", "between_minus_within", + "same_label_auroc", "same_label_auprc_balanced"): + control_rows.append({ + "rank": rank, "epitope": epitope, "distance": "mismatch_fraction", + "control": "v_j_identity", "metric": metric, "value": vj_result[metric], + }) + try: + controls["shuffled_labels_cosine"] = shuffled_label_control( + cosine_values, candidates, pairs, args.permutations, args.seed + rank * 1000 + ) + except ValueError as error: + controls["shuffled_labels_cosine"] = { + "status": "not_estimable_at_available_target_support", + "reason": str(error), + "requested_permutations": args.permutations, + } + assert_finite_tree(metrics, f"metrics_{epitope}") + assert_finite_tree(bootstraps, f"bootstrap_{epitope}") + assert_finite_tree(controls, f"controls_{epitope}") + stable_json(target_dir / "metrics.json", metrics) + stable_json(target_dir / "bootstrap.json", bootstraps) + stable_json(target_dir / "controls.json", controls) + candidates.drop(columns=["is_ylq"]).to_csv( + target_dir / "candidates.tsv", sep="\t", index=False + ) + pairs.to_csv(target_dir / "pair_manifest.tsv", sep="\t", index=False) + epitope_results.append({ + "rank": rank, + "epitope": epitope, + "positive_cdr3": int(selected["positive_cdr3"]), + "negative_cdr3": int(selected["selected_unique_negative_cdr3"]), + "pairs": len(pairs), + "artifact_sha256": { + path.name: sha256(path) for path in sorted(target_dir.iterdir()) if path.is_file() + }, + }) + + metric_table = pd.DataFrame(metric_rows) + metric_table.to_csv(args.output_dir / "per_epitope_metrics.tsv", sep="\t", index=False) + pd.DataFrame(control_rows).to_csv( + args.output_dir / "per_epitope_controls.tsv", sep="\t", index=False + ) + pd.DataFrame(paired_effect_rows).to_csv( + args.output_dir / "per_epitope_rtp_minus_rp_bootstrap.tsv", sep="\t", index=False + ) + distribution, wins, win_summary = summarize_distribution(metric_table) + distribution.to_csv(args.output_dir / "distribution_summary.tsv", sep="\t", index=False) + wins.to_csv(args.output_dir / "win_assignments.tsv", sep="\t", index=False) + win_summary.to_csv(args.output_dir / "win_summary.tsv", sep="\t", index=False) + point_effects = metric_table.pivot_table( + index=["rank", "epitope", "distance", "metric"], columns="model", values="value" + ).reset_index() + point_effects["rtp_minus_rp"] = point_effects["rtp"] - point_effects["rp"] + point_effects.to_csv(args.output_dir / "rtp_minus_rp_effects.tsv", sep="\t", index=False) + effect_summary_rows = [] + for (distance, metric), group in point_effects.groupby(["distance", "metric"]): + values = group["rtp_minus_rp"].to_numpy(float) + negative_favors_rtp = metric == "within_between_ratio" + effect_summary_rows.append({ + "distance": distance, + "metric": metric, + "epitopes": len(values), + "median_rtp_minus_rp": float(np.median(values)), + "q1_rtp_minus_rp": float(np.percentile(values, 25)), + "q3_rtp_minus_rp": float(np.percentile(values, 75)), + "rtp_win_count": int(np.sum(values < 0 if negative_favors_rtp else values > 0)), + "direction": "negative_favors_rtp" if negative_favors_rtp + else "positive_favors_rtp", + }) + pd.DataFrame(effect_summary_rows).to_csv( + args.output_dir / "rtp_minus_rp_distribution.tsv", sep="\t", index=False + ) + + result = { + "status": "complete", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "models": model_report, + "extraction": extraction, + "epitopes": epitope_results, + "epitope_weighting": "each epitope contributes one point to distribution summaries", + "pooled_pair_estimate_reported": False, + "selection_statement": ( + "Up to ten selected only by post-filter motif-member support; no model metric used. " + f"Actual evaluable count={expected_epitopes}, shortfall=" + f"{preflight['support_gate']['evaluable_epitope_shortfall']}." + ), + "claim_scope": "exploratory within-VDJdb motif/epitope organization; pooled donors", + "circularity_caveat": preflight["circularity_caveat"], + "single_seed": True, + "models_trained_during_evaluation": False, + } + hashes = { + path.name: sha256(path) for path in sorted(args.output_dir.iterdir()) if path.is_file() + } + result["artifact_sha256"] = hashes + stable_json(args.output_dir / "RESULTS.json", result) + print(json.dumps(result, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/evaluate_vdjdb_ylq_motif_pooled.py b/benchmark/evaluate_vdjdb_ylq_motif_pooled.py index 9516cf2..fc1bed1 100644 --- a/benchmark/evaluate_vdjdb_ylq_motif_pooled.py +++ b/benchmark/evaluate_vdjdb_ylq_motif_pooled.py @@ -373,7 +373,10 @@ def main() -> None: "models": model_report, "extraction": extraction, "artifact_sha256": hashes, - "selection_statement": "All four prespecified frozen checkpoints reported; no YLQ-based selection.", + "selection_statement": ( + "All seven nonempty matched R/T/P factorial checkpoints reported; " + "no YLQ-based selection." + ), "circularity_caveat": preflight["circularity_caveat"], "claim_scope": "within-VDJdb motif/epitope organization; not cross-donor or independent motif evidence", "exploratory_n40_protocol": preflight["exploratory_n40_protocol"], diff --git a/benchmark/external_residue_models.py b/benchmark/external_residue_models.py new file mode 100644 index 0000000..35810be --- /dev/null +++ b/benchmark/external_residue_models.py @@ -0,0 +1,152 @@ +"""Shared models and datasets for the frozen residue-state benchmark. + +The public encoders remain frozen. Only these task heads are trained. Every +residue-level condition uses the same head topology; the sole shape-dependent +component is the initial linear projection from the public encoder width. +""" + +from __future__ import annotations + +from pathlib import Path + +import numpy as np +import torch +import torch.nn as nn +from torch.utils.data import Dataset + + +class ResidueArrayDataset(Dataset): + """Index a memory-mapped frozen residue matrix without loading it eagerly.""" + + def __init__(self, features_path, mask_path, rows, targets): + self.features = np.load(Path(features_path), mmap_mode="r") + self.mask = np.load(Path(mask_path), mmap_mode="r") + self.rows = np.asarray(rows, dtype=np.int64) + self.targets = np.asarray(targets) + if self.features.shape[:2] != self.mask.shape: + raise ValueError("Frozen feature and mask shapes do not agree.") + if len(self.rows) != len(self.targets): + raise ValueError("Rows and targets must have identical lengths.") + + def __len__(self): + return len(self.rows) + + def __getitem__(self, index): + row = self.rows[index] + return ( + torch.from_numpy(np.asarray(self.features[row], dtype=np.float32)), + torch.from_numpy(np.asarray(self.mask[row], dtype=np.bool_)), + torch.as_tensor(self.targets[index]), + ) + + +class FrozenResidueDecoder(nn.Module): + """Position-aware decoder over frozen per-residue states. + + Learned output queries cross-attend to every residue state. Unlike global + mean pooling, this interface never averages away residue order before the + task head sees it. + """ + + def __init__( + self, + input_dim, + vocab_size=25, + max_len=40, + hidden_dim=512, + num_layers=3, + nhead=8, + ff_mult=4, + dropout=0.2, + ): + super().__init__() + self.max_len = max_len + self.input_norm = nn.LayerNorm(input_dim) + self.input_projection = nn.Linear(input_dim, hidden_dim) + self.source_position = nn.Parameter(torch.randn(max_len, hidden_dim) * 0.02) + self.output_queries = nn.Parameter(torch.randn(max_len, hidden_dim) * 0.02) + layer = nn.TransformerDecoderLayer( + d_model=hidden_dim, + nhead=nhead, + dim_feedforward=hidden_dim * ff_mult, + dropout=dropout, + activation="gelu", + batch_first=True, + norm_first=True, + ) + self.decoder = nn.TransformerDecoder(layer, num_layers=num_layers) + self.output = nn.Linear(hidden_dim, vocab_size) + + def forward(self, features, residue_mask): + if features.ndim != 3 or residue_mask.shape != features.shape[:2]: + raise ValueError("Expected features [B,L,D] and mask [B,L].") + memory = self.input_projection(self.input_norm(features)) + memory = memory + self.source_position[: memory.shape[1]].unsqueeze(0) + queries = self.output_queries.unsqueeze(0).expand(features.shape[0], -1, -1) + decoded = self.decoder( + queries, + memory, + memory_key_padding_mask=~residue_mask.bool(), + ) + return self.output(decoded) + + +class FrozenResiduePgenHead(nn.Module): + """Trainable position-aware pgen probe over frozen residue states.""" + + def __init__( + self, + input_dim, + max_len=40, + hidden_dim=256, + num_layers=2, + nhead=8, + ff_mult=4, + dropout=0.2, + ): + super().__init__() + self.input_norm = nn.LayerNorm(input_dim) + self.input_projection = nn.Linear(input_dim, hidden_dim) + self.source_position = nn.Parameter(torch.randn(max_len, hidden_dim) * 0.02) + layer = nn.TransformerEncoderLayer( + d_model=hidden_dim, + nhead=nhead, + dim_feedforward=hidden_dim * ff_mult, + dropout=dropout, + activation="gelu", + batch_first=True, + norm_first=True, + ) + self.context = nn.TransformerEncoder(layer, num_layers=num_layers) + self.query = nn.Parameter(torch.randn(1, 1, hidden_dim) * 0.02) + self.pool = nn.MultiheadAttention(hidden_dim, nhead, dropout=dropout, batch_first=True) + self.regressor = nn.Sequential( + nn.LayerNorm(hidden_dim), + nn.Linear(hidden_dim, 512), + nn.GELU(), + nn.Dropout(dropout), + nn.Linear(512, 256), + nn.GELU(), + nn.Dropout(dropout), + nn.Linear(256, 1), + ) + + def forward(self, features, residue_mask): + if features.ndim != 3 or residue_mask.shape != features.shape[:2]: + raise ValueError("Expected features [B,L,D] and mask [B,L].") + hidden = self.input_projection(self.input_norm(features)) + hidden = hidden + self.source_position[: hidden.shape[1]].unsqueeze(0) + hidden = self.context(hidden, src_key_padding_mask=~residue_mask.bool()) + query = self.query.expand(features.shape[0], -1, -1) + pooled, _ = self.pool( + query, + hidden, + hidden, + key_padding_mask=~residue_mask.bool(), + need_weights=False, + ) + return self.regressor(pooled[:, 0]).squeeze(-1) + + +def parameter_count(model): + return int(sum(parameter.numel() for parameter in model.parameters())) diff --git a/benchmark/extract_vdjdb_latent.py b/benchmark/extract_vdjdb_latent.py new file mode 100644 index 0000000..ba8c5de --- /dev/null +++ b/benchmark/extract_vdjdb_latent.py @@ -0,0 +1,79 @@ +"""Extract one frozen IRRM-CODEC latent matrix for an ordered VDJdb cohort.""" +from __future__ import annotations + +import argparse +import hashlib +import json +from dataclasses import asdict +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.multitask_data import resolve_encoder_tokenizer +from irrm_codec.multitask_transformer import IRRMCodecConfig, IRRMCodecTransformer +from irrm_codec.tokenization import PAD_ID + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for block in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(block) + return digest.hexdigest() + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--cohort", type=Path, required=True) + parser.add_argument("--checkpoint", type=Path, required=True) + parser.add_argument("--tokenizer", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--batch-size", type=int, default=512) + parser.add_argument("--device", choices=("cpu", "cuda"), default="cuda") + args = parser.parse_args() + if args.output.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output}") + + cohort = pd.read_csv(args.cohort, sep="\t") + checkpoint = torch.load(args.checkpoint, map_location="cpu", weights_only=False) + config = IRRMCodecConfig(**checkpoint["model_config"]) + tokenizer = resolve_encoder_tokenizer("data_anchor", str(args.tokenizer)) + if tokenizer.vocab_size != config.input_vocab_size: + raise ValueError("Tokenizer vocabulary differs from checkpoint architecture") + encoded = [tokenizer.encode(sequence, config.max_sequence_len) + for sequence in cohort["cdr3"].astype(str)] + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA requested but unavailable") + model = IRRMCodecTransformer(config).to(device) + model.load_state_dict(checkpoint["model_state"], strict=True) + model.eval() + matrix = np.lib.format.open_memmap( + args.output, mode="w+", dtype=np.float32, + shape=(len(cohort), config.latent_dim), + ) + with torch.inference_mode(): + for start in range(0, len(encoded), args.batch_size): + rows = encoded[start:start + args.batch_size] + width = max(map(len, rows)) + tokens = torch.full((len(rows), width), PAD_ID, dtype=torch.long, device=device) + for index, ids in enumerate(rows): + tokens[index, :len(ids)] = torch.tensor(ids, dtype=torch.long, device=device) + matrix[start:start + len(rows)] = model.encode(tokens, tokens.ne(PAD_ID)).float().cpu().numpy() + matrix.flush() + if not np.isfinite(matrix).all(): + raise ValueError("Extracted latent contains non-finite values") + metadata = { + "status": "complete", "rows": len(cohort), "shape": list(matrix.shape), + "checkpoint": str(args.checkpoint), "checkpoint_sha256": sha256(args.checkpoint), + "checkpoint_epoch_zero_based": int(checkpoint["epoch"]), + "model_config": asdict(config), "cohort_sha256": sha256(args.cohort), + "latent_sha256": sha256(args.output), "ordering_preserved": True, + } + args.output.with_suffix(".json").write_text(json.dumps(metadata, indent=2, sort_keys=True)+"\n") + + +if __name__ == "__main__": + main() diff --git a/benchmark/finalize_external_residue_pca256.py b/benchmark/finalize_external_residue_pca256.py new file mode 100644 index 0000000..67dd22e --- /dev/null +++ b/benchmark/finalize_external_residue_pca256.py @@ -0,0 +1,57 @@ +"""Fail-closed catalog construction for train-only residue PCA vectors.""" + +import argparse +import json +from pathlib import Path + +import numpy as np + + +NAMES = ("esm2_8m_residue", "tcr_bert_residue", "sceptr_residue") + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--rows", type=int, default=99430) + parser.add_argument("--components", type=int, default=256) + return parser.parse_args() + + +def main(): + args = parse_args() + output = Path(args.output_dir) + catalog, summary = {}, {} + for name in NAMES: + report_path = output / f"{name}_report.json" + report = json.loads(report_path.read_text(encoding="utf-8")) + array_path = output / f"{name}_{args.components}.npy" + matrix = np.load(array_path, mmap_mode="r") + if report.get("status") != "accepted" or report.get("validation_or_test_used_for_fit"): + raise ValueError(f"Rejected or leaky projection report for {name}") + if tuple(matrix.shape) != (args.rows, args.components): + raise ValueError(f"Wrong projected shape for {name}: {matrix.shape}") + if not np.isfinite(matrix).all(): + raise ValueError(f"Non-finite projection for {name}") + catalog[name] = { + "path": str(array_path), + "shape": list(matrix.shape), + "sha256": report["output_sha256"], + "interface": f"flattened_residue_states_train_only_pca{args.components}", + } + summary[name] = { + "source_dim": report["flattened_dim"], + "components_fitted": args.components, + "explained_variance": {str(args.components): report["explained_variance_ratio"]}, + "solver": report["solver"], + "fit_split": "train", + "fit_rows_sha256": report["fit_rows_sha256"], + "capped_by_source_dim": False, + } + (output / "representations.json").write_text(json.dumps(catalog, indent=2), encoding="utf-8") + (output / "bottleneck_summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8") + print(f"status=accepted representations={len(catalog)} rows={args.rows} dim={args.components}") + + +if __name__ == "__main__": + main() diff --git a/benchmark/finalize_external_residue_pca_single.py b/benchmark/finalize_external_residue_pca_single.py new file mode 100644 index 0000000..c8a250f --- /dev/null +++ b/benchmark/finalize_external_residue_pca_single.py @@ -0,0 +1,71 @@ +"""Fail-closed catalog construction for one train-only residue PCA vector.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +import numpy as np + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--representation", required=True) + parser.add_argument("--rows", type=int, default=99430) + parser.add_argument("--components", type=int, required=True) + return parser.parse_args() + + +def main(): + args = parse_args() + output = Path(args.output_dir) + name = f"{args.representation}_residue" + report_path = output / f"{name}_report.json" + report = json.loads(report_path.read_text(encoding="utf-8")) + array_path = output / f"{name}_{args.components}.npy" + matrix = np.load(array_path, mmap_mode="r") + if report.get("status") != "accepted" or report.get("validation_or_test_used_for_fit"): + raise ValueError("Rejected or leaky projection report") + if report.get("fit_split") != "train" or report.get("components") != args.components: + raise ValueError("Projection provenance or dimensionality mismatch") + if tuple(matrix.shape) != (args.rows, args.components): + raise ValueError(f"Wrong projected shape: {matrix.shape}") + if not np.isfinite(matrix).all(): + raise ValueError("Non-finite projection") + catalog = { + name: { + "path": str(array_path), + "shape": list(matrix.shape), + "sha256": report["output_sha256"], + "interface": f"flattened_residue_states_train_only_pca{args.components}", + } + } + summary = { + name: { + "source_dim": report["flattened_dim"], + "components_fitted": args.components, + "explained_variance": { + str(args.components): report["explained_variance_ratio"] + }, + "solver": report["solver"], + "fit_split": "train", + "fit_rows_sha256": report["fit_rows_sha256"], + "capped_by_source_dim": False, + } + } + (output / "representations.json").write_text( + json.dumps(catalog, indent=2), encoding="utf-8" + ) + (output / "bottleneck_summary.json").write_text( + json.dumps(summary, indent=2), encoding="utf-8" + ) + print( + f"status=accepted representation={name} rows={args.rows} " + f"dim={args.components} explained={report['explained_variance_ratio']:.6f}" + ) + + +if __name__ == "__main__": + main() diff --git a/benchmark/finalize_vdjdb_epitope_prediction.py b/benchmark/finalize_vdjdb_epitope_prediction.py new file mode 100644 index 0000000..eb74689 --- /dev/null +++ b/benchmark/finalize_vdjdb_epitope_prediction.py @@ -0,0 +1,117 @@ +"""Finalize an already-scored VDJdb epitope-prediction output directory.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +import numpy as np +import pandas as pd + +from benchmark.evaluate_vdjdb_epitope_prediction import ( + aggregate_metrics, + create_figure, + latex_table, + paired_statistics, + sha256, + stable_json, +) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output-dir", type=Path, required=True) + args = parser.parse_args() + output = args.output_dir + raw_path = output / "fold_metrics.csv" + predictions = output / "predictions.parquet" + samples_path = output / "samples.tsv" + splits_path = output / "split_assignments.csv" + for path in (raw_path, predictions, samples_path, splits_path): + if not path.exists(): + raise FileNotFoundError(path) + + raw = pd.read_csv(raw_path) + expected_representations = { + "r", "t", "p", "rt", "rp", "tp", "rtp", "tcr_bert", "sceptr_cdr3", + "esm2_35m", "kmer_tfidf", + } + if set(raw["representation"]) != expected_representations: + raise ValueError("Fold metrics do not contain all eleven planned representations.") + observed = raw.groupby(["protocol", "representation"]).size() + expected_observations = { + "sequence_stratified": 15, + "exact_cdr3_grouped": 15, + "redcea_similarity_grouped": 12, + } + for (protocol, _), count in observed.items(): + if int(count) != expected_observations[protocol]: + raise ValueError(f"Incomplete {protocol} representation: {count}") + + aggregate = aggregate_metrics(raw) + aggregate.to_csv(output / "aggregated_metrics.csv", index=False, lineterminator="\n") + differences, tests = paired_statistics(raw) + differences.to_csv(output / "paired_macro_f1_differences.csv", index=False, + lineterminator="\n") + tests.to_csv(output / "paired_tests.csv", index=False, lineterminator="\n") + for protocol in aggregate["protocol"].unique(): + (output / f"table_{protocol}.tex").write_text( + latex_table(aggregate, protocol), encoding="utf-8" + ) + create_figure(raw, aggregate, output) + + samples = pd.read_csv(samples_path, sep="\t") + sizes = samples.groupby("label").size() + label_counts = samples.groupby("cdr3")["label"].nunique() + audit = { + "sequences": int(len(samples)), + "epitopes": int(samples["label"].nunique()), + "class_size_min": int(sizes.min()), + "class_size_median": float(np.median(sizes)), + "class_size_max": int(sizes.max()), + "duplicate_cdr3_rows": int(samples["cdr3"].duplicated(keep=False).sum()), + "duplicate_cdr3_sequences_exist": bool(samples["cdr3"].duplicated().any()), + "identical_cdr3_with_different_labels": int((label_counts > 1).sum()), + } + outputs = ( + "samples.tsv", "class_sizes.csv", "split_assignments.csv", "fold_metrics.csv", + "aggregated_metrics.csv", "paired_macro_f1_differences.csv", "paired_tests.csv", + "predictions.parquet", "epitope_prediction.png", "epitope_prediction.pdf", + "table_sequence_stratified.tex", "table_exact_cdr3_grouped.tex", + "table_redcea_similarity_grouped.tex", + ) + representation_summary = ( + raw.groupby(["representation", "display_name"], sort=False) + .agg(dim=("dim", "median"), dim_min=("dim", "min"), dim_max=("dim", "max")) + .reset_index() + ) + for column in ("dim", "dim_min", "dim_max"): + representation_summary[column] = representation_summary[column].round().astype(int) + + result = { + "status": "complete", + "recovered_from_completed_scoring": True, + "dataset": audit, + "protocols": { + "sequence_stratified": "5 folds x 3 seeds", + "exact_cdr3_grouped": "alias of sequence-stratified because every CDR3 is unique", + "redcea_similarity_grouped": "4 folds x 3 seeds; connected source_cid components", + "inner_tuning": "training-only C in {0.1, 1.0}; macro F1 selection", + "classifier": "balanced L2 multinomial logistic regression", + }, + "representations": representation_summary.to_dict(orient="records"), + + "convergence": { + "fold_fits": int(len(raw)), + "converged_before_max_iter": int(raw["converged_before_max_iter"].sum()) + if "converged_before_max_iter" in raw else None, + }, + "outputs": {name: sha256(output / name) for name in outputs}, + } + stable_json(output / "RESULTS.json", result) + print(json.dumps({"status": "complete", "output": str(output), **audit}, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/fit_external_model_bottleneck.py b/benchmark/fit_external_model_bottleneck.py new file mode 100644 index 0000000..3b3a727 --- /dev/null +++ b/benchmark/fit_external_model_bottleneck.py @@ -0,0 +1,161 @@ +"""Issue 2: reduce every representation to a common bottleneck dimension with PCA. + +The scaler and the PCA are fitted on the training split only and then applied to +validation and test, so no information from the held-out rows leaks into the +projection. Representations arrive on very different scales (TCRemP holds alignment +distances in the hundreds, transformer activations sit near zero), so each one is +standardized before the PCA. + +One PCA is fitted at the largest requested width. Principal components are ordered by +explained variance, so the narrower bottlenecks are prefixes of the same fit and cost +nothing extra. +""" + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +from joblib import dump +from sklearn.decomposition import PCA, IncrementalPCA +from sklearn.preprocessing import StandardScaler + +from irrm_codec.utils import setup_logging + +# Above this input width the full SVD needs more memory than it is worth, so the +# incremental solver streams the training split in batches instead. +INCREMENTAL_PCA_MIN_DIM = 2000 + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--representations-dir", default="data/benchmark/trb/representations") + p.add_argument("--output-dir", default="data/benchmark/trb/bottleneck") + p.add_argument("--dims", type=int, nargs="+", default=[32, 64, 128]) + p.add_argument("--representations", nargs="+") + p.add_argument("--batch-size", type=int, default=4096, help="IncrementalPCA batch size.") + p.add_argument("--seed", type=int, default=42) + p.add_argument("--overwrite", action="store_true") + return p.parse_args() + + +def fit_projection(matrix, train_rows, n_components, batch_size, seed, log): + """Standardize and fit a PCA on the training rows only.""" + scaler = StandardScaler() + incremental = matrix.shape[1] >= INCREMENTAL_PCA_MIN_DIM + + if incremental: + # Two streamed passes: one to learn the scaling, one to fit the components. + for start in range(0, len(train_rows), batch_size): + scaler.partial_fit(np.asarray(matrix[train_rows[start : start + batch_size]])) + pca = IncrementalPCA(n_components=n_components, batch_size=batch_size) + for start in range(0, len(train_rows), batch_size): + block = np.asarray(matrix[train_rows[start : start + batch_size]], dtype=np.float64) + if len(block) < n_components: + break # A trailing batch smaller than the component count cannot be fitted. + pca.partial_fit(scaler.transform(block)) + else: + train = np.asarray(matrix[train_rows], dtype=np.float64) + scaler.fit(train) + pca = PCA(n_components=n_components, random_state=seed) + pca.fit(scaler.transform(train)) + + log.info( + "fitted %s pca n_components=%d", + "incremental" if incremental else "full", + n_components, + ) + return scaler, pca + + +def transform_all(matrix, scaler, pca, batch_size): + """Project every row, streaming so the full float64 copy never materializes.""" + out = np.empty((matrix.shape[0], pca.n_components_), dtype=np.float32) + for start in range(0, matrix.shape[0], batch_size): + block = np.asarray(matrix[start : start + batch_size], dtype=np.float64) + out[start : start + batch_size] = pca.transform(scaler.transform(block)).astype(np.float32) + return out + + +def main(): + args = parse_args() + dataset_dir = Path(args.dataset_dir) + reps_dir = Path(args.representations_dir) + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "fit_bottleneck.log") + + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + train_rows = pd.read_csv(dataset_dir / "manifests" / "train.tsv", sep="\t")["row_index"].to_numpy() + log.info("dataset rows=%d train rows=%d", len(frame), len(train_rows)) + + catalog = json.loads((reps_dir / "representations.json").read_text(encoding="utf-8")) + names = args.representations or list(catalog) + max_dim = max(args.dims) + + summary_path = output_dir / "bottleneck_summary.json" + summary = json.loads(summary_path.read_text(encoding="utf-8")) if summary_path.exists() else {} + + for name in names: + source = Path(catalog[name]["path"]) + matrix = np.load(source, mmap_mode="r") + if matrix.shape[0] != len(frame): + raise ValueError(f"{name} has {matrix.shape[0]} rows, expected {len(frame)}.") + + # A representation narrower than the bottleneck cannot be reduced to it; SCEPTR + # is already 64-dimensional, so its widest projection is capped at its own width. + n_components = min(max_dim, matrix.shape[1], len(train_rows)) + if name in summary and not args.overwrite: + log.info("%s already projected, skipping", name) + continue + + log.info("fitting %s dim=%d -> %d", name, matrix.shape[1], n_components) + started = time.perf_counter() + scaler, pca = fit_projection( + matrix, train_rows, n_components, args.batch_size, args.seed, log + ) + projected = transform_all(matrix, scaler, pca, args.batch_size) + elapsed = time.perf_counter() - started + + dump({"scaler": scaler, "pca": pca}, output_dir / f"{name}_projection.joblib") + + ratios = np.asarray(pca.explained_variance_ratio_, dtype=np.float64) + explained = {} + for dim in sorted(args.dims): + if dim > n_components: + explained[str(dim)] = None + continue + np.save(output_dir / f"{name}_{dim}.npy", projected[:, :dim]) + explained[str(dim)] = round(float(ratios[:dim].sum()), 6) + + summary[name] = { + "source_dim": int(matrix.shape[1]), + "components_fitted": int(n_components), + "explained_variance": explained, + "seconds": round(elapsed, 2), + "solver": "incremental" if matrix.shape[1] >= INCREMENTAL_PCA_MIN_DIM else "full", + "capped_by_source_dim": bool(n_components < max_dim), + } + summary_path.write_text(json.dumps(summary, indent=2), encoding="utf-8") + log.info("%s done in %.1f s explained=%s", name, elapsed, explained) + + log.info("=" * 68) + header = " ".join(f"{d:>8d}" for d in sorted(args.dims)) + log.info("%-10s %6s %s", "repr", "dim", header) + for name, info in summary.items(): + cells = " ".join( + f"{info['explained_variance'][str(d)]:8.4f}" + if info["explained_variance"].get(str(d)) is not None + else " -" + for d in sorted(args.dims) + ) + log.info("%-10s %6d %s", name, info["source_dim"], cells) + log.info("wrote %s", summary_path) + + +if __name__ == "__main__": + main() + diff --git a/benchmark/fit_external_residue_pca256.py b/benchmark/fit_external_residue_pca256.py new file mode 100644 index 0000000..5ae99f6 --- /dev/null +++ b/benchmark/fit_external_residue_pca256.py @@ -0,0 +1,176 @@ +"""Fit a train-only PCA from flattened residue states to one compact clonotype vector. + +The public encoder states are already frozen. We flatten the zero-padded [40,D] +tensor in residue order, standardize each flattened coordinate using the locked +training split only, fit a seeded randomized PCA, and apply that fixed projection to +all rows. Validation and test rows never participate in fitting. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + + +REPRESENTATIONS = ("esm2_8m", "tcr_bert", "sceptr") + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for block in iter(lambda: handle.read(8 << 20), b""): + digest.update(block) + return digest.hexdigest() + + +def rows_sha256(rows: np.ndarray) -> str: + return hashlib.sha256(np.asarray(rows, dtype=" 0 else 0.0 + return ( + mean.cpu().numpy().astype(np.float32), + scale.cpu().numpy().astype(np.float32), + components.cpu().numpy().astype(np.float32), + explained, + ) + + +def transform_to_memmap(matrix, mean, scale, components, output, batch_size, device): + projected = np.lib.format.open_memmap( + output, mode="w+", dtype=np.float32, shape=(matrix.shape[0], components.shape[1]) + ) + mean_t = torch.from_numpy(mean).to(device) + scale_t = torch.from_numpy(scale).to(device) + components_t = torch.from_numpy(components).to(device) + for start in range(0, matrix.shape[0], batch_size): + stop = min(start + batch_size, matrix.shape[0]) + block = np.asarray(matrix[start:stop], dtype=np.float32).reshape(stop - start, -1) + x = torch.from_numpy(block).to(device) + x.sub_(mean_t).div_(scale_t) + projected[start:stop] = (x @ components_t).cpu().numpy() + projected.flush() + return projected + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dataset-dir", required=True) + parser.add_argument("--residue-dir", required=True) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--representation", choices=REPRESENTATIONS, required=True) + parser.add_argument("--components", type=int, default=256) + parser.add_argument("--oversample", type=int, default=32) + parser.add_argument("--power-iterations", type=int, default=4) + parser.add_argument("--batch-size", type=int, default=2048) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def main(): + args = parse_args() + if not torch.cuda.is_available(): + raise RuntimeError("Residue PCA fitting must run in a GPU Slurm allocation.") + device = torch.device("cuda") + dataset_dir, residue_dir, output_dir = map( + Path, (args.dataset_dir, args.residue_dir, args.output_dir) + ) + output_dir.mkdir(parents=True, exist_ok=True) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + train_manifest = dataset_dir / "manifests" / "train.tsv" + train_rows = pd.read_csv(train_manifest, sep="\t")["row_index"].to_numpy(np.int64) + source = residue_dir / f"{args.representation}_residue.npy" + source_mask = residue_dir / f"{args.representation}_residue_mask.npy" + matrix = np.load(source, mmap_mode="r") + mask = np.load(source_mask, mmap_mode="r") + if matrix.ndim != 3 or matrix.shape[:2] != mask.shape or matrix.shape[0] != len(frame): + raise ValueError(f"Unexpected residue/mask shapes: {matrix.shape}, {mask.shape}") + started = time.perf_counter() + mean, scale, components, explained = fit_randomized_pca( + matrix, + train_rows, + args.components, + args.oversample, + args.power_iterations, + args.seed, + device, + ) + output = output_dir / f"{args.representation}_residue_{args.components}.npy" + projected = transform_to_memmap( + matrix, mean, scale, components, output, args.batch_size, device + ) + for start in range(0, len(projected), args.batch_size): + if not np.isfinite(projected[start : start + args.batch_size]).all(): + raise ValueError("Non-finite projected values.") + projection_path = output_dir / f"{args.representation}_residue_projection.npz" + np.savez( + projection_path, + mean=mean, + scale=scale, + components=components, + fit_rows=train_rows, + ) + report = { + "status": "accepted", + "representation": f"{args.representation}_residue", + "source": str(source), + "source_sha256": sha256(source), + "source_shape": list(matrix.shape), + "flattened_dim": int(matrix.shape[1] * matrix.shape[2]), + "output": str(output), + "output_sha256": sha256(output), + "output_shape": list(projected.shape), + "projection": str(projection_path), + "projection_sha256": sha256(projection_path), + "components": args.components, + "explained_variance_ratio": explained, + "fit_split": "train", + "fit_rows": int(len(train_rows)), + "fit_rows_sha256": rows_sha256(train_rows), + "train_manifest": str(train_manifest), + "train_manifest_sha256": sha256(train_manifest), + "validation_or_test_used_for_fit": False, + "standardization": "per_flattened_coordinate_train_only", + "solver": "torch_randomized_pca_lowrank", + "oversample": args.oversample, + "power_iterations": args.power_iterations, + "seed": args.seed, + "finite": True, + "seconds": round(time.perf_counter() - started, 2), + } + report_path = output_dir / f"{args.representation}_residue_report.json" + report_path.write_text(json.dumps(report, indent=2), encoding="utf-8") + print(json.dumps(report, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/preflight_author_global_embeddings.py b/benchmark/preflight_author_global_embeddings.py new file mode 100644 index 0000000..a6cfb71 --- /dev/null +++ b/benchmark/preflight_author_global_embeddings.py @@ -0,0 +1,134 @@ +"""Fail-closed CPU preflight for author-native global embedding benchmarks.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import logging +from pathlib import Path + +import numpy as np +import pandas as pd + +from benchmark.cache_external_model_embeddings import encode_esm2, encode_sceptr + + +def sha256_file(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def read_table(path: Path) -> pd.DataFrame: + if path.suffix.lower() == ".parquet": + return pd.read_parquet(path) + return pd.read_csv(path, sep="\t") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--locked-dataset", type=Path, required=True) + parser.add_argument("--redcea-cohort", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--locked-sha256", required=True) + parser.add_argument("--redcea-sha256", required=True) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + args.output_dir.mkdir(parents=True, exist_ok=False) + + actual_hashes = { + "locked_dataset": sha256_file(args.locked_dataset), + "redcea_cohort": sha256_file(args.redcea_cohort), + } + expected_hashes = { + "locked_dataset": args.locked_sha256, + "redcea_cohort": args.redcea_sha256, + } + if actual_hashes != expected_hashes: + raise RuntimeError( + f"Input hash mismatch: expected={expected_hashes}, actual={actual_hashes}" + ) + + locked = read_table(args.locked_dataset) + redcea = read_table(args.redcea_cohort) + for name, frame in (("locked", locked), ("redcea", redcea)): + if "junction_aa" not in frame and "cdr3" not in frame: + raise ValueError(f"{name} input lacks junction_aa/cdr3") + seq_col = "junction_aa" if "junction_aa" in frame else "cdr3" + if frame[seq_col].astype(str).duplicated().any() and name == "redcea": + raise ValueError("REDCEA cohort must contain unique clonotypes") + + locked_sequences = locked["junction_aa"].astype(str).head(2).tolist() + redcea_seq_col = "junction_aa" if "junction_aa" in redcea else "cdr3" + redcea_sequences = redcea[redcea_seq_col].astype(str).head(2).tolist() + + class SmokeArgs: + device = "cpu" + batch_size = 2 + + log = logging.getLogger("author_global_preflight") + esm35 = encode_esm2(locked_sequences, SmokeArgs(), log, model_name="esm2_35m") + if esm35.shape != (2, 480) or not np.isfinite(esm35).all(): + raise RuntimeError(f"ESM2-35M smoke failed: shape={esm35.shape}") + + sceptr_cdr3 = encode_sceptr( + locked_sequences, + SmokeArgs(), + log, + frame=locked.head(2).copy(), + cdr3_only=True, + ) + if sceptr_cdr3.shape != (2, 64) or not np.isfinite(sceptr_cdr3).all(): + raise RuntimeError(f"SCEPTR-CDR3 smoke failed: shape={sceptr_cdr3.shape}") + + if not {"v_call", "j_call"}.issubset(redcea.columns): + raise ValueError("REDCEA cohort lacks v_call/j_call for SCEPTR-default") + sceptr_default = encode_sceptr( + redcea_sequences, + SmokeArgs(), + log, + frame=redcea.head(2).rename(columns={"cdr3": "junction_aa"}).copy(), + cdr3_only=False, + ) + if sceptr_default.shape != (2, 64) or not np.isfinite(sceptr_default).all(): + raise RuntimeError(f"SCEPTR-default smoke failed: shape={sceptr_default.shape}") + + report = { + "status": "accepted", + "input_hashes": actual_hashes, + "row_counts": {"locked": len(locked), "redcea": len(redcea)}, + "representations": { + "esm2_35m": { + "model": "esm2_t12_35M_UR50D", + "pooling": "final-layer residue mean excluding special/pad tokens", + "modality": "sequence-only", + "smoke_shape": list(esm35.shape), + }, + "sceptr_cdr3": { + "model": "SCEPTR variant.cdr3_only()", + "pooling": "native contextualized CLS64", + "modality": "sequence-only", + "smoke_shape": list(sceptr_cdr3.shape), + }, + "sceptr": { + "model": "SCEPTR default", + "pooling": "native contextualized CLS64", + "modality": "annotation-aware TRBV+CDR3B+TRBJ", + "smoke_shape": list(sceptr_default.shape), + }, + }, + } + output = args.output_dir / "PREFLIGHT.json" + output.write_text(json.dumps(report, indent=2, sort_keys=True), encoding="utf-8") + print(json.dumps(report, sort_keys=True)) + + + +if __name__ == "__main__": + main() diff --git a/benchmark/preflight_external_model_benchmark.py b/benchmark/preflight_external_model_benchmark.py new file mode 100644 index 0000000..9a84772 --- /dev/null +++ b/benchmark/preflight_external_model_benchmark.py @@ -0,0 +1,217 @@ +"""Fail-closed preflight for the locked external-model benchmark. + +This script performs metadata/import/model-cache checks on a Slurm CPU node. It does +not fit a model or produce benchmark scores. Its JSON output is the gate used before +external representation extraction. +""" + +from __future__ import annotations + +import argparse +import hashlib +import importlib +import importlib.util +import json +import os +import platform +import sys +from pathlib import Path +from typing import Any + +import numpy as np +import pandas as pd + + +REQUIRED_COLUMNS = { + "junction_aa", + "v_call", + "j_call", + "log10_pgen_1mm", +} +SPECIAL_REPRESENTATIONS = ("onehot", "tcremp", "rtp") +EXTERNAL_REPRESENTATIONS = ("esm2_8m", "tcr_bert", "sceptr") + + +def sha256_file(path: Path, chunk_size: int = 1024 * 1024) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(chunk_size): + digest.update(chunk) + return digest.hexdigest() + + +def read_manifest_rows(path: Path) -> np.ndarray: + frame = pd.read_csv(path, sep="\t") + if "row_index" not in frame: + raise ValueError(f"{path} has no row_index column") + rows = frame["row_index"].to_numpy(dtype=np.int64) + if len(rows) != len(np.unique(rows)): + raise ValueError(f"{path} contains duplicate row_index values") + return rows + + +def validate_splits(dataset_dir: Path, n_rows: int) -> dict[str, Any]: + manifests = dataset_dir / "manifests" + split_rows = { + split: read_manifest_rows(manifests / f"{split}.tsv") + for split in ("train", "val", "test") + } + for split, rows in split_rows.items(): + if np.any(rows < 0) or np.any(rows >= n_rows): + raise ValueError(f"{split} has out-of-range row_index") + sets = {name: set(rows.tolist()) for name, rows in split_rows.items()} + overlaps = { + "train_val": len(sets["train"] & sets["val"]), + "train_test": len(sets["train"] & sets["test"]), + "val_test": len(sets["val"] & sets["test"]), + } + if any(overlaps.values()): + raise ValueError(f"split overlap detected: {overlaps}") + if len(set.union(*sets.values())) != n_rows: + raise ValueError("train/val/test manifests do not cover the dataset exactly") + return { + "counts": {name: int(len(rows)) for name, rows in split_rows.items()}, + "overlaps": overlaps, + "manifest_sha256": { + name: sha256_file(manifests / f"{name}.tsv") for name in split_rows + }, + } + + +def module_report(name: str) -> dict[str, Any]: + spec = importlib.util.find_spec(name) + report: dict[str, Any] = {"available": spec is not None} + if spec is None: + return report + try: + module = importlib.import_module(name) + report.update( + { + "import_ok": True, + "version": getattr(module, "__version__", None), + "path": getattr(module, "__file__", None), + } + ) + except Exception as exc: # preflight records the exact import blocker + report.update({"import_ok": False, "error": f"{type(exc).__name__}: {exc}"}) + return report + + +def inspect_hf_cache() -> dict[str, Any]: + cache_root = Path( + os.environ.get( + "HF_HOME", + os.environ.get("HUGGINGFACE_HUB_CACHE", str(Path.home() / ".cache" / "huggingface")), + ) + ) + hub_root = cache_root if cache_root.name == "hub" else cache_root / "hub" + candidates = { + "tcr_bert": hub_root / "models--wukevin--tcr-bert", + } + return { + "root": str(hub_root), + "models": { + name: { + "path": str(path), + "exists": path.exists(), + "snapshots": sorted(p.name for p in (path / "snapshots").glob("*")) + if (path / "snapshots").exists() + else [], + } + for name, path in candidates.items() + }, + } + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dataset-dir", type=Path, required=True) + parser.add_argument("--rtp-embeddings", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--expected-rows", type=int, default=99_430) + parser.add_argument("--expected-latent-dim", type=int, default=128) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + args.output.parent.mkdir(parents=True, exist_ok=True) + dataset_path = args.dataset_dir / "dataset.parquet" + ready_path = args.dataset_dir / "READY.json" + if not dataset_path.exists() or not ready_path.exists(): + raise FileNotFoundError("locked dataset.parquet/READY.json is missing") + + frame = pd.read_parquet(dataset_path) + missing = sorted(REQUIRED_COLUMNS - set(frame.columns)) + if missing: + raise ValueError(f"dataset missing required columns: {missing}") + if len(frame) != args.expected_rows: + raise ValueError(f"dataset has {len(frame)} rows, expected {args.expected_rows}") + if frame["junction_aa"].duplicated().any(): + raise ValueError("locked dataset contains duplicate CDR3 amino-acid sequences") + if not np.isfinite(frame["log10_pgen_1mm"].to_numpy(dtype=float)).all(): + raise ValueError("log10_pgen_1mm contains non-finite targets") + + split_report = validate_splits(args.dataset_dir, len(frame)) + rtp = np.load(args.rtp_embeddings, mmap_mode="r") + if rtp.shape != (args.expected_rows, args.expected_latent_dim): + raise ValueError( + f"RTP embedding shape is {rtp.shape}, expected " + f"({args.expected_rows}, {args.expected_latent_dim})" + ) + # Streamed finiteness check avoids making an unnecessary 50 MB copy. + for start in range(0, len(rtp), 8192): + if not np.isfinite(np.asarray(rtp[start : start + 8192])).all(): + raise ValueError(f"RTP embeddings non-finite at block beginning {start}") + + v = frame["v_call"].fillna("").astype(str).str.strip() + j = frame["j_call"].fillna("").astype(str).str.strip() + sceptr_candidate = v.ne("") & j.ne("") + report = { + "status": "accepted_metadata_gate", + "note": "Imports/caches are inventoried; encoder execution is a separate Slurm gate.", + "python": { + "executable": sys.executable, + "version": sys.version, + "platform": platform.platform(), + }, + "dataset": { + "path": str(dataset_path), + "rows": int(len(frame)), + "dataset_sha256": sha256_file(dataset_path), + "ready_sha256": sha256_file(ready_path), + "unique_cdr3": int(frame["junction_aa"].nunique()), + "finite_log10_pgen_1mm": True, + "split": split_report, + }, + "rtp": { + "path": str(args.rtp_embeddings), + "shape": list(rtp.shape), + "dtype": str(rtp.dtype), + "finite": True, + "sha256": sha256_file(args.rtp_embeddings), + }, + "sceptr_metadata": { + "candidate_rows_with_v_and_j": int(sceptr_candidate.sum()), + "missing_v": int(v.eq("").sum()), + "missing_j": int(j.eq("").sum()), + "candidate_by_split": {}, + "warning": "SCEPTR uses V/J calls and is annotation-aware, unlike the sequence-only encoders.", + }, + "modules": { + name: module_report(name) + for name in ("torch", "sklearn", "transformers", "esm", "sceptr") + }, + "hf_cache": inspect_hf_cache(), + "planned_representations": [*SPECIAL_REPRESENTATIONS, *EXTERNAL_REPRESENTATIONS], + } + for split in ("train", "val", "test"): + rows = read_manifest_rows(args.dataset_dir / "manifests" / f"{split}.tsv") + report["sceptr_metadata"]["candidate_by_split"][split] = int(sceptr_candidate.iloc[rows].sum()) + + args.output.write_text(json.dumps(report, indent=2, sort_keys=True), encoding="utf-8") + print(json.dumps(report, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/preflight_external_residue_benchmark.py b/benchmark/preflight_external_residue_benchmark.py new file mode 100644 index 0000000..ce61e04 --- /dev/null +++ b/benchmark/preflight_external_residue_benchmark.py @@ -0,0 +1,137 @@ +"""Fail-closed gate for the unpooled frozen-residue benchmark.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from benchmark.external_residue_models import ( + FrozenResidueDecoder, + FrozenResiduePgenHead, + parameter_count, +) +from irrm_codec.losses import inverse_loss, pgen_loss +from irrm_codec.tokenization import encode + + +REPRESENTATIONS = ("esm2_8m", "tcr_bert", "sceptr") + + +def sha256_file(path, chunk_size=1024 * 1024): + digest = hashlib.sha256() + with Path(path).open("rb") as handle: + while block := handle.read(chunk_size): + digest.update(block) + return digest.hexdigest() + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--cohort-dir", required=True) + parser.add_argument("--smoke-dir", required=True) + parser.add_argument("--output", required=True) + return parser.parse_args() + + +def load_rows(cohort, split): + path = cohort / "manifests" / f"{split}.tsv" + rows = pd.read_csv(path, sep="\t")["row_index"].to_numpy(dtype=np.int64) + if len(np.unique(rows)) != len(rows): + raise ValueError(f"Duplicate row identity in {split}") + return rows, sha256_file(path) + + +def main(): + args = parse_args() + cohort, smoke = Path(args.cohort_dir), Path(args.smoke_dir) + cohort_report = json.loads((cohort / "COHORT.json").read_text(encoding="utf-8")) + if cohort_report.get("status") != "accepted" or cohort_report.get("split_overlap") != 0: + raise ValueError("Locked cohort is not accepted/non-overlapping") + frame = pd.read_parquet(cohort / "dataset.parquet") + expected_counts = {"train": 79544, "val": 9943, "test": 9943} + split_rows, manifest_hashes = {}, {} + for split, expected in expected_counts.items(): + split_rows[split], manifest_hashes[split] = load_rows(cohort, split) + if len(split_rows[split]) != expected: + raise ValueError(f"{split} count changed") + if len(set(split_rows["train"]) & set(split_rows["val"])): + raise ValueError("train/val overlap") + if len(set(split_rows["train"]) & set(split_rows["test"])): + raise ValueError("train/test overlap") + if len(set(split_rows["val"]) & set(split_rows["test"])): + raise ValueError("val/test overlap") + + catalog = json.loads((smoke / "residue_representations.json").read_text(encoding="utf-8")) + targets = torch.tensor( + [encode(sequence, max_len=40) for sequence in frame.junction_aa.iloc[:2]], dtype=torch.long + ) + pgen = torch.tensor(frame.log10_pgen_1mm.iloc[:2].to_numpy(), dtype=torch.float32) + checks = {} + for name in REPRESENTATIONS: + entry = catalog[name] + features = np.load(entry["features"]) + mask = np.load(entry["mask"]) + if features.shape[0] < 2 or features.shape[1] != 40: + raise ValueError(f"{name} smoke shape invalid: {features.shape}") + lengths = frame.junction_aa.iloc[: len(features)].str.len().to_numpy() + if not np.array_equal(mask.sum(axis=1), lengths): + raise ValueError(f"{name} mask/length mismatch") + if not np.isfinite(features).all(): + raise ValueError(f"{name} smoke features non-finite") + x = torch.from_numpy(features[:2].astype(np.float32)) + m = torch.from_numpy(mask[:2]) + decoder = FrozenResidueDecoder(features.shape[-1]).eval() + regressor = FrozenResiduePgenHead(features.shape[-1]).eval() + with torch.no_grad(): + logits = decoder(x, m) + reconstruction_smoke = inverse_loss(logits, targets) + prediction = regressor(x, m) + pgen_smoke = pgen_loss(prediction, pgen) + if not torch.isfinite(reconstruction_smoke) or not torch.isfinite(pgen_smoke): + raise ValueError(f"{name} smoke loss is non-finite") + checks[name] = { + "shape": list(features.shape), + "dtype": str(features.dtype), + "mask_counts_equal_lengths": True, + "features_sha256": sha256_file(entry["features"]), + "mask_sha256": sha256_file(entry["mask"]), + "decoder_parameters": parameter_count(decoder), + "pgen_head_parameters": parameter_count(regressor), + "finite_reconstruction_smoke_loss": float(reconstruction_smoke), + "finite_pgen_smoke_loss": float(pgen_smoke), + } + report = { + "status": "accepted", + "protocol": "frozen per-residue states; no global pooling before trainable task head", + "cohort": { + "rows": len(frame), + "dataset_sha256": sha256_file(cohort / "dataset.parquet"), + "split_counts": expected_counts, + "manifest_sha256": manifest_hashes, + "overlap": 0, + }, + "representations": checks, + "controls": { + "encoder_frozen": True, + "decoder_trained_separately_per_representation": True, + "pgen_head_trained_separately_per_representation": True, + "checkpoint_selection": "validation loss only", + "test_used_for_selection": False, + "pgen_normalization": "train-only", + "important_scope": "best-available frozen interface, not a matched compact-vector comparison", + }, + } + output = Path(args.output) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(report, indent=2), encoding="utf-8") + print(json.dumps(report, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/preflight_external_sceptr_pca128.py b/benchmark/preflight_external_sceptr_pca128.py new file mode 100644 index 0000000..9dc8c78 --- /dev/null +++ b/benchmark/preflight_external_sceptr_pca128.py @@ -0,0 +1,105 @@ +"""Standalone fail-closed smoke gate for the SCEPTR residue-PCA 128D study.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from benchmark.fit_external_residue_pca256 import fit_randomized_pca +from benchmark.train_external_model_pgen import FROZEN_ARMS, RegressionHead +from irrm_codec.inverse_model import InverseModel + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for block in iter(lambda: handle.read(8 << 20), b""): + digest.update(block) + return digest.hexdigest() + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dataset-dir", required=True) + parser.add_argument("--residue-dir", required=True) + parser.add_argument("--output", required=True) + return parser.parse_args() + + +def main(): + args = parse_args() + dataset_dir = Path(args.dataset_dir) + residue_dir = Path(args.residue_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + splits = { + name: pd.read_csv(dataset_dir / "manifests" / f"{name}.tsv", sep="\t")[ + "row_index" + ].to_numpy(np.int64) + for name in ("train", "val", "test") + } + if tuple(map(len, splits.values())) != (79544, 9943, 9943): + raise ValueError("Locked split counts changed") + split_sets = {name: set(rows.tolist()) for name, rows in splits.items()} + if any( + split_sets[a] & split_sets[b] + for a, b in (("train", "val"), ("train", "test"), ("val", "test")) + ): + raise ValueError("Split row overlap") + source = residue_dir / "sceptr_residue.npy" + matrix = np.load(source, mmap_mode="r") + if tuple(matrix.shape) != (len(frame), 40, 64): + raise ValueError(f"Unexpected SCEPTR residue shape {matrix.shape}") + for start in range(0, len(matrix), 4096): + if not np.isfinite(matrix[start : start + 4096]).all(): + raise ValueError("Non-finite SCEPTR residue states") + + rng = np.random.default_rng(7) + toy = rng.normal(size=(30, 4, 5)).astype(np.float32) + mean, scale, components, explained = fit_randomized_pca( + toy, + np.arange(20), + n_components=6, + oversample=2, + niter=2, + seed=42, + device=torch.device("cpu"), + ) + scores = ((toy.reshape(30, -1) - mean) / scale) @ components + if scores.shape != (30, 6) or not np.isfinite(scores).all() or not 0 < explained <= 1: + raise ValueError("Randomized PCA smoke failed") + if FROZEN_ARMS.get("sceptr_residue_pca128_mlp") != "sceptr_residue": + raise ValueError("Pgen arm mapping is missing or incorrect") + with torch.no_grad(): + features = torch.randn(4, 128) + prediction = RegressionHead(128)(features) + logits = InverseModel(embedding_dim=128, max_len=40)(features) + if prediction.shape != (4,) or logits.shape != (4, 40, 25): + raise ValueError("Head shape smoke failed") + if not torch.isfinite(prediction).all() or not torch.isfinite(logits).all(): + raise ValueError("Non-finite head smoke") + + report = { + "status": "accepted", + "rows": len(frame), + "split_counts": {name: len(rows) for name, rows in splits.items()}, + "split_overlap": 0, + "source_shape": list(matrix.shape), + "source_sha256": sha256(source), + "target_dim": 128, + "pgen_arm": "sceptr_residue_pca128_mlp", + "finite_smoke": True, + } + output = Path(args.output) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(report, indent=2), encoding="utf-8") + print(json.dumps(report, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_external_model_cohort.py b/benchmark/prepare_external_model_cohort.py new file mode 100644 index 0000000..e42ede1 --- /dev/null +++ b/benchmark/prepare_external_model_cohort.py @@ -0,0 +1,188 @@ +"""Build the locked, common-row cohort used by every external representation. + +The source benchmark and its split labels remain immutable. Rows with V/J calls that +SCEPTR cannot standardize as functional human genes are removed *before* model scoring; +the same filtered rows are then used for every representation. Original row identity is +retained in ``source_row_index`` and all emitted matrices are checked by that mapping. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd + + +def sha256_file(path: Path, chunk_size: int = 1024 * 1024) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(chunk_size): + digest.update(chunk) + return digest.hexdigest() + + +def manifest_rows(path: Path) -> np.ndarray: + return pd.read_csv(path, sep="\t")["row_index"].to_numpy(dtype=np.int64) + + +def deterministic_rank(sequence: str, seed: int) -> str: + return hashlib.sha256(f"{seed}|{sequence}".encode("utf-8")).hexdigest() + + +def nested_training_subsets( + frame: pd.DataFrame, train_rows: np.ndarray, sizes=(1_000, 10_000), seed=42 +) -> dict[str, np.ndarray]: + ranked = sorted( + train_rows.tolist(), + key=lambda row: (deterministic_rank(str(frame.at[row, "junction_aa"]), seed), row), + ) + subsets: dict[str, np.ndarray] = {} + previous: list[int] = [] + for size in sizes: + if len(ranked) < size: + raise ValueError(f"only {len(ranked)} filtered train rows, cannot emit {size}") + previous_set = set(previous) + chosen = previous + [row for row in ranked if row not in previous_set][: size - len(previous)] + subsets[str(size // 1000) + "k"] = np.asarray(chosen, dtype=np.int64) + previous = chosen + subsets["all"] = np.asarray(ranked, dtype=np.int64) + return subsets + + +def subset_matrix(source: Path, source_rows: np.ndarray, output: Path) -> dict[str, object]: + matrix = np.load(source, mmap_mode="r") + if np.any(source_rows < 0) or np.any(source_rows >= matrix.shape[0]): + raise ValueError(f"{source}: row mapping exceeds matrix shape {matrix.shape}") + target = np.lib.format.open_memmap( + output, mode="w+", dtype=np.float32, shape=(len(source_rows), matrix.shape[1]) + ) + for start in range(0, len(source_rows), 4096): + block = np.asarray(matrix[source_rows[start : start + 4096]], dtype=np.float32) + if not np.isfinite(block).all(): + raise ValueError(f"{source}: non-finite block at filtered row {start}") + target[start : start + len(block)] = block + target.flush() + del target + return { + "source": str(source), + "source_sha256": sha256_file(source), + "output": str(output), + "output_sha256": sha256_file(output), + "shape": [int(len(source_rows)), int(matrix.shape[1])], + } + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--source-dataset-dir", type=Path, required=True) + parser.add_argument("--rtp-embeddings", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + import tidytcells as tt + + source_dataset = args.source_dataset_dir / "dataset.parquet" + source_frame = pd.read_parquet(source_dataset).reset_index(drop=True) + standardized: dict[str, pd.Series] = {} + usable = np.ones(len(source_frame), dtype=bool) + dropped: dict[str, int] = {} + for column, gene_type in (("v_call", "v"), ("j_call", "j")): + values = source_frame[column].map( + lambda value: tt.tr.standardize( + value, species="homosapiens", enforce_functional=True, log_failures=False + ) + ) + standardized[column] = values + invalid = values.isna().to_numpy() + dropped[f"nonfunctional_or_invalid_{gene_type}"] = int(invalid.sum()) + usable &= ~invalid + + source_rows = np.flatnonzero(usable).astype(np.int64) + output = args.output_dir + manifests = output / "manifests" + reps = output / "representations" + manifests.mkdir(parents=True, exist_ok=True) + reps.mkdir(parents=True, exist_ok=True) + + filtered = source_frame.iloc[source_rows].copy() + filtered["source_row_index"] = source_rows + filtered["v_call"] = standardized["v_call"].iloc[source_rows].to_numpy() + filtered["j_call"] = standardized["j_call"].iloc[source_rows].to_numpy() + filtered["row_index"] = np.arange(len(filtered), dtype=np.int64) + filtered.to_parquet(output / "dataset.parquet", index=False) + + source_to_new = {int(source): int(new) for new, source in enumerate(source_rows)} + split_new: dict[str, np.ndarray] = {} + source_manifest_hashes: dict[str, str] = {} + for split in ("train", "val", "test"): + path = args.source_dataset_dir / "manifests" / f"{split}.tsv" + original = manifest_rows(path) + kept = [source_to_new[int(row)] for row in original if int(row) in source_to_new] + split_new[split] = np.asarray(kept, dtype=np.int64) + filtered.iloc[split_new[split]].to_csv(manifests / f"{split}.tsv", sep="\t", index=False) + source_manifest_hashes[split] = sha256_file(path) + + sets = {name: set(rows.tolist()) for name, rows in split_new.items()} + if any(sets[a] & sets[b] for a, b in (("train", "val"), ("train", "test"), ("val", "test"))): + raise ValueError("filtered split overlap") + if len(set.union(*sets.values())) != len(filtered): + raise ValueError("filtered splits do not cover the common cohort") + + subsets = nested_training_subsets(filtered, split_new["train"], seed=args.seed) + for name, rows in subsets.items(): + filtered.iloc[rows].to_csv(manifests / f"train_{name}.tsv", sep="\t", index=False) + + matrix_reports = { + "tcremp": subset_matrix( + args.source_dataset_dir / "embeddings.npy", source_rows, reps / "tcremp.npy" + ), + "rtp": subset_matrix(args.rtp_embeddings, source_rows, reps / "rtp.npy"), + } + catalog = { + name: { + "path": report["output"], + "rows": report["shape"][0], + "dim": report["shape"][1], + "sha256": report["output_sha256"], + "source": report["source"], + "source_sha256": report["source_sha256"], + } + for name, report in matrix_reports.items() + } + (reps / "representations.json").write_text( + json.dumps(catalog, indent=2, sort_keys=True), encoding="utf-8" + ) + + report = { + "status": "accepted", + "definition": "common functional-human-V/J intersection fixed before model evaluation", + "source_dataset": str(source_dataset), + "source_dataset_sha256": sha256_file(source_dataset), + "source_rows": int(len(source_frame)), + "common_rows": int(len(filtered)), + "dropped_total": int(len(source_frame) - len(filtered)), + "dropped": dropped, + "split_counts": {name: int(len(rows)) for name, rows in split_new.items()}, + "split_overlap": 0, + "source_manifest_sha256": source_manifest_hashes, + "sequence_sha256": hashlib.sha256( + "\n".join(filtered["junction_aa"].astype(str)).encode("utf-8") + ).hexdigest(), + "nested_train_counts": {name: int(len(rows)) for name, rows in subsets.items()}, + "matrices": matrix_reports, + "sceptr_modality": "sequence plus V/J annotations; reported separately from sequence-only models", + } + (output / "COHORT.json").write_text(json.dumps(report, indent=2, sort_keys=True), encoding="utf-8") + print(json.dumps(report, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_single_aa_challenge.py b/benchmark/prepare_single_aa_challenge.py new file mode 100644 index 0000000..7281314 --- /dev/null +++ b/benchmark/prepare_single_aa_challenge.py @@ -0,0 +1,203 @@ +"""Prepare a deterministic, parent-disjoint single-amino-acid challenge. + +Only locked benchmark *test* clonotypes are eligible parents. The generated +mutants are scoring inputs, never additional training observations for an +IRRM encoder. Probe folds are assigned at the parent level. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd + + +AA = "ACDEFGHIKLMNPQRSTVWY" + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def stable_json(path: Path, payload: object) -> None: + path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def parent_folds(parent_ids: np.ndarray, seed: int) -> dict[str, str]: + ids = np.asarray(sorted(map(str, parent_ids)), dtype=object) + rng = np.random.default_rng(seed) + shuffled = ids[rng.permutation(len(ids))] + n_train = int(np.floor(0.6 * len(ids))) + n_val = int(np.floor(0.2 * len(ids))) + if min(n_train, n_val, len(ids) - n_train - n_val) < 1: + raise ValueError("At least five parents are required for 60/20/20 probe folds.") + return { + str(identifier): ("train" if i < n_train else "val" if i < n_train + n_val else "test") + for i, identifier in enumerate(shuffled) + } + + +def choose_parents(table: pd.DataFrame, indices: np.ndarray, limit: int, seed: int) -> pd.DataFrame: + eligible = table.iloc[indices].copy() + eligible = eligible[eligible["junction_aa"].astype(str).str.len() >= 4] + eligible["length"] = eligible["junction_aa"].astype(str).str.len() + if eligible.empty: + raise ValueError("No held-out parent has a mutable internal residue.") + # Proportional, deterministic length-stratified sampling prevents the most + # common CDR3 length from monopolizing a bounded challenge. + if len(eligible) > limit: + rng = np.random.default_rng(seed) + selected: list[int] = [] + groups = list(eligible.groupby("length", sort=True)) + raw = {length: limit * len(group) / len(eligible) for length, group in groups} + quotas = {length: int(np.floor(value)) for length, value in raw.items()} + remainder_order = sorted( + groups, key=lambda item: (-(raw[item[0]] - quotas[item[0]]), -len(item[1]), item[0]) + ) + for length, _group in remainder_order[: limit - sum(quotas.values())]: + quotas[length] += 1 + for length, group in groups: + take = min(quotas[length], len(group)) + if take: + selected.extend(rng.choice(group.index.to_numpy(), size=take, replace=False).tolist()) + eligible = eligible.loc[sorted(selected)] + if len(eligible) != limit: + raise AssertionError(f"Length-stratified sampler selected {len(eligible)} parents, expected {limit}.") + return eligible.sort_values("row_index", kind="mergesort").reset_index(drop=True) + + +def generate_mutants( + parents: pd.DataFrame, + benchmark_sequences: set[str], + variants_per_parent: int, + seed: int, +) -> pd.DataFrame: + if variants_per_parent < 2: + raise ValueError("At least two mutants per parent are required for within-parent ranking.") + used = set(benchmark_sequences) + rows: list[dict] = [] + for row in parents.to_dict(orient="records"): + parent_id = f"parent-{int(row['row_index']):06d}" + sequence = str(row["junction_aa"]) + candidates = [(pos, aa) for pos in range(1, len(sequence) - 1) for aa in AA if aa != sequence[pos]] + rng = np.random.default_rng(seed + int(row["row_index"]) * 104729) + accepted = 0 + for candidate_index in rng.permutation(len(candidates)): + position, new_aa = candidates[int(candidate_index)] + mutant = sequence[:position] + new_aa + sequence[position + 1:] + if mutant in used: + continue + used.add(mutant) + mutant_id = f"{parent_id}-m{accepted + 1:02d}" + rows.append({ + "clone_id": mutant_id, + "parent_id": parent_id, + "parent_row_index": int(row["row_index"]), + "parent_sequence": sequence, + "junction_aa": mutant, + "mutation_position_zero_based": int(position), + "mutation_position_fraction": float(position / (len(sequence) - 1)), + "from_aa": sequence[position], + "to_aa": new_aa, + "length": len(sequence), + "v_call": str(row.get("v_call", "")), + "j_call": str(row.get("j_call", "")), + "locus": "TRB", + }) + accepted += 1 + if accepted == variants_per_parent: + break + if accepted != variants_per_parent: + raise ValueError(f"Could not generate {variants_per_parent} unique mutants for {parent_id}.") + result = pd.DataFrame(rows) + if result["junction_aa"].duplicated().any() or set(result["junction_aa"]) & benchmark_sequences: + raise AssertionError("Generated mutants are not unique and benchmark-disjoint.") + mismatch = [ + sum(a != b for a, b in zip(row.parent_sequence, row.junction_aa)) + for row in result.itertuples(index=False) + ] + if set(mismatch) != {1}: + raise AssertionError("A generated variant is not exactly one substitution from its parent.") + return result + + +def prepare(data_dir: Path, output_dir: Path, max_parents: int, variants: int, seed: int) -> dict: + # Keep deterministic generation utilities importable in lightweight local + # test environments that do not install the model's PyTorch dependency. + from irrm_codec.multitask_data import load_prepared_benchmark, select_split_indices + if output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {output_dir}") + output_dir.mkdir(parents=True) + table, embeddings = load_prepared_benchmark(data_dir) + test_indices = select_split_indices(table, data_dir, "test") + parents = choose_parents(table, test_indices, max_parents, seed) + folds = parent_folds(np.array([f"parent-{int(i):06d}" for i in parents["row_index"]]), seed) + parents["parent_id"] = [f"parent-{int(i):06d}" for i in parents["row_index"]] + parents["probe_split"] = parents["parent_id"].map(folds) + mutants = generate_mutants(parents, set(table["junction_aa"].astype(str)), variants, seed) + mutants["probe_split"] = mutants["parent_id"].map(folds) + if mutants["probe_split"].isna().any(): + raise AssertionError("A mutant lacks a parent-derived probe split.") + + parent_target_path = output_dir / "parent_tcremp.npy" + np.save(parent_target_path, np.asarray(embeddings[parents["row_index"].to_numpy(int)], dtype=np.float32)) + parents_path = output_dir / "parents.tsv" + mutants_path = output_dir / "mutants.tsv" + scoring_path = output_dir / "mutants_airr.tsv" + parents.to_csv(parents_path, sep="\t", index=False, lineterminator="\n") + mutants.to_csv(mutants_path, sep="\t", index=False, lineterminator="\n") + mutants[["clone_id", "junction_aa", "v_call", "j_call", "locus"]].to_csv( + scoring_path, sep="\t", index=False, lineterminator="\n" + ) + split_counts = mutants.groupby("probe_split")["parent_id"].nunique().to_dict() + report = { + "status": "ready_for_independent_target_scoring", + "seed": seed, + "source_split": "locked benchmark test only", + "parents": int(len(parents)), + "mutants": int(len(mutants)), + "variants_per_parent": variants, + "all_pairs_edit_distance": 1, + "parent_disjoint_probe_folds": True, + "probe_parent_counts": {str(key): int(value) for key, value in split_counts.items()}, + "benchmark_mutant_overlap": 0, + "tcremp_shape": [int(len(parents)), int(embeddings.shape[1])], + "sources": { + "dataset": {"path": str(data_dir / "dataset.parquet"), "sha256": sha256(data_dir / "dataset.parquet")}, + "embeddings": {"path": str(data_dir / "embeddings.npy"), "sha256": sha256(data_dir / "embeddings.npy")}, + "test_manifest": {"path": str(data_dir / "manifests/test.tsv"), "sha256": sha256(data_dir / "manifests/test.tsv")}, + }, + "artifacts": { + path.name: sha256(path) for path in (parents_path, mutants_path, scoring_path, parent_target_path) + }, + } + stable_json(output_dir / "PREPARED.json", report) + return report + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--data-dir", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--max-parents", type=int, default=2000) + parser.add_argument("--variants-per-parent", type=int, default=3) + parser.add_argument("--seed", type=int, default=42) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + report = prepare(args.data_dir, args.output_dir, args.max_parents, args.variants_per_parent, args.seed) + print(json.dumps(report, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_vdjdb_redcea_clonotypes.py b/benchmark/prepare_vdjdb_redcea_clonotypes.py new file mode 100644 index 0000000..6580093 --- /dev/null +++ b/benchmark/prepare_vdjdb_redcea_clonotypes.py @@ -0,0 +1,209 @@ +"""Prepare a leakage-controlled, per-clonotype REDCEA VDJdb benchmark. + +The REDCEA member table is used only as a membership/label source. Its UMAP +coordinates and cluster identifiers are retained for provenance but never used +as model features or evaluation targets. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from collections import Counter, defaultdict +from pathlib import Path + +import pandas as pd + +from benchmark.prepare_vdjdb_epitope_cohort import read_benchmark_sequences + + +AA = frozenset("ACDEFGHIKLMNPQRSTVWY") +REQUIRED_COLUMNS = { + "species", "antigen.epitope", "antigen.gene", "antigen.species", + "mhc.a", "mhc.b", "mhc.class", "gene", "cdr3aa", "cid", "csz", + "v.segm", "j.segm", +} + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def stable_json(path: Path, value: object) -> None: + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def canonical_aa(value: object, max_length: int) -> str | None: + sequence = str(value).strip().upper() + if not sequence or len(sequence) > max_length or any(aa not in AA for aa in sequence): + return None + return sequence + + +def prepare_cohort( + members: pd.DataFrame, + benchmark_sequences: dict[str, set[str]], + min_clonotypes: int, + max_length: int, +) -> tuple[pd.DataFrame, pd.DataFrame, dict]: + missing = REQUIRED_COLUMNS.difference(members.columns) + if missing: + raise ValueError(f"REDCEA member table is missing columns: {sorted(missing)}") + counts: Counter[str] = Counter(source_rows=len(members)) + rows_by_sequence: dict[str, list[dict]] = defaultdict(list) + for raw in members.to_dict(orient="records"): + if str(raw["gene"]).strip().upper() != "TRB": + counts["non_trb_rows"] += 1 + continue + sequence = canonical_aa(raw["cdr3aa"], max_length=max_length) + if sequence is None: + counts["invalid_sequence_rows"] += 1 + continue + label = str(raw["antigen.epitope"]).strip().upper() + if not label: + counts["empty_epitope_rows"] += 1 + continue + rows_by_sequence[sequence].append({ + "cdr3": sequence, + "label": label, + "species": str(raw["species"]).strip(), + "antigen_gene": str(raw["antigen.gene"]).strip(), + "antigen_species": str(raw["antigen.species"]).strip(), + "mhc_a": str(raw["mhc.a"]).strip(), + "mhc_b": str(raw["mhc.b"]).strip(), + "mhc_class": str(raw["mhc.class"]).strip(), + "v_call": str(raw["v.segm"]).strip(), + "j_call": str(raw["j.segm"]).strip(), + "cid": str(raw["cid"]).strip(), + "csz": int(float(raw["csz"])), + "length": len(sequence), + }) + + retained: list[dict] = [] + overlap_by_split: Counter[str] = Counter() + for sequence, source_rows in sorted(rows_by_sequence.items()): + labels = {row["label"] for row in source_rows} + if len(labels) != 1: + counts["ambiguous_multilabel_cdr3"] += 1 + continue + overlapping = [ + split for split, sequences in benchmark_sequences.items() if sequence in sequences + ] + if overlapping: + counts["benchmark_overlap_cdr3"] += 1 + overlap_by_split.update(overlapping) + continue + representative = min( + source_rows, + key=lambda row: ( + row["label"], row["species"], row["cid"], row["v_call"], row["j_call"] + ), + ).copy() + representative["source_rows"] = len(source_rows) + representative["source_cids"] = "|".join(sorted({row["cid"] for row in source_rows})) + retained.append(representative) + + provisional = pd.DataFrame(retained) + support = provisional.groupby("label")["cdr3"].nunique().sort_index() + eligible_labels = set(support[support >= min_clonotypes].index) + cohort = provisional[provisional["label"].isin(eligible_labels)].copy() + cohort.sort_values(["label", "cdr3"], inplace=True, kind="mergesort") + cohort.reset_index(drop=True, inplace=True) + if cohort.empty or cohort["cdr3"].duplicated().any(): + raise ValueError("Prepared cohort is empty or contains duplicate CDR3 sequences.") + if (cohort.groupby("label").size() < min_clonotypes).any(): + raise AssertionError("A retained label is below the preregistered support threshold.") + + summary = ( + cohort.groupby("label", sort=True) + .agg( + unique_cdr3=("cdr3", "size"), + redcea_clusters=("cid", "nunique"), + species=("species", lambda x: "|".join(sorted(set(x)))), + antigen_species=("antigen_species", lambda x: "|".join(sorted(set(x)))), + length_min=("length", "min"), + length_median=("length", "median"), + length_max=("length", "max"), + ) + .reset_index() + ) + report = { + "filter_counts": dict(sorted(counts.items())), + "benchmark_overlap_by_split": dict(sorted(overlap_by_split.items())), + "labels_before_support_gate": int(len(support)), + "labels_after_support_gate": int(cohort["label"].nunique()), + "clonotypes_after_support_gate": int(len(cohort)), + "min_clonotypes_per_epitope": int(min_clonotypes), + "support_before_gate": {str(k): int(v) for k, v in support.items()}, + } + return cohort, summary, report + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--cluster-members", type=Path, required=True) + parser.add_argument("--benchmark-dir", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--min-clonotypes", type=int, default=20) + parser.add_argument("--max-length", type=int, default=40) + parser.add_argument("--source-git-commit", required=True) + parser.add_argument("--source-git-blob", required=True) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + if args.min_clonotypes < 11: + raise ValueError("At least 11 clonotypes are required for precision@10.") + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + benchmark_sequences, benchmark_hashes = read_benchmark_sequences(args.benchmark_dir) + members = pd.read_csv(args.cluster_members, sep="\t", dtype=str, keep_default_na=False) + cohort, summary, report = prepare_cohort( + members, benchmark_sequences, args.min_clonotypes, args.max_length + ) + cohort_path = args.output_dir / "cohort.tsv" + summary_path = args.output_dir / "epitope_support.tsv" + cohort.to_csv(cohort_path, sep="\t", index=False, lineterminator="\n") + summary.to_csv(summary_path, sep="\t", index=False, lineterminator="\n") + manifest = { + "status": "accepted_for_frozen_embedding_evaluation", + "study": "REDCEA motif-member per-clonotype epitope geometry", + "source": { + "path": str(args.cluster_members), + "sha256": sha256(args.cluster_members), + "git_commit": args.source_git_commit, + "git_blob": args.source_git_blob, + "expected_repository_path": "results/redcea/cluster_members_TRB.txt", + }, + "cohort": { + "path": str(cohort_path), "sha256": sha256(cohort_path), + "rows": len(cohort), "labels": int(cohort["label"].nunique()), + "species": sorted(cohort["species"].unique().tolist()), + "minimum_label_support": args.min_clonotypes, + }, + "epitope_support": {"path": str(summary_path), "sha256": sha256(summary_path)}, + "benchmark_manifest_sha256": benchmark_hashes, + "filters": report, + "protocol": { + "unit": "unique exact TRB CDR3 amino-acid clonotype", + "label": "exact antigen.epitope from REDCEA member table", + "donors_and_publications": "pooled; not used for filtering or splitting", + "ambiguous_multilabel_cdr3": "removed entirely", + "benchmark_train_val_test_overlap": "removed entirely", + "redcea_cid": "provenance only; not an evaluation unit or feature", + "redcea_x_y": "excluded; UMAP visualization coordinates are never features", + }, + } + stable_json(args.output_dir / "PREFLIGHT.json", manifest) + print(json.dumps(manifest, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/prepare_vdjdb_viral_motif_top10.py b/benchmark/prepare_vdjdb_viral_motif_top10.py new file mode 100644 index 0000000..f65f903 --- /dev/null +++ b/benchmark/prepare_vdjdb_viral_motif_top10.py @@ -0,0 +1,453 @@ +"""Prepare an exploratory top-10 viral official-motif VDJdb benchmark.""" + +from __future__ import annotations + +import argparse +import csv +import json +import math +import os +from collections import Counter, defaultdict +from pathlib import Path + +from benchmark.prepare_vdjdb_epitope_cohort import ( + VALID_AA, + clean_text, + normalized_context, + parse_json_object, + read_benchmark_sequences, + sha256_file, + stable_json, + write_tsv, +) +from benchmark.prepare_vdjdb_ylq_motif_pooled import ( + TARGET_CONTEXT, + build_pairs, + select_compact_negatives, +) + + +def read_species_list(path: Path) -> list[str]: + values = [] + for line in path.read_text(encoding="utf-8").splitlines(): + value = line.strip() + if value and not value.startswith("#"): + values.append(value) + if not values or len(values) != len(set(values)): + raise ValueError("Viral antigen-species list must be nonempty and unique.") + return values + + +def read_official_members(path: Path) -> tuple[dict[tuple[str, str, str], set[str]], dict]: + counts: Counter[str] = Counter() + membership: dict[tuple[str, str, str], set[str]] = defaultdict(set) + with path.open("r", encoding="utf-8", newline="") as handle: + reader = csv.DictReader(handle, delimiter="\t") + required = { + "species", "antigen.epitope", "antigen.species", "mhc.a", "mhc.b", + "mhc.class", "gene", "cdr3aa", "cid", "v.segm", "j.segm", + } + missing = required.difference(reader.fieldnames or []) + if missing: + raise ValueError(f"Official cluster-members file lacks columns: {sorted(missing)}") + for row in reader: + counts["source_rows"] += 1 + if normalized_context(row["species"]) != "HOMOSAPIENS": + continue + if normalized_context(row["gene"]) != "TRB": + continue + context = ( + normalized_context(row["mhc.a"]), normalized_context(row["mhc.b"]), + normalized_context(row["mhc.class"]), + ) + if context != TARGET_CONTEXT: + continue + counts["exact_context_trb_rows"] += 1 + sequence = normalized_context(row["cdr3aa"]) + peptide = normalized_context(row["antigen.epitope"]) + antigen_species = clean_text(row["antigen.species"]) + cid = clean_text(row["cid"]) + if not sequence or len(sequence) > 40 or set(sequence).difference(VALID_AA): + counts["invalid_member_cdr3"] += 1 + continue + if not peptide or not antigen_species or not cid: + counts["missing_member_label_species_or_cid"] += 1 + continue + membership[(sequence, peptide, antigen_species)].add(cid) + counts["valid_exact_context_membership_rows"] += 1 + return membership, { + "counts": dict(sorted(counts.items())), + "unique_sequence_peptide_species_memberships": len(membership), + } + + +def read_joined_records( + vdjdb_path: Path, + membership: dict[tuple[str, str, str], set[str]], + benchmark: dict[str, set[str]], + min_score: float, +) -> tuple[list[dict], dict]: + counts: Counter[str] = Counter() + overlaps: Counter[str] = Counter() + grouped: dict[str, list[dict]] = defaultdict(list) + with vdjdb_path.open("r", encoding="utf-8", newline="") as handle: + reader = csv.DictReader(handle, delimiter="\t") + required = { + "gene", "cdr3", "v.segm", "j.segm", "species", "mhc.a", "mhc.b", + "mhc.class", "antigen.epitope", "antigen.species", "reference.id", + "vdjdb.score", "meta", "cdr3fix", + } + missing = required.difference(reader.fieldnames or []) + if missing: + raise ValueError(f"Pinned VDJdb table lacks columns: {sorted(missing)}") + for row in reader: + counts["source_rows"] += 1 + if normalized_context(row["gene"]) != "TRB" \ + or normalized_context(row["species"]) != "HOMOSAPIENS": + continue + context = ( + normalized_context(row["mhc.a"]), normalized_context(row["mhc.b"]), + normalized_context(row["mhc.class"]), + ) + if context != TARGET_CONTEXT: + continue + counts["exact_context_trb_rows"] += 1 + sequence = normalized_context(row["cdr3"]) + if not sequence or len(sequence) > 40 or set(sequence).difference(VALID_AA): + counts["invalid_cdr3"] += 1 + continue + fix = parse_json_object(row.get("cdr3fix", "")) + if fix.get("good") is not True: + counts["cdr3fix_not_good"] += 1 + continue + fixed = normalized_context(fix.get("cdr3")) + if fixed and fixed != sequence: + counts["cdr3fix_changes_sequence"] += 1 + continue + try: + score = float(row["vdjdb.score"]) + except ValueError: + score = math.nan + if not math.isfinite(score) or score < min_score: + counts["low_or_invalid_score"] += 1 + continue + peptide = normalized_context(row["antigen.epitope"]) + antigen_species = clean_text(row["antigen.species"]) + key = (sequence, peptide, antigen_species) + if key not in membership: + counts["not_exact_official_motif_member"] += 1 + continue + counts["exact_official_membership_join_rows"] += 1 + overlapping = [split for split, sequences in benchmark.items() if sequence in sequences] + if overlapping: + counts["benchmark_overlap_rows"] += 1 + for split in overlapping: + overlaps[split] += 1 + continue + meta = parse_json_object(row.get("meta", "")) + subject = clean_text(meta.get("subject.id") or meta.get("subject_id")) + study = clean_text(meta.get("study.id") or meta.get("study_id") or row["reference.id"]) + grouped[sequence].append({ + "cdr3": sequence, + "epitope": peptide, + "antigen_species": antigen_species, + "mhc_a": TARGET_CONTEXT[0], + "mhc_b": TARGET_CONTEXT[1], + "mhc_class": TARGET_CONTEXT[2], + "v_call": normalized_context(row["v.segm"]), + "j_call": normalized_context(row["j.segm"]), + "reference_id": clean_text(row["reference.id"]), + "vdjdb_score": score, + "donor_key": f"{study}|{subject}" if subject else "", + "motif_cids": membership[key], + "length": len(sequence), + }) + + retained = [] + for sequence, rows in sorted(grouped.items()): + labels = {(row["epitope"], row["antigen_species"]) for row in rows} + if len(labels) != 1: + counts["ambiguous_multilabel_or_species_cdr3"] += 1 + continue + representative = min( + rows, + key=lambda row: ( + -row["vdjdb_score"], row["epitope"], row["antigen_species"], + row["v_call"], row["j_call"], row["reference_id"], + ), + ).copy() + representative["source_rows"] = len(rows) + representative["donor_count_descriptive_only"] = len({ + row["donor_key"] for row in rows if row["donor_key"] + }) + representative["motif_cids"] = ",".join(sorted({ + cid for row in rows for cid in row["motif_cids"] + })) + retained.append(representative) + counts["pooled_exact_cdr3_after_global_dedup"] = len(retained) + return retained, { + "filter_counts": dict(sorted(counts.items())), + "benchmark_overlap_rows_by_split": dict(sorted(overlaps.items())), + } + + +def rank_epitopes(records: list[dict], viral_species: set[str]) -> tuple[list[dict], list[dict]]: + species_counts = Counter(record["antigen_species"] for record in records) + viral = [record for record in records if record["antigen_species"] in viral_species] + by_epitope: dict[str, list[dict]] = defaultdict(list) + for record in viral: + by_epitope[record["epitope"]].append(record) + ranking = [] + for peptide, rows in by_epitope.items(): + ranking.append({ + "epitope": peptide, + "unique_cdr3": len(rows), + "antigen_species": ",".join(sorted({row["antigen_species"] for row in rows})), + "species_count": len({row["antigen_species"] for row in rows}), + }) + ranking.sort(key=lambda row: (-row["unique_cdr3"], row["epitope"])) + inventory = [ + { + "antigen_species": species, + "unique_cdr3": count, + "classified_viral_by_exact_allowlist": int(species in viral_species), + } + for species, count in sorted(species_counts.items(), key=lambda item: (-item[1], item[0])) + ] + return ranking, inventory + + +def choose_top10(ranking: list[dict], requested_threshold: int) -> tuple[list[dict], dict]: + requested_epitopes = 10 + evaluable = [row for row in ranking if row["unique_cdr3"] >= 2] + if not evaluable: + raise ValueError("No viral epitope has two distinct post-filter CDR3s.") + passing = [row for row in evaluable if row["unique_cdr3"] >= requested_threshold] + if len(passing) >= requested_epitopes: + threshold = requested_threshold + relaxed = False + selected_count = requested_epitopes + elif len(evaluable) >= requested_epitopes: + threshold = int(evaluable[requested_epitopes - 1]["unique_cdr3"]) + relaxed = True + selected_count = requested_epitopes + else: + threshold = int(evaluable[-1]["unique_cdr3"]) + relaxed = True + selected_count = len(evaluable) + selected = [row.copy() for row in evaluable if row["unique_cdr3"] >= threshold][ + :selected_count + ] + for index, row in enumerate(selected, start=1): + row["rank"] = index + return selected, { + "requested_minimum_unique_cdr3": requested_threshold, + "epitopes_meeting_requested_threshold": len(passing), + "requested_epitopes": requested_epitopes, + "selected_epitopes": len(selected), + "evaluable_epitope_shortfall": requested_epitopes - len(selected), + "all_post_filter_viral_epitopes": len(ranking), + "viral_epitopes_with_two_distinct_cdr3": len(evaluable), + "viral_epitopes_below_distinct_pair_minimum": len(ranking) - len(evaluable), + "effective_minimum_unique_cdr3": threshold, + "threshold_transparently_lowered": relaxed, + "selection_rule": ( + "post-filter unique CDR3 descending, then exact peptide lexical; at least two " + "distinct target CDR3s required for within-target pairs" + ), + "model_metrics_used_for_selection": False, + } + + +def write_epitope_dataset( + output_dir: Path, + rank: int, + epitope: str, + positives: list[dict], + eligible_negatives: list[dict], + controls_per_positive: int, + max_pairs: int, + seed: int, +) -> dict: + directory = output_dir / f"epitope-{rank:02d}-{epitope}" + directory.mkdir() + negatives, assignments, strata, control_report = select_compact_negatives( + positives, eligible_negatives, controls_per_positive, seed + rank * 1000 + ) + candidates = [] + fields = [ + "candidate_index", "is_target", "cdr3", "epitope", "antigen_species", + "mhc_a", "mhc_b", "mhc_class", "v_call", "j_call", "reference_id", + "vdjdb_score", "length", "motif_cids", "source_rows", + "donor_count_descriptive_only", + ] + for index, record in enumerate([*positives, *negatives]): + candidate = dict(record) + candidate["candidate_index"] = index + candidate["is_target"] = int(index < len(positives)) + candidates.append(candidate) + if len({row["cdr3"] for row in candidates}) != len(candidates): + raise ValueError(f"{epitope} candidate set is not exact-CDR3 deduplicated.") + write_tsv(directory / "candidates.tsv", candidates, fields) + write_tsv(directory / "control_selection.tsv", assignments, list(assignments[0])) + write_tsv(directory / "control_length_strata.tsv", strata, list(strata[0])) + pairs, matching = build_pairs(positives, negatives, seed + rank * 1000) + pairs_before_cap = len(pairs) + if len(pairs) > max_pairs: + pairs = pairs[:max_pairs] + matching["pairs_before_deterministic_cap"] = pairs_before_cap + matching["primary_pair_cap"] = max_pairs + matching["pairs_after_deterministic_cap"] = len(pairs) + matching["positive_pairs_used_for_evaluation"] = len(pairs) + matching["pair_cap_rule"] = "first seeded-shuffled distinct positive pairs" + write_tsv(directory / "pair_manifest.tsv", pairs, list(pairs[0])) + report = { + "rank": rank, + "epitope": epitope, + "positive_cdr3": len(positives), + "selected_unique_negative_cdr3": len(negatives), + "eligible_viral_negative_cdr3_before_compaction": len(eligible_negatives), + "candidate_cdr3": len(candidates), + "matching": matching, + "compact_control_selection": control_report, + "artifacts": { + "candidates_sha256": sha256_file(directory / "candidates.tsv"), + "pairs_sha256": sha256_file(directory / "pair_manifest.tsv"), + "control_selection_sha256": sha256_file(directory / "control_selection.tsv"), + "control_length_strata_sha256": sha256_file(directory / "control_length_strata.tsv"), + }, + } + stable_json(directory / "PREFLIGHT.json", report) + return {"report": report, "candidates": candidates} + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--vdjdb-tsv", type=Path, required=True) + parser.add_argument("--cluster-members", type=Path, required=True) + parser.add_argument("--motif-pwms", type=Path, required=True) + parser.add_argument("--benchmark-dir", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--viral-species-list", type=Path) + parser.add_argument("--inventory-only", action="store_true") + parser.add_argument("--min-score", type=float, default=1.0) + parser.add_argument("--requested-min-positives", type=int, default=40) + parser.add_argument("--controls-per-positive", type=int, default=4) + parser.add_argument("--max-pairs-per-epitope", type=int, default=5000) + parser.add_argument("--seed", type=int, default=42) + args = parser.parse_args() + if args.output_dir.exists(): + raise FileExistsError(f"Refusing to overwrite {args.output_dir}") + args.output_dir.mkdir(parents=True) + + benchmark, benchmark_hashes = read_benchmark_sequences(args.benchmark_dir) + membership, motif_report = read_official_members(args.cluster_members) + records, join_report = read_joined_records( + args.vdjdb_tsv, membership, benchmark, args.min_score + ) + all_species = Counter(record["antigen_species"] for record in records) + write_tsv( + args.output_dir / "antigen_species_inventory.tsv", + [{"antigen_species": key, "unique_cdr3": value} + for key, value in sorted(all_species.items(), key=lambda item: (-item[1], item[0]))], + ["antigen_species", "unique_cdr3"], + ) + if args.inventory_only: + report = { + "status": "inventory_complete", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "exact_context": list(TARGET_CONTEXT), + "unique_antigen_species": len(all_species), + "retained_unique_cdr3": len(records), + "motif_inventory": motif_report, + "vdjdb_join_and_quality": join_report, + "artifact_sha256": sha256_file(args.output_dir / "antigen_species_inventory.tsv"), + } + stable_json(args.output_dir / "INVENTORY.json", report) + print(json.dumps(report, indent=2, sort_keys=True)) + return + if args.viral_species_list is None: + raise ValueError("--viral-species-list is required outside inventory-only mode.") + viral_species_values = read_species_list(args.viral_species_list) + ranking, inventory = rank_epitopes(records, set(viral_species_values)) + write_tsv(args.output_dir / "antigen_species_classification.tsv", inventory, list(inventory[0])) + write_tsv(args.output_dir / "viral_epitope_candidates.tsv", ranking, list(ranking[0])) + selected, gate = choose_top10(ranking, args.requested_min_positives) + write_tsv(args.output_dir / "selected_top10.tsv", selected, list(selected[0])) + + viral_records = [record for record in records + if record["antigen_species"] in set(viral_species_values)] + datasets = [] + master: dict[str, dict] = {} + for selected_row in selected: + epitope = selected_row["epitope"] + positives = [record for record in viral_records if record["epitope"] == epitope] + negatives = [record for record in viral_records if record["epitope"] != epitope] + dataset = write_epitope_dataset( + args.output_dir, selected_row["rank"], epitope, positives, negatives, + args.controls_per_positive, args.max_pairs_per_epitope, args.seed, + ) + datasets.append(dataset["report"]) + for record in dataset["candidates"]: + master.setdefault(record["cdr3"], record) + master_rows = [] + for index, cdr3 in enumerate(sorted(master)): + row = dict(master[cdr3]) + row["master_index"] = index + master_rows.append(row) + write_tsv( + args.output_dir / "master_candidates.tsv", master_rows, + ["master_index", "cdr3", "epitope", "antigen_species", "mhc_a", "mhc_b", + "mhc_class", "v_call", "j_call", "reference_id", "vdjdb_score", "length", + "motif_cids", "source_rows", "donor_count_descriptive_only"], + ) + manifest = { + "status": "ready", + "slurm_job_id": os.environ.get("SLURM_JOB_ID"), + "exact_context": {"mhc_a": TARGET_CONTEXT[0], "mhc_b": TARGET_CONTEXT[1], + "mhc_class": TARGET_CONTEXT[2]}, + "pooling": "all records pooled; donor metadata descriptive only", + "viral_species_rule": ( + "Exact, case-sensitive antigen.species membership in the pinned allowlist; no " + "substring, epitope, antigen-gene, or model-score inference." + ), + "viral_antigen_species_exact": viral_species_values, + "support_gate": gate, + "selected": datasets, + "master_candidate_cdr3": len(master_rows), + "motif_inventory": motif_report, + "vdjdb_join_and_quality": join_report, + "sources": { + "vdjdb": {"path": str(args.vdjdb_tsv), "sha256": sha256_file(args.vdjdb_tsv)}, + "cluster_members": {"path": str(args.cluster_members), + "sha256": sha256_file(args.cluster_members)}, + "motif_pwms": {"path": str(args.motif_pwms), + "sha256": sha256_file(args.motif_pwms)}, + "viral_species_list": {"path": str(args.viral_species_list), + "sha256": sha256_file(args.viral_species_list)}, + "benchmark_manifests": benchmark_hashes, + }, + "artifacts": { + "selected_top10_sha256": sha256_file(args.output_dir / "selected_top10.tsv"), + "candidate_ranking_sha256": sha256_file( + args.output_dir / "viral_epitope_candidates.tsv" + ), + "master_candidates_sha256": sha256_file(args.output_dir / "master_candidates.tsv"), + }, + "official_motif_rule": ( + "Exact sequence+peptide+antigen.species membership in official cluster_members.txt " + "after exact HomoSapiens/TRB/HLA-A*02:01/B2M/MHCI filtering." + ), + "circularity_caveat": ( + "Official motif membership is sequence-cluster-conditioned. This is an exploratory " + "within-VDJdb motif/epitope-organization analysis, not evidence independent of " + "sequence motif or composition." + ), + "embedding_extraction_performed": False, + } + stable_json(args.output_dir / "PREFLIGHT.json", manifest) + print(json.dumps(manifest, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/train_external_model_decoder.py b/benchmark/train_external_model_decoder.py new file mode 100644 index 0000000..5bed724 --- /dev/null +++ b/benchmark/train_external_model_decoder.py @@ -0,0 +1,271 @@ +"""Issue 2: train the IRRM-CODEC decoder on one representation and score reconstruction. + +The decoder architecture, optimizer, schedule and early stopping are identical for every +representation, so the only thing that varies between runs is the bottleneck vector the +decoder reads. Inputs are standardized with train-split statistics: the projections +arrive on very different scales, and a shared learning rate on unequal scales would make +"identical training settings" true on paper only. The repo's forward/inverse trainers +normalize their embeddings the same way. + +Reported metrics: exact sequence match, amino-acid token accuracy, normalized +Levenshtein distance, fraction of predictions within edit distance 1, inference speed. +""" + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +from torch.utils.data import DataLoader, TensorDataset + +from irrm_codec.inverse_model import InverseModel +from irrm_codec.losses import inverse_loss +from irrm_codec.tokenization import AA_VOCAB, ID2AA, encode + +GAP_ID = AA_VOCAB["-"] +from irrm_codec.utils import choose_device, save_checkpoint, set_seed, setup_logging + + +def levenshtein_distance(left: str, right: str) -> int: + if len(left) > len(right): + left, right = right, left + previous = list(range(len(left) + 1)) + for right_index, right_char in enumerate(right, start=1): + current = [right_index] + for left_index, left_char in enumerate(left, start=1): + current.append(min(current[-1] + 1, previous[left_index] + 1, + previous[left_index - 1] + (left_char != right_char))) + previous = current + return previous[-1] + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--bottleneck-dir", default="data/benchmark/trb/bottleneck") + p.add_argument("--representation", required=True) + p.add_argument("--bottleneck-dim", type=int, default=64) + p.add_argument("--output-dir", default="artifacts/benchmark/reconstruction") + p.add_argument("--seed", type=int, default=42) + p.add_argument("--epochs", type=int, default=60) + p.add_argument("--batch-size", type=int, default=256) + p.add_argument("--lr", type=float, default=1e-3) + p.add_argument("--weight-decay", type=float, default=1e-4) + p.add_argument("--patience", type=int, default=8, help="Early-stopping patience in epochs.") + p.add_argument("--max-len", type=int, default=40) + p.add_argument("--train-subset", default="all", help="Training subset manifest: 1k, 10k or all.") + p.add_argument("--threads", type=int, default=8) + p.add_argument("--num-workers", type=int, default=0) + return p.parse_args() + + +def load_split_rows(dataset_dir, name): + return pd.read_csv(Path(dataset_dir) / "manifests" / f"{name}.tsv", sep="\t")["row_index"].to_numpy() + + +def decode_tokens(token_ids): + """Turn predicted token ids back into a gap-free amino-acid string.""" + return "".join(ID2AA[int(t)] for t in token_ids if int(t) > GAP_ID) + + +def build_tensors(matrix, rows, sequences, max_len): + features = torch.from_numpy(np.asarray(matrix[rows], dtype=np.float32)) + targets = torch.tensor( + [encode(sequences[i], max_len=max_len) for i in rows], dtype=torch.long + ) + return features, targets + + +@torch.no_grad() +def evaluate(model, loader, device, sequences, rows, max_len, collect_predictions=False): + """Run the decoder over a split and score it at the sequence level.""" + model.eval() + loss_sum, steps = 0.0, 0 + token_hits, token_total = 0, 0 + predictions = [] + + for features, targets in loader: + features, targets = features.to(device), targets.to(device) + logits = model(features) + loss_sum += inverse_loss(logits, targets).item() + steps += 1 + + predicted = logits.argmax(dim=-1) + # encode() gap-pads to a fixed width, so every position is filled and most of + # them are gaps. Scoring those would let a model inflate token accuracy by + # predicting padding, so accuracy counts real residues only. + residues = targets.gt(GAP_ID) + token_hits += predicted.eq(targets).logical_and(residues).sum().item() + token_total += residues.sum().item() + predictions.extend(decode_tokens(row) for row in predicted.cpu().numpy()) + + truth = [sequences[i] for i in rows] + distances = np.array([levenshtein_distance(p, t) for p, t in zip(predictions, truth)]) + lengths = np.array([max(len(t), 1) for t in truth]) + + metrics = { + "loss": loss_sum / max(steps, 1), + "token_accuracy": token_hits / max(token_total, 1), + "exact_match": float(np.mean(distances == 0)), + "normalized_levenshtein": float(np.mean(distances / lengths)), + "within_edit_distance_1": float(np.mean(distances <= 1)), + "mean_edit_distance": float(distances.mean()), + } + return (metrics, predictions, truth) if collect_predictions else (metrics, None, None) + + +@torch.no_grad() +def measure_inference_speed(model, features, device, batch_size): + """Throughput on the test split, excluding metric computation.""" + model.eval() + warmup = features[: min(batch_size, len(features))].to(device) + model(warmup) + + started = time.perf_counter() + for start in range(0, len(features), batch_size): + model(features[start : start + batch_size].to(device)) + elapsed = time.perf_counter() - started + return { + "sequences_per_second": len(features) / elapsed, + "ms_per_sequence": elapsed / len(features) * 1000, + "batch_size": batch_size, + "device": str(device), + } + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + set_seed(args.seed) + device = choose_device() + + run_name = f"{args.representation}_d{args.bottleneck_dim}_{args.train_subset}_seed{args.seed}" + output_dir = Path(args.output_dir) / run_name + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "train.log") + + dataset_dir = Path(args.dataset_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + sequences = frame["junction_aa"].tolist() + + source = Path(args.bottleneck_dir) / f"{args.representation}_{args.bottleneck_dim}.npy" + matrix = np.load(source, mmap_mode="r") + log.info("run=%s device=%s features=%s", run_name, device, matrix.shape) + + train_rows = load_split_rows(dataset_dir, f"train_{args.train_subset}") + val_rows = load_split_rows(dataset_dir, "val") + test_rows = load_split_rows(dataset_dir, "test") + + train_x, train_y = build_tensors(matrix, train_rows, sequences, args.max_len) + val_x, val_y = build_tensors(matrix, val_rows, sequences, args.max_len) + test_x, test_y = build_tensors(matrix, test_rows, sequences, args.max_len) + + # Train-split statistics only, so no held-out information reaches the projection. + mean = train_x.mean(dim=0, keepdim=True) + std = train_x.std(dim=0, keepdim=True).clamp_min(1e-6) + train_x, val_x, test_x = ((t - mean) / std for t in (train_x, val_x, test_x)) + np.save(output_dir / "mean.npy", mean.numpy()) + np.save(output_dir / "std.npy", std.numpy()) + + loaders = { + name: DataLoader( + TensorDataset(x, y), + batch_size=args.batch_size, + shuffle=(name == "train"), + num_workers=args.num_workers, + ) + for name, (x, y) in ( + ("train", (train_x, train_y)), + ("val", (val_x, val_y)), + ("test", (test_x, test_y)), + ) + } + + model = InverseModel(embedding_dim=args.bottleneck_dim, max_len=args.max_len).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + log.info("model params=%.2fM train=%d val=%d test=%d", + sum(p.numel() for p in model.parameters()) / 1e6, + len(train_rows), len(val_rows), len(test_rows)) + + best_val = float("inf") + best_epoch = 0 + history = [] + training_started = time.perf_counter() + + for epoch in range(1, args.epochs + 1): + model.train() + epoch_loss, steps = 0.0, 0 + for features, targets in loaders["train"]: + features, targets = features.to(device), targets.to(device) + logits = model(features) + loss = inverse_loss(logits, targets) + optimizer.zero_grad(set_to_none=True) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + epoch_loss += loss.item() + steps += 1 + + train_loss = epoch_loss / max(steps, 1) + val_metrics, _, _ = evaluate(model, loaders["val"], device, sequences, val_rows, args.max_len) + history.append({"epoch": epoch, "train_loss": train_loss, **{f"val_{k}": v for k, v in val_metrics.items()}}) + log.info( + "epoch=%d train_loss=%.4f val_loss=%.4f val_exact=%.4f val_tok=%.4f", + epoch, train_loss, val_metrics["loss"], val_metrics["exact_match"], val_metrics["token_accuracy"], + ) + + if val_metrics["loss"] < best_val - 1e-5: + best_val, best_epoch = val_metrics["loss"], epoch + save_checkpoint(output_dir / "best.pt", model, optimizer, epoch, val_metrics) + elif epoch - best_epoch >= args.patience: + log.info("early stopping at epoch=%d (best epoch=%d)", epoch, best_epoch) + break + + training_seconds = time.perf_counter() - training_started + save_checkpoint(output_dir / "last.pt", model, optimizer, len(history), history[-1]) + + model.load_state_dict(torch.load(output_dir / "best.pt", map_location=device)["model_state"]) + test_metrics, predictions, truth = evaluate( + model, loaders["test"], device, sequences, test_rows, args.max_len, collect_predictions=True + ) + speed = measure_inference_speed(model, test_x, device, args.batch_size) + + pd.DataFrame( + { + "row_index": test_rows, + "true_cdr3": truth, + "predicted_cdr3": predictions, + "edit_distance": [levenshtein_distance(p, t) for p, t in zip(predictions, truth)], + } + ).to_csv(output_dir / "test_predictions.csv", index=False) + + pd.DataFrame(history).to_csv(output_dir / "history.csv", index=False) + result = { + "run_name": run_name, + "representation": args.representation, + "bottleneck_dim": args.bottleneck_dim, + "train_subset": args.train_subset, + "train_size": int(len(train_rows)), + "seed": args.seed, + "epochs_ran": len(history), + "best_epoch": best_epoch, + "best_val_loss": best_val, + "training_seconds": round(training_seconds, 2), + "test": test_metrics, + "inference": speed, + "config": vars(args), + } + (output_dir / "metrics.json").write_text(json.dumps(result, indent=2), encoding="utf-8") + + log.info("=" * 60) + log.info("test exact_match=%.4f token_accuracy=%.4f", test_metrics["exact_match"], test_metrics["token_accuracy"]) + log.info("test norm_levenshtein=%.4f within_ed1=%.4f", test_metrics["normalized_levenshtein"], test_metrics["within_edit_distance_1"]) + log.info("training_seconds=%.1f inference=%.0f seq/s", training_seconds, speed["sequences_per_second"]) + log.info("wrote %s", output_dir / "metrics.json") + + +if __name__ == "__main__": + main() diff --git a/benchmark/train_external_model_pgen.py b/benchmark/train_external_model_pgen.py new file mode 100644 index 0000000..66002ab --- /dev/null +++ b/benchmark/train_external_model_pgen.py @@ -0,0 +1,425 @@ +"""Issue 3: train one Pgen-prediction arm and score it on the benchmark test split. + +Arms: + irrm_scratch PgenModel from a random initialization + irrm_pretrained PgenModel initialized from the sequence-to-TCRemP encoder + tfidf_ridge 1-3-mer character TF-IDF + Ridge regression + sceptr_mlp frozen SCEPTR embeddings + the shared regression head + tcr_bert_mlp frozen TCR-BERT embeddings + the same head + esm2_8m_mlp frozen ESM-2 8M embeddings + the same head + rtp_mlp frozen DATA-ANCHOR R+T+P embeddings + the same head + sceptr_residue_pca128_mlp frozen train-only residue-PCA 128D SCEPTR vector + +The four frozen-embedding arms share one head and one training configuration, so the +only thing that varies between them is the representation. The two IRRM arms differ only +in initialization, which is the comparison the issue asks about. + +Targets stay in raw log10 units, matching the repo's pgen trainer, so RMSE, MAE and bias +are directly interpretable as log10 error. +""" + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +import torch.nn as nn +from scipy import stats +from torch.utils.data import DataLoader, TensorDataset + +from irrm_codec.losses import pgen_loss +from irrm_codec.pgen_model import PgenModel +from irrm_codec.tokenization import PAD_ID, encode +from irrm_codec.utils import choose_device, save_checkpoint, set_seed, setup_logging + +SEQUENCE_ARMS = ("irrm_scratch", "irrm_pretrained") +FROZEN_ARMS = { + "sceptr_mlp": "sceptr", + "tcr_bert_mlp": "tcr_bert", + "esm2_8m_mlp": "esm2_8m", + "onehot_mlp": "onehot", + "tcremp_mlp": "tcremp", + "esm2_35m_mlp": "esm2_35m", + "rtp_mlp": "rtp", + "sceptr_cdr3_mlp": "sceptr_cdr3", + "sceptr_residue_pca256_mlp": "sceptr_residue", + "tcr_bert_residue_pca256_mlp": "tcr_bert_residue", + "esm2_8m_residue_pca256_mlp": "esm2_8m_residue", + "sceptr_residue_pca128_mlp": "sceptr_residue", + "tcr_bert_residue_pca128_mlp": "tcr_bert_residue", + "esm2_8m_residue_pca128_mlp": "esm2_8m_residue", +} +ARMS = (*SEQUENCE_ARMS, "tfidf_ridge", *FROZEN_ARMS) + +# Ridge has no training loop, so the penalty is selected on validation instead. This is +# the baseline's equivalent of early stopping; fixing it arbitrarily would handicap it. +RIDGE_ALPHAS = (0.01, 0.1, 1.0, 10.0, 100.0) + + +def parse_args(): + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--arm", required=True, choices=ARMS) + p.add_argument("--target", default="log10_pgen_1mm", choices=("log10_pgen", "log10_pgen_1mm")) + p.add_argument("--dataset-dir", default="data/benchmark/trb") + p.add_argument("--representations-dir", default="data/benchmark/trb/representations") + p.add_argument("--pretrained-checkpoint", default="artifacts/benchmark/forward_encoder/best.pt") + p.add_argument("--output-dir", default="artifacts/benchmark/pgen") + p.add_argument("--train-subset", default="all") + p.add_argument("--seed", type=int, default=42) + p.add_argument("--epochs", type=int, default=60) + p.add_argument("--batch-size", type=int, default=256) + p.add_argument("--lr", type=float, default=1e-3) + p.add_argument("--weight-decay", type=float, default=1e-4) + # Wider than the reconstruction runs use: the cosine schedule only pays off if training + # reaches the low-learning-rate tail, and stopping at epoch 17 of 60 would decay the + # rate by under a fifth. + p.add_argument("--patience", type=int, default=12) + p.add_argument("--max-len", type=int, default=40) + p.add_argument("--threads", type=int, default=8) + return p.parse_args() + + +class RegressionHead(nn.Module): + """One head shared by every frozen representation, so only the input differs.""" + + def __init__(self, input_dim, hidden_dims=(512, 256), dropout=0.2): + super().__init__() + layers = [] + previous = input_dim + for width in hidden_dims: + layers += [nn.Linear(previous, width), nn.GELU(), nn.Dropout(dropout)] + previous = width + layers.append(nn.Linear(previous, 1)) + self.net = nn.Sequential(*layers) + + def forward(self, features): + return self.net(features).squeeze(-1) + + +def load_rows(dataset_dir, name): + return pd.read_csv(Path(dataset_dir) / "manifests" / f"{name}.tsv", sep="\t")["row_index"].to_numpy() + + +def peak_memory_mb(): + """True peak resident set size, plus GPU peak when a device was used.""" + result = {} + try: + import resource + + # ru_maxrss is in kilobytes on Linux. + result["peak_rss_mb"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 + except (ImportError, AttributeError): + try: + import psutil + + result["peak_rss_mb"] = psutil.Process().memory_info().rss / 1024**2 + except ImportError: + result["peak_rss_mb"] = None + if torch.cuda.is_available(): + result["peak_gpu_mb"] = torch.cuda.max_memory_allocated() / 1024**2 + return result + + +def regression_metrics(predictions, truth): + residual = predictions - truth + total_variance = np.var(truth) + return { + "rmse": float(np.sqrt(np.mean(residual**2))), + "mae": float(np.mean(np.abs(residual))), + "bias": float(np.mean(residual)), + "r2": float(1.0 - np.mean(residual**2) / total_variance) if total_variance > 0 else float("nan"), + "pearson_r": float(stats.pearsonr(predictions, truth)[0]), + "spearman_rho": float(stats.spearmanr(predictions, truth)[0]), + } + + +def build_features(args, frame, rows_by_split, log): + """Return per-split model inputs for the requested arm.""" + if args.arm in SEQUENCE_ARMS: + tokens = { + name: torch.tensor( + [encode(frame.junction_aa.iloc[i], max_len=args.max_len) for i in rows], + dtype=torch.long, + ) + for name, rows in rows_by_split.items() + } + return tokens, None + + representation = FROZEN_ARMS[args.arm] + representations_dir = Path(args.representations_dir) + catalog_path = representations_dir / "representations.json" + catalog = json.loads(catalog_path.read_text(encoding="utf-8")) + source = Path(catalog[representation]["path"]) + matrix = np.load(source, mmap_mode="r") + if matrix.shape[0] != len(frame): + raise ValueError(f"{representation} rows={matrix.shape[0]} dataset rows={len(frame)}") + features = { + name: torch.from_numpy(np.asarray(matrix[rows], dtype=np.float32)) + for name, rows in rows_by_split.items() + } + # Train-split statistics only: a shared learning rate across representations with + # different scales would not be the identical setting the issue requires. + mean = features["train"].mean(dim=0, keepdim=True) + raw_std = features["train"].std(dim=0, keepdim=True) + zero_variance = raw_std < 1e-6 + std = torch.where(zero_variance, torch.ones_like(raw_std), raw_std) + for name in features: + features[name] = (features[name] - mean) / std + log.info("%s features dim=%d zero_variance_columns=%d", representation, + features["train"].shape[1], int(zero_variance.sum())) + return features, (mean, std) + + +def build_model(args, input_dim, log): + if args.arm in SEQUENCE_ARMS: + model = PgenModel(max_len=args.max_len) + if args.arm == "irrm_pretrained": + state = torch.load(args.pretrained_checkpoint, map_location="cpu")["model_state"] + own = model.state_dict() + # Everything but the output layer matches: PgenModel is ForwardModel with + # output_dim=1, so only mlp. differs in shape. + transferable = {k: v for k, v in state.items() if k in own and own[k].shape == v.shape} + model.load_state_dict(transferable, strict=False) + log.info( + "transferred %d/%d tensors from %s", + len(transferable), len(own), args.pretrained_checkpoint, + ) + return model + return RegressionHead(input_dim) + + +def run_epoch(model, loader, device, is_sequence, optimizer=None): + is_train = optimizer is not None + model.train(mode=is_train) + loss_sum, steps = 0.0, 0 + for batch in loader: + inputs, target = batch[0].to(device), batch[-1].to(device) + with torch.set_grad_enabled(is_train): + prediction = model(inputs, inputs.ne(PAD_ID)) if is_sequence else model(inputs) + loss = pgen_loss(prediction, target) + if is_train: + optimizer.zero_grad(set_to_none=True) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + loss_sum += loss.item() + steps += 1 + return loss_sum / max(steps, 1) + + +@torch.no_grad() +def predict_all(model, inputs, device, is_sequence, batch_size): + model.eval() + chunks = [] + for start in range(0, len(inputs), batch_size): + block = inputs[start : start + batch_size].to(device) + prediction = model(block, block.ne(PAD_ID)) if is_sequence else model(block) + chunks.append(prediction.cpu().numpy()) + return np.concatenate(chunks) + + +def fit_ridge(args, frame, rows_by_split, targets, log): + """1-3-mer character TF-IDF into Ridge, with the penalty chosen on validation.""" + from sklearn.feature_extraction.text import TfidfVectorizer + from sklearn.linear_model import Ridge + + started = time.perf_counter() + sequences = { + name: frame.junction_aa.iloc[rows].tolist() for name, rows in rows_by_split.items() + } + vectorizer = TfidfVectorizer(analyzer="char", ngram_range=(1, 3)) + train_features = vectorizer.fit_transform(sequences["train"]) + val_features = vectorizer.transform(sequences["val"]) + + best = (None, float("inf"), None) + for alpha in RIDGE_ALPHAS: + model = Ridge(alpha=alpha).fit(train_features, targets["train"]) + rmse = float(np.sqrt(np.mean((model.predict(val_features) - targets["val"]) ** 2))) + log.info("ridge alpha=%.3g val_rmse=%.4f", alpha, rmse) + if rmse < best[1]: + best = (model, rmse, alpha) + model, val_rmse, alpha = best + training_seconds = time.perf_counter() - started + log.info("selected alpha=%.3g val_rmse=%.4f features=%d", alpha, val_rmse, train_features.shape[1]) + + # Vectorization is part of this arm's inference path, so it belongs inside the timed + # section; excluding it would report the Ridge solve alone and overstate throughput + # by orders of magnitude. + inference_started = time.perf_counter() + test_features = vectorizer.transform(sequences["test"]) + predictions = model.predict(test_features) + elapsed = time.perf_counter() - inference_started + + return ( + predictions, + training_seconds, + { + "sequences_per_second": len(predictions) / elapsed, + "ms_per_sequence": elapsed / len(predictions) * 1000, + "batch_size": len(predictions), + "device": "cpu", + }, + {"alpha": alpha, "val_rmse": val_rmse, "n_features": int(train_features.shape[1])}, + [], + ) + + +def fit_neural(args, features, targets, log): + device = choose_device() + is_sequence = args.arm in SEQUENCE_ARMS + if torch.cuda.is_available(): + torch.cuda.reset_peak_memory_stats() + + loaders = { + name: DataLoader( + TensorDataset(features[name], torch.from_numpy(targets[name].astype(np.float32))), + batch_size=args.batch_size, + shuffle=(name == "train"), + ) + for name in ("train", "val") + } + + model = build_model(args, features["train"].shape[-1], log).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + # A constant learning rate leaves the model bouncing around the minimum: validation + # loss oscillates, early stopping fires at an arbitrary epoch, and the IRRM arms end up + # spreading roughly tenfold wider across seeds than the frozen-embedding arms. + scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=args.epochs) + log.info("device=%s params=%.2fM", device, sum(p.numel() for p in model.parameters()) / 1e6) + + best_val, best_epoch = float("inf"), 0 + best_state = None + history = [] + started = time.perf_counter() + + for epoch in range(1, args.epochs + 1): + train_loss = run_epoch(model, loaders["train"], device, is_sequence, optimizer) + val_loss = run_epoch(model, loaders["val"], device, is_sequence) + scheduler.step() + history.append({"epoch": epoch, "train_loss": train_loss, "val_loss": val_loss}) + if epoch % 5 == 0 or epoch == 1: + log.info("epoch=%d train_loss=%.4f val_loss=%.4f", epoch, train_loss, val_loss) + + if val_loss < best_val - 1e-6: + best_val, best_epoch = val_loss, epoch + best_state = {k: v.detach().cpu().clone() for k, v in model.state_dict().items()} + elif epoch - best_epoch >= args.patience: + log.info("early stopping at epoch=%d (best epoch=%d)", epoch, best_epoch) + break + + training_seconds = time.perf_counter() - started + if best_state is not None: + model.load_state_dict(best_state) + + inference_started = time.perf_counter() + predictions = predict_all(model, features["test"], device, is_sequence, args.batch_size) + elapsed = time.perf_counter() - inference_started + + return ( + predictions, + training_seconds, + { + "sequences_per_second": len(predictions) / elapsed, + "ms_per_sequence": elapsed / len(predictions) * 1000, + "batch_size": args.batch_size, + "device": str(device), + }, + {"best_val_loss": best_val, "best_epoch": best_epoch, "epochs_ran": len(history)}, + history, + model, + optimizer, + ) + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + set_seed(args.seed) + + run_name = f"{args.arm}_{args.target}_{args.train_subset}_seed{args.seed}" + output_dir = Path(args.output_dir) / run_name + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "train.log") + + dataset_dir = Path(args.dataset_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + rows_by_split = { + "train": load_rows(dataset_dir, f"train_{args.train_subset}"), + "val": load_rows(dataset_dir, "val"), + "test": load_rows(dataset_dir, "test"), + } + targets = { + name: frame[args.target].to_numpy()[rows] for name, rows in rows_by_split.items() + } + # log10 Pgen sits near -6.5, so a freshly initialized network spends its first epochs + # just finding the offset while Ridge fits an intercept for free. Standardizing the + # target on train statistics removes that asymmetry; predictions are mapped back + # before any metric is computed, so the reported errors stay in log10 units. + target_mean = float(targets["train"].mean()) + target_std = max(float(targets["train"].std()), 1e-6) + scaled_targets = {name: (values - target_mean) / target_std for name, values in targets.items()} + log.info( + "run=%s train=%d val=%d test=%d target_mean=%.3f", + run_name, *(len(r) for r in rows_by_split.values()), targets["train"].mean(), + ) + + history, model, optimizer = [], None, None + if args.arm == "tfidf_ridge": + scaled_predictions, training_seconds, speed, extra, history = fit_ridge( + args, frame, rows_by_split, scaled_targets, log + ) + else: + features, _ = build_features(args, frame, rows_by_split, log) + scaled_predictions, training_seconds, speed, extra, history, model, optimizer = fit_neural( + args, features, scaled_targets, log + ) + save_checkpoint(output_dir / "best.pt", model, optimizer, extra["best_epoch"], extra) + + predictions = scaled_predictions * target_std + target_mean + metrics = regression_metrics(predictions, targets["test"]) + pd.DataFrame( + { + "row_index": rows_by_split["test"], + "cdr3": frame.junction_aa.iloc[rows_by_split["test"]].to_numpy(), + "true": targets["test"], + "predicted": predictions, + } + ).to_csv(output_dir / "test_predictions.csv", index=False) + if history: + pd.DataFrame(history).to_csv(output_dir / "history.csv", index=False) + + result = { + "run_name": run_name, + "arm": args.arm, + "target": args.target, + "train_subset": args.train_subset, + "train_size": int(len(rows_by_split["train"])), + "seed": args.seed, + "training_seconds": round(training_seconds, 2), + "test": metrics, + "inference": speed, + "memory": peak_memory_mb(), + "target_scaling": {"mean": target_mean, "std": target_std}, + "arm_details": extra, + "config": vars(args), + } + (output_dir / "metrics.json").write_text(json.dumps(result, indent=2), encoding="utf-8") + + log.info("=" * 60) + log.info( + "test rmse=%.4f mae=%.4f r2=%.4f pearson=%.4f spearman=%.4f bias=%.4f", + metrics["rmse"], metrics["mae"], metrics["r2"], + metrics["pearson_r"], metrics["spearman_rho"], metrics["bias"], + ) + log.info( + "training=%.0f s inference=%.0f seq/s peak_rss=%.0f MB", + training_seconds, speed["sequences_per_second"], result["memory"].get("peak_rss_mb") or 0, + ) + log.info("wrote %s", output_dir / "metrics.json") + + +if __name__ == "__main__": + main() diff --git a/benchmark/train_external_residue_decoder.py b/benchmark/train_external_residue_decoder.py new file mode 100644 index 0000000..0529ca6 --- /dev/null +++ b/benchmark/train_external_residue_decoder.py @@ -0,0 +1,222 @@ +"""Train one decoder on one frozen, unpooled residue-state representation.""" + +from __future__ import annotations + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +from torch.utils.data import DataLoader + +from benchmark.external_residue_models import ( + FrozenResidueDecoder, + ResidueArrayDataset, + parameter_count, +) +from irrm_codec.losses import inverse_loss +from irrm_codec.tokenization import AA_VOCAB, ID2AA, encode +from irrm_codec.utils import choose_device, save_checkpoint, set_seed, setup_logging + + +GAP_ID = AA_VOCAB["-"] +REPRESENTATIONS = ("esm2_8m", "tcr_bert", "sceptr") + + +def levenshtein_distance(left: str, right: str) -> int: + """Return exact edit distance without an optional third-party dependency.""" + if len(left) > len(right): + left, right = right, left + previous = list(range(len(left) + 1)) + for right_index, right_char in enumerate(right, start=1): + current = [right_index] + for left_index, left_char in enumerate(left, start=1): + current.append( + min( + current[-1] + 1, + previous[left_index] + 1, + previous[left_index - 1] + (left_char != right_char), + ) + ) + previous = current + return previous[-1] + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dataset-dir", required=True) + parser.add_argument("--residue-dir", required=True) + parser.add_argument("--representation", choices=REPRESENTATIONS, required=True) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--epochs", type=int, default=60) + parser.add_argument("--batch-size", type=int, default=64) + parser.add_argument("--lr", type=float, default=3e-4) + parser.add_argument("--weight-decay", type=float, default=1e-4) + parser.add_argument("--patience", type=int, default=8) + parser.add_argument("--max-len", type=int, default=40) + parser.add_argument("--threads", type=int, default=4) + parser.add_argument("--num-workers", type=int, default=0) + return parser.parse_args() + + +def load_rows(dataset_dir, split): + return pd.read_csv(Path(dataset_dir) / "manifests" / f"{split}.tsv", sep="\t")[ + "row_index" + ].to_numpy() + + +def decode_tokens(token_ids): + return "".join(ID2AA[int(token)] for token in token_ids if int(token) > GAP_ID) + + +def make_loader(features_path, mask_path, rows, targets, args, shuffle): + dataset = ResidueArrayDataset(features_path, mask_path, rows, targets[rows]) + return DataLoader( + dataset, + batch_size=args.batch_size, + shuffle=shuffle, + num_workers=args.num_workers, + pin_memory=torch.cuda.is_available(), + ) + + +def train_epoch(model, loader, device, optimizer): + model.train() + total, steps = 0.0, 0 + for features, mask, target in loader: + features, mask, target = features.to(device), mask.to(device), target.long().to(device) + loss = inverse_loss(model(features, mask), target) + optimizer.zero_grad(set_to_none=True) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + total += loss.item() + steps += 1 + return total / max(steps, 1) + + +@torch.no_grad() +def evaluate(model, loader, device, sequences, rows, collect=False): + model.eval() + total, steps, token_hits, token_total = 0.0, 0, 0, 0 + predictions = [] + for features, mask, target in loader: + features, mask, target = features.to(device), mask.to(device), target.long().to(device) + logits = model(features, mask) + total += inverse_loss(logits, target).item() + steps += 1 + predicted = logits.argmax(dim=-1) + residues = target.gt(GAP_ID) + token_hits += predicted.eq(target).logical_and(residues).sum().item() + token_total += residues.sum().item() + predictions.extend(decode_tokens(row) for row in predicted.cpu().numpy()) + truth = [sequences[index] for index in rows] + distances = np.asarray([levenshtein_distance(pred, true) for pred, true in zip(predictions, truth)]) + lengths = np.asarray([max(len(sequence), 1) for sequence in truth]) + metrics = { + "loss": total / max(steps, 1), + "token_accuracy": token_hits / max(token_total, 1), + "exact_match": float(np.mean(distances == 0)), + "normalized_levenshtein": float(np.mean(distances / lengths)), + "within_edit_distance_1": float(np.mean(distances <= 1)), + "mean_edit_distance": float(distances.mean()), + } + return metrics, (predictions if collect else None), (truth if collect else None) + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + set_seed(args.seed) + device = choose_device() + dataset_dir, residue_dir = Path(args.dataset_dir), Path(args.residue_dir) + run_name = f"{args.representation}_residue_seed{args.seed}" + output_dir = Path(args.output_dir) / run_name + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "train.log") + + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + sequences = frame.junction_aa.tolist() + targets = np.asarray([encode(sequence, max_len=args.max_len) for sequence in sequences], dtype=np.int64) + rows = {split: load_rows(dataset_dir, split) for split in ("train", "val", "test")} + feature_path = residue_dir / f"{args.representation}_residue.npy" + mask_path = residue_dir / f"{args.representation}_residue_mask.npy" + feature_matrix = np.load(feature_path, mmap_mode="r") + if feature_matrix.shape[0] != len(frame) or feature_matrix.shape[1] != args.max_len: + raise ValueError(f"Frozen feature shape mismatch: {feature_matrix.shape}") + loaders = { + split: make_loader(feature_path, mask_path, rows[split], targets, args, split == "train") + for split in rows + } + model = FrozenResidueDecoder( + input_dim=feature_matrix.shape[-1], max_len=args.max_len + ).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + log.info( + "run=%s device=%s frozen_shape=%s params=%d train=%d val=%d test=%d", + run_name, + device, + feature_matrix.shape, + parameter_count(model), + *(len(rows[split]) for split in ("train", "val", "test")), + ) + + best_val, best_epoch, history = float("inf"), 0, [] + started = time.perf_counter() + for epoch in range(1, args.epochs + 1): + train_loss = train_epoch(model, loaders["train"], device, optimizer) + val_metrics, _, _ = evaluate(model, loaders["val"], device, sequences, rows["val"]) + history.append({"epoch": epoch, "train_loss": train_loss, **{f"val_{k}": v for k, v in val_metrics.items()}}) + log.info( + "epoch=%d train_loss=%.4f val_loss=%.4f val_exact=%.4f val_token=%.4f", + epoch, + train_loss, + val_metrics["loss"], + val_metrics["exact_match"], + val_metrics["token_accuracy"], + ) + if val_metrics["loss"] < best_val - 1e-5: + best_val, best_epoch = val_metrics["loss"], epoch + save_checkpoint(output_dir / "best.pt", model, optimizer, epoch, val_metrics) + elif epoch - best_epoch >= args.patience: + break + training_seconds = time.perf_counter() - started + checkpoint = torch.load(output_dir / "best.pt", map_location=device) + model.load_state_dict(checkpoint["model_state"]) + test, predictions, truth = evaluate( + model, loaders["test"], device, sequences, rows["test"], collect=True + ) + pd.DataFrame( + { + "row_index": rows["test"], + "true_cdr3": truth, + "predicted_cdr3": predictions, + "edit_distance": [levenshtein_distance(pred, true) for pred, true in zip(predictions, truth)], + } + ).to_csv(output_dir / "test_predictions.csv", index=False) + pd.DataFrame(history).to_csv(output_dir / "history.csv", index=False) + result = { + "run_name": run_name, + "representation": args.representation, + "interface": "frozen_residue_states_no_global_pooling", + "seed": args.seed, + "train_size": int(len(rows["train"])), + "best_epoch": best_epoch, + "best_val_loss": best_val, + "epochs_ran": len(history), + "training_seconds": round(training_seconds, 2), + "parameters": parameter_count(model), + "frozen_shape": list(feature_matrix.shape), + "test": test, + "config": vars(args), + } + (output_dir / "metrics.json").write_text(json.dumps(result, indent=2), encoding="utf-8") + log.info("status=complete test=%s", test) + + +if __name__ == "__main__": + main() diff --git a/benchmark/train_external_residue_pgen.py b/benchmark/train_external_residue_pgen.py new file mode 100644 index 0000000..d01dcd3 --- /dev/null +++ b/benchmark/train_external_residue_pgen.py @@ -0,0 +1,182 @@ +"""Train a position-aware pgen probe on frozen, unpooled residue states.""" + +from __future__ import annotations + +import argparse +import json +import time +from pathlib import Path + +import numpy as np +import pandas as pd +import torch +from scipy import stats +from torch.utils.data import DataLoader + +from benchmark.external_residue_models import ( + FrozenResiduePgenHead, + ResidueArrayDataset, + parameter_count, +) +from irrm_codec.losses import pgen_loss +from irrm_codec.utils import choose_device, save_checkpoint, set_seed, setup_logging + + +REPRESENTATIONS = ("esm2_8m", "tcr_bert", "sceptr") + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dataset-dir", required=True) + parser.add_argument("--residue-dir", required=True) + parser.add_argument("--representation", choices=REPRESENTATIONS, required=True) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--target", default="log10_pgen_1mm") + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--epochs", type=int, default=60) + parser.add_argument("--batch-size", type=int, default=128) + parser.add_argument("--lr", type=float, default=3e-4) + parser.add_argument("--weight-decay", type=float, default=1e-4) + parser.add_argument("--patience", type=int, default=12) + parser.add_argument("--threads", type=int, default=4) + parser.add_argument("--num-workers", type=int, default=0) + return parser.parse_args() + + +def load_rows(dataset_dir, split): + return pd.read_csv(Path(dataset_dir) / "manifests" / f"{split}.tsv", sep="\t")[ + "row_index" + ].to_numpy() + + +def regression_metrics(prediction, truth): + residual = prediction - truth + variance = np.var(truth) + return { + "rmse": float(np.sqrt(np.mean(residual**2))), + "mae": float(np.mean(np.abs(residual))), + "bias": float(np.mean(residual)), + "r2": float(1 - np.mean(residual**2) / variance), + "pearson_r": float(stats.pearsonr(prediction, truth)[0]), + "spearman_rho": float(stats.spearmanr(prediction, truth)[0]), + } + + +def run_epoch(model, loader, device, optimizer=None): + training = optimizer is not None + model.train(training) + total, steps = 0.0, 0 + for features, mask, target in loader: + features, mask, target = features.to(device), mask.to(device), target.float().to(device) + with torch.set_grad_enabled(training): + loss = pgen_loss(model(features, mask), target) + if training: + optimizer.zero_grad(set_to_none=True) + loss.backward() + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + total += loss.item() + steps += 1 + return total / max(steps, 1) + + +@torch.no_grad() +def predict(model, loader, device): + model.eval() + output = [] + for features, mask, _ in loader: + output.append(model(features.to(device), mask.to(device)).cpu().numpy()) + return np.concatenate(output) + + +def main(): + args = parse_args() + torch.set_num_threads(args.threads) + set_seed(args.seed) + device = choose_device() + dataset_dir, residue_dir = Path(args.dataset_dir), Path(args.residue_dir) + frame = pd.read_parquet(dataset_dir / "dataset.parquet") + rows = {split: load_rows(dataset_dir, split) for split in ("train", "val", "test")} + raw_target = frame[args.target].to_numpy(dtype=np.float64) + target_mean = float(raw_target[rows["train"]].mean()) + target_std = float(raw_target[rows["train"]].std()) + scaled = ((raw_target - target_mean) / target_std).astype(np.float32) + feature_path = residue_dir / f"{args.representation}_residue.npy" + mask_path = residue_dir / f"{args.representation}_residue_mask.npy" + feature_matrix = np.load(feature_path, mmap_mode="r") + loaders = { + split: DataLoader( + ResidueArrayDataset(feature_path, mask_path, rows[split], scaled[rows[split]]), + batch_size=args.batch_size, + shuffle=(split == "train"), + num_workers=args.num_workers, + pin_memory=torch.cuda.is_available(), + ) + for split in rows + } + model = FrozenResiduePgenHead(input_dim=feature_matrix.shape[-1]).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr, weight_decay=args.weight_decay) + scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=args.epochs) + run_name = f"{args.representation}_residue_{args.target}_seed{args.seed}" + output_dir = Path(args.output_dir) / run_name + output_dir.mkdir(parents=True, exist_ok=True) + log = setup_logging(output_dir / "train.log") + log.info( + "run=%s device=%s frozen_shape=%s params=%d", + run_name, + device, + feature_matrix.shape, + parameter_count(model), + ) + best_val, best_epoch, history = float("inf"), 0, [] + started = time.perf_counter() + for epoch in range(1, args.epochs + 1): + train_loss = run_epoch(model, loaders["train"], device, optimizer) + val_loss = run_epoch(model, loaders["val"], device) + scheduler.step() + history.append({"epoch": epoch, "train_loss": train_loss, "val_loss": val_loss}) + if epoch % 5 == 0 or epoch == 1: + log.info("epoch=%d train_loss=%.5f val_loss=%.5f", epoch, train_loss, val_loss) + if val_loss < best_val - 1e-6: + best_val, best_epoch = val_loss, epoch + save_checkpoint(output_dir / "best.pt", model, optimizer, epoch, {"val_loss": val_loss}) + elif epoch - best_epoch >= args.patience: + break + training_seconds = time.perf_counter() - started + model.load_state_dict(torch.load(output_dir / "best.pt", map_location=device)["model_state"]) + scaled_prediction = predict(model, loaders["test"], device) + prediction = scaled_prediction * target_std + target_mean + truth = raw_target[rows["test"]] + metrics = regression_metrics(prediction, truth) + pd.DataFrame(history).to_csv(output_dir / "history.csv", index=False) + pd.DataFrame( + { + "row_index": rows["test"], + "cdr3": frame.junction_aa.iloc[rows["test"]].to_numpy(), + "true": truth, + "predicted": prediction, + } + ).to_csv(output_dir / "test_predictions.csv", index=False) + result = { + "run_name": run_name, + "representation": args.representation, + "interface": "frozen_residue_states_no_global_pooling", + "target": args.target, + "seed": args.seed, + "train_size": int(len(rows["train"])), + "best_epoch": best_epoch, + "best_val_loss": best_val, + "epochs_ran": len(history), + "training_seconds": round(training_seconds, 2), + "parameters": parameter_count(model), + "frozen_shape": list(feature_matrix.shape), + "target_scaling": {"fit_split": "train", "mean": target_mean, "std": target_std}, + "test": metrics, + "config": vars(args), + } + (output_dir / "metrics.json").write_text(json.dumps(result, indent=2), encoding="utf-8") + log.info("status=complete test=%s", metrics) + + +if __name__ == "__main__": + main() diff --git a/benchmark/validate_single_aa_targets.py b/benchmark/validate_single_aa_targets.py new file mode 100644 index 0000000..68c1998 --- /dev/null +++ b/benchmark/validate_single_aa_targets.py @@ -0,0 +1,99 @@ +"""Identity-align independently scored mutation-challenge targets.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path + +import numpy as np +import pandas as pd + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + while chunk := handle.read(1024 * 1024): + digest.update(chunk) + return digest.hexdigest() + + +def align_targets(prepared: Path, pgen_path: Path, representations_path: Path, + tcremp_path: Path, output_dir: Path) -> dict: + mutants = pd.read_csv(prepared / "mutants.tsv", sep="\t", dtype={"clone_id": str}) + pgen = pd.read_csv(pgen_path, sep="\t", dtype={"clone_id": str}) + representations = pd.read_csv(representations_path, sep="\t", dtype={"clone_id": str}) + tcremp = pd.read_parquet(tcremp_path) + for name, frame in (("mutants", mutants), ("pgen", pgen), + ("representations", representations), ("tcremp", tcremp)): + if "clone_id" not in frame or frame["clone_id"].isna().any() or frame["clone_id"].duplicated().any(): + raise ValueError(f"{name} lacks complete unique clone_id values.") + expected = mutants["clone_id"].astype(str).tolist() + expected_set = set(expected) + for name, frame in (("pgen", pgen), ("representations", representations), ("tcremp", tcremp)): + observed = set(frame["clone_id"].astype(str)) + if observed != expected_set: + raise ValueError(f"{name} clone IDs differ: missing={len(expected_set-observed)} extra={len(observed-expected_set)}") + pgen = pgen.set_index("clone_id").loc[expected] + representations = representations.set_index("clone_id").loc[expected] + tcremp = tcremp.set_index("clone_id").loc[expected] + sidecar_sequence_column = next( + (column for column in ("cdr3aa_TRB", "junction_aa") if column in representations), None + ) + if sidecar_sequence_column is None: + raise ValueError(f"TCRemP sidecar lacks a recognized TRB sequence column: {list(representations.columns)}") + if not np.array_equal(representations[sidecar_sequence_column].astype(str).to_numpy(), mutants["junction_aa"].astype(str).to_numpy()): + raise ValueError("TCRemP sidecar sequences do not align to generated mutants by clone_id.") + if not np.array_equal(pgen["junction_aa"].astype(str).to_numpy(), mutants["junction_aa"].astype(str).to_numpy()): + raise ValueError("Pgen sequences do not align to generated mutants by clone_id.") + exact_values = pd.to_numeric(pgen["log10_pgen"], errors="coerce").to_numpy(np.float64) + target_values = pd.to_numeric(pgen["log10_pgen_1mm"], errors="coerce").to_numpy(np.float64) + if not np.isfinite(target_values).all(): + raise ValueError( + f"Nonfinite declared log10_pgen_1mm targets: {int((~np.isfinite(target_values)).sum())}" + ) + matrix = tcremp.to_numpy(np.float32) + if matrix.ndim != 2 or matrix.shape[1] != 9000 or not np.isfinite(matrix).all(): + raise ValueError(f"Invalid TCRemP matrix {matrix.shape}.") + output_dir.mkdir(parents=True, exist_ok=False) + matrix_path = output_dir / "mutant_tcremp.npy" + target_path = output_dir / "targets.tsv" + np.save(matrix_path, matrix, allow_pickle=False) + result = mutants.copy() + # Exact pgen can legitimately be zero for a valid mutant. It is not an + # evaluation target; retain its nonfinite count as a diagnostic but keep + # only the finite 1-mismatch target in the accepted table. + result["log10_pgen_1mm"] = target_values + result.to_csv(target_path, sep="\t", index=False, lineterminator="\n") + report = { + "status": "accepted_for_frozen_delta_evaluation", + "alignment": "unique clone_id plus exact junction_aa agreement", + "tcremp_sidecar_sequence_column": sidecar_sequence_column, + "rows": len(result), + "tcremp_shape": list(matrix.shape), + "pgen_target": "log10_pgen_1mm", + "finite_pgen_target": True, + "nonfinite_exact_log10_pgen_diagnostic_rows": int((~np.isfinite(exact_values)).sum()), + "finite_tcremp": True, + "sources": {str(path): sha256(path) for path in (pgen_path, representations_path, tcremp_path)}, + "artifacts": {matrix_path.name: sha256(matrix_path), target_path.name: sha256(target_path)}, + } + (output_dir / "TARGETS.json").write_text(json.dumps(report, indent=2, sort_keys=True) + "\n") + return report + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--prepared", type=Path, required=True) + parser.add_argument("--pgen", type=Path, required=True) + parser.add_argument("--representations", type=Path, required=True) + parser.add_argument("--tcremp", type=Path, required=True) + parser.add_argument("--output-dir", type=Path, required=True) + args = parser.parse_args() + print(json.dumps(align_targets(args.prepared, args.pgen, args.representations, + args.tcremp, args.output_dir), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/benchmark/viral_antigen_species_2025_07_30.txt b/benchmark/viral_antigen_species_2025_07_30.txt new file mode 100644 index 0000000..cf35dc8 --- /dev/null +++ b/benchmark/viral_antigen_species_2025_07_30.txt @@ -0,0 +1,7 @@ +# Exact antigen.species values in the pinned VDJdb 2025-07-30 snapshot that +# denote viral antigens after the preregistered A*02:01/B2M/MHCI/TRB filters. +# Matching is exact and case-sensitive; HomoSapiens is intentionally excluded. +InfluenzaA +EBV +SARS-CoV-2 +HIV-1 diff --git a/experiments/trb/anchored-tokenizer-study/stage_manifest.json b/experiments/trb/anchored-tokenizer-study/stage_manifest.json new file mode 100644 index 0000000..9aedc0b --- /dev/null +++ b/experiments/trb/anchored-tokenizer-study/stage_manifest.json @@ -0,0 +1,73 @@ +{ + "study": "leakage-safe sequence-only TRB terminal-anchor tokenizers", + "status": "germline_submitted", + "base_git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "uncommitted_remote_code_is_hash_locked": true, + "cpu_preflight_job_id": "1426217", + "cpu_preflight_sha256": "08d1d582842c2bdab0bafcd5d429f3b3042d02cb715b50e2638b5da652435a38", + "benchmark": { + "path": "/home/evlasova/irrm-codec/data/benchmark/trb", + "ready_sha256": "ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167", + "target_standardizer_sha256": "ed0052ad510b7e0299628796162037cbb1a3c7e5e8d661ca4a668eb49a830b24", + "rows": 99430, + "train_rows": 79544, + "val_rows": 9943, + "test_rows": 9943 + }, + "matched_training": { + "inference_modality": "sequence_only", + "decoder_vocab_size": 25, + "objectives": ["reconstruction", "tcremp", "log10_pgen_1mm"], + "loss_weights": {"reconstruction": 1.0, "tcremp": 1.0, "pgen": 1.0}, + "seed": 42, + "d_model": 320, + "latent_dim": 128, + "encoder_layers": 4, + "decoder_layers": 4, + "nhead": 8, + "ff_dim": 1280, + "batch_size": 64, + "epochs": 40, + "optimizer": "AdamW", + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "normalizer_fit": "locked train only", + "selection": "validation joint objective only" + }, + "gpu_batch_script_sha256": "dcf3ef80f59e42ccde5b48cb97925603ec6062000b2b2cde12b378268effd452", + "runs": { + "edge_k": { + "condition": "EDGE-3", + "bundle_sha256": "8333622c01ad10bd3d176f71131705ad68feb0a1eed5039ed6ee352081888a24", + "input_vocab_size": 16256, + "parameter_count": 26344873, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/anchor-edge3-rtp-seed42", + "job_id": "1426221", + "terminal": true, + "best_epoch": 31, + "best_validation_joint_loss": 0.2154474285803342, + "test_loss_descriptive": 0.2144757355439235 + }, + "data_anchor": { + "condition": "DATA-ANCHOR", + "bundle_sha256": "8ef9aeddf8c069d4db898369f01f97e80160ba2ceb3c2354f18547467beeed4d", + "input_vocab_size": 1228, + "parameter_count": 21535913, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/anchor-data-rtp-seed42", + "job_id": "1426222", + "terminal": true, + "best_epoch": 25, + "best_validation_joint_loss": 0.20576476722275314, + "test_loss_descriptive": 0.20348657863661399 + }, + "germline_anchor": { + "condition": "GERMLINE-ANCHOR", + "bundle_sha256": "6e48150050325d916a2d09b3a7a0db4d74ad7233319dd49e01ba904d93d435b1", + "input_vocab_size": 387, + "parameter_count": 21266793, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/anchor-germline-rtp-seed42", + "job_id": "1426317", + "submission_gate": "satisfied: EDGE-3 and DATA-ANCHOR terminal before submission" + } + } +} diff --git a/experiments/trb/phase1-rq1-char-seed42/experiment_manifest.json b/experiments/trb/phase1-rq1-char-seed42/experiment_manifest.json new file mode 100644 index 0000000..3377a8e --- /dev/null +++ b/experiments/trb/phase1-rq1-char-seed42/experiment_manifest.json @@ -0,0 +1,35 @@ +{ + "phase": "Phase 1 / RQ1", + "tokenizer": "char", + "seed": 42, + "gpu_concurrency_cap": 2, + "submission_rule": "Exactly the two registered baselines; no further GPU jobs until both are terminal and summarized.", + "base_git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "saved_pr_revision": "330dfdfb48bd867a195599043405e4d89999673e", + "benchmark_path": "/home/evlasova/irrm-codec/data/benchmark/trb", + "benchmark_preflight": "/home/evlasova/irrm-codec/experiments/trb/phase1-rq1-char-seed42/preflight.json", + "training_code_sha256": { + "irrm_codec/tokenization.py": "649d157fa9c87f304a314f5009fed304d511562fa0f56df57dc4c0f06aa11936", + "irrm_codec/multitask_data.py": "5c8f1b1f1e21d2044028291d7e49e54090cce475d5e124cc3798ff2876b5f52f", + "irrm_codec/multitask_losses.py": "1d46e24c335fee02ac7344c6278de5b112d9f3bc57915a25df31db444d361649", + "irrm_codec/multitask_metrics.py": "891e52658e9470f8d213f517125670fbedd752efeb636493ca2a41a99e309e64", + "irrm_codec/multitask_transformer.py": "deab3ff9edc851a37683f1c2cd314e262c6b09171d407db7621962f58ed67cfa", + "irrm_codec/train_multitask.py": "0eae9a7d4dd233e52c386a4e086d262b6236d4fb8505550ea77898f5d30ce4de" + }, + "experiments": [ + { + "experiment_id": "rq1-char-r-seed42", + "condition": "R", + "loss_weights": {"reconstruction": 1.0, "tcremp": 0.0, "pgen": 0.0}, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq1-char-r-seed42", + "job_id": "1425896" + }, + { + "experiment_id": "rq1-char-rtp-seed42", + "condition": "R+T+P", + "loss_weights": {"reconstruction": 1.0, "tcremp": 1.0, "pgen": 1.0}, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq1-char-rtp-seed42", + "job_id": "1425897" + } + ] +} diff --git a/experiments/trb/phase2-rq23-char-seed42/experiment_manifest.json b/experiments/trb/phase2-rq23-char-seed42/experiment_manifest.json new file mode 100644 index 0000000..730e96b --- /dev/null +++ b/experiments/trb/phase2-rq23-char-seed42/experiment_manifest.json @@ -0,0 +1,36 @@ +{ + "phase": "Phase 2 / RQ2-RQ3", + "tokenizer": "char", + "seed": 42, + "gpu_concurrency_cap": 2, + "submission_rule": "Exactly the two registered head ablations; do not launch further variants.", + "base_git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "saved_pr_revision": "330dfdfb48bd867a195599043405e4d89999673e", + "benchmark_path": "/home/evlasova/irrm-codec/data/benchmark/trb", + "reused_benchmark_preflight": "/home/evlasova/irrm-codec/experiments/trb/phase1-rq1-char-seed42/preflight.json", + "benchmark_ready_sha256": "ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167", + "training_code_sha256": { + "irrm_codec/tokenization.py": "649d157fa9c87f304a314f5009fed304d511562fa0f56df57dc4c0f06aa11936", + "irrm_codec/multitask_data.py": "5c8f1b1f1e21d2044028291d7e49e54090cce475d5e124cc3798ff2876b5f52f", + "irrm_codec/multitask_losses.py": "1d46e24c335fee02ac7344c6278de5b112d9f3bc57915a25df31db444d361649", + "irrm_codec/multitask_metrics.py": "891e52658e9470f8d213f517125670fbedd752efeb636493ca2a41a99e309e64", + "irrm_codec/multitask_transformer.py": "deab3ff9edc851a37683f1c2cd314e262c6b09171d407db7621962f58ed67cfa", + "irrm_codec/train_multitask.py": "0eae9a7d4dd233e52c386a4e086d262b6236d4fb8505550ea77898f5d30ce4de" + }, + "experiments": [ + { + "experiment_id": "rq2-char-rt-seed42", + "condition": "R+T", + "loss_weights": {"reconstruction": 1.0, "tcremp": 1.0, "pgen": 0.0}, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq2-char-rt-seed42", + "job_id": "1425901" + }, + { + "experiment_id": "rq2-char-rp-seed42", + "condition": "R+P", + "loss_weights": {"reconstruction": 1.0, "tcremp": 0.0, "pgen": 1.0}, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq2-char-rp-seed42", + "job_id": "1425902" + } + ] +} diff --git a/experiments/trb/rq1-char-r-seed42/experiment_config.json b/experiments/trb/rq1-char-r-seed42/experiment_config.json new file mode 100644 index 0000000..9176424 --- /dev/null +++ b/experiments/trb/rq1-char-r-seed42/experiment_config.json @@ -0,0 +1,56 @@ +{ + "experiment_id": "rq1-char-r-seed42", + "research_question": "Phase 1 / RQ1 character-tokenizer matched baseline", + "condition": "reconstruction_only_R", + "base_git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "saved_pr_revision": "330dfdfb48bd867a195599043405e4d89999673e", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq1-char-r-seed42", + "tokenizer": "char", + "seed": 42, + "train_subset": "all", + "pgen_target": "log10_pgen_1mm", + "model": { + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 320, + "nhead": 8, + "encoder_layers": 4, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4 + }, + "loss": { + "tcremp": 0.0, + "pgen": 0.0, + "reconstruction": 1.0, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0.0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1.0, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "constraint": "gpu", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "job_id": "1425896" + } +} diff --git a/experiments/trb/rq1-char-rtp-seed42/experiment_config.json b/experiments/trb/rq1-char-rtp-seed42/experiment_config.json new file mode 100644 index 0000000..9bba372 --- /dev/null +++ b/experiments/trb/rq1-char-rtp-seed42/experiment_config.json @@ -0,0 +1,56 @@ +{ + "experiment_id": "rq1-char-rtp-seed42", + "research_question": "Phase 1 / RQ1 character-tokenizer matched baseline", + "condition": "full_multitask_R_plus_T_plus_P", + "base_git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "saved_pr_revision": "330dfdfb48bd867a195599043405e4d89999673e", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq1-char-rtp-seed42", + "tokenizer": "char", + "seed": 42, + "train_subset": "all", + "pgen_target": "log10_pgen_1mm", + "model": { + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 320, + "nhead": 8, + "encoder_layers": 4, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4 + }, + "loss": { + "tcremp": 1.0, + "pgen": 1.0, + "reconstruction": 1.0, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0.0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1.0, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "constraint": "gpu", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "job_id": "1425897" + } +} diff --git a/experiments/trb/rq2-char-rp-seed42/experiment_config.json b/experiments/trb/rq2-char-rp-seed42/experiment_config.json new file mode 100644 index 0000000..dcc9475 --- /dev/null +++ b/experiments/trb/rq2-char-rp-seed42/experiment_config.json @@ -0,0 +1,56 @@ +{ + "experiment_id": "rq2-char-rp-seed42", + "research_question": "Phase 2 / RQ2-RQ3 character-tokenizer head ablation", + "condition": "reconstruction_plus_pgen_R_plus_P", + "base_git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "saved_pr_revision": "330dfdfb48bd867a195599043405e4d89999673e", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq2-char-rp-seed42", + "tokenizer": "char", + "seed": 42, + "train_subset": "all", + "pgen_target": "log10_pgen_1mm", + "model": { + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 320, + "nhead": 8, + "encoder_layers": 4, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4 + }, + "loss": { + "tcremp": 0.0, + "pgen": 1.0, + "reconstruction": 1.0, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0.0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1.0, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "constraint": "gpu", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "job_id": "1425902" + } +} diff --git a/experiments/trb/rq2-char-rt-seed42/experiment_config.json b/experiments/trb/rq2-char-rt-seed42/experiment_config.json new file mode 100644 index 0000000..8fea052 --- /dev/null +++ b/experiments/trb/rq2-char-rt-seed42/experiment_config.json @@ -0,0 +1,56 @@ +{ + "experiment_id": "rq2-char-rt-seed42", + "research_question": "Phase 2 / RQ2-RQ3 character-tokenizer head ablation", + "condition": "reconstruction_plus_tcremp_R_plus_T", + "base_git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "saved_pr_revision": "330dfdfb48bd867a195599043405e4d89999673e", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq2-char-rt-seed42", + "tokenizer": "char", + "seed": 42, + "train_subset": "all", + "pgen_target": "log10_pgen_1mm", + "model": { + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 320, + "nhead": 8, + "encoder_layers": 4, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4 + }, + "loss": { + "tcremp": 1.0, + "pgen": 0.0, + "reconstruction": 1.0, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0.0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1.0, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "constraint": "gpu", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "job_id": "1425901" + } +} diff --git a/experiments/trb/rq4-wordpiece-r-seed42/experiment_config.json b/experiments/trb/rq4-wordpiece-r-seed42/experiment_config.json new file mode 100644 index 0000000..e006c7a --- /dev/null +++ b/experiments/trb/rq4-wordpiece-r-seed42/experiment_config.json @@ -0,0 +1,33 @@ +{ + "experiment_id": "rq4-wordpiece-r-seed42", + "research_question": "RQ4 WordPiece tokenizer study matched character baseline", + "condition": "wordpiece_reconstruction_only_R", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq4-wordpiece-r-seed42", + "tokenizer": { + "type": "wordpiece", + "path": "/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/tokenizer.json", + "sha256": "064c1b6a60fec3a14913e821954c7eaf1a70b2335b77ef79fe4e2ed4fac62634", + "vocab_size": 256, + "train_manifest_sha256": "6399cbea503191a652e7ecef0b8b859793f4ece16322fd49ce2ed03364484b01" + }, + "seed": 42, + "model": { + "max_sequence_len": 40, "d_model": 320, "latent_dim": 320, "nhead": 8, + "encoder_layers": 4, "decoder_layers": 4, "ff_dim": 1280, "dropout": 0.1, + "tcremp_head_dim": 1024, "pgen_head_dim": 256, "decoder_memory_tokens": 4, + "input_vocab_size": 256, "output_vocab_size": 25, + "share_input_output_embeddings": false, + "expected_parameter_count": 21779177, + "embedding_adjustment": "WordPiece requires a separate 256x320 encoder embedding; the 25x320 character decoder embedding remains unchanged. This adds 81,920 parameters versus the shared character baseline." + }, + "loss": {"reconstruction": 1.0, "tcremp": 0.0, "pgen": 0.0}, + "training": { + "batch_size": 64, "epochs": 40, "learning_rate": 0.0003, + "weight_decay": 0.0001, "gradient_accumulation_steps": 1, + "max_grad_norm": 1.0, "early_stopping_patience": 0, + "scheduler_factor": 0.5, "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, "amp": true + }, + "slurm": {"partition": "medium", "gpus": 1, "cpus": 8, "memory": "48G", "time": "12:00:00", "job_id": "1425944"} +} diff --git a/experiments/trb/rq4-wordpiece-rtp-seed42/experiment_config.json b/experiments/trb/rq4-wordpiece-rtp-seed42/experiment_config.json new file mode 100644 index 0000000..6caa21f --- /dev/null +++ b/experiments/trb/rq4-wordpiece-rtp-seed42/experiment_config.json @@ -0,0 +1,33 @@ +{ + "experiment_id": "rq4-wordpiece-rtp-seed42", + "research_question": "RQ4 WordPiece tokenizer study matched character baseline", + "condition": "wordpiece_full_R_plus_T_plus_P", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq4-wordpiece-rtp-seed42", + "tokenizer": { + "type": "wordpiece", + "path": "/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/tokenizer.json", + "sha256": "064c1b6a60fec3a14913e821954c7eaf1a70b2335b77ef79fe4e2ed4fac62634", + "vocab_size": 256, + "train_manifest_sha256": "6399cbea503191a652e7ecef0b8b859793f4ece16322fd49ce2ed03364484b01" + }, + "seed": 42, + "model": { + "max_sequence_len": 40, "d_model": 320, "latent_dim": 320, "nhead": 8, + "encoder_layers": 4, "decoder_layers": 4, "ff_dim": 1280, "dropout": 0.1, + "tcremp_head_dim": 1024, "pgen_head_dim": 256, "decoder_memory_tokens": 4, + "input_vocab_size": 256, "output_vocab_size": 25, + "share_input_output_embeddings": false, + "expected_parameter_count": 21779177, + "embedding_adjustment": "WordPiece requires a separate 256x320 encoder embedding; the 25x320 character decoder embedding remains unchanged. This adds 81,920 parameters versus the shared character baseline." + }, + "loss": {"reconstruction": 1.0, "tcremp": 1.0, "pgen": 1.0}, + "training": { + "batch_size": 64, "epochs": 40, "learning_rate": 0.0003, + "weight_decay": 0.0001, "gradient_accumulation_steps": 1, + "max_grad_norm": 1.0, "early_stopping_patience": 0, + "scheduler_factor": 0.5, "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, "amp": true + }, + "slurm": {"partition": "medium", "gpus": 1, "cpus": 8, "memory": "48G", "time": "12:00:00", "job_id": "1425945"} +} diff --git a/experiments/trb/rq4-wordpiece-seed42/experiment_manifest.json b/experiments/trb/rq4-wordpiece-seed42/experiment_manifest.json new file mode 100644 index 0000000..9c3745b --- /dev/null +++ b/experiments/trb/rq4-wordpiece-seed42/experiment_manifest.json @@ -0,0 +1,25 @@ +{ + "phase": "RQ4 tokenizer study", + "tokenizer_dir": "/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42", + "tokenizer_sha256": "064c1b6a60fec3a14913e821954c7eaf1a70b2335b77ef79fe4e2ed4fac62634", + "train_manifest_sha256": "6399cbea503191a652e7ecef0b8b859793f4ece16322fd49ce2ed03364484b01", + "preflight_job_id": "1425943", + "preflight_status": "ready", + "gpu_concurrency_cap": 2, + "submission_rule": "Exactly the registered WordPiece R and R+T+P baselines; no other GPU variants.", + "seed": 42, + "epochs": 40, + "architecture_adjustment": { + "reason": "WordPiece input vocabulary differs from the character reconstruction vocabulary.", + "input_vocab_size": 256, + "output_vocab_size": 25, + "shared_embeddings": false, + "character_baseline_parameters": 21697257, + "wordpiece_parameters": 21779177, + "parameter_increase": 81920 + }, + "experiments": [ + {"experiment_id": "rq4-wordpiece-r-seed42", "weights_r_t_p": [1, 0, 0], "job_id": "1425944"}, + {"experiment_id": "rq4-wordpiece-rtp-seed42", "weights_r_t_p": [1, 1, 1], "job_id": "1425945"} + ] +} diff --git a/experiments/trb/rq5-char-rtp-d128-depths-seed42/experiment_manifest.json b/experiments/trb/rq5-char-rtp-d128-depths-seed42/experiment_manifest.json new file mode 100644 index 0000000..d4cbd28 --- /dev/null +++ b/experiments/trb/rq5-char-rtp-d128-depths-seed42/experiment_manifest.json @@ -0,0 +1,52 @@ +{ + "phase": "RQ5 Stage 2 encoder-depth sweep", + "tokenizer": "char", + "supervision": "R+T+P", + "latent_dim": 128, + "decoder_layers": 4, + "seed": 42, + "epochs": 40, + "gpu_concurrency_cap": 2, + "submission_status": "completed", + "submission_rule": "Only encoder depths 2 and 6 after successful CPU preflight and explicit continuation.", + "selection": { + "criterion": "minimum best-checkpoint validation loss only", + "validation_losses": { + "d128": 0.19693734171098476, + "d320": 0.20322377112032147, + "d512": 0.2087959912276347 + }, + "selected_latent_dim": 128, + "test_metrics_used_for_selection": false, + "selected_baseline_job_id": "1425949" + }, + "benchmark_path": "/home/evlasova/irrm-codec/data/benchmark/trb", + "benchmark_ready_sha256": "ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167", + "preflight": { + "job_id": "1425954", + "status": "ready", + "report_path": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-depths-seed42/preflight.json", + "runtime": { + "python": "3.11.15", + "torch": "2.4.1+cu121" + } + }, + "candidates": [ + { + "encoder_layers": 2, + "decoder_layers": 4, + "parameter_count": 18677033, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-e2d4-seed42", + "job_id": "1425955", + "status": "completed" + }, + { + "encoder_layers": 6, + "decoder_layers": 4, + "parameter_count": 23608873, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-e6d4-seed42", + "job_id": "1425956", + "status": "completed" + } + ] +} diff --git a/experiments/trb/rq5-char-rtp-d128-e2d4-seed42/experiment_config.json b/experiments/trb/rq5-char-rtp-d128-e2d4-seed42/experiment_config.json new file mode 100644 index 0000000..878cbfb --- /dev/null +++ b/experiments/trb/rq5-char-rtp-d128-e2d4-seed42/experiment_config.json @@ -0,0 +1,59 @@ +{ + "experiment_id": "rq5-char-rtp-d128-e2d4-seed42", + "research_question": "RQ5 Stage 2 encoder-depth sweep at validation-selected latent_dim=128", + "condition": "char_R_plus_T_plus_P_latent_d128_encoder2_decoder4", + "selection_basis": "latent_dim=128 selected solely by minimum Stage-1 validation loss", + "baseline_job_id": "1425949", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-e2d4-seed42", + "tokenizer": "char", + "seed": 42, + "model": { + "input_vocab_size": 25, + "output_vocab_size": 25, + "share_input_output_embeddings": true, + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 128, + "nhead": 8, + "encoder_layers": 2, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_dim": 9000, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4, + "parameter_count": 18677033 + }, + "loss": { + "reconstruction": 1, + "tcremp": 1, + "pgen": 1, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "status": "completed", + "job_id": "1425955" + } +} diff --git a/experiments/trb/rq5-char-rtp-d128-e6d4-seed42/experiment_config.json b/experiments/trb/rq5-char-rtp-d128-e6d4-seed42/experiment_config.json new file mode 100644 index 0000000..0fd1126 --- /dev/null +++ b/experiments/trb/rq5-char-rtp-d128-e6d4-seed42/experiment_config.json @@ -0,0 +1,59 @@ +{ + "experiment_id": "rq5-char-rtp-d128-e6d4-seed42", + "research_question": "RQ5 Stage 2 encoder-depth sweep at validation-selected latent_dim=128", + "condition": "char_R_plus_T_plus_P_latent_d128_encoder6_decoder4", + "selection_basis": "latent_dim=128 selected solely by minimum Stage-1 validation loss", + "baseline_job_id": "1425949", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-e6d4-seed42", + "tokenizer": "char", + "seed": 42, + "model": { + "input_vocab_size": 25, + "output_vocab_size": 25, + "share_input_output_embeddings": true, + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 128, + "nhead": 8, + "encoder_layers": 6, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_dim": 9000, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4, + "parameter_count": 23608873 + }, + "loss": { + "reconstruction": 1, + "tcremp": 1, + "pgen": 1, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "status": "completed", + "job_id": "1425956" + } +} diff --git a/experiments/trb/rq5-char-rtp-d128-seed42/experiment_config.json b/experiments/trb/rq5-char-rtp-d128-seed42/experiment_config.json new file mode 100644 index 0000000..54bb4c4 --- /dev/null +++ b/experiments/trb/rq5-char-rtp-d128-seed42/experiment_config.json @@ -0,0 +1,57 @@ +{ + "experiment_id": "rq5-char-rtp-d128-seed42", + "research_question": "RQ5 Stage 1 character full-multitask latent bottleneck width sweep", + "condition": "char_R_plus_T_plus_P_latent_d128", + "baseline_job_id": "1425897", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-seed42", + "tokenizer": "char", + "seed": 42, + "model": { + "input_vocab_size": 25, + "output_vocab_size": 25, + "share_input_output_embeddings": true, + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 128, + "nhead": 8, + "encoder_layers": 4, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_dim": 9000, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4, + "parameter_count": 21142953 + }, + "loss": { + "reconstruction": 1, + "tcremp": 1, + "pgen": 1, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "job_id": "1425949" + } +} diff --git a/experiments/trb/rq5-char-rtp-d512-seed42/experiment_config.json b/experiments/trb/rq5-char-rtp-d512-seed42/experiment_config.json new file mode 100644 index 0000000..f34fe2e --- /dev/null +++ b/experiments/trb/rq5-char-rtp-d512-seed42/experiment_config.json @@ -0,0 +1,57 @@ +{ + "experiment_id": "rq5-char-rtp-d512-seed42", + "research_question": "RQ5 Stage 1 character full-multitask latent bottleneck width sweep", + "condition": "char_R_plus_T_plus_P_latent_d512", + "baseline_job_id": "1425897", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d512-seed42", + "tokenizer": "char", + "seed": 42, + "model": { + "input_vocab_size": 25, + "output_vocab_size": 25, + "share_input_output_embeddings": true, + "max_sequence_len": 40, + "d_model": 320, + "latent_dim": 512, + "nhead": 8, + "encoder_layers": 4, + "decoder_layers": 4, + "ff_dim": 1280, + "dropout": 0.1, + "tcremp_dim": 9000, + "tcremp_head_dim": 1024, + "pgen_head_dim": 256, + "decoder_memory_tokens": 4, + "parameter_count": 22251561 + }, + "loss": { + "reconstruction": 1, + "tcremp": 1, + "pgen": 1, + "tcremp_mse_fraction": 0.7, + "pgen_huber_delta": 0.5, + "label_smoothing": 0 + }, + "training": { + "batch_size": 64, + "epochs": 40, + "learning_rate": 0.0003, + "weight_decay": 0.0001, + "gradient_accumulation_steps": 1, + "max_grad_norm": 1, + "early_stopping_patience": 0, + "scheduler_factor": 0.5, + "scheduler_patience": 2, + "scheduler_min_lr": 0.000001, + "amp": true + }, + "slurm": { + "partition": "medium", + "gpus": 1, + "cpus": 8, + "memory": "48G", + "time": "12:00:00", + "job_id": "1425950" + } +} diff --git a/experiments/trb/rq5-char-rtp-widths-seed42/experiment_manifest.json b/experiments/trb/rq5-char-rtp-widths-seed42/experiment_manifest.json new file mode 100644 index 0000000..17d0f79 --- /dev/null +++ b/experiments/trb/rq5-char-rtp-widths-seed42/experiment_manifest.json @@ -0,0 +1,34 @@ +{ + "phase": "RQ5 Stage 1 bottleneck-width sweep", + "tokenizer": "char", + "supervision": "R+T+P", + "seed": 42, + "epochs": 40, + "gpu_concurrency_cap": 2, + "submission_rule": "Exactly d128 and d512; d320 is reused from completed job 1425897.", + "benchmark_path": "/home/evlasova/irrm-codec/data/benchmark/trb", + "benchmark_ready_sha256": "ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167", + "preflight_job_id": "1425948", + "preflight_status": "ready", + "width_definition": "latent_dim only; d_model=320 and nhead=8 fixed", + "baselines": [ + { + "latent_dim": 128, + "parameter_count": 21142953, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-seed42", + "job_id": "1425949" + }, + { + "latent_dim": 320, + "parameter_count": 21697257, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq1-char-rtp-seed42", + "job_id": "1425897" + }, + { + "latent_dim": 512, + "parameter_count": 22251561, + "output_dir": "/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d512-seed42", + "job_id": "1425950" + } + ] +} diff --git a/experiments/trb/wordpiece-sweep-seed42/experiment_manifest.json b/experiments/trb/wordpiece-sweep-seed42/experiment_manifest.json new file mode 100644 index 0000000..60da434 --- /dev/null +++ b/experiments/trb/wordpiece-sweep-seed42/experiment_manifest.json @@ -0,0 +1,159 @@ +{ + "phase": "WordPiece vocabulary-size sweep Stage A", + "git_revision": "3c873ff7b05e876a80cd226c8099fc1f8b282e91", + "implementation_state": "uncommitted focused sweep files preserved in the existing dirty worktree", + "implementation_sha256": { + "scripts/prepare_wordpiece_sweep.py": "3695f7a58aaf735bf56e6de960ce0eb11193cd4a929f77b1ea3e54155b4ecec5", + "scripts/preflight_wordpiece_sweep.py": "379f31dd2bccf1f51b99f148ca15aea86d2618a5be816eeae208bdaebb9a67ec", + "slurm/prepare_wordpiece_sweep.sbatch": "ace4cd922c31de4ab5671774f947e1972ed5c8010757b1017a9623c6727510fd", + "slurm/train_wordpiece_sweep.sbatch": "68171f1923559a94cbe6c8e3782fff2abf65bc519ad281fa5753cdd0e4c3699f" + }, + "tokenizer_type": "wordpiece", + "vocab_sizes": [44, 64, 128, 256, 512, 1024, 2048, 4096], + "tokenizer_root": "/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-sweep-seed42", + "fit_split": "locked train manifest only", + "fit_rows": 79544, + "special_token_ids": {"pad": 0, "bos": 1, "eos": 2, "unk": 3}, + "selected_char_baseline": { + "job_id": "1425949", + "experiment_id": "rq5-char-rtp-d128-seed42", + "selection_basis": "minimum validation objective", + "latent_dim": 128, + "encoder_layers": 4, + "decoder_layers": 4 + }, + "model_invariants": { + "character_decoder_vocab_size": 25, + "separate_encoder_decoder_embeddings": true, + "full_rtp_weights": [1, 1, 1], + "seed": 42, + "epochs": 40, + "batch_size": 64, + "optimizer": "AdamW", + "learning_rate": 0.0003, + "locked_train_only_normalizer": true + }, + "selection_rule": { + "primary": "minimum full validation objective", + "secondary": ["validation pgen RMSE", "validation reconstruction", "validation TCRemP"], + "test_metrics_used_for_selection": false + }, + "gpu_concurrency_cap": 2, + "submission_order": [[44, 64], [128, 256], [512, 1024], [2048, 4096]], + "cpu_gate": { + "job_id": "1426071", + "status": "accepted", + "benchmark_ready_sha256": "ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167", + "train_manifest_sha256": "6399cbea503191a652e7ecef0b8b859793f4ece16322fd49ce2ed03364484b01", + "train_corpus_sha256": "2478f48a82470e66ec78b0ec9fa06841868c6eed4697d387735f275a9c65597c" + }, + "completed_conditions": { + "44": { + "job_id": "1426073", + "best_epoch": 30, + "best_validation_loss": 0.19666322000361444, + "validation_pgen_rmse": 0.3436580250763355, + "validation_reconstruction_loss": 0.004775686473650997, + "validation_tcremp_cosine": 0.9922292748291728, + "walltime_seconds_from_log": 2890.775, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "5942370dbc2bbf36c3ad059077517c1c0cc41028c002ca4615e5e2ceda856f56" + }, + "64": { + "job_id": "1426074", + "best_epoch": 28, + "best_validation_loss": 0.20685211541870166, + "validation_pgen_rmse": 0.3242212150811544, + "validation_reconstruction_loss": 0.007868499768547392, + "validation_tcremp_cosine": 0.9918381557562432, + "walltime_seconds_from_log": 3059.946, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "36aa6aefd1745e0c11a2453829dc585ca09cc77a15680c4d05b70deb0b2dacef" + }, + "128": { + "job_id": "1426122", + "best_epoch": 26, + "best_validation_loss": 0.20901615753579544, + "validation_pgen_rmse": 0.2838516566076911, + "validation_reconstruction_loss": 0.009563876309816215, + "validation_tcremp_cosine": 0.9917293340642124, + "walltime_seconds_from_log": 2814.008, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "545d0485a07e60bbc549a22a9e8940d8a5c392420a9ccd9b1604bf95360826ef" + }, + "256": { + "job_id": "1426123", + "best_epoch": 23, + "best_validation_loss": 0.20649890744307267, + "validation_pgen_rmse": 0.27295139267261015, + "validation_reconstruction_loss": 0.009048107677470638, + "validation_tcremp_cosine": 0.9917872234284248, + "walltime_seconds_from_log": 2953.805, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "096de58b79b41b69693d40e6b4bfd57f31fae9d2aab1c5e9d727b3154b0db251" + }, + "512": { + "job_id": "1426176", + "best_epoch": 25, + "best_validation_loss": 0.2104906694103532, + "validation_pgen_rmse": 0.30843847231625027, + "validation_reconstruction_loss": 0.008969121246607934, + "validation_tcremp_cosine": 0.9916971205322241, + "walltime_seconds_from_log": 2827.815, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "740c521273e8ee34589ff928b262fd8c60aa34bbd88d567bba0daae73223e03a" + }, + "1024": { + "job_id": "1426177", + "best_epoch": 28, + "best_validation_loss": 0.21072169335227994, + "validation_pgen_rmse": 0.3169206069630301, + "validation_reconstruction_loss": 0.006642488566201312, + "validation_tcremp_cosine": 0.9915933634905607, + "walltime_seconds_from_log": 2946.908, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "64d8967b0633b4c645daf025f189fb209cc824297820e52e1def790817b7c338" + }, + "2048": { + "job_id": "1426180", + "best_epoch": 24, + "best_validation_loss": 0.21218146349443082, + "validation_pgen_rmse": 0.3269114392204356, + "validation_reconstruction_loss": 0.011945437021755085, + "validation_tcremp_cosine": 0.9917859220653428, + "walltime_seconds_from_log": 2821.125, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "4351751bc12f601785eb6efcd4e5d1b984919c0a0992a3214d6c219a998a225b" + }, + "4096": { + "job_id": "1426181", + "best_epoch": 25, + "best_validation_loss": 0.21656744164125932, + "validation_pgen_rmse": 0.4111111972200827, + "validation_reconstruction_loss": 0.012061045652630643, + "validation_tcremp_cosine": 0.9918066222555235, + "walltime_seconds_from_log": 2929.382, + "artifacts_verified": true, + "error_scan_clean": true, + "best_checkpoint_sha256": "932cd6e4135862beb4fba3781a5593d7915e3471e40670d4a2c47b2a3276d6d6" + } + }, + "validation_ranking": [44, 256, 64, 128, 512, 1024, 2048, 4096], + "selected_condition": { + "vocab_size": 44, + "selection_basis": "minimum full validation objective", + "best_validation_loss": 0.19666322000361444, + "character_baseline_validation_loss": 0.19693734171098476, + "replication_required_before_confirmatory_claim": true + }, + "active_conditions": {}, + "submission_status": "stage_a_complete", + "replication_status": "not_authorized" +} diff --git a/experiments/trb/wordpiece-sweep-seed42/validation_results.md b/experiments/trb/wordpiece-sweep-seed42/validation_results.md new file mode 100644 index 0000000..4c947c3 --- /dev/null +++ b/experiments/trb/wordpiece-sweep-seed42/validation_results.md @@ -0,0 +1,80 @@ +# Leakage-safe TRB WordPiece vocabulary sweep (Stage A) + +Status: complete. Selection used only the full validation objective. Test metrics were +recorded after checkpoint selection and were not used to rank conditions. + +## Locked controls + +- Train-only tokenizer fit: 79,544 sequences; train manifest SHA-256 + `6399cbea503191a652e7ecef0b8b859793f4ece16322fd49ce2ed03364484b01`. +- Benchmark READY SHA-256: + `ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167`. +- Special IDs: PAD/BOS/EOS/UNK = 0/1/2/3; zero UNK and exact roundtrip on train, + validation, and test for every vocabulary. +- Matched model: full R+T+P, seed 42, latent 128, encoder/decoder 4+4, 40 epochs, + batch 64, AdamW 3e-4, locked train-only normalizer, separate WordPiece encoder and + unchanged 25-token character decoder. + +## Validation-only ranking + +| Rank | WordPiece vocab | Job | Best epoch | Full val objective | Val pgen RMSE | Val recon loss | Val token acc | Val TCRemP cosine | Val TCRemP std MSE | Params | Walltime | +|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:| +| 1 | 44 | 1426073 | 30 | 0.196663 | 0.343658 | 0.004776 | 0.998500 | 0.992229 | 0.258091 | 21,157,033 | 48m11s | +| 2 | 256 | 1426123 | 23 | 0.206499 | 0.272951 | 0.009048 | 0.996913 | 0.991787 | 0.270087 | 21,224,873 | 49m14s | +| 3 | 64 | 1426074 | 28 | 0.206852 | 0.324221 | 0.007868 | 0.997243 | 0.991838 | 0.269134 | 21,163,433 | 51m00s | +| 4 | 128 | 1426122 | 26 | 0.209016 | 0.283852 | 0.009564 | 0.996720 | 0.991729 | 0.272229 | 21,183,913 | 46m54s | +| 5 | 512 | 1426176 | 25 | 0.210491 | 0.308438 | 0.008969 | 0.997031 | 0.991697 | 0.273659 | 21,306,793 | 47m08s | +| 6 | 1024 | 1426177 | 28 | 0.210722 | 0.316921 | 0.006642 | 0.997884 | 0.991593 | 0.276770 | 21,470,633 | 49m07s | +| 7 | 2048 | 1426180 | 24 | 0.212181 | 0.326911 | 0.011945 | 0.996184 | 0.991786 | 0.270806 | 21,798,313 | 47m01s | +| 8 | 4096 | 1426181 | 25 | 0.216567 | 0.411111 | 0.012061 | 0.995960 | 0.991807 | 0.269719 | 22,453,673 | 48m49s | + +The preregistered selection is WordPiece-44. Its validation objective is 0.000274 +(0.139%) lower than the matched character baseline (0.196937), a small single-seed +difference that requires replication before a confirmatory claim. + +## Held-out test metrics (descriptive only) + +| Vocab | Total | Pgen RMSE | Recon loss | Exact match | Length accuracy | Mean edit | TCRemP cosine | TCRemP std MSE | +|---:|---:|---:|---:|---:|---:|---:|---:|---:| +| 44 | 0.195894 | 0.341319 | 0.005795 | 0.978980 | 0.990747 | 0.047068 | 0.992311 | 0.255408 | +| 64 | 0.205969 | 0.325752 | 0.009292 | 0.964397 | 0.985015 | 0.081867 | 0.991931 | 0.265650 | +| 128 | 0.207857 | 0.289369 | 0.010379 | 0.959871 | 0.977371 | 0.087298 | 0.991808 | 0.269085 | +| 256 | 0.203443 | 0.270520 | 0.009503 | 0.963693 | 0.982199 | 0.084783 | 0.991930 | 0.265257 | +| 512 | 0.207351 | 0.315414 | 0.009045 | 0.966610 | 0.981897 | 0.075128 | 0.991832 | 0.268639 | +| 1024 | 0.209171 | 0.315975 | 0.007251 | 0.972543 | 0.983405 | 0.059841 | 0.991686 | 0.273637 | +| 2048 | 0.210649 | 0.329018 | 0.012147 | 0.955245 | 0.974052 | 0.096047 | 0.991866 | 0.268131 | +| 4096 | 0.216030 | 0.419660 | 0.013340 | 0.951725 | 0.970331 | 0.107010 | 0.991912 | 0.266441 | + +## Token interpretation + +The winning 44-token tokenizer is effectively the smallest valid standard WordPiece +system: `C` is the start token in all 79,544 training sequences, and most continuation +pieces are single amino acids. `##F` is strongly end-enriched (mean normalized position +0.934; end log2 enrichment 3.378). Frequent pieces include `##S` (166,534 occurrences, +94.0% of sequences) and `##A` (118,254, 97.7%). + +Train-only descriptive presence associations show lower `log10_pgen_1mm` for sequences +containing `##V` (mean difference -1.211; high-vs-low-quartile log2 enrichment -1.483), +`##W` (-1.267; -1.852), and internal `##C` (-1.342; -1.909). These are descriptive, +unadjusted associations, not biological or causal claims. + +At vocabulary 64, multi-residue boundary pieces emerge (`CA`, `CAS`, `##YEQYF`, +`##TQYF`, `##EQFF`). At 256, the same boundary families remain common. At 4096, +the vocabulary fragments into much rarer context-specific pieces: `##YEQYF` occurs in +2.49% of train sequences and is positively associated with higher pgen +(mean difference +0.665; quartile log2 enrichment +1.005), while rare single-residue +fallbacks such as `##F` show strong negative associations. This pattern is consistent +with reduced statistical sharing at very large vocabularies and accompanies worse joint +validation objectives, but it does not establish a biological mechanism. + +## Artifacts + +- Tokenizers and audits: + `/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-sweep-seed42` +- Model runs: + `/home/evlasova/irrm-codec/experiments/trb/wp-sweep-v-rtp-seed42` +- Each run contains `best.pt`, `last.pt`, `history.json`, `run_config.json`, + `test_metrics.json`, `target_standardizer.npz`, and logs. All terminal artifact and + failure scans passed. + +No replication or additional architecture jobs were launched. diff --git a/irrm_codec/multitask_losses.py b/irrm_codec/multitask_losses.py index e454026..b110f26 100644 --- a/irrm_codec/multitask_losses.py +++ b/irrm_codec/multitask_losses.py @@ -17,28 +17,53 @@ class MultiTaskLossWeights: class IRRMCodecMultiTaskLoss(nn.Module): - """Combine normalized losses without mixing incompatible target scales. - - The TCRemP and pgen heads predict standardized train-target values. TCRemP - cosine loss is nevertheless computed after de-standardization, so the model - is optimized and evaluated in the original embedding geometry as well. - """ + """Combine normalized losses without mixing incompatible target scales.""" def __init__( self, weights: MultiTaskLossWeights | None = None, tcremp_mse_fraction: float = 0.7, + tcremp_centered_cosine_weight: float = 0.0, + tcremp_pairwise_log_distance_weight: float = 0.0, pgen_huber_delta: float = 0.5, label_smoothing: float = 0.0, ): super().__init__() if not 0.0 <= tcremp_mse_fraction <= 1.0: raise ValueError("tcremp_mse_fraction must lie in [0, 1].") + for name, value in ( + ("tcremp_centered_cosine_weight", tcremp_centered_cosine_weight), + ("tcremp_pairwise_log_distance_weight", tcremp_pairwise_log_distance_weight), + ): + if not 0.0 <= value <= 1.0: + raise ValueError(f"{name} must lie in [0, 1].") + if tcremp_centered_cosine_weight + tcremp_pairwise_log_distance_weight > 1.0: + raise ValueError("TCRemP geometry weights must sum to at most 1.") self.weights = weights or MultiTaskLossWeights() self.tcremp_mse_fraction = tcremp_mse_fraction + self.tcremp_centered_cosine_weight = tcremp_centered_cosine_weight + self.tcremp_pairwise_log_distance_weight = tcremp_pairwise_log_distance_weight self.pgen_huber_delta = pgen_huber_delta self.label_smoothing = label_smoothing + @staticmethod + def _pairwise_log_cosine_distance( + prediction: torch.Tensor, + target: torch.Tensor, + ) -> torch.Tensor: + """Match off-diagonal raw-space cosine distances on a log scale.""" + if prediction.size(0) < 2: + return prediction.new_zeros(()) + pred_unit = F.normalize(prediction.float(), dim=-1) + target_unit = F.normalize(target.float(), dim=-1) + pred_distance = (1.0 - pred_unit @ pred_unit.T).clamp_min(1e-7) + target_distance = (1.0 - target_unit @ target_unit.T).clamp_min(1e-7) + mask = ~torch.eye(prediction.size(0), dtype=torch.bool, device=prediction.device) + return F.smooth_l1_loss( + pred_distance[mask].log(), + target_distance[mask].log(), + ) + def forward( self, outputs: dict[str, torch.Tensor | None], @@ -66,10 +91,34 @@ def forward( tcremp_target, dim=-1, ).mean() - tcremp_loss = ( + tcremp_legacy = ( self.tcremp_mse_fraction * tcremp_mse + (1.0 - self.tcremp_mse_fraction) * tcremp_cosine ) + if self.tcremp_centered_cosine_weight > 0: + tcremp_centered_cosine = 1.0 - F.cosine_similarity( + pred_tcremp_std.float(), + target_tcremp_std.float(), + dim=-1, + ).mean() + else: + tcremp_centered_cosine = pred_tcremp_std.new_zeros(()) + if self.tcremp_pairwise_log_distance_weight > 0: + tcremp_pairwise = self._pairwise_log_cosine_distance( + pred_tcremp_raw, + tcremp_target, + ) + else: + tcremp_pairwise = pred_tcremp_std.new_zeros(()) + geometry_weight = ( + self.tcremp_centered_cosine_weight + + self.tcremp_pairwise_log_distance_weight + ) + tcremp_loss = ( + (1.0 - geometry_weight) * tcremp_legacy + + self.tcremp_centered_cosine_weight * tcremp_centered_cosine + + self.tcremp_pairwise_log_distance_weight * tcremp_pairwise + ) safe_pgen_std = pgen_std.clamp_min(1e-8) target_pgen_std = (pgen_target - pgen_mean) / safe_pgen_std @@ -78,14 +127,12 @@ def forward( target_pgen_std, delta=self.pgen_huber_delta, ) - reconstruction_loss = F.cross_entropy( reconstruction_logits.reshape(-1, reconstruction_logits.size(-1)), reconstruction_target.reshape(-1), ignore_index=PAD_ID, label_smoothing=self.label_smoothing, ) - total = ( self.weights.tcremp * tcremp_loss + self.weights.pgen * pgen_loss @@ -96,6 +143,8 @@ def forward( "tcremp_loss": tcremp_loss, "tcremp_mse_standardized": tcremp_mse, "tcremp_cosine_loss_raw": tcremp_cosine, + "tcremp_centered_cosine_loss": tcremp_centered_cosine, + "tcremp_pairwise_log_distance_loss": tcremp_pairwise, "pgen_loss": pgen_loss, "reconstruction_loss": reconstruction_loss, } diff --git a/irrm_codec/train_multitask.py b/irrm_codec/train_multitask.py index d2298ea..09ddc8b 100644 --- a/irrm_codec/train_multitask.py +++ b/irrm_codec/train_multitask.py @@ -60,6 +60,8 @@ def parse_args() -> argparse.Namespace: parser.add_argument("--pgen-loss-weight", type=float, default=1.0) parser.add_argument("--reconstruction-loss-weight", type=float, default=1.0) parser.add_argument("--tcremp-mse-fraction", type=float, default=0.7) + parser.add_argument("--tcremp-centered-cosine-weight", type=float, default=0.0) + parser.add_argument("--tcremp-pairwise-log-distance-weight", type=float, default=0.0) parser.add_argument("--pgen-huber-delta", type=float, default=0.5) parser.add_argument("--label-smoothing", type=float, default=0.0) @@ -141,6 +143,16 @@ def validate_args(args: argparse.Namespace) -> None: == 0 ): raise ValueError("At least one task loss weight must be positive.") + geometry_weight = ( + args.tcremp_centered_cosine_weight + + args.tcremp_pairwise_log_distance_weight + ) + if ( + args.tcremp_centered_cosine_weight < 0 + or args.tcremp_pairwise_log_distance_weight < 0 + or geometry_weight > 1 + ): + raise ValueError("TCRemP geometry weights must be non-negative and sum to at most 1.") def choose_device(requested: str) -> torch.device: @@ -462,6 +474,8 @@ def main() -> None: reconstruction=args.reconstruction_loss_weight, ), tcremp_mse_fraction=args.tcremp_mse_fraction, + tcremp_centered_cosine_weight=args.tcremp_centered_cosine_weight, + tcremp_pairwise_log_distance_weight=args.tcremp_pairwise_log_distance_weight, pgen_huber_delta=args.pgen_huber_delta, label_smoothing=args.label_smoothing, ) diff --git a/scripts/preflight_data_anchor_objectives.py b/scripts/preflight_data_anchor_objectives.py index 37e285e..4266c31 100644 --- a/scripts/preflight_data_anchor_objectives.py +++ b/scripts/preflight_data_anchor_objectives.py @@ -26,8 +26,11 @@ CONDITIONS = { "r": {"reconstruction": 1.0, "tcremp": 0.0, "pgen": 0.0}, + "t": {"reconstruction": 0.0, "tcremp": 1.0, "pgen": 0.0}, "p": {"reconstruction": 0.0, "tcremp": 0.0, "pgen": 1.0}, + "rt": {"reconstruction": 1.0, "tcremp": 1.0, "pgen": 0.0}, "rp": {"reconstruction": 1.0, "tcremp": 0.0, "pgen": 1.0}, + "tp": {"reconstruction": 0.0, "tcremp": 1.0, "pgen": 1.0}, } @@ -185,7 +188,8 @@ def main() -> None: report = { "status": "ready", "slurm_job_id": os.environ.get("SLURM_JOB_ID"), - "required_conditions": ["r", "p", "rp"], + "required_conditions": ["r", "t", "p", "rt", "rp", "tp"], + "newly_required_conditions": ["t", "rt", "tp"], "fixed_reference": { "condition": "rtp", "job_id": "1426222", @@ -211,7 +215,10 @@ def main() -> None: }, "splits": {split: len(value) for split, value in indices.items()}, "conditions": reports, - "note": "P-only retains the identical decoder and TCRemP head; their inactive metrics are non-interpretable.", + "note": ( + "Every condition retains the identical decoder and all auxiliary heads. Metrics from " + "heads with zero loss weight are non-interpretable." + ), } stable_json(args.output_root / "PREFLIGHT.json", report) print(json.dumps(report, indent=2, sort_keys=True)) diff --git a/scripts/run_vdjdb_tcremp_umap.sbatch b/scripts/run_vdjdb_tcremp_umap.sbatch new file mode 100644 index 0000000..0c64396 --- /dev/null +++ b/scripts/run_vdjdb_tcremp_umap.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-tcremp-umap +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=08:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/tcremp-umap-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/tcremp-umap-%j.err + +set -euo pipefail +repo=/home/evlasova/irrm-codec +runtime=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-runtime-v1 +out=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/tcremp-umap-${SLURM_JOB_ID} +cd "$repo" +"$runtime/bin/python" benchmark/create_vdjdb_tcremp_umap.py \ + --cohort /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv \ + --tcremp /home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/tcremp.npy \ + --output-dir "$out" diff --git a/scripts/run_vdjdb_umap_candidates.sbatch b/scripts/run_vdjdb_umap_candidates.sbatch new file mode 100644 index 0000000..c400b96 --- /dev/null +++ b/scripts/run_vdjdb_umap_candidates.sbatch @@ -0,0 +1,18 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-umap +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-%j.err + +set -euo pipefail +repo=/home/evlasova/irrm-codec +out=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-${SLURM_JOB_ID} +cd "$repo" +/home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/create_vdjdb_umap_candidates.py \ + --cohort /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv \ + --native-evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728 \ + --output-dir "$out" diff --git a/scripts/run_vdjdb_umap_candidates_runtime.sbatch b/scripts/run_vdjdb_umap_candidates_runtime.sbatch new file mode 100644 index 0000000..6941960 --- /dev/null +++ b/scripts/run_vdjdb_umap_candidates_runtime.sbatch @@ -0,0 +1,25 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-umap +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-%j.err + +set -euo pipefail +repo=/home/evlasova/irrm-codec +runtime=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-runtime-v1 +out=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-${SLURM_JOB_ID} +base_python=/home/evlasova/.conda/envs/irrm-codec/bin/python +cd "$repo" +if [[ ! -x "$runtime/bin/python" ]]; then + "$base_python" -m venv --system-site-packages "$runtime" + "$runtime/bin/python" -m pip install --upgrade pip + "$runtime/bin/python" -m pip install umap-learn +fi +"$runtime/bin/python" benchmark/create_vdjdb_umap_candidates.py \ + --cohort /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv \ + --native-evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728 \ + --output-dir "$out" diff --git a/scripts/run_vdjdb_uniform100.sbatch b/scripts/run_vdjdb_uniform100.sbatch new file mode 100644 index 0000000..5ff14ba --- /dev/null +++ b/scripts/run_vdjdb_uniform100.sbatch @@ -0,0 +1,22 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-uniform100 +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.err + +set -euo pipefail + +repo=/home/evlasova/irrm-codec +out=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/evaluation-${SLURM_JOB_ID} +mkdir -p /home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1 + +cd "$repo" +python benchmark/evaluate_vdjdb_uniform100.py \ + --cohort /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv \ + --native-evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728 \ + --external-representations /home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/vdjdb/representations \ + --output-dir "$out" diff --git a/scripts/run_vdjdb_uniform100_direct.sbatch b/scripts/run_vdjdb_uniform100_direct.sbatch new file mode 100644 index 0000000..9159b5f --- /dev/null +++ b/scripts/run_vdjdb_uniform100_direct.sbatch @@ -0,0 +1,21 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-uniform100 +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.err + +set -euo pipefail + +repo=/home/evlasova/irrm-codec +out=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/evaluation-${SLURM_JOB_ID} + +cd "$repo" +/home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_vdjdb_uniform100.py \ + --cohort /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv \ + --native-evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728 \ + --external-representations /home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/vdjdb/representations \ + --output-dir "$out" diff --git a/scripts/run_vdjdb_uniform100_separation.sbatch b/scripts/run_vdjdb_uniform100_separation.sbatch new file mode 100644 index 0000000..32f3198 --- /dev/null +++ b/scripts/run_vdjdb_uniform100_separation.sbatch @@ -0,0 +1,20 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-u100-sep +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/separation-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/separation-%j.err + +set -euo pipefail +repo=/home/evlasova/irrm-codec +out=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/separation-${SLURM_JOB_ID} +cd "$repo" +/home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_vdjdb_uniform100_separation.py \ + --cohort /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv \ + --native-evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728 \ + --external-representations /home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/vdjdb/representations \ + --uniform-evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813 \ + --output-dir "$out" diff --git a/scripts/run_vdjdb_whole_umap.sbatch b/scripts/run_vdjdb_whole_umap.sbatch new file mode 100644 index 0000000..18902a0 --- /dev/null +++ b/scripts/run_vdjdb_whole_umap.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-whole-umap +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=08:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/whole-umap-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/whole-umap-%j.err + +set -euo pipefail +repo=/home/evlasova/irrm-codec +runtime=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/umap-runtime-v1 +out=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/whole-umap-${SLURM_JOB_ID} +cd "$repo" +"$runtime/bin/python" benchmark/create_vdjdb_whole_umap.py \ + --cohort /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv \ + --native-evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728 \ + --output-dir "$out" diff --git a/slurm/benchmark_vdjdb_irrm_cpu.sbatch b/slurm/benchmark_vdjdb_irrm_cpu.sbatch new file mode 100644 index 0000000..c71fb29 --- /dev/null +++ b/slurm/benchmark_vdjdb_irrm_cpu.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-irrm-cpu +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=32G +#SBATCH --time=2:00:00 + +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-cpu-${SLURM_JOB_ID}" +mkdir -p "$OUT" +cd "$ROOT" +/home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/benchmark_vdjdb_irrm_runtime.py \ + --cohort "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/cohort.airr.tsv" \ + --sequence-column junction_aa \ + --checkpoint "$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt" \ + --tokenizer "$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" \ + --output "$OUT/RESULTS.json" --device cpu --batch-size 256 diff --git a/slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch b/slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch new file mode 100644 index 0000000..644620b --- /dev/null +++ b/slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch @@ -0,0 +1,13 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-irrm-cpu +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=32G +#SBATCH --time=2:00:00 +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-cpu-${SLURM_JOB_ID}" +mkdir -p "$OUT" +cd "$ROOT" +PYTHONPATH="$ROOT" /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/benchmark_vdjdb_irrm_runtime.py --cohort "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/cohort.airr.tsv" --sequence-column junction_aa --checkpoint "$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt" --tokenizer "$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" --output "$OUT/RESULTS.json" --device cpu --batch-size 256 diff --git a/slurm/benchmark_vdjdb_irrm_gpu.sbatch b/slurm/benchmark_vdjdb_irrm_gpu.sbatch new file mode 100644 index 0000000..dd5f669 --- /dev/null +++ b/slurm/benchmark_vdjdb_irrm_gpu.sbatch @@ -0,0 +1,20 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-irrm-gpu +#SBATCH --partition=short +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=2:00:00 + +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-gpu-${SLURM_JOB_ID}" +mkdir -p "$OUT" +cd "$ROOT" +/home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/benchmark_vdjdb_irrm_runtime.py \ + --cohort "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/cohort.airr.tsv" \ + --sequence-column junction_aa \ + --checkpoint "$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt" \ + --tokenizer "$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" \ + --output "$OUT/RESULTS.json" --device cuda --batch-size 512 diff --git a/slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch b/slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch new file mode 100644 index 0000000..deee79e --- /dev/null +++ b/slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch @@ -0,0 +1,14 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-irrm-gpu +#SBATCH --partition=short +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=2:00:00 +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-gpu-${SLURM_JOB_ID}" +mkdir -p "$OUT" +cd "$ROOT" +PYTHONPATH="$ROOT" /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/benchmark_vdjdb_irrm_runtime.py --cohort "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/cohort.airr.tsv" --sequence-column junction_aa --checkpoint "$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt" --tokenizer "$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" --output "$OUT/RESULTS.json" --device cuda --batch-size 512 diff --git a/slurm/benchmark_vdjdb_tcremp_runtime.sbatch b/slurm/benchmark_vdjdb_tcremp_runtime.sbatch new file mode 100644 index 0000000..d22a274 --- /dev/null +++ b/slurm/benchmark_vdjdb_tcremp_runtime.sbatch @@ -0,0 +1,30 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-tcremp-runtime +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=2:00:00 + +set -euo pipefail +THREADS="${1:?Pass the requested TCRemP worker count (1 or 16)}" +case "$THREADS" in 1|16) ;; *) echo "threads must be 1 or 16" >&2; exit 2;; esac +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/tcremp-${THREADS}cpu-${SLURM_JOB_ID}" +TCREMP_ROOT=/home/evlasova/tcremp-git/tcremp +PYTHON=/home/evlasova/.conda/envs/vdjdb-redcea/bin/python +mkdir -p "$OUT/raw_tcremp" +cd "$ROOT" +STARTED="$(date -Iseconds)" +SECONDS=0 +PYTHONPATH="$TCREMP_ROOT:$ROOT" "$PYTHON" -m tcremp.tcremp_run \ + -i "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/cohort.airr.tsv" \ + -o "$OUT/raw_tcremp" -e cohort -c TRB -s HomoSapiens -x clone_id \ + -p "$TCREMP_ROOT/tcremp/resources/tcremp_prototypes_TRB.tsv" \ + -np "$THREADS" -llen 4 -hlen 41 --skip-clustering 2>&1 | tee "$OUT/tcremp.log" +python - "$OUT/RESULTS.json" "$THREADS" "$SECONDS" "$STARTED" <<'PY' +import json, sys +from pathlib import Path +path, threads, seconds, started = map(str, sys.argv[1:]) +Path(path).write_text(json.dumps({"status": "complete", "threads": int(threads), "wall_seconds_including_load_and_write": int(seconds), "started": started}, indent=2) + "\n") +PY diff --git a/slurm/cache_author_global_embeddings.sbatch b/slurm/cache_author_global_embeddings.sbatch new file mode 100644 index 0000000..876a9f7 --- /dev/null +++ b/slurm/cache_author_global_embeddings.sbatch @@ -0,0 +1,42 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-cache +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=08:00:00 +#SBATCH --array=0-1%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/cache-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/cache-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-global-author-v1" +RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" +LOCKED="$REPO/experiments/trb/external-model-benchmark/cohort" +LOCKED_REPS="$LOCKED/representations" +REDCEA="$REPO/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +REDCEA_REPS="$BASE/vdjdb/representations" + +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export HF_HOME="$RUNTIME/huggingface" +export TORCH_HOME="$RUNTIME/torch" +export PYTHONUNBUFFERED=1 +export TOKENIZERS_PARALLELISM=false +export HF_HUB_DISABLE_TELEMETRY=1 +mkdir -p "$BASE/logs" "$REDCEA_REPS" +cd "$REPO" + +nvidia-smi --query-gpu=name,memory.total --format=csv,noheader +if [[ "$SLURM_ARRAY_TASK_ID" == 0 ]]; then + "$PYTHON" benchmark/cache_external_model_embeddings.py --dataset-dir "$LOCKED" --output-dir "$LOCKED_REPS" --encoders esm2_35m --device cuda --batch-size 256 --threads "${SLURM_CPUS_PER_TASK:-8}" + "$PYTHON" benchmark/cache_external_model_embeddings.py --dataset-dir "$LOCKED" --dataset-file "$REDCEA" --output-dir "$REDCEA_REPS" --encoders esm2_35m tcr_bert --device cuda --batch-size 256 --threads "${SLURM_CPUS_PER_TASK:-8}" + sha256sum "$LOCKED_REPS/esm2_35m.npy" "$REDCEA_REPS/esm2_35m.npy" "$REDCEA_REPS/tcr_bert.npy" +else + "$PYTHON" benchmark/cache_external_model_embeddings.py --dataset-dir "$LOCKED" --output-dir "$LOCKED_REPS" --encoders sceptr_cdr3 --device cuda --batch-size 256 --threads "${SLURM_CPUS_PER_TASK:-8}" + "$PYTHON" benchmark/cache_external_model_embeddings.py --dataset-dir "$LOCKED" --dataset-file "$REDCEA" --output-dir "$REDCEA_REPS" --encoders sceptr sceptr_cdr3 --device cuda --batch-size 256 --threads "${SLURM_CPUS_PER_TASK:-8}" + sha256sum "$LOCKED_REPS/sceptr_cdr3.npy" "$REDCEA_REPS/sceptr.npy" "$REDCEA_REPS/sceptr_cdr3.npy" +fi +echo "status=accepted task=$SLURM_ARRAY_TASK_ID" diff --git a/slurm/cache_author_global_sceptr_cdr3.sbatch b/slurm/cache_author_global_sceptr_cdr3.sbatch new file mode 100644 index 0000000..8bcda81 --- /dev/null +++ b/slurm/cache_author_global_sceptr_cdr3.sbatch @@ -0,0 +1,32 @@ +#!/bin/bash +#SBATCH --job-name=irrm-sceptr-cdr3-redcea +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=03:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/sceptr-cdr3-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/sceptr-cdr3-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-global-author-v1" +RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" +LOCKED="$REPO/experiments/trb/external-model-benchmark/cohort" +REDCEA="$REPO/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +OUT="$BASE/vdjdb/representations" + +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export HF_HOME="$RUNTIME/huggingface" +export TORCH_HOME="$RUNTIME/torch" +export PYTHONUNBUFFERED=1 +export TOKENIZERS_PARALLELISM=false +mkdir -p "$BASE/logs" "$OUT" +cd "$REPO" + +nvidia-smi --query-gpu=name,memory.total --format=csv,noheader +"$PYTHON" benchmark/cache_external_model_embeddings.py --dataset-dir "$LOCKED" --dataset-file "$REDCEA" --output-dir "$OUT" --encoders sceptr_cdr3 --device cuda --batch-size 256 --threads "${SLURM_CPUS_PER_TASK:-8}" +sha256sum "$OUT/sceptr_cdr3.npy" +echo "status=accepted" diff --git a/slurm/cache_external_model_embeddings.sbatch b/slurm/cache_external_model_embeddings.sbatch new file mode 100644 index 0000000..cefc4b9 --- /dev/null +++ b/slurm/cache_external_model_embeddings.sbatch @@ -0,0 +1,42 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-cache +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=06:00:00 +#SBATCH --array=0-2%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/cache-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/cache-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" +COHORT="$REPO/experiments/trb/external-model-benchmark/cohort" +ENCODERS=(esm2_8m tcr_bert sceptr) +ENCODER="${ENCODERS[$SLURM_ARRAY_TASK_ID]}" + +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export HF_HOME="$RUNTIME/huggingface" +export TORCH_HOME="$RUNTIME/torch" +export PYTHONUNBUFFERED=1 +export TOKENIZERS_PARALLELISM=false +export HF_HUB_DISABLE_TELEMETRY=1 +mkdir -p "$REPO/experiments/trb/external-model-benchmark/logs" +cd "$REPO" + +nvidia-smi --query-gpu=name,memory.total --format=csv,noheader +echo "encoder=$ENCODER python=$PYTHON" +"$PYTHON" benchmark/cache_external_model_embeddings.py \ + --dataset-dir "$COHORT" \ + --output-dir "$COHORT/representations" \ + --encoders "$ENCODER" \ + --rtp-embeddings "$COHORT/representations/rtp.npy" \ + --device cuda \ + --batch-size 256 \ + --threads "${SLURM_CPUS_PER_TASK:-8}" + +sha256sum "$COHORT/representations/$ENCODER.npy" +echo "status=accepted encoder=$ENCODER" diff --git a/slurm/cache_external_residue_embeddings.sbatch b/slurm/cache_external_residue_embeddings.sbatch new file mode 100644 index 0000000..745d802 --- /dev/null +++ b/slurm/cache_external_residue_embeddings.sbatch @@ -0,0 +1,37 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-cache +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=06:00:00 +#SBATCH --array=0-2%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/cache-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/cache-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-v1" +RUNTIME="$BASE/runtime-v2" +ENCODERS=(esm2_8m tcr_bert sceptr) +ENCODER="${ENCODERS[$SLURM_ARRAY_TASK_ID]}" +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export HF_HOME="$RUNTIME/huggingface" +export TORCH_HOME="$RUNTIME/torch" +export TOKENIZERS_PARALLELISM=false +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/representations" +cd "$REPO" +nvidia-smi --query-gpu=name,memory.total --format=csv,noheader +"$PYTHON" benchmark/cache_external_residue_embeddings.py \ + --dataset-dir "$BASE/cohort" \ + --output-dir "$ROOT/representations" \ + --encoders "$ENCODER" \ + --device cuda \ + --batch-size 128 \ + --threads "${SLURM_CPUS_PER_TASK:-8}" +sha256sum "$ROOT/representations/${ENCODER}_residue.npy" "$ROOT/representations/${ENCODER}_residue_mask.npy" +echo "status=accepted encoder=$ENCODER" diff --git a/slurm/collect_author_global_comparison.sbatch b/slurm/collect_author_global_comparison.sbatch new file mode 100644 index 0000000..a3754bc --- /dev/null +++ b/slurm/collect_author_global_comparison.sbatch @@ -0,0 +1,25 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-final +#SBATCH --partition=medium +#SBATCH --cpus-per-task=4 +#SBATCH --mem=24G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/final-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/final-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +OLD="$REPO/experiments/trb/external-model-benchmark" +BASE="$REPO/experiments/trb/external-global-author-v1" +VDJDB_EVAL="${1:?pass completed VDJdb evaluation path}" +OUT="$BASE/final-$SLURM_JOB_ID" + +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$BASE/logs" +cd "$REPO" + +"$PYTHON" benchmark/collect_author_global_comparison.py --old-reconstruction-summary "$OLD/results/reconstruction/reconstruction_summary.csv" --old-pgen-summary "$OLD/results/pgen/pgen_summary.csv" --new-reconstruction-dir "$BASE/reconstruction" --new-pgen-dir "$BASE/pgen" --control-pgen-dir "$BASE/pgen-onehot-fixed" --reference-vdjdb-metrics "$REPO/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728/metrics.json" --external-vdjdb-summary "$VDJDB_EVAL/external_retrieval_summary.tsv" --output-dir "$OUT" +sha256sum "$OUT/final_author_global_comparison.tsv" "$OUT/final_author_global_comparison.md" "$OUT/MANIFEST.json" > "$OUT/HASHES.sha256" +echo "status=complete output=$OUT" diff --git a/slurm/collect_external_model_benchmark.sbatch b/slurm/collect_external_model_benchmark.sbatch new file mode 100644 index 0000000..eaa6754 --- /dev/null +++ b/slurm/collect_external_model_benchmark.sbatch @@ -0,0 +1,29 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-collect +#SBATCH --partition=medium +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/collect-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/collect-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/results/reconstruction" "$ROOT/results/pgen" +cd "$REPO" + +"$PYTHON" benchmark/collect_external_reconstruction.py \ + --runs-dir "$ROOT/reconstruction" \ + --bottleneck-dir "$ROOT/bottleneck" \ + --bottleneck-dim 64 \ + --output-dir "$ROOT/results/reconstruction" +"$PYTHON" benchmark/collect_external_pgen.py \ + --runs-dir "$ROOT/pgen" \ + --output-dir "$ROOT/results/pgen" +find "$ROOT/results" -type f ! -name HASHES.sha256 ! -name HASHES.sha256.tmp -print0 | sort -z | xargs -0 sha256sum > "$ROOT/results/HASHES.sha256.tmp" +mv "$ROOT/results/HASHES.sha256.tmp" "$ROOT/results/HASHES.sha256" +echo "status=accepted" diff --git a/slurm/collect_external_pca256_pgen.sbatch b/slurm/collect_external_pca256_pgen.sbatch new file mode 100644 index 0000000..be60e06 --- /dev/null +++ b/slurm/collect_external_pca256_pgen.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-pca256-pgen-sum +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=4G +#SBATCH --time=00:20:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pgen-summary-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pgen-summary-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca256-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +mkdir -p "$ROOT/results/pgen" +cd "$REPO" +"$PYTHON" benchmark/collect_external_pgen.py --runs-dir "$ROOT/pgen" --output-dir "$ROOT/results/pgen" +sha256sum "$ROOT/results/pgen"/* > "$ROOT/results/pgen/HASHES.sha256" +echo status=accepted diff --git a/slurm/collect_external_pca256_reconstruction.sbatch b/slurm/collect_external_pca256_reconstruction.sbatch new file mode 100644 index 0000000..55bf223 --- /dev/null +++ b/slurm/collect_external_pca256_reconstruction.sbatch @@ -0,0 +1,21 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-pca256-recon-sum +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=4G +#SBATCH --time=00:20:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-summary-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-summary-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca256-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +mkdir -p "$ROOT/results/reconstruction" +cd "$REPO" +"$PYTHON" benchmark/collect_external_reconstruction.py \ + --runs-dir "$ROOT/reconstruction" --output-dir "$ROOT/results/reconstruction" \ + --bottleneck-dir "$ROOT/bottleneck" --bottleneck-dim 256 +sha256sum "$ROOT/results/reconstruction"/* > "$ROOT/results/reconstruction/HASHES.sha256" +echo status=accepted diff --git a/slurm/collect_external_residue_benchmark.sbatch b/slurm/collect_external_residue_benchmark.sbatch new file mode 100644 index 0000000..ac789f5 --- /dev/null +++ b/slurm/collect_external_residue_benchmark.sbatch @@ -0,0 +1,25 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-collect +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=2 +#SBATCH --mem=8G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/collect-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/collect-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/residue-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/results" +cd "$REPO" +"$PYTHON" benchmark/collect_external_residue_benchmark.py \ + --reconstruction-dir "$ROOT/reconstruction" \ + --pgen-dir "$ROOT/pgen" \ + --output-dir "$ROOT/results" +find "$ROOT/results" -maxdepth 1 -type f ! -name HASHES.sha256 -print0 | sort -z | xargs -0 sha256sum > "$ROOT/results/HASHES.sha256" +cat "$ROOT/results/HASHES.sha256" +echo "status=complete" diff --git a/slurm/collect_external_residue_pca128_all.sbatch b/slurm/collect_external_residue_pca128_all.sbatch new file mode 100644 index 0000000..28416c2 --- /dev/null +++ b/slurm/collect_external_residue_pca128_all.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pca128-sum +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=4G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/summary-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/summary-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca128-v1" +SCEPTR_ROOT="$BASE/residue-pca128-sceptr-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +mkdir -p "$ROOT/results/reconstruction" "$ROOT/results/pgen" +cd "$REPO" +"$PYTHON" benchmark/collect_external_reconstruction.py \ + --runs-dir "$ROOT/reconstruction" --output-dir "$ROOT/results/reconstruction" \ + --bottleneck-dir "$ROOT/bottleneck" --bottleneck-dim 128 +"$PYTHON" benchmark/collect_external_pgen.py \ + --runs-dir "$ROOT/pgen" --output-dir "$ROOT/results/pgen" +"$PYTHON" benchmark/combine_external_pca128_results.py \ + --main-root "$ROOT" --sceptr-root "$SCEPTR_ROOT" +sha256sum "$ROOT/results/reconstruction"/* "$ROOT/results/pgen"/* \ + "$ROOT/results/all_baselines"/* > "$ROOT/results/HASHES.sha256" +echo status=accepted diff --git a/slurm/collect_external_rtp128_reconstruction.sbatch b/slurm/collect_external_rtp128_reconstruction.sbatch new file mode 100644 index 0000000..f5a86c8 --- /dev/null +++ b/slurm/collect_external_rtp128_reconstruction.sbatch @@ -0,0 +1,72 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp128-sum +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=2 +#SBATCH --mem=8G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/summary-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/summary-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/native-rtp128-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +mkdir -p "$ROOT/results/reconstruction" +cd "$REPO" + +"$PYTHON" benchmark/collect_external_reconstruction.py \ + --runs-dir "$ROOT/reconstruction" \ + --output-dir "$ROOT/results/reconstruction" \ + --bottleneck-dir "$ROOT/bottleneck" \ + --bottleneck-dim 128 + +"$PYTHON" - "$ROOT" <<'PY' +import hashlib +import json +import sys +from pathlib import Path + +import pandas as pd + +root = Path(sys.argv[1]) +runs = pd.read_csv(root / "results/reconstruction/reconstruction_runs.csv") +summary = pd.read_csv(root / "results/reconstruction/reconstruction_summary.csv") +assert len(runs) == 3 and set(runs.seed) == {42, 43, 44} +assert runs.representation.eq("rtp").all() and runs.bottleneck_dim.eq(128).all() +assert len(summary) == 1 and summary.loc[0, "representation"] == "rtp" +assert int(summary.loc[0, "seeds"]) == 3 + +def sha256(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + +artifacts = {} +for path in sorted((root / "results/reconstruction").glob("*")): + if path.is_file(): + artifacts[str(path)] = sha256(path) +for path in sorted((root / "reconstruction").glob("*/metrics.json")): + artifacts[str(path)] = sha256(path) +report = { + "status": "accepted", + "interface": "native_rtp_128d", + "seeds": [42, 43, 44], + "pgen_reference": { + "note": "not rerun; previously completed native RTP-128 external MLP", + "rmse_mean": 0.2375036700, + "rmse_std": 0.0007641427, + }, + "reconstruction": summary.iloc[0].to_dict(), + "artifacts": artifacts, +} +(root / "RESULTS.json").write_text(json.dumps(report, indent=2), encoding="utf-8") +print(json.dumps(report, indent=2)) +PY + +sha256sum "$ROOT/RESULTS.json" "$ROOT/results/reconstruction"/* > "$ROOT/RESULT_HASHES.sha256" +if grep -R -E -i 'traceback|out of memory|nan|inf' "$ROOT/logs"/*.err; then + echo "error/nonfinite signature found" >&2 + exit 1 +fi +echo status=accepted diff --git a/slurm/collect_external_sceptr_pca128.sbatch b/slurm/collect_external_sceptr_pca128.sbatch new file mode 100644 index 0000000..302c72b --- /dev/null +++ b/slurm/collect_external_sceptr_pca128.sbatch @@ -0,0 +1,24 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-sceptr-pca128-sum +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=4G +#SBATCH --time=00:20:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/summary-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/summary-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +mkdir -p "$ROOT/results/reconstruction" "$ROOT/results/pgen" +cd "$REPO" +"$PYTHON" benchmark/collect_external_reconstruction.py \ + --runs-dir "$ROOT/reconstruction" --output-dir "$ROOT/results/reconstruction" \ + --bottleneck-dir "$ROOT/bottleneck" --bottleneck-dim 128 +"$PYTHON" benchmark/collect_external_pgen.py \ + --runs-dir "$ROOT/pgen" --output-dir "$ROOT/results/pgen" +sha256sum "$ROOT/results/reconstruction"/* "$ROOT/results/pgen"/* \ + > "$ROOT/results/HASHES.sha256" +echo status=accepted diff --git a/slurm/diagnose_vdjdb_decoded_tcremp_geometry.sbatch b/slurm/diagnose_vdjdb_decoded_tcremp_geometry.sbatch new file mode 100644 index 0000000..037e830 --- /dev/null +++ b/slurm/diagnose_vdjdb_decoded_tcremp_geometry.sbatch @@ -0,0 +1,10 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-tcremp-geom +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=04:00:00 +set -euo pipefail +cd /home/evlasova/irrm-codec +PYTHONPATH=/home/evlasova/irrm-codec /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/diagnose_vdjdb_decoded_tcremp_geometry.py \ No newline at end of file diff --git a/slurm/evaluate_latent_secondary.sbatch b/slurm/evaluate_latent_secondary.sbatch new file mode 100644 index 0000000..940e074 --- /dev/null +++ b/slurm/evaluate_latent_secondary.sbatch @@ -0,0 +1,64 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-latent-secondary +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=32 +#SBATCH --mem=128G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/latent-secondary/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/latent-secondary/slurm-%x-%j.err + +set -euo pipefail +MODE="${1:?mode must be preflight or evaluate}" +PREFLIGHT_ROOT="${2:-}" +ROOT="/home/evlasova/irrm-codec" +BASE="$ROOT/experiments/trb/latent-secondary" +OUTPUT="$BASE/${MODE}-${SLURM_JOB_ID}" +DATA="$ROOT/data/benchmark/trb" +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK}" +export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK}" + +test -x "$PYTHON" +test -f "$DATA/READY.json" +test -f "$TOKENIZER" +test ! -e "$OUTPUT" +mkdir -p "$BASE" +cd "$ROOT" + +COMMON=( + --data-dir "$DATA" + --tokenizer "$TOKENIZER" + --output-dir "$OUTPUT" + --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" + --model "t:$ROOT/experiments/trb/data-anchor-t-seed42/best.pt:$ROOT/experiments/trb/data-anchor-t-seed42/run_config.json" + --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" + --model "rt:$ROOT/experiments/trb/data-anchor-rt-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rt-seed42/run_config.json" + --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" + --model "tp:$ROOT/experiments/trb/data-anchor-tp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-tp-seed42/run_config.json" + --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" + --batch-size 128 + --seed 42 +) + +if [[ "$MODE" == "preflight" ]]; then + "$PYTHON" -m compileall -q benchmark/evaluate_latent_secondary.py tests/test_latent_secondary.py + "$PYTHON" - <<'PY' +import runpy +namespace = runpy.run_path('tests/test_latent_secondary.py') +for name, value in sorted(namespace.items()): + if name.startswith('test_') and callable(value): + value() +print('direct tests passed') +PY + "$PYTHON" -m benchmark.evaluate_latent_secondary "${COMMON[@]}" --preflight-only +elif [[ "$MODE" == "evaluate" ]]; then + test -n "$PREFLIGHT_ROOT" + test -f "$PREFLIGHT_ROOT/PREFLIGHT.json" + "$PYTHON" -m benchmark.evaluate_latent_secondary \ + "${COMMON[@]}" --accepted-preflight "$PREFLIGHT_ROOT/PREFLIGHT.json" +else + echo "unsupported mode: $MODE" >&2 + exit 2 +fi diff --git a/slurm/evaluate_latent_sufficiency.sbatch b/slurm/evaluate_latent_sufficiency.sbatch new file mode 100644 index 0000000..9ae6551 --- /dev/null +++ b/slurm/evaluate_latent_sufficiency.sbatch @@ -0,0 +1,55 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-latent-suff +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=32 +#SBATCH --mem=192G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/latent-sufficiency/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/latent-sufficiency/slurm-%x-%j.err + +set -euo pipefail +ROOT="/home/evlasova/irrm-codec" +BASE="$ROOT/experiments/trb/latent-sufficiency" +OUTPUT="$BASE/evaluation-${SLURM_JOB_ID}" +DATA="$ROOT/data/benchmark/trb" +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK}" +export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK}" + +test -x "$PYTHON" +test -f "$DATA/READY.json" +test -f "$DATA/target_standardizer.npz" +test -f "$TOKENIZER" +test ! -e "$OUTPUT" +mkdir -p "$BASE" +cd "$ROOT" + +"$PYTHON" -m compileall -q benchmark/evaluate_latent_sufficiency.py tests/test_latent_sufficiency.py +"$PYTHON" - <<'PY' +import runpy +scope = runpy.run_path("tests/test_latent_sufficiency.py") +for name in sorted(scope): + if name.startswith("test_"): + scope[name]() +print("direct latent-sufficiency tests passed") +PY + +"$PYTHON" -m benchmark.evaluate_latent_sufficiency \ + --data-dir "$DATA" \ + --normalizer "$DATA/target_standardizer.npz" \ + --tokenizer "$TOKENIZER" \ + --output-dir "$OUTPUT" \ + --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "t:$ROOT/experiments/trb/data-anchor-t-seed42/best.pt:$ROOT/experiments/trb/data-anchor-t-seed42/run_config.json" \ + --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rt:$ROOT/experiments/trb/data-anchor-rt-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rt-seed42/run_config.json" \ + --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "tp:$ROOT/experiments/trb/data-anchor-tp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-tp-seed42/run_config.json" \ + --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" \ + --batch-size 256 --alphas 0.01,1,100 --bootstrap 2000 --seed 42 + +test -s "$OUTPUT/RESULTS.json" +test -s "$OUTPUT/summary.tsv" +test -s "$OUTPUT/OUTPUT_HASHES.json" diff --git a/slurm/evaluate_rtp_data_anchor_length_errors.sbatch b/slurm/evaluate_rtp_data_anchor_length_errors.sbatch new file mode 100644 index 0000000..7417e60 --- /dev/null +++ b/slurm/evaluate_rtp_data_anchor_length_errors.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp-lenerr +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-length-errors-$SLURM_JOB_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER" +test -f "$CHECKPOINT" +cd "$ROOT_DIR" +export PYTHONPATH="$ROOT_DIR${PYTHONPATH:+:$PYTHONPATH}" +"$PYTHON_BIN" benchmark/evaluate_rtp_reconstruction_by_length.py \ + --data-dir "$DATA_DIR" --tokenizer "$TOKENIZER" --checkpoint "$CHECKPOINT" \ + --output-dir "$OUTPUT_DIR" --batch-size 64 --num-workers 8 --device cuda diff --git a/slurm/evaluate_rtp_data_anchor_position_errors.sbatch b/slurm/evaluate_rtp_data_anchor_position_errors.sbatch new file mode 100644 index 0000000..5da2eb7 --- /dev/null +++ b/slurm/evaluate_rtp_data_anchor_position_errors.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp-poserr +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-position-errors-$SLURM_JOB_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER" +test -f "$CHECKPOINT" +cd "$ROOT_DIR" +export PYTHONPATH="$ROOT_DIR${PYTHONPATH:+:$PYTHONPATH}" +"$PYTHON_BIN" benchmark/evaluate_rtp_reconstruction_by_position.py \ + --data-dir "$DATA_DIR" --tokenizer "$TOKENIZER" --checkpoint "$CHECKPOINT" \ + --output-dir "$OUTPUT_DIR" --batch-size 64 --num-workers 8 --device cuda diff --git a/slurm/evaluate_rtp_data_anchor_substitutions.sbatch b/slurm/evaluate_rtp_data_anchor_substitutions.sbatch new file mode 100644 index 0000000..61e6954 --- /dev/null +++ b/slurm/evaluate_rtp_data_anchor_substitutions.sbatch @@ -0,0 +1,33 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp-subst +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-substitutions-$SLURM_JOB_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER" +test -f "$CHECKPOINT" +cd "$ROOT_DIR" +"$PYTHON_BIN" benchmark/evaluate_reconstruction_substitutions.py \ + --data-dir "$DATA_DIR" \ + --tokenizer "$TOKENIZER" \ + --checkpoint "$CHECKPOINT" \ + --output-dir "$OUTPUT_DIR" \ + --batch-size 64 \ + --num-workers 8 \ + --device cuda diff --git a/slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch b/slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch new file mode 100644 index 0000000..e1b4ffd --- /dev/null +++ b/slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch @@ -0,0 +1,34 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp-subst +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err + +set -euo pipefail + +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" +OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-substitutions-$SLURM_JOB_ID" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER" +test -f "$CHECKPOINT" +cd "$ROOT_DIR" +export PYTHONPATH="$ROOT_DIR${PYTHONPATH:+:$PYTHONPATH}" +"$PYTHON_BIN" benchmark/evaluate_reconstruction_substitutions.py \ + --data-dir "$DATA_DIR" \ + --tokenizer "$TOKENIZER" \ + --checkpoint "$CHECKPOINT" \ + --output-dir "$OUTPUT_DIR" \ + --batch-size 64 \ + --num-workers 8 \ + --device cuda diff --git a/slurm/evaluate_rtp_error_analysis.sbatch b/slurm/evaluate_rtp_error_analysis.sbatch new file mode 100644 index 0000000..8a634c4 --- /dev/null +++ b/slurm/evaluate_rtp_error_analysis.sbatch @@ -0,0 +1,14 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp-errana +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +set -euo pipefail +ROOT_DIR=/home/evlasova/irrm-codec +cd "$ROOT_DIR"; export PYTHONPATH="$ROOT_DIR${PYTHONPATH:+:$PYTHONPATH}" +/home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_rtp_error_analysis.py --data-dir "$ROOT_DIR/data/benchmark/trb" --tokenizer "$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" --checkpoint "$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" --output-dir "$ROOT_DIR/experiments/trb/rtp-data-anchor-error-analysis-$SLURM_JOB_ID" --batch-size 64 --num-workers 8 --device cuda diff --git a/slurm/evaluate_single_aa_challenge.sbatch b/slurm/evaluate_single_aa_challenge.sbatch new file mode 100644 index 0000000..ddd32e8 --- /dev/null +++ b/slurm/evaluate_single_aa_challenge.sbatch @@ -0,0 +1,32 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-aa1-eval +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=32 +#SBATCH --mem=192G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.err + +set -euo pipefail +TARGET_ROOT="${1:?Validated target job directory required}" +ROOT=/home/evlasova/irrm-codec +BASE="$ROOT/experiments/trb/single-aa-challenge" +OUT="$BASE/evaluation-${SLURM_JOB_ID}" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +test -f "$TARGET_ROOT/targets/TARGETS.json" +test ! -e "$OUT" +cd "$ROOT" +export OMP_NUM_THREADS="$SLURM_CPUS_PER_TASK" +export MKL_NUM_THREADS="$SLURM_CPUS_PER_TASK" +"$PYTHON" -m benchmark.evaluate_single_aa_challenge \ + --prepared "$TARGET_ROOT/prepared" --targets "$TARGET_ROOT/targets" \ + --tokenizer "$TOKENIZER" --output-dir "$OUT" --bootstrap 0 --batch-size 128 --seed 42 \ + --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "t:$ROOT/experiments/trb/data-anchor-t-seed42/best.pt:$ROOT/experiments/trb/data-anchor-t-seed42/run_config.json" \ + --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rt:$ROOT/experiments/trb/data-anchor-rt-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rt-seed42/run_config.json" \ + --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "tp:$ROOT/experiments/trb/data-anchor-tp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-tp-seed42/run_config.json" \ + --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" diff --git a/slurm/evaluate_tcremp_geometry_biology.sbatch b/slurm/evaluate_tcremp_geometry_biology.sbatch new file mode 100644 index 0000000..1200e62 --- /dev/null +++ b/slurm/evaluate_tcremp_geometry_biology.sbatch @@ -0,0 +1,32 @@ +#!/bin/bash -l +#SBATCH --job-name=tcremp-geom-bio +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +set -euo pipefail +VARIANT="${1:?Variant centered or relational required}" +case "$VARIANT" in centered|relational) ;; *) exit 2 ;; esac +ROOT=/home/evlasova/irrm-codec +MODEL="$ROOT/experiments/trb/tcremp-geometry-t-${VARIANT}-seed42" +OUT="$ROOT/experiments/trb/vdjdb-tcremp-geometry-${VARIANT}-${SLURM_JOB_ID}" +COHORT="$ROOT/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +test -f "$MODEL/best.pt" +mkdir -p "$OUT" +cd "$ROOT" +PYTHONPATH="$ROOT" "$PYTHON" benchmark/extract_vdjdb_latent.py \ + --cohort "$COHORT" --checkpoint "$MODEL/best.pt" --tokenizer "$TOKENIZER" \ + --output "$OUT/embeddings_t.npy" --batch-size 512 --device cuda +PYTHONPATH="$ROOT" "$PYTHON" benchmark/evaluate_vdjdb_decoded_tcremp.py \ + --cohort "$COHORT" --rtp "$OUT/embeddings_t.npy" \ + --checkpoint "$MODEL/best.pt" --standardizer "$MODEL/target_standardizer.npz" \ + --uniform-evaluation "$ROOT/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813" \ + --existing-separation "$ROOT/experiments/trb/vdjdb-uniform100-v1/separation-1428106" \ + --native-tcremp "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/tcremp.npy" \ + --output-dir "$OUT/decoded_eval" --batch-size 256 --device cuda diff --git a/slurm/evaluate_vdjdb_author_global.sbatch b/slurm/evaluate_vdjdb_author_global.sbatch new file mode 100644 index 0000000..b290746 --- /dev/null +++ b/slurm/evaluate_vdjdb_author_global.sbatch @@ -0,0 +1,26 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-vdjdb +#SBATCH --partition=medium +#SBATCH --cpus-per-task=16 +#SBATCH --mem=96G +#SBATCH --time=06:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/vdjdb-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/vdjdb-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-global-author-v1" +COHORT="$REPO/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +REFERENCE="$REPO/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728" +GATE="${AUTHOR_GLOBAL_PREFLIGHT:-$BASE/preflight-1427529/PREFLIGHT.json}" +OUT="$BASE/vdjdb/evaluation-$SLURM_JOB_ID" + +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$BASE/logs" "$BASE/vdjdb" +cd "$REPO" + +"$PYTHON" benchmark/evaluate_vdjdb_author_global.py --cohort "$COHORT" --preflight "$GATE" --representations-dir "$BASE/vdjdb/representations" --reference-evaluation "$REFERENCE" --output-dir "$OUT" +sha256sum "$OUT/RESULTS.json" "$OUT/external_metrics.json" "$OUT/external_retrieval_summary.tsv" "$OUT/external_per_epitope.tsv" > "$OUT/HASHES.sha256" +echo "status=complete output=$OUT" diff --git a/slurm/evaluate_vdjdb_decoded_tcremp.sbatch b/slurm/evaluate_vdjdb_decoded_tcremp.sbatch new file mode 100644 index 0000000..4bd87ee --- /dev/null +++ b/slurm/evaluate_vdjdb_decoded_tcremp.sbatch @@ -0,0 +1,21 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-decoded-tcremp +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=16:00:00 + +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb_decoded_tcremp/${SLURM_JOB_ID}" +cd "$ROOT" +PYTHONPATH="$ROOT" /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_vdjdb_decoded_tcremp.py \ + --cohort "$ROOT/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" \ + --rtp "$ROOT/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728/embeddings_rtp.npy" \ + --checkpoint "$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt" \ + --standardizer "$ROOT/experiments/trb/anchor-data-rtp-seed42/target_standardizer.npz" \ + --uniform-evaluation "$ROOT/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813" \ + --existing-separation "$ROOT/experiments/trb/vdjdb-uniform100-v1/separation-1428106" \ + --native-tcremp "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/tcremp.npy" \ + --output-dir "$OUT" --batch-size 256 diff --git a/slurm/evaluate_vdjdb_epitope_prediction.sbatch b/slurm/evaluate_vdjdb_epitope_prediction.sbatch new file mode 100644 index 0000000..179a6ee --- /dev/null +++ b/slurm/evaluate_vdjdb_epitope_prediction.sbatch @@ -0,0 +1,42 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-epitope-prediction +#SBATCH --partition=medium +#SBATCH --constraint=hpc +#SBATCH --cpus-per-task=20 +#SBATCH --mem=160G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/epitope-prediction-v1/logs/run-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/epitope-prediction-v1/logs/run-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/epitope-prediction-v1" +COHORT="$REPO/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +UNIFORM="$REPO/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813" +NATIVE="$REPO/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728" +EXTERNAL="$REPO/experiments/trb/external-global-author-v1/vdjdb/representations" +OUT="${EPITOPE_PREDICTION_OUT:-$BASE/evaluation-$SLURM_JOB_ID}" + +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +export OMP_NUM_THREADS=1 +export MKL_NUM_THREADS=1 +export OPENBLAS_NUM_THREADS=1 +mkdir -p "$BASE/logs" +cd "$REPO" + +"$PYTHON" benchmark/evaluate_vdjdb_epitope_prediction.py \ + --cohort "$COHORT" \ + --uniform-evaluation "$UNIFORM" \ + --native-evaluation "$NATIVE" \ + --external-representations "$EXTERNAL" \ + --output-dir "$OUT" \ + --seeds 42 43 44 \ + --folds 5 \ + --c-grid 0.1 1.0 \ + --max-iter 400 \ + --jobs 16 + +sha256sum "$OUT"/* > "$OUT/HASHES.sha256" +echo "status=complete output=$OUT" diff --git a/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch b/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch new file mode 100644 index 0000000..92aa85c --- /dev/null +++ b/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch @@ -0,0 +1,45 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-redcea-eval +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=32 +#SBATCH --mem=128G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.err + +set -euo pipefail +PREFLIGHT_ROOT="${1:?Preflight job directory is required}" +ROOT="/home/evlasova/irrm-codec" +BASE="$ROOT/experiments/trb/vdjdb-redcea-clonotypes" +OUTPUT="$BASE/evaluation-${SLURM_JOB_ID}" +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK}" +export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK}" + +test -x "$PYTHON" +test -f "$PREFLIGHT_ROOT/cohort/PREFLIGHT.json" +test -f "$PREFLIGHT_ROOT/cohort/cohort.tsv" +test -f "$TOKENIZER" +test ! -e "$OUTPUT" +cd "$ROOT" +"$PYTHON" -m benchmark.evaluate_vdjdb_redcea_clonotypes \ + --cohort "$PREFLIGHT_ROOT/cohort/cohort.tsv" \ + --preflight "$PREFLIGHT_ROOT/cohort/PREFLIGHT.json" \ + --tokenizer "$TOKENIZER" \ + --output-dir "$OUTPUT" \ + --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "t:$ROOT/experiments/trb/data-anchor-t-seed42/best.pt:$ROOT/experiments/trb/data-anchor-t-seed42/run_config.json" \ + --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rt:$ROOT/experiments/trb/data-anchor-rt-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rt-seed42/run_config.json" \ + --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "tp:$ROOT/experiments/trb/data-anchor-tp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-tp-seed42/run_config.json" \ + --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" \ + --batch-size 128 \ + --max-positive-candidates 20 \ + --negative-ratio 4 \ + --bootstrap 2000 \ + --silhouette-sample 10000 \ + --seed 42 + diff --git a/slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch b/slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch new file mode 100644 index 0000000..dcbde96 --- /dev/null +++ b/slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch @@ -0,0 +1,20 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-tonly-tcremp +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=16 +#SBATCH --mem=64G +#SBATCH --time=16:00:00 +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb_tonly_decoded_tcremp/${SLURM_JOB_ID}" +cd "$ROOT" +PYTHONPATH="$ROOT" /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_vdjdb_decoded_tcremp.py \ + --cohort "$ROOT/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" \ + --rtp "$ROOT/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728/embeddings_t.npy" \ + --checkpoint "$ROOT/experiments/trb/data-anchor-t-seed42/best.pt" \ + --standardizer "$ROOT/experiments/trb/data-anchor-t-seed42/target_standardizer.npz" \ + --uniform-evaluation "$ROOT/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813" \ + --existing-separation "$ROOT/experiments/trb/vdjdb-uniform100-v1/separation-1428106" \ + --native-tcremp "$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/tcremp.npy" \ + --output-dir "$OUT" --batch-size 256 \ No newline at end of file diff --git a/slurm/evaluate_vdjdb_uniform100_tcremp.sbatch b/slurm/evaluate_vdjdb_uniform100_tcremp.sbatch new file mode 100644 index 0000000..b963e67 --- /dev/null +++ b/slurm/evaluate_vdjdb_uniform100_tcremp.sbatch @@ -0,0 +1,45 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-tcremp +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=32 +#SBATCH --mem=96G +#SBATCH --time=16:00:00 + +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-${SLURM_JOB_ID}" +COHORT="$ROOT/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +PAIRS="$ROOT/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813/uniform_pairs.npz" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +TCREMP_PYTHON=/home/evlasova/.conda/envs/vdjdb-redcea/bin/python +TCREMP_ROOT=/home/evlasova/tcremp-git/tcremp +mkdir -p "$OUT/raw_tcremp" +cd "$ROOT" +"$PYTHON" - "$COHORT" "$OUT/cohort.airr.tsv" <<'PY' +import sys +import pandas as pd +x = pd.read_csv(sys.argv[1], sep="\t") +pd.DataFrame({"clone_id": range(len(x)), "junction_aa": x.cdr3, "v_call": x.v_call, "j_call": x.j_call, "locus": "TRB"}).to_csv(sys.argv[2], sep="\t", index=False) +PY +PYTHONPATH="$TCREMP_ROOT:$ROOT" "$TCREMP_PYTHON" -m tcremp.tcremp_run -i "$OUT/cohort.airr.tsv" -o "$OUT/raw_tcremp" -e cohort -c TRB -s HomoSapiens -x clone_id -p "$TCREMP_ROOT/tcremp/resources/tcremp_prototypes_TRB.tsv" -np "$SLURM_CPUS_PER_TASK" -llen 4 -hlen 41 --skip-clustering +"$PYTHON" - "$COHORT" "$PAIRS" "$OUT/raw_tcremp/cohort_tcremp.parquet" "$OUT" <<'PY' +import json, sys +from pathlib import Path +import numpy as np +import pandas as pd +from benchmark.evaluate_vdjdb_uniform100_separation import separation_metrics +cohort, pairs, raw, out = map(Path, sys.argv[1:]) +x, p, r = pd.read_csv(cohort, sep="\t"), np.load(pairs), pd.read_parquet(raw) +v = r.drop(columns="clone_id").select_dtypes(include=[np.number]); v.index = r.clone_id.astype(int) +if v.shape[1] != 9000 or not v.index.is_unique or set(v.index) != set(range(len(x))): raise ValueError("Invalid TCRemP alignment") +m = v.loc[np.arange(len(x))].to_numpy(np.float32) +if not np.isfinite(m).all(): raise ValueError("Non-finite TCRemP") +np.save(out / "tcremp.npy", m, allow_pickle=False) +q, e = separation_metrics(m[p["original_indices"]], p["within"], p["between"], x.iloc[p["original_indices"]].label.astype(str).to_numpy()) +e.insert(0, "model", "TCRemP prototypes") +e.to_csv(out / "per_epitope.tsv", sep="\t", index=False) +s = {"model": "TCRemP prototypes", "macro_auroc": float(e.auroc.mean()), "macro_cohen_d": float(e.cohen_d.mean()), "queries": len(q), "epitopes": len(e)} +pd.DataFrame([s]).to_csv(out / "summary.tsv", sep="\t", index=False) +(out / "RESULTS.json").write_text(json.dumps({"status": "complete", "summary": s, "matrix_shape": list(m.shape), "protocol": "cosine distance on Fig. 2 fixed uniform-100 pairs"}, indent=2) + "\n") +PY diff --git a/slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch b/slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch new file mode 100644 index 0000000..e1b1c55 --- /dev/null +++ b/slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch @@ -0,0 +1,61 @@ +#!/bin/bash -l +#SBATCH --job-name=vdjdb-tcremp128 +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=32 +#SBATCH --mem=192G +#SBATCH --time=16:00:00 + +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-pca128-${SLURM_JOB_ID}" +TRAIN_DATA="$ROOT/experiments/trb/external-model-benchmark/cohort" +TRAIN_TCREMP="$TRAIN_DATA/representations/tcremp.npy" +VDJDB_TCREMP="$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-1429926/tcremp.npy" +COHORT="$ROOT/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +PAIRS="$ROOT/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813/uniform_pairs.npz" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +mkdir -p "$OUT" +cd "$ROOT" +"$PYTHON" - "$TRAIN_TCREMP" "$TRAIN_DATA/manifests/train.tsv" "$VDJDB_TCREMP" "$COHORT" "$PAIRS" "$OUT" <<'PY' +import hashlib +import json +import sys +from pathlib import Path + +import numpy as np +import pandas as pd +from joblib import dump +from benchmark.evaluate_vdjdb_uniform100_separation import separation_metrics +from benchmark.fit_external_model_bottleneck import fit_projection, transform_all + +train_matrix_path, train_rows_path, vdjdb_matrix_path, cohort_path, pairs_path, out = map(Path, sys.argv[1:]) +out.mkdir(parents=True, exist_ok=True) +train_matrix = np.load(train_matrix_path, mmap_mode="r") +train_rows = pd.read_csv(train_rows_path, sep="\t")["row_index"].to_numpy(dtype=int) +vdjdb = np.load(vdjdb_matrix_path, mmap_mode="r") +if train_matrix.shape[1] != 9000 or vdjdb.shape != (68302, 9000): + raise ValueError(f"Unexpected TCRemP shapes: train={train_matrix.shape}, VDJdb={vdjdb.shape}") +class Log: + def info(self, *args): print(*args, flush=True) +scaler, pca = fit_projection(train_matrix, train_rows, 128, 4096, 42, Log()) +dump({"scaler": scaler, "pca": pca, "fit_rows": len(train_rows), "source": str(train_matrix_path)}, out / "tcremp_pca128.joblib") +projected = transform_all(vdjdb, scaler, pca, 4096) +np.save(out / "tcremp_pca128.npy", projected, allow_pickle=False) +cohort = pd.read_csv(cohort_path, sep="\t") +pairs = np.load(pairs_path) +original = pairs["original_indices"] +query, epitope = separation_metrics(projected[original], pairs["within"], pairs["between"], cohort.iloc[original].label.astype(str).to_numpy()) +query.insert(0, "model", "TCRemP prototypes PCA-128") +epitope.insert(0, "model", "TCRemP prototypes PCA-128") +query.to_parquet(out / "per_query.parquet", index=False) +epitope.to_csv(out / "per_epitope.tsv", sep="\t", index=False, lineterminator="\n") +summary = {"model": "TCRemP prototypes PCA-128", "macro_auroc": float(epitope.auroc.mean()), "macro_cohen_d": float(epitope.cohen_d.mean()), "queries": len(query), "epitopes": len(epitope)} +pd.DataFrame([summary]).to_csv(out / "summary.tsv", sep="\t", index=False, lineterminator="\n") +def sha256(path): + h = hashlib.sha256() + with open(path, "rb") as handle: + for block in iter(lambda: handle.read(1024 * 1024), b""): h.update(block) + return h.hexdigest() +(out / "RESULTS.json").write_text(json.dumps({"status": "complete", "summary": summary, "projection": {"method": "StandardScaler plus IncrementalPCA", "output_dim": 128, "fit_data": str(train_matrix_path), "fit_rows": len(train_rows), "fit_split": str(train_rows_path), "seed": 42}, "source_tcremp": {"path": str(vdjdb_matrix_path), "sha256": sha256(vdjdb_matrix_path), "shape": list(vdjdb.shape)}, "protocol": "cosine distance on the identical Fig. 2 fixed uniform-100 pairs"}, indent=2, sort_keys=True) + "\n") +PY diff --git a/slurm/evaluate_vdjdb_viral_motif_top10.sbatch b/slurm/evaluate_vdjdb_viral_motif_top10.sbatch new file mode 100644 index 0000000..7e345c3 --- /dev/null +++ b/slurm/evaluate_vdjdb_viral_motif_top10.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-viral10-eval +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=64G +#SBATCH --time=12:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.err + +set -euo pipefail +PREFLIGHT_DIR="${1:?Top-10 preflight directory is required}" +ROOT="/home/evlasova/irrm-codec" +OUTPUT="$ROOT/experiments/trb/vdjdb-viral-motif-top10/evaluation-${SLURM_JOB_ID}" +TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +test -f "$PREFLIGHT_DIR/PREFLIGHT.json" +cd "$ROOT" +"$PYTHON" -m benchmark.evaluate_vdjdb_viral_motif_top10 \ + --preflight-dir "$PREFLIGHT_DIR" --tokenizer "$TOKENIZER" --output-dir "$OUTPUT" \ + --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "t:$ROOT/experiments/trb/data-anchor-t-seed42/best.pt:$ROOT/experiments/trb/data-anchor-t-seed42/run_config.json" \ + --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rt:$ROOT/experiments/trb/data-anchor-rt-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rt-seed42/run_config.json" \ + --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "tp:$ROOT/experiments/trb/data-anchor-tp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-tp-seed42/run_config.json" \ + --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" \ + --batch-size 128 --bootstrap 2000 --permutations 1000 --seed 42 diff --git a/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch b/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch index 40e13a0..cb51dfa 100644 --- a/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch +++ b/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch @@ -19,7 +19,10 @@ cd "$ROOT" "$PYTHON" -m benchmark.evaluate_vdjdb_ylq_motif_pooled \ --preflight-dir "$PREFLIGHT_DIR" --tokenizer "$TOKENIZER" --output-dir "$OUTPUT" \ --model "r:$ROOT/experiments/trb/data-anchor-r-seed42/best.pt:$ROOT/experiments/trb/data-anchor-r-seed42/run_config.json" \ + --model "t:$ROOT/experiments/trb/data-anchor-t-seed42/best.pt:$ROOT/experiments/trb/data-anchor-t-seed42/run_config.json" \ --model "p:$ROOT/experiments/trb/data-anchor-p-seed42/best.pt:$ROOT/experiments/trb/data-anchor-p-seed42/run_config.json" \ + --model "rt:$ROOT/experiments/trb/data-anchor-rt-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rt-seed42/run_config.json" \ --model "rp:$ROOT/experiments/trb/data-anchor-rp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-rp-seed42/run_config.json" \ + --model "tp:$ROOT/experiments/trb/data-anchor-tp-seed42/best.pt:$ROOT/experiments/trb/data-anchor-tp-seed42/run_config.json" \ --model "rtp:$ROOT/experiments/trb/anchor-data-rtp-seed42/best.pt:$ROOT/experiments/trb/anchor-data-rtp-seed42/run_config.json" \ --batch-size 128 --bootstrap 2000 --permutations 1000 --seed 42 diff --git a/slurm/finalize_external_residue_pca128_all.sbatch b/slurm/finalize_external_residue_pca128_all.sbatch new file mode 100644 index 0000000..bb22016 --- /dev/null +++ b/slurm/finalize_external_residue_pca128_all.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pca128-gate +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=8G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/gate-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/gate-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca128-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +cd "$REPO" +"$PYTHON" benchmark/finalize_external_residue_pca256.py \ + --output-dir "$ROOT/bottleneck" --rows 99430 --components 128 +sha256sum "$ROOT/bottleneck"/* > "$ROOT/bottleneck/HASHES.sha256" +echo status=accepted diff --git a/slurm/finalize_external_residue_pca256.sbatch b/slurm/finalize_external_residue_pca256.sbatch new file mode 100644 index 0000000..ee75687 --- /dev/null +++ b/slurm/finalize_external_residue_pca256.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pca-gate +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=8G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/finalize-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/finalize-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca256-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +cd "$REPO" +"$PYTHON" benchmark/finalize_external_residue_pca256.py --output-dir "$ROOT/bottleneck" +sha256sum "$ROOT/bottleneck"/*_256.npy "$ROOT/bottleneck/representations.json" \ + "$ROOT/bottleneck/bottleneck_summary.json" > "$ROOT/bottleneck/HASHES.sha256" +echo status=accepted diff --git a/slurm/finalize_external_sceptr_pca128.sbatch b/slurm/finalize_external_sceptr_pca128.sbatch new file mode 100644 index 0000000..c2cf9fb --- /dev/null +++ b/slurm/finalize_external_sceptr_pca128.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-sceptr-pca128-gate +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=8G +#SBATCH --time=00:20:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/gate-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/gate-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +cd "$REPO" +"$PYTHON" benchmark/finalize_external_residue_pca_single.py \ + --output-dir "$ROOT/bottleneck" --representation sceptr \ + --rows 99430 --components 128 +sha256sum "$ROOT/bottleneck"/* > "$ROOT/bottleneck/HASHES.sha256" diff --git a/slurm/finalize_vdjdb_epitope_prediction.sbatch b/slurm/finalize_vdjdb_epitope_prediction.sbatch new file mode 100644 index 0000000..9782b12 --- /dev/null +++ b/slurm/finalize_vdjdb_epitope_prediction.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash -l +#SBATCH --job-name=finalize-epitope-prediction +#SBATCH --partition=short +#SBATCH --constraint=hpc +#SBATCH --cpus-per-task=2 +#SBATCH --mem=16G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/epitope-prediction-v1/logs/finalize-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/epitope-prediction-v1/logs/finalize-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +OUT="${EPITOPE_PREDICTION_OUT:-$REPO/experiments/trb/epitope-prediction-v1/evaluation-1429982}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export MPLBACKEND=Agg +cd "$REPO" +"$PYTHON" benchmark/finalize_vdjdb_epitope_prediction.py --output-dir "$OUT" +sha256sum "$OUT"/* > "$OUT/HASHES.sha256" diff --git a/slurm/fit_author_global_bottleneck.sbatch b/slurm/fit_author_global_bottleneck.sbatch new file mode 100644 index 0000000..90c3eb6 --- /dev/null +++ b/slurm/fit_author_global_bottleneck.sbatch @@ -0,0 +1,23 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-pca +#SBATCH --partition=medium +#SBATCH --cpus-per-task=16 +#SBATCH --mem=96G +#SBATCH --time=03:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pca-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pca-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +OLD="$REPO/experiments/trb/external-model-benchmark" +BASE="$REPO/experiments/trb/external-global-author-v1" +OUT="$BASE/bottleneck" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$BASE/logs" "$OUT" +cd "$REPO" + +"$PYTHON" benchmark/fit_external_model_bottleneck.py --dataset-dir "$OLD/cohort" --representations-dir "$OLD/cohort/representations" --output-dir "$OUT" --dims 64 --representations esm2_35m sceptr_cdr3 --batch-size 4096 --seed 42 +sha256sum "$OUT"/*_64.npy "$OUT/bottleneck_summary.json" > "$OUT/HASHES.sha256" +echo "status=accepted output=$OUT" diff --git a/slurm/fit_external_model_bottleneck.sbatch b/slurm/fit_external_model_bottleneck.sbatch new file mode 100644 index 0000000..cb833b5 --- /dev/null +++ b/slurm/fit_external_model_bottleneck.sbatch @@ -0,0 +1,31 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-pca +#SBATCH --partition=medium +#SBATCH --cpus-per-task=32 +#SBATCH --mem=192G +#SBATCH --time=08:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/pca-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/pca-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark" +COHORT="$ROOT/cohort" +OUT="$ROOT/bottleneck" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$OUT" +cd "$REPO" + +"$PYTHON" benchmark/fit_external_model_bottleneck.py \ + --dataset-dir "$COHORT" \ + --representations-dir "$COHORT/representations" \ + --output-dir "$OUT" \ + --dims 64 \ + --representations onehot tcremp esm2_8m tcr_bert sceptr rtp \ + --batch-size 4096 \ + --seed 42 + +sha256sum "$OUT"/*_64.npy "$OUT/bottleneck_summary.json" > "$OUT/HASHES.sha256" +echo "status=accepted" diff --git a/slurm/fit_external_residue_pca128_all.sbatch b/slurm/fit_external_residue_pca128_all.sbatch new file mode 100644 index 0000000..09e8c5e --- /dev/null +++ b/slurm/fit_external_residue_pca128_all.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pca128 +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=64G +#SBATCH --time=04:00:00 +#SBATCH --array=0-2%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/pca-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/pca-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca128-v1" +REPRESENTATIONS=(esm2_8m tcr_bert sceptr) +REPRESENTATION="${REPRESENTATIONS[$SLURM_ARRAY_TASK_ID]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/bottleneck" +cd "$REPO" +"$PYTHON" benchmark/fit_external_residue_pca256.py \ + --dataset-dir "$BASE/cohort" --residue-dir "$BASE/residue-v1/representations" \ + --output-dir "$ROOT/bottleneck" --representation "$REPRESENTATION" \ + --components 128 --oversample 32 --power-iterations 4 --batch-size 2048 --seed 42 +echo "status=accepted representation=$REPRESENTATION" diff --git a/slurm/fit_external_residue_pca256.sbatch b/slurm/fit_external_residue_pca256.sbatch new file mode 100644 index 0000000..afc255d --- /dev/null +++ b/slurm/fit_external_residue_pca256.sbatch @@ -0,0 +1,30 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pca256 +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=64G +#SBATCH --time=04:00:00 +#SBATCH --array=0-2%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pca-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pca-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca256-v1" +REPRESENTATIONS=(esm2_8m tcr_bert sceptr) +REPRESENTATION="${REPRESENTATIONS[$SLURM_ARRAY_TASK_ID]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/bottleneck" +cd "$REPO" +"$PYTHON" benchmark/fit_external_residue_pca256.py \ + --dataset-dir "$BASE/cohort" \ + --residue-dir "$BASE/residue-v1/representations" \ + --output-dir "$ROOT/bottleneck" \ + --representation "$REPRESENTATION" \ + --components 256 --oversample 32 --power-iterations 4 --batch-size 2048 --seed 42 +echo "status=accepted representation=$REPRESENTATION" diff --git a/slurm/fit_external_sceptr_pca128.sbatch b/slurm/fit_external_sceptr_pca128.sbatch new file mode 100644 index 0000000..7ee5dd5 --- /dev/null +++ b/slurm/fit_external_sceptr_pca128.sbatch @@ -0,0 +1,27 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-sceptr-pca128 +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=64G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/pca-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/pca-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca128-sceptr-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/bottleneck" +cd "$REPO" +"$PYTHON" benchmark/fit_external_residue_pca256.py \ + --dataset-dir "$BASE/cohort" \ + --residue-dir "$BASE/residue-v1/representations" \ + --output-dir "$ROOT/bottleneck" --representation sceptr \ + --components 128 --oversample 32 --power-iterations 4 \ + --batch-size 2048 --seed 42 +echo status=accepted diff --git a/slurm/install_external_benchmark_runtime.sbatch b/slurm/install_external_benchmark_runtime.sbatch new file mode 100644 index 0000000..e78f6cb --- /dev/null +++ b/slurm/install_external_benchmark_runtime.sbatch @@ -0,0 +1,109 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-runtime +#SBATCH --partition=medium +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/runtime-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/runtime-%j.err + +set -euo pipefail + +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark/runtime-v2" +SITE="$ROOT/site-packages" +HF_HOME="$ROOT/huggingface" +TORCH_HOME="$ROOT/torch" +REPORT="$ROOT/RUNTIME.json" + +mkdir -p "$REPO/experiments/trb/external-model-benchmark/logs" "$SITE" "$HF_HOME" "$TORCH_HOME" + +# The student report named the model/checkpoint versions but did not pin the +# transformers/fair-esm library builds. Pin compatible library versions here and record +# the complete installed distribution inventory below. --target keeps the shared conda +# environment unchanged; its Python executable remains the runtime. +"$PYTHON" -m pip install \ + --disable-pip-version-check \ + --target "$SITE" \ + --upgrade \ + --no-deps \ + "sceptr==1.2.0" \ + "fair-esm==2.0.0" \ + "transformers==4.44.2" \ + "libtcrlm==1.1.3" \ + "tidytcells==2.2.1" \ + "blosum==2.2.0" \ + "tokenizers==0.19.1" \ + "huggingface-hub==0.36.2" \ + "safetensors==0.4.5" \ + "regex==2024.11.6" \ + "requests==2.32.3" \ + "filelock==3.16.1" \ + "packaging==24.2" \ + "PyYAML==6.0.2" \ + "tqdm==4.67.1" \ + "fsspec==2024.10.0" \ + "urllib3==2.2.3" \ + "charset-normalizer==3.4.0" \ + "chardet==5.2.0" \ + "idna==3.10" \ + "certifi==2024.8.30" \ + "rapidfuzz==3.10.1" + +export PYTHONPATH="$SITE${PYTHONPATH:+:$PYTHONPATH}" +export HF_HOME TORCH_HOME + +"$PYTHON" - <<'PY' +import hashlib +import importlib +import importlib.metadata +import json +import os +import pathlib +import sys + +root = pathlib.Path(os.environ["HF_HOME"]).parent +packages = [ + "sceptr", "fair-esm", "transformers", "tokenizers", "huggingface-hub", + "safetensors", "rapidfuzz", +] +modules = {} +for name in ("torch", "sceptr", "esm", "transformers"): + module = importlib.import_module(name) + modules[name] = { + "version": getattr(module, "__version__", None), + "path": str(pathlib.Path(module.__file__).resolve()), + } + +distributions = {} +for package in packages: + try: + distributions[package] = importlib.metadata.version(package) + except importlib.metadata.PackageNotFoundError: + distributions[package] = None + +report = { + "status": "accepted", + "python": sys.executable, + "site_packages": str(root / "site-packages"), + "hf_home": os.environ["HF_HOME"], + "torch_home": os.environ["TORCH_HOME"], + "modules": modules, + "distributions": distributions, + "provenance_note": ( + "Student report pins SCEPTR 1.2.0, esm2_t6_8M_UR50D and " + "wukevin/tcr-bert but not fair-esm/transformers library versions; " + "this rerun pins compatible library builds explicitly." + ), +} +if modules["torch"]["version"] != "2.4.1+cu121" or "/.conda/envs/irrm-codec/" not in modules["torch"]["path"]: + raise RuntimeError(f"isolated packages shadowed validated conda torch: {modules['torch']}") +(root / "RUNTIME.json").write_text(json.dumps(report, indent=2, sort_keys=True), encoding="utf-8") +print(json.dumps(report, indent=2, sort_keys=True)) +PY + +cd "$REPO" +sha256sum slurm/install_external_benchmark_runtime.sbatch "$REPORT" > "$ROOT/HASHES.sha256" +echo "status=accepted" +echo "runtime=$ROOT" diff --git a/slurm/preflight_author_global_embeddings.sbatch b/slurm/preflight_author_global_embeddings.sbatch new file mode 100644 index 0000000..01f9b17 --- /dev/null +++ b/slurm/preflight_author_global_embeddings.sbatch @@ -0,0 +1,31 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-gate +#SBATCH --partition=medium +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/preflight-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-global-author-v1" +RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" +LOCKED="$REPO/experiments/trb/external-model-benchmark/cohort/dataset.parquet" +REDCEA="$REPO/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" +OUT="$BASE/preflight-$SLURM_JOB_ID" + +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export HF_HOME="$RUNTIME/huggingface" +export TORCH_HOME="$RUNTIME/torch" +export PYTHONUNBUFFERED=1 +export TOKENIZERS_PARALLELISM=false +export HF_HUB_DISABLE_TELEMETRY=1 +mkdir -p "$BASE/logs" +cd "$REPO" + +"$PYTHON" -m py_compile benchmark/cache_external_model_embeddings.py benchmark/preflight_author_global_embeddings.py benchmark/train_external_model_pgen.py +"$PYTHON" benchmark/preflight_author_global_embeddings.py --locked-dataset "$LOCKED" --redcea-cohort "$REDCEA" --locked-sha256 44aa9f8f73c23c0e42ef2bc113a5e4ee3f49fcc335e3c84f0d2eacd59021c191 --redcea-sha256 b3e5852e6952b8f4f529a60287aa76d4308dae37151b7f2becfb4ff87bd98575 --output-dir "$OUT" +sha256sum "$OUT/PREFLIGHT.json" > "$OUT/HASHES.sha256" +echo "status=accepted output=$OUT" diff --git a/slurm/preflight_data_anchor_factorial.sbatch b/slurm/preflight_data_anchor_factorial.sbatch new file mode 100644 index 0000000..f753c8d --- /dev/null +++ b/slurm/preflight_data_anchor_factorial.sbatch @@ -0,0 +1,30 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-data-factorial-pre +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/data-anchor-full-factorial-gate/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/data-anchor-full-factorial-gate/slurm-%x-%j.err + +set -euo pipefail +ROOT_DIR="/home/evlasova/irrm-codec" +DATA_DIR="$ROOT_DIR/data/benchmark/trb" +TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" +REFERENCE="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/run_config.json" +OUTPUT_ROOT="$ROOT_DIR/experiments/trb/data-anchor-full-factorial-gate" +PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" + +test -x "$PYTHON_BIN" +test -f "$DATA_DIR/READY.json" +test -f "$TOKENIZER" +test -f "$REFERENCE" +test ! -e "$OUTPUT_ROOT/PREFLIGHT.json" +mkdir -p "$OUTPUT_ROOT" +cd "$ROOT_DIR" +"$PYTHON_BIN" -m scripts.preflight_data_anchor_objectives \ + --data-dir "$DATA_DIR" \ + --tokenizer "$TOKENIZER" \ + --reference-run-config "$REFERENCE" \ + --output-root "$OUTPUT_ROOT" diff --git a/slurm/preflight_external_model_benchmark.sbatch b/slurm/preflight_external_model_benchmark.sbatch new file mode 100644 index 0000000..95f13d5 --- /dev/null +++ b/slurm/preflight_external_model_benchmark.sbatch @@ -0,0 +1,32 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-preflight +#SBATCH --partition=medium +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/preflight-%j.err + +set -euo pipefail + +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +DATASET="$REPO/data/benchmark/trb" +RTP="$REPO/experiments/trb/latent-sufficiency/evaluation-1426737/embeddings_rtp.npy" +OUT="$REPO/experiments/trb/external-model-benchmark/preflight-${SLURM_JOB_ID}" + +mkdir -p "$REPO/experiments/trb/external-model-benchmark/logs" "$OUT" +cd "$REPO" + +"$PYTHON" benchmark/preflight_external_model_benchmark.py \ + --dataset-dir "$DATASET" \ + --rtp-embeddings "$RTP" \ + --output "$OUT/PREFLIGHT.json" + +sha256sum \ + benchmark/preflight_external_model_benchmark.py \ + slurm/preflight_external_model_benchmark.sbatch \ + "$OUT/PREFLIGHT.json" > "$OUT/HASHES.sha256" + +echo "status=accepted" +echo "output=$OUT" diff --git a/slurm/preflight_external_residue_benchmark.sbatch b/slurm/preflight_external_residue_benchmark.sbatch new file mode 100644 index 0000000..bc6845b --- /dev/null +++ b/slurm/preflight_external_residue_benchmark.sbatch @@ -0,0 +1,39 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/preflight-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-v1" +RUNTIME="$BASE/runtime-v2" +SMOKE="$ROOT/preflight-$SLURM_JOB_ID/smoke" +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export HF_HOME="$RUNTIME/huggingface" +export TORCH_HOME="$RUNTIME/torch" +export TOKENIZERS_PARALLELISM=false +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$SMOKE" +cd "$REPO" + +"$PYTHON" benchmark/cache_external_residue_embeddings.py \ + --dataset-dir "$BASE/cohort" \ + --output-dir "$SMOKE" \ + --encoders esm2_8m tcr_bert sceptr \ + --device cpu \ + --batch-size 8 \ + --threads "${SLURM_CPUS_PER_TASK:-8}" \ + --limit 8 +"$PYTHON" benchmark/preflight_external_residue_benchmark.py \ + --cohort-dir "$BASE/cohort" \ + --smoke-dir "$SMOKE" \ + --output "$ROOT/preflight-$SLURM_JOB_ID/PREFLIGHT.json" +sha256sum "$ROOT/preflight-$SLURM_JOB_ID/PREFLIGHT.json" +echo "status=accepted job=$SLURM_JOB_ID" diff --git a/slurm/preflight_external_residue_pca128_all.sbatch b/slurm/preflight_external_residue_pca128_all.sbatch new file mode 100644 index 0000000..701a6fd --- /dev/null +++ b/slurm/preflight_external_residue_pca128_all.sbatch @@ -0,0 +1,32 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pca128-pre +#SBATCH --partition=short +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/preflight-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca128-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +mkdir -p "$ROOT/logs" +cd "$REPO" +"$PYTHON" -m py_compile \ + benchmark/audit_external_residue_alignment.py \ + benchmark/fit_external_residue_pca256.py \ + benchmark/finalize_external_residue_pca256.py \ + benchmark/train_external_model_decoder.py \ + benchmark/train_external_model_pgen.py \ + benchmark/combine_external_pca128_results.py +"$PYTHON" benchmark/audit_external_residue_alignment.py \ + --dataset-dir "$BASE/cohort" --residue-dir "$BASE/residue-v1/representations" \ + --output "$ROOT/RESIDUE_AUDIT.json" --seed 42 +bash -n slurm/fit_external_residue_pca128_all.sbatch \ + slurm/finalize_external_residue_pca128_all.sbatch \ + slurm/train_external_residue_pca128_remaining.sbatch \ + slurm/collect_external_residue_pca128_all.sbatch +echo status=accepted diff --git a/slurm/preflight_external_rtp128_reconstruction.sbatch b/slurm/preflight_external_rtp128_reconstruction.sbatch new file mode 100644 index 0000000..f71ca2b --- /dev/null +++ b/slurm/preflight_external_rtp128_reconstruction.sbatch @@ -0,0 +1,100 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp128-pre +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=4 +#SBATCH --mem=16G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/preflight-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/native-rtp128-v1" +SOURCE="$BASE/cohort/representations/rtp.npy" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/bottleneck" "$ROOT/reconstruction" "$ROOT/results" +cd "$REPO" + +"$PYTHON" -m py_compile \ + benchmark/train_external_model_decoder.py \ + benchmark/collect_external_reconstruction.py +bash -n \ + slurm/train_external_rtp128_reconstruction.sbatch \ + slurm/collect_external_rtp128_reconstruction.sbatch + +"$PYTHON" - "$SOURCE" "$BASE/cohort" "$ROOT" <<'PY' +import hashlib +import json +import os +import sys +from pathlib import Path + +import numpy as np +import pandas as pd +import torch + +from irrm_codec.inverse_model import InverseModel + +source, cohort, root = map(Path, sys.argv[1:]) +matrix = np.load(source, mmap_mode="r") +assert matrix.shape == (99_430, 128), matrix.shape +for start in range(0, len(matrix), 8192): + assert np.isfinite(np.asarray(matrix[start:start + 8192])).all() + +splits = {} +sets = {} +for name in ("train", "val", "test"): + rows = pd.read_csv(cohort / "manifests" / f"{name}.tsv", sep="\t")["row_index"].to_numpy() + splits[name] = int(len(rows)) + sets[name] = set(map(int, rows)) +assert splits == {"train": 79_544, "val": 9_943, "test": 9_943}, splits +assert not (sets["train"] & sets["val"] or sets["train"] & sets["test"] or sets["val"] & sets["test"]) +assert len(sets["train"] | sets["val"] | sets["test"]) == 99_430 + +smoke = InverseModel(embedding_dim=128, max_len=40)(torch.zeros(2, 128)) +assert smoke.shape == (2, 40, 25) and torch.isfinite(smoke).all() + +target = root / "bottleneck" / "rtp_128.npy" +if target.is_symlink() or target.exists(): + target.unlink() +target.symlink_to(source) +assert target.resolve() == source.resolve() + +def sha256(path): + digest = hashlib.sha256() + with path.open("rb") as handle: + for block in iter(lambda: handle.read(8 * 1024 * 1024), b""): + digest.update(block) + return digest.hexdigest() + +report = { + "status": "accepted", + "representation": "rtp", + "interface": "native_128d_no_projection", + "source": str(source), + "source_sha256": sha256(source), + "shape": list(matrix.shape), + "dtype": str(matrix.dtype), + "finite": True, + "splits": splits, + "split_overlap": 0, + "decoder": "independently_trained_InverseModel", + "seeds": [42, 43, 44], + "environment_python": sys.executable, +} +(root / "PREFLIGHT.json").write_text(json.dumps(report, indent=2), encoding="utf-8") +print(json.dumps(report, indent=2)) +PY + +sha256sum \ + benchmark/train_external_model_decoder.py \ + benchmark/collect_external_reconstruction.py \ + slurm/preflight_external_rtp128_reconstruction.sbatch \ + slurm/train_external_rtp128_reconstruction.sbatch \ + slurm/collect_external_rtp128_reconstruction.sbatch \ + "$ROOT/PREFLIGHT.json" > "$ROOT/PREFLIGHT_HASHES.sha256" +echo status=accepted diff --git a/slurm/preflight_external_sceptr_pca128.sbatch b/slurm/preflight_external_sceptr_pca128.sbatch new file mode 100644 index 0000000..491f13f --- /dev/null +++ b/slurm/preflight_external_sceptr_pca128.sbatch @@ -0,0 +1,36 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-sceptr-pca128-pre +#SBATCH --partition=short +#SBATCH --cpus-per-task=2 +#SBATCH --mem=8G +#SBATCH --time=00:20:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/preflight-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/preflight-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca128-sceptr-v1" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +mkdir -p "$ROOT/logs" +cd "$REPO" +test -f "$BASE/cohort/dataset.parquet" +test -f "$BASE/cohort/manifests/train.tsv" +test -f "$BASE/residue-v1/representations/sceptr_residue.npy" +"$PYTHON" -m py_compile \ + benchmark/fit_external_residue_pca256.py \ + benchmark/finalize_external_residue_pca_single.py \ + benchmark/preflight_external_sceptr_pca128.py \ + benchmark/train_external_model_decoder.py \ + benchmark/train_external_model_pgen.py +"$PYTHON" benchmark/preflight_external_sceptr_pca128.py \ + --dataset-dir "$BASE/cohort" \ + --residue-dir "$BASE/residue-v1/representations" \ + --output "$ROOT/PREFLIGHT.json" +bash -n \ + slurm/fit_external_sceptr_pca128.sbatch \ + slurm/finalize_external_sceptr_pca128.sbatch \ + slurm/train_external_sceptr_pca128_heads.sbatch \ + slurm/collect_external_sceptr_pca128.sbatch +echo status=accepted diff --git a/slurm/preflight_single_aa_challenge.sbatch b/slurm/preflight_single_aa_challenge.sbatch new file mode 100644 index 0000000..61c8beb --- /dev/null +++ b/slurm/preflight_single_aa_challenge.sbatch @@ -0,0 +1,52 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-aa1-preflight +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.err + +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +BASE="$ROOT/experiments/trb/single-aa-challenge" +OUT="$BASE/preflight-${SLURM_JOB_ID}" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +TCREMP_PYTHON=/home/evlasova/.conda/envs/vdjdb-redcea/bin/python +TCREMP_ROOT=/home/evlasova/tcremp-git/tcremp +PROTOTYPES="$TCREMP_ROOT/tcremp/resources/tcremp_prototypes_TRB.tsv" +MIRPY_PROVENANCE=/home/evlasova/.conda/envs/vdjdb-redcea/lib/python3.11/site-packages/mir-1.0.0.dist-info/direct_url.json +mkdir -p "$BASE" +test ! -e "$OUT" +mkdir -p "$OUT/raw_tcremp" +test "$(git -C "$TCREMP_ROOT" rev-parse HEAD)" = 372bbb64aa9572e1e2ba04a0060a9c03cd7796c6 +test "$(sha256sum "$PROTOTYPES" | cut -d' ' -f1)" = 38cbb5e75d900ef61476bf3af2ed2ff0150a05988bfe568946cd3de5e167f36b +grep -q 468ddae2107da212bb0db9497a3dc9cc44b00eaf "$MIRPY_PROVENANCE" +cd "$ROOT" +"$PYTHON" -m compileall -q benchmark/prepare_single_aa_challenge.py benchmark/validate_single_aa_targets.py benchmark/evaluate_single_aa_challenge.py +"$PYTHON" -c "import runpy; ns=runpy.run_path('tests/test_single_aa_challenge.py'); ns['test_mutants_are_unique_one_substitution_and_parent_split_is_disjoint']()" +PYTHONPATH="$TCREMP_ROOT:$ROOT" "$TCREMP_PYTHON" -c "from tcremp.tcremp_run import main; from mir.embedding.prototype_embedding import PrototypeEmbedding; print('tcremp_import_ok')" +"$PYTHON" -m benchmark.prepare_single_aa_challenge \ + --data-dir "$ROOT/data/benchmark/trb" --output-dir "$OUT/prepared" \ + --max-parents 10 --variants-per-parent 3 --seed 42 +PYTHONPATH="$TCREMP_ROOT:$ROOT" "$TCREMP_PYTHON" -m tcremp.tcremp_run \ + -i "$OUT/prepared/mutants_airr.tsv" -o "$OUT/raw_tcremp" -e mutants \ + -c TRB -s HomoSapiens -x clone_id -p "$PROTOTYPES" -np 8 \ + -llen 4 -hlen 41 --skip-clustering +"$PYTHON" -m irrm_codec.calc_pgen_1mm \ + --airr-path "$OUT/prepared/mutants_airr.tsv" --output-path "$OUT/mutants_pgen.tsv" \ + --chain TRB --species human --locus beta --clone-id-col clone_id \ + --cdr3-col junction_aa --threads 8 --chunk-size 10 +"$PYTHON" -m benchmark.validate_single_aa_targets \ + --prepared "$OUT/prepared" --pgen "$OUT/mutants_pgen.tsv" \ + --representations "$OUT/raw_tcremp/mutants_tcremp_representations.tsv" \ + --tcremp "$OUT/raw_tcremp/mutants_tcremp.parquet" --output-dir "$OUT/targets" +sha256sum "$OUT/prepared/PREPARED.json" "$OUT/targets/TARGETS.json" > "$OUT/SHA256SUMS" +cp "$MIRPY_PROVENANCE" "$OUT/mirpy_direct_url.json" +sha256sum "$TCREMP_PYTHON" "$MIRPY_PROVENANCE" "$PROTOTYPES" >> "$OUT/SHA256SUMS" +printf '{"status":"accepted","job_id":"%s","project_python":"%s","tcremp_python":"%s","tcremp_commit":"%s","mirpy_commit":"%s","prototype_sha256":"%s"}\n' \ + "$SLURM_JOB_ID" "$PYTHON" "$TCREMP_PYTHON" \ + 372bbb64aa9572e1e2ba04a0060a9c03cd7796c6 \ + 468ddae2107da212bb0db9497a3dc9cc44b00eaf \ + 38cbb5e75d900ef61476bf3af2ed2ff0150a05988bfe568946cd3de5e167f36b > "$OUT/PREFLIGHT.json" diff --git a/slurm/prepare_external_model_cohort.sbatch b/slurm/prepare_external_model_cohort.sbatch new file mode 100644 index 0000000..133121a --- /dev/null +++ b/slurm/prepare_external_model_cohort.sbatch @@ -0,0 +1,44 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-cohort +#SBATCH --partition=medium +#SBATCH --cpus-per-task=16 +#SBATCH --mem=96G +#SBATCH --time=04:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/cohort-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/cohort-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" +SOURCE="$REPO/data/benchmark/trb" +RTP="$REPO/experiments/trb/latent-sufficiency/evaluation-1426737/embeddings_rtp.npy" +OUT="$REPO/experiments/trb/external-model-benchmark/cohort" + +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$REPO/experiments/trb/external-model-benchmark/logs" "$OUT" +cd "$REPO" + +"$PYTHON" benchmark/prepare_external_model_cohort.py \ + --source-dataset-dir "$SOURCE" \ + --rtp-embeddings "$RTP" \ + --output-dir "$OUT" \ + --seed 42 + +"$PYTHON" benchmark/cache_external_model_embeddings.py \ + --dataset-dir "$OUT" \ + --output-dir "$OUT/representations" \ + --encoders onehot \ + --rtp-embeddings "$OUT/representations/rtp.npy" \ + --device cpu \ + --threads "${SLURM_CPUS_PER_TASK:-16}" + +"$PYTHON" -m pytest tests/test_external_model_benchmark.py -q +sha256sum \ + benchmark/prepare_external_model_cohort.py \ + benchmark/cache_external_model_embeddings.py \ + "$OUT/COHORT.json" \ + "$OUT/representations/representations.json" > "$OUT/PREPARATION_HASHES.sha256" +echo "status=accepted" +echo "cohort=$OUT" diff --git a/slurm/prepare_single_aa_challenge.sbatch b/slurm/prepare_single_aa_challenge.sbatch new file mode 100644 index 0000000..9f39915 --- /dev/null +++ b/slurm/prepare_single_aa_challenge.sbatch @@ -0,0 +1,45 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-aa1-targets +#SBATCH --partition=medium +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=32 +#SBATCH --mem=96G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.err + +set -euo pipefail +PREFLIGHT="${1:?Accepted preflight directory required}" +ROOT=/home/evlasova/irrm-codec +BASE="$ROOT/experiments/trb/single-aa-challenge" +OUT="$BASE/targets-${SLURM_JOB_ID}" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +TCREMP_PYTHON=/home/evlasova/.conda/envs/vdjdb-redcea/bin/python +TCREMP_ROOT=/home/evlasova/tcremp-git/tcremp +PROTOTYPES="$TCREMP_ROOT/tcremp/resources/tcremp_prototypes_TRB.tsv" +MIRPY_PROVENANCE=/home/evlasova/.conda/envs/vdjdb-redcea/lib/python3.11/site-packages/mir-1.0.0.dist-info/direct_url.json +test "$("$PYTHON" -c "import json; print(json.load(open('$PREFLIGHT/PREFLIGHT.json'))['status'])")" = accepted +test ! -e "$OUT" +mkdir -p "$OUT/raw_tcremp" +test "$(git -C "$TCREMP_ROOT" rev-parse HEAD)" = 372bbb64aa9572e1e2ba04a0060a9c03cd7796c6 +test "$(sha256sum "$PROTOTYPES" | cut -d' ' -f1)" = 38cbb5e75d900ef61476bf3af2ed2ff0150a05988bfe568946cd3de5e167f36b +grep -q 468ddae2107da212bb0db9497a3dc9cc44b00eaf "$MIRPY_PROVENANCE" +cd "$ROOT" +"$PYTHON" -m benchmark.prepare_single_aa_challenge \ + --data-dir "$ROOT/data/benchmark/trb" --output-dir "$OUT/prepared" \ + --max-parents 2000 --variants-per-parent 3 --seed 42 +PYTHONPATH="$TCREMP_ROOT:$ROOT" "$TCREMP_PYTHON" -m tcremp.tcremp_run \ + -i "$OUT/prepared/mutants_airr.tsv" -o "$OUT/raw_tcremp" -e mutants \ + -c TRB -s HomoSapiens -x clone_id -p "$PROTOTYPES" -np 32 \ + -llen 4 -hlen 41 --skip-clustering +"$PYTHON" -m irrm_codec.calc_pgen_1mm \ + --airr-path "$OUT/prepared/mutants_airr.tsv" --output-path "$OUT/mutants_pgen.tsv" \ + --chain TRB --species human --locus beta --clone-id-col clone_id \ + --cdr3-col junction_aa --threads 32 --chunk-size 50 +"$PYTHON" -m benchmark.validate_single_aa_targets \ + --prepared "$OUT/prepared" --pgen "$OUT/mutants_pgen.tsv" \ + --representations "$OUT/raw_tcremp/mutants_tcremp_representations.tsv" \ + --tcremp "$OUT/raw_tcremp/mutants_tcremp.parquet" --output-dir "$OUT/targets" +sha256sum "$OUT/prepared/PREPARED.json" "$OUT/targets/TARGETS.json" > "$OUT/SHA256SUMS" +cp "$MIRPY_PROVENANCE" "$OUT/mirpy_direct_url.json" +sha256sum "$TCREMP_PYTHON" "$MIRPY_PROVENANCE" "$PROTOTYPES" >> "$OUT/SHA256SUMS" diff --git a/slurm/prepare_vdjdb_redcea_clonotypes.sbatch b/slurm/prepare_vdjdb_redcea_clonotypes.sbatch new file mode 100644 index 0000000..255c61d --- /dev/null +++ b/slurm/prepare_vdjdb_redcea_clonotypes.sbatch @@ -0,0 +1,41 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-redcea-pre +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=4 +#SBATCH --mem=16G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.err + +set -euo pipefail +ROOT="/home/evlasova/irrm-codec" +BASE="$ROOT/experiments/trb/vdjdb-redcea-clonotypes" +OUTPUT="$BASE/preflight-${SLURM_JOB_ID}" +SOURCE="$OUTPUT/cluster_members_TRB.txt" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +COMMIT="77961e2bec255311176d5168b4b8534fdbee24e4" +BLOB="904320e903c646dc266639eb570461893d29aa2d" +URL="https://raw.githubusercontent.com/antigenomics/vdjdb-motifs/${COMMIT}/results/redcea/cluster_members_TRB.txt" + +test -x "$PYTHON" +test -f "$ROOT/data/benchmark/trb/READY.json" +test ! -e "$OUTPUT" +mkdir -p "$OUTPUT" +cd "$ROOT" +"$PYTHON" -m compileall -q \ + benchmark/prepare_vdjdb_redcea_clonotypes.py \ + benchmark/evaluate_vdjdb_redcea_clonotypes.py +"$PYTHON" -c "import runpy; m=runpy.run_path('tests/test_vdjdb_redcea_clonotypes.py'); m['test_preparation_deduplicates_removes_ambiguity_overlap_and_applies_support']()" +"$PYTHON" -c "import runpy; m=runpy.run_path('tests/test_vdjdb_redcea_evaluation.py'); m['test_perfect_epitope_geometry_scores_perfect_retrieval']()" +curl --fail --location --retry 3 --output "$SOURCE" "$URL" +ACTUAL_BLOB="$(git hash-object "$SOURCE")" +test "$ACTUAL_BLOB" = "$BLOB" +"$PYTHON" -m benchmark.prepare_vdjdb_redcea_clonotypes \ + --cluster-members "$SOURCE" \ + --benchmark-dir "$ROOT/data/benchmark/trb" \ + --output-dir "$OUTPUT/cohort" \ + --min-clonotypes 20 \ + --max-length 40 \ + --source-git-commit "$COMMIT" \ + --source-git-blob "$BLOB" diff --git a/slurm/prepare_vdjdb_viral_motif_top10.sbatch b/slurm/prepare_vdjdb_viral_motif_top10.sbatch new file mode 100644 index 0000000..5d8ffdf --- /dev/null +++ b/slurm/prepare_vdjdb_viral_motif_top10.sbatch @@ -0,0 +1,33 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-viral10-pre +#SBATCH --partition=short +#SBATCH --constraint=compute +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.err + +set -euo pipefail +MODE="${1:-prepare}" +ROOT="/home/evlasova/irrm-codec" +SNAPSHOT="/projects/immunestatus/vdjdb/vdjdb-2025-07-30" +OUTPUT="$ROOT/experiments/trb/vdjdb-viral-motif-top10/${MODE}-${SLURM_JOB_ID}" +SPECIES="$ROOT/benchmark/viral_antigen_species_2025_07_30.txt" +PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" +mkdir -p "$ROOT/experiments/trb/vdjdb-viral-motif-top10" +cd "$ROOT" +if test "$MODE" = "inventory"; then + "$PYTHON" -m benchmark.prepare_vdjdb_viral_motif_top10 \ + --vdjdb-tsv "$SNAPSHOT/vdjdb.txt" --cluster-members "$SNAPSHOT/cluster_members.txt" \ + --motif-pwms "$SNAPSHOT/motif_pwms.txt" --benchmark-dir "$ROOT/data/benchmark/trb" \ + --output-dir "$OUTPUT" --inventory-only --min-score 1 --seed 42 +else + test -f "$SPECIES" + "$PYTHON" -m benchmark.prepare_vdjdb_viral_motif_top10 \ + --vdjdb-tsv "$SNAPSHOT/vdjdb.txt" --cluster-members "$SNAPSHOT/cluster_members.txt" \ + --motif-pwms "$SNAPSHOT/motif_pwms.txt" --benchmark-dir "$ROOT/data/benchmark/trb" \ + --output-dir "$OUTPUT" --viral-species-list "$SPECIES" --min-score 1 \ + --requested-min-positives 40 --controls-per-positive 4 \ + --max-pairs-per-epitope 5000 --seed 42 +fi diff --git a/slurm/smoke_tcremp_geometry_loss.sbatch b/slurm/smoke_tcremp_geometry_loss.sbatch new file mode 100644 index 0000000..3a9ccc6 --- /dev/null +++ b/slurm/smoke_tcremp_geometry_loss.sbatch @@ -0,0 +1,31 @@ +#!/bin/bash -l +#SBATCH --job-name=tcremp-geom-smoke +#SBATCH --partition=short +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=00:30:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +set -euo pipefail +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/tcremp-geometry-smoke-${SLURM_JOB_ID}" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +cd "$ROOT" +PYTHONPATH="$ROOT" "$PYTHON" tests/test_tcremp_geometry_loss.py +PYTHONPATH="$ROOT" "$PYTHON" -m irrm_codec.train_multitask \ + --data-dir "$ROOT/data/benchmark/trb" --standardizer-path "$ROOT/data/benchmark/trb/target_standardizer.npz" \ + --output-dir "$OUT" --train-subset all --pgen-target log10_pgen_1mm \ + --tokenizer-type data_anchor --tokenizer-path "$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" \ + --max-sequence-len 40 --d-model 320 --latent-dim 128 --nhead 8 \ + --encoder-layers 4 --decoder-layers 4 --ff-dim 1280 --dropout 0.1 \ + --tcremp-head-dim 1024 --pgen-head-dim 256 --decoder-memory-tokens 4 \ + --tcremp-loss-weight 1 --pgen-loss-weight 0 --reconstruction-loss-weight 0 \ + --tcremp-mse-fraction 1 --tcremp-centered-cosine-weight 0.15 \ + --tcremp-pairwise-log-distance-weight 0.35 \ + --batch-size 4 --epochs 1 --lr 0.0003 --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 --max-grad-norm 1 --early-stopping-patience 0 \ + --scheduler-factor 0.5 --scheduler-patience 2 --scheduler-min-lr 0.000001 \ + --seed 42 --num-workers 0 --device cuda --amp --no-progress \ + --max-train-batches 2 --max-eval-batches 2 --skip-generation-metrics --no-save-test-predictions \ No newline at end of file diff --git a/slurm/train_author_global_onehot_fixed.sbatch b/slurm/train_author_global_onehot_fixed.sbatch new file mode 100644 index 0000000..a5499ad --- /dev/null +++ b/slurm/train_author_global_onehot_fixed.sbatch @@ -0,0 +1,27 @@ +#!/bin/bash +#SBATCH --job-name=irrm-onehot-pgen-fixed +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=03:00:00 +#SBATCH --array=0-2%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-onehot-fixed-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-onehot-fixed-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +OLD="$REPO/experiments/trb/external-model-benchmark" +BASE="$REPO/experiments/trb/external-global-author-v1" +SEEDS=(42 43 44) +SEED="${SEEDS[$SLURM_ARRAY_TASK_ID]}" + +export PYTHONPATH="$OLD/runtime-v2/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$BASE/logs" "$BASE/pgen-onehot-fixed" +cd "$REPO" + +"$PYTHON" benchmark/train_external_model_pgen.py --dataset-dir "$OLD/cohort" --representations-dir "$OLD/cohort/representations" --output-dir "$BASE/pgen-onehot-fixed" --arm onehot_mlp --target log10_pgen_1mm --train-subset all --seed "$SEED" --epochs 60 --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 12 --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted seed=$SEED" diff --git a/slurm/train_author_global_pgen.sbatch b/slurm/train_author_global_pgen.sbatch new file mode 100644 index 0000000..be973cb --- /dev/null +++ b/slurm/train_author_global_pgen.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-pgen +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=03:00:00 +#SBATCH --array=0-5%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +OLD="$REPO/experiments/trb/external-model-benchmark" +BASE="$REPO/experiments/trb/external-global-author-v1" +ARMS=(esm2_35m_mlp sceptr_cdr3_mlp) +SEEDS=(42 43 44) +ARM="${ARMS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$OLD/runtime-v2/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$BASE/logs" "$BASE/pgen" +cd "$REPO" + +"$PYTHON" benchmark/train_external_model_pgen.py --dataset-dir "$OLD/cohort" --representations-dir "$OLD/cohort/representations" --output-dir "$BASE/pgen" --arm "$ARM" --target log10_pgen_1mm --train-subset all --seed "$SEED" --epochs 60 --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 12 --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted arm=$ARM seed=$SEED" diff --git a/slurm/train_author_global_pgen_controls.sbatch b/slurm/train_author_global_pgen_controls.sbatch new file mode 100644 index 0000000..a1078ec --- /dev/null +++ b/slurm/train_author_global_pgen_controls.sbatch @@ -0,0 +1,29 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-controls +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=64G +#SBATCH --time=03:00:00 +#SBATCH --array=0-5%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-controls-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-controls-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +OLD="$REPO/experiments/trb/external-model-benchmark" +BASE="$REPO/experiments/trb/external-global-author-v1" +ARMS=(onehot_mlp tcremp_mlp) +SEEDS=(42 43 44) +ARM="${ARMS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" + +export PYTHONPATH="$OLD/runtime-v2/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$BASE/logs" "$BASE/pgen" +cd "$REPO" + +"$PYTHON" benchmark/train_external_model_pgen.py --dataset-dir "$OLD/cohort" --representations-dir "$OLD/cohort/representations" --output-dir "$BASE/pgen" --arm "$ARM" --target log10_pgen_1mm --train-subset all --seed "$SEED" --epochs 60 --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 12 --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted arm=$ARM seed=$SEED" diff --git a/slurm/train_author_global_reconstruction.sbatch b/slurm/train_author_global_reconstruction.sbatch new file mode 100644 index 0000000..6964911 --- /dev/null +++ b/slurm/train_author_global_reconstruction.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash +#SBATCH --job-name=irrm-author-global-recon +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=24G +#SBATCH --time=03:00:00 +#SBATCH --array=0-5%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/recon-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/recon-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +OLD="$REPO/experiments/trb/external-model-benchmark" +BASE="$REPO/experiments/trb/external-global-author-v1" +REPS=(esm2_35m sceptr_cdr3) +SEEDS=(42 43 44) +REP="${REPS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$OLD/runtime-v2/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$BASE/logs" "$BASE/reconstruction" +cd "$REPO" + +"$PYTHON" benchmark/train_external_model_decoder.py --dataset-dir "$OLD/cohort" --bottleneck-dir "$BASE/bottleneck" --output-dir "$BASE/reconstruction" --representation "$REP" --bottleneck-dim 64 --train-subset all --seed "$SEED" --epochs 60 --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 8 --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted representation=$REP seed=$SEED" diff --git a/slurm/train_data_anchor_objective.sbatch b/slurm/train_data_anchor_objective.sbatch index c625aa2..11faf10 100644 --- a/slurm/train_data_anchor_objective.sbatch +++ b/slurm/train_data_anchor_objective.sbatch @@ -10,18 +10,18 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err set -euo pipefail -CONDITION="${1:?Condition r, p, or rp is required}" +CONDITION="${1:?Condition t, rt, or tp is required}" case "$CONDITION" in - r) RECON=1; TCREMP=0; PGEN=0 ;; - p) RECON=0; TCREMP=0; PGEN=1 ;; - rp) RECON=1; TCREMP=0; PGEN=1 ;; + t) RECON=0; TCREMP=1; PGEN=0 ;; + rt) RECON=1; TCREMP=1; PGEN=0 ;; + tp) RECON=0; TCREMP=1; PGEN=1 ;; *) echo "Refusing unregistered DATA-ANCHOR objective condition" >&2; exit 2 ;; esac ROOT_DIR="/home/evlasova/irrm-codec" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" -MATRIX_ROOT="$ROOT_DIR/experiments/trb/data-anchor-objective-matrix" +MATRIX_ROOT="$ROOT_DIR/experiments/trb/data-anchor-full-factorial-gate" PREFLIGHT="$MATRIX_ROOT/PREFLIGHT.json" CONDITION_CONFIG="$MATRIX_ROOT/configs/$CONDITION.json" OUTPUT_DIR="$ROOT_DIR/experiments/trb/data-anchor-$CONDITION-seed42" diff --git a/slurm/train_external_pca256_pgen.sbatch b/slurm/train_external_pca256_pgen.sbatch new file mode 100644 index 0000000..e8cf0b9 --- /dev/null +++ b/slurm/train_external_pca256_pgen.sbatch @@ -0,0 +1,32 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-pca256-pgen +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=03:00:00 +#SBATCH --array=0-8%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pgen-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pgen-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca256-v1" +ARMS=(esm2_8m_residue_pca256_mlp tcr_bert_residue_pca256_mlp sceptr_residue_pca256_mlp) +SEEDS=(42 43 44) +ARM="${ARMS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/pgen" +cd "$REPO" +"$PYTHON" benchmark/train_external_model_pgen.py \ + --dataset-dir "$BASE/cohort" --representations-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/pgen" --arm "$ARM" --target log10_pgen_1mm \ + --train-subset all --seed "$SEED" --epochs 60 --batch-size 256 \ + --lr 0.001 --weight-decay 0.0001 --patience 12 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted arm=$ARM seed=$SEED" diff --git a/slurm/train_external_pca256_reconstruction.sbatch b/slurm/train_external_pca256_reconstruction.sbatch new file mode 100644 index 0000000..2aeb97b --- /dev/null +++ b/slurm/train_external_pca256_reconstruction.sbatch @@ -0,0 +1,32 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-pca256-recon +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --array=0-8%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca256-v1" +REPRESENTATIONS=(esm2_8m_residue tcr_bert_residue sceptr_residue) +SEEDS=(42 43 44) +REPRESENTATION="${REPRESENTATIONS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/reconstruction" +cd "$REPO" +"$PYTHON" benchmark/train_external_model_decoder.py \ + --dataset-dir "$BASE/cohort" --bottleneck-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/reconstruction" --representation "$REPRESENTATION" \ + --bottleneck-dim 256 --train-subset all --seed "$SEED" --epochs 60 \ + --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 8 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted representation=$REPRESENTATION seed=$SEED" diff --git a/slurm/train_external_pca256_sceptr_reconstruction.sbatch b/slurm/train_external_pca256_sceptr_reconstruction.sbatch new file mode 100644 index 0000000..0d100d1 --- /dev/null +++ b/slurm/train_external_pca256_sceptr_reconstruction.sbatch @@ -0,0 +1,30 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-pca256-sceptr-recon +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --array=0-2%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-sceptr-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-sceptr-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca256-v1" +SEEDS=(42 43 44) +SEED="${SEEDS[$SLURM_ARRAY_TASK_ID]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/reconstruction" +cd "$REPO" +"$PYTHON" benchmark/train_external_model_decoder.py \ + --dataset-dir "$BASE/cohort" --bottleneck-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/reconstruction" --representation sceptr_residue \ + --bottleneck-dim 256 --train-subset all --seed "$SEED" --epochs 60 \ + --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 8 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted representation=sceptr_residue seed=$SEED" diff --git a/slurm/train_external_pgen.sbatch b/slurm/train_external_pgen.sbatch new file mode 100644 index 0000000..51cc1e9 --- /dev/null +++ b/slurm/train_external_pgen.sbatch @@ -0,0 +1,40 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-pgen +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=03:00:00 +#SBATCH --array=0-11%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/pgen-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/pgen-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark" +ARMS=(sceptr_mlp tcr_bert_mlp esm2_8m_mlp rtp_mlp) +SEEDS=(42 43 44) +ARM="${ARMS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/pgen" +cd "$REPO" + +"$PYTHON" benchmark/train_external_model_pgen.py \ + --dataset-dir "$ROOT/cohort" \ + --representations-dir "$ROOT/cohort/representations" \ + --output-dir "$ROOT/pgen" \ + --arm "$ARM" \ + --target log10_pgen_1mm \ + --train-subset all \ + --seed "$SEED" \ + --epochs 60 \ + --batch-size 256 \ + --lr 0.001 \ + --weight-decay 0.0001 \ + --patience 12 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted arm=$ARM seed=$SEED" diff --git a/slurm/train_external_pgen_tfidf.sbatch b/slurm/train_external_pgen_tfidf.sbatch new file mode 100644 index 0000000..df70ac4 --- /dev/null +++ b/slurm/train_external_pgen_tfidf.sbatch @@ -0,0 +1,28 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-tfidf +#SBATCH --partition=medium +#SBATCH --cpus-per-task=16 +#SBATCH --mem=96G +#SBATCH --time=02:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/tfidf-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/tfidf-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/pgen" +cd "$REPO" + +"$PYTHON" benchmark/train_external_model_pgen.py \ + --dataset-dir "$ROOT/cohort" \ + --representations-dir "$ROOT/cohort/representations" \ + --output-dir "$ROOT/pgen" \ + --arm tfidf_ridge \ + --target log10_pgen_1mm \ + --train-subset all \ + --seed 42 \ + --threads "${SLURM_CPUS_PER_TASK:-16}" +echo "status=accepted arm=tfidf_ridge" diff --git a/slurm/train_external_reconstruction.sbatch b/slurm/train_external_reconstruction.sbatch new file mode 100644 index 0000000..940a6e7 --- /dev/null +++ b/slurm/train_external_reconstruction.sbatch @@ -0,0 +1,41 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-recon +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=24G +#SBATCH --time=03:00:00 +#SBATCH --array=0-17%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/recon-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/recon-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +ROOT="$REPO/experiments/trb/external-model-benchmark" +RUNTIME="$ROOT/runtime-v2" +REPRESENTATIONS=(onehot tcremp esm2_8m tcr_bert sceptr rtp) +SEEDS=(42 43 44) +REPRESENTATION="${REPRESENTATIONS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/reconstruction" +cd "$REPO" + +"$PYTHON" benchmark/train_external_model_decoder.py \ + --dataset-dir "$ROOT/cohort" \ + --bottleneck-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/reconstruction" \ + --representation "$REPRESENTATION" \ + --bottleneck-dim 64 \ + --train-subset all \ + --seed "$SEED" \ + --epochs 60 \ + --batch-size 256 \ + --lr 0.001 \ + --weight-decay 0.0001 \ + --patience 8 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted representation=$REPRESENTATION seed=$SEED" diff --git a/slurm/train_external_residue_pca128_remaining.sbatch b/slurm/train_external_residue_pca128_remaining.sbatch new file mode 100644 index 0000000..ad99aec --- /dev/null +++ b/slurm/train_external_residue_pca128_remaining.sbatch @@ -0,0 +1,51 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pca128-heads +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --array=0-11%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/head-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/head-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca128-v1" +REPRESENTATIONS=(esm2_8m_residue tcr_bert_residue) +ARMS=(esm2_8m_residue_pca128_mlp tcr_bert_residue_pca128_mlp) +SEEDS=(42 43 44) +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/reconstruction" "$ROOT/pgen" +cd "$REPO" + +if (( SLURM_ARRAY_TASK_ID < 6 )); then + REP_INDEX=$((SLURM_ARRAY_TASK_ID / 3)) + SEED_INDEX=$((SLURM_ARRAY_TASK_ID % 3)) + ARM="${ARMS[$REP_INDEX]}" + SEED="${SEEDS[$SEED_INDEX]}" + "$PYTHON" benchmark/train_external_model_pgen.py \ + --dataset-dir "$BASE/cohort" --representations-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/pgen" --arm "$ARM" --target log10_pgen_1mm \ + --train-subset all --seed "$SEED" --epochs 60 --batch-size 256 \ + --lr 0.001 --weight-decay 0.0001 --patience 12 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" + echo "status=accepted task=pgen arm=$ARM seed=$SEED" +else + OFFSET=$((SLURM_ARRAY_TASK_ID - 6)) + REP_INDEX=$((OFFSET / 3)) + SEED_INDEX=$((OFFSET % 3)) + REPRESENTATION="${REPRESENTATIONS[$REP_INDEX]}" + SEED="${SEEDS[$SEED_INDEX]}" + "$PYTHON" benchmark/train_external_model_decoder.py \ + --dataset-dir "$BASE/cohort" --bottleneck-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/reconstruction" --representation "$REPRESENTATION" \ + --bottleneck-dim 128 --train-subset all --seed "$SEED" --epochs 60 \ + --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 8 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" + echo "status=accepted task=reconstruction representation=$REPRESENTATION seed=$SEED" +fi diff --git a/slurm/train_external_residue_pgen.sbatch b/slurm/train_external_residue_pgen.sbatch new file mode 100644 index 0000000..26289b2 --- /dev/null +++ b/slurm/train_external_residue_pgen.sbatch @@ -0,0 +1,39 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-pgen +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=64G +#SBATCH --time=06:00:00 +#SBATCH --array=0-8%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/pgen-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/pgen-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-v1" +REPRESENTATIONS=(esm2_8m tcr_bert sceptr) +SEEDS=(42 43 44) +REPRESENTATION="${REPRESENTATIONS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/pgen" +cd "$REPO" +"$PYTHON" benchmark/train_external_residue_pgen.py \ + --dataset-dir "$BASE/cohort" \ + --residue-dir "$ROOT/representations" \ + --output-dir "$ROOT/pgen" \ + --representation "$REPRESENTATION" \ + --target log10_pgen_1mm \ + --seed "$SEED" \ + --epochs 60 \ + --batch-size 128 \ + --lr 0.0003 \ + --weight-decay 0.0001 \ + --patience 12 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted representation=$REPRESENTATION seed=$SEED" diff --git a/slurm/train_external_residue_reconstruction.sbatch b/slurm/train_external_residue_reconstruction.sbatch new file mode 100644 index 0000000..7f3b740 --- /dev/null +++ b/slurm/train_external_residue_reconstruction.sbatch @@ -0,0 +1,38 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-res-recon +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=64G +#SBATCH --time=06:00:00 +#SBATCH --array=0-8%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/recon-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/recon-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-v1" +REPRESENTATIONS=(esm2_8m tcr_bert sceptr) +SEEDS=(42 43 44) +REPRESENTATION="${REPRESENTATIONS[$((SLURM_ARRAY_TASK_ID / 3))]}" +SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID % 3))]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/reconstruction" +cd "$REPO" +"$PYTHON" benchmark/train_external_residue_decoder.py \ + --dataset-dir "$BASE/cohort" \ + --residue-dir "$ROOT/representations" \ + --output-dir "$ROOT/reconstruction" \ + --representation "$REPRESENTATION" \ + --seed "$SEED" \ + --epochs 60 \ + --batch-size 64 \ + --lr 0.0003 \ + --weight-decay 0.0001 \ + --patience 8 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted representation=$REPRESENTATION seed=$SEED" diff --git a/slurm/train_external_rtp128_reconstruction.sbatch b/slurm/train_external_rtp128_reconstruction.sbatch new file mode 100644 index 0000000..bdaa06d --- /dev/null +++ b/slurm/train_external_rtp128_reconstruction.sbatch @@ -0,0 +1,40 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-rtp128-recon +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --array=0-2%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/recon-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/recon-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/native-rtp128-v1" +SEEDS=(42 43 44) +SEED="${SEEDS[$SLURM_ARRAY_TASK_ID]}" +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +cd "$REPO" + +test "$("$PYTHON" -c 'import json; print(json.load(open("experiments/trb/external-model-benchmark/native-rtp128-v1/PREFLIGHT.json"))["status"])')" = accepted + +"$PYTHON" benchmark/train_external_model_decoder.py \ + --dataset-dir "$BASE/cohort" \ + --bottleneck-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/reconstruction" \ + --representation rtp \ + --bottleneck-dim 128 \ + --train-subset all \ + --seed "$SEED" \ + --epochs 60 \ + --batch-size 256 \ + --lr 0.001 \ + --weight-decay 0.0001 \ + --patience 8 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" +echo "status=accepted representation=rtp native_dim=128 seed=$SEED" diff --git a/slurm/train_external_sceptr_pca128_heads.sbatch b/slurm/train_external_sceptr_pca128_heads.sbatch new file mode 100644 index 0000000..e977fd0 --- /dev/null +++ b/slurm/train_external_sceptr_pca128_heads.sbatch @@ -0,0 +1,42 @@ +#!/bin/bash -l +#SBATCH --job-name=irrm-sceptr-pca128-heads +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=32G +#SBATCH --time=04:00:00 +#SBATCH --array=0-5%2 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/head-%A-%a.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/head-%A-%a.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +BASE="$REPO/experiments/trb/external-model-benchmark" +ROOT="$BASE/residue-pca128-sceptr-v1" +SEEDS=(42 43 44) +export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +mkdir -p "$ROOT/logs" "$ROOT/reconstruction" "$ROOT/pgen" +cd "$REPO" + +if (( SLURM_ARRAY_TASK_ID < 3 )); then + SEED="${SEEDS[$SLURM_ARRAY_TASK_ID]}" + "$PYTHON" benchmark/train_external_model_decoder.py \ + --dataset-dir "$BASE/cohort" --bottleneck-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/reconstruction" --representation sceptr_residue \ + --bottleneck-dim 128 --train-subset all --seed "$SEED" --epochs 60 \ + --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 8 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" + echo "status=accepted task=reconstruction seed=$SEED" +else + SEED="${SEEDS[$((SLURM_ARRAY_TASK_ID - 3))]}" + "$PYTHON" benchmark/train_external_model_pgen.py \ + --dataset-dir "$BASE/cohort" --representations-dir "$ROOT/bottleneck" \ + --output-dir "$ROOT/pgen" --arm sceptr_residue_pca128_mlp \ + --target log10_pgen_1mm --train-subset all --seed "$SEED" --epochs 60 \ + --batch-size 256 --lr 0.001 --weight-decay 0.0001 --patience 12 \ + --threads "${SLURM_CPUS_PER_TASK:-4}" + echo "status=accepted task=pgen seed=$SEED" +fi diff --git a/slurm/train_tcremp_geometry_ablation.sbatch b/slurm/train_tcremp_geometry_ablation.sbatch new file mode 100644 index 0000000..331fdea --- /dev/null +++ b/slurm/train_tcremp_geometry_ablation.sbatch @@ -0,0 +1,36 @@ +#!/bin/bash -l +#SBATCH --job-name=tcremp-geom-t +#SBATCH --partition=medium +#SBATCH --constraint=gpu +#SBATCH --gres=gpu:1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=48G +#SBATCH --time=16:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +set -euo pipefail +VARIANT="${1:?Variant centered or relational required}" +case "$VARIANT" in + centered) C=0.30; P=0.00 ;; + relational) C=0.15; P=0.35 ;; + *) echo "Unknown variant: $VARIANT" >&2; exit 2 ;; +esac +ROOT=/home/evlasova/irrm-codec +OUT="$ROOT/experiments/trb/tcremp-geometry-t-${VARIANT}-seed42" +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +test ! -e "$OUT/best.pt" +cd "$ROOT" +PYTHONPATH="$ROOT" "$PYTHON" -m irrm_codec.train_multitask \ + --data-dir "$ROOT/data/benchmark/trb" --standardizer-path "$ROOT/data/benchmark/trb/target_standardizer.npz" \ + --output-dir "$OUT" --train-subset all --pgen-target log10_pgen_1mm \ + --tokenizer-type data_anchor --tokenizer-path "$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" \ + --max-sequence-len 40 --d-model 320 --latent-dim 128 --nhead 8 \ + --encoder-layers 4 --decoder-layers 4 --ff-dim 1280 --dropout 0.1 \ + --tcremp-head-dim 1024 --pgen-head-dim 256 --decoder-memory-tokens 4 \ + --tcremp-loss-weight 1 --pgen-loss-weight 0 --reconstruction-loss-weight 0 \ + --tcremp-mse-fraction 1 --tcremp-centered-cosine-weight "$C" \ + --tcremp-pairwise-log-distance-weight "$P" \ + --batch-size 64 --epochs 40 --lr 0.0003 --weight-decay 0.0001 \ + --gradient-accumulation-steps 1 --max-grad-norm 1 --early-stopping-patience 0 \ + --scheduler-factor 0.5 --scheduler-patience 2 --scheduler-min-lr 0.000001 \ + --seed 42 --num-workers 8 --device cuda --amp --no-progress --no-save-test-predictions \ No newline at end of file diff --git a/slurm/validate_external_model_cohort.sbatch b/slurm/validate_external_model_cohort.sbatch new file mode 100644 index 0000000..87c3268 --- /dev/null +++ b/slurm/validate_external_model_cohort.sbatch @@ -0,0 +1,63 @@ +#!/bin/bash +#SBATCH --job-name=irrm-ext-validate +#SBATCH --partition=medium +#SBATCH --cpus-per-task=8 +#SBATCH --mem=32G +#SBATCH --time=01:00:00 +#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/validate-%j.out +#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/validate-%j.err + +set -euo pipefail +REPO=/home/evlasova/irrm-codec +PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python +RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" +ROOT="$REPO/experiments/trb/external-model-benchmark" +COHORT="$ROOT/cohort" +export PYTHONPATH="$RUNTIME/site-packages:$REPO${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONUNBUFFERED=1 +cd "$REPO" + +"$PYTHON" -m py_compile \ + benchmark/prepare_external_model_cohort.py \ + benchmark/cache_external_model_embeddings.py \ + benchmark/fit_external_model_bottleneck.py \ + benchmark/train_external_model_decoder.py \ + benchmark/train_external_model_pgen.py + +"$PYTHON" - <<'PY' +import json +from pathlib import Path +import numpy as np +import pandas as pd +import torch +import esm +import sceptr +import transformers +import benchmark.cache_external_model_embeddings +import benchmark.fit_external_model_bottleneck +import benchmark.train_external_model_decoder +import benchmark.train_external_model_pgen + +root = Path("/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/cohort") +report = json.loads((root / "COHORT.json").read_text()) +catalog = json.loads((root / "representations/representations.json").read_text()) +assert report["status"] == "accepted" and report["common_rows"] == 99430 +assert report["dropped_total"] == 0 and report["split_overlap"] == 0 +expected = {"onehot": (99430, 1000), "tcremp": (99430, 9000), "rtp": (99430, 128)} +for name, shape in expected.items(): + matrix = np.load(catalog[name]["path"], mmap_mode="r") + assert matrix.shape == shape, (name, matrix.shape, shape) +frame = pd.read_parquet(root / "dataset.parquet") +assert len(frame) == 99430 and frame.junction_aa.nunique() == 99430 +print(json.dumps({ + "status": "accepted", + "rows": len(frame), + "split_counts": report["split_counts"], + "representations": {name: list(shape) for name, shape in expected.items()}, + "torch": torch.__version__, + "esm": esm.__version__, + "transformers": transformers.__version__, + "sceptr_import": True, +}, indent=2, sort_keys=True)) +PY +echo "status=accepted" diff --git a/tests/test_author_global_embeddings.py b/tests/test_author_global_embeddings.py new file mode 100644 index 0000000..201bf38 --- /dev/null +++ b/tests/test_author_global_embeddings.py @@ -0,0 +1,60 @@ +import sys +from types import SimpleNamespace + +import numpy as np +import pandas as pd +import pytest +torch = pytest.importorskip("torch") + +from benchmark.cache_external_model_embeddings import ENCODERS, _mean_pool, encode_sceptr + + +class _Log: + def info(self, *args, **kwargs): + pass + + +class _FakeModel: + def __init__(self, seen): + self.seen = seen + + def calc_vector_representations(self, frame): + self.seen.append(tuple(frame.columns)) + return np.ones((len(frame), 64), dtype=np.float32) + + +def test_author_global_encoder_catalog_contains_preregistered_conditions(): + assert "esm2_35m" in ENCODERS + assert "sceptr" in ENCODERS + assert "sceptr_cdr3" in ENCODERS + + +def test_mean_pool_uses_only_real_residue_positions(): + states = torch.tensor([[[1.0, 2.0], [3.0, 6.0], [99.0, 99.0]]]) + keep = torch.tensor([[True, True, False]]) + assert torch.allclose(_mean_pool(states, keep), torch.tensor([[2.0, 4.0]])) + + +def test_sceptr_default_and_cdr3_only_use_native_vector_api(monkeypatch): + default_seen, cdr3_seen = [], [] + fake = SimpleNamespace( + enable_hardware_acceleration=lambda: None, + calc_vector_representations=_FakeModel(default_seen).calc_vector_representations, + variant=SimpleNamespace(cdr3_only=lambda: _FakeModel(cdr3_seen)), + ) + monkeypatch.setitem(sys.modules, "sceptr", fake) + frame = pd.DataFrame( + { + "junction_aa": ["CASSF", "CASRF"], + "v_call": ["TRBV1", "TRBV2"], + "j_call": ["TRBJ1", "TRBJ2"], + } + ) + args = SimpleNamespace(device="cpu", batch_size=2) + default = encode_sceptr(frame["junction_aa"].tolist(), args, _Log(), frame=frame) + cdr3 = encode_sceptr( + frame["junction_aa"].tolist(), args, _Log(), frame=frame, cdr3_only=True + ) + assert default.shape == cdr3.shape == (2, 64) + assert default_seen == [("TRBV", "CDR3B", "TRBJ")] + assert cdr3_seen == [("CDR3B",)] diff --git a/tests/test_data_anchor_factorial.py b/tests/test_data_anchor_factorial.py new file mode 100644 index 0000000..ed0ace5 --- /dev/null +++ b/tests/test_data_anchor_factorial.py @@ -0,0 +1,16 @@ +from scripts.preflight_data_anchor_objectives import CONDITIONS + + +def test_full_nonempty_three_head_factorial_is_registered() -> None: + observed = { + name: (weights["reconstruction"], weights["tcremp"], weights["pgen"]) + for name, weights in CONDITIONS.items() + } + assert observed == { + "r": (1.0, 0.0, 0.0), + "t": (0.0, 1.0, 0.0), + "p": (0.0, 0.0, 1.0), + "rt": (1.0, 1.0, 0.0), + "rp": (1.0, 0.0, 1.0), + "tp": (0.0, 1.0, 1.0), + } diff --git a/tests/test_external_model_benchmark.py b/tests/test_external_model_benchmark.py new file mode 100644 index 0000000..266db47 --- /dev/null +++ b/tests/test_external_model_benchmark.py @@ -0,0 +1,52 @@ +from pathlib import Path + +import numpy as np +import pandas as pd +import pytest + +from benchmark.preflight_external_model_benchmark import read_manifest_rows, validate_splits +from benchmark.prepare_external_model_cohort import nested_training_subsets + + +def _write_manifest(root: Path, name: str, rows: list[int]) -> None: + pd.DataFrame({"row_index": rows}).to_csv(root / f"{name}.tsv", sep="\t", index=False) + + +def test_validate_splits_requires_exact_nonoverlapping_cover(tmp_path: Path) -> None: + manifests = tmp_path / "manifests" + manifests.mkdir() + _write_manifest(manifests, "train", [0, 2, 4]) + _write_manifest(manifests, "val", [1]) + _write_manifest(manifests, "test", [3, 5]) + report = validate_splits(tmp_path, 6) + assert report["counts"] == {"train": 3, "val": 1, "test": 2} + assert report["overlaps"] == {"train_val": 0, "train_test": 0, "val_test": 0} + + +def test_validate_splits_rejects_overlap(tmp_path: Path) -> None: + manifests = tmp_path / "manifests" + manifests.mkdir() + _write_manifest(manifests, "train", [0, 1]) + _write_manifest(manifests, "val", [1, 2]) + _write_manifest(manifests, "test", [3]) + with pytest.raises(ValueError, match="overlap"): + validate_splits(tmp_path, 4) + + +def test_read_manifest_rejects_duplicate_identity(tmp_path: Path) -> None: + path = tmp_path / "rows.tsv" + pd.DataFrame({"row_index": np.array([2, 2])}).to_csv(path, sep="\t", index=False) + with pytest.raises(ValueError, match="duplicate"): + read_manifest_rows(path) + + +def test_nested_training_subsets_are_exact_deterministic_and_nested() -> None: + frame = pd.DataFrame({"junction_aa": [f"CASS{i:05d}F" for i in range(12_000)]}) + train = np.arange(len(frame), dtype=np.int64) + first = nested_training_subsets(frame, train, seed=42) + second = nested_training_subsets(frame, train[::-1], seed=42) + assert len(first["1k"]) == 1_000 + assert len(first["10k"]) == 10_000 + assert set(first["1k"]) < set(first["10k"]) + assert np.array_equal(first["1k"], second["1k"]) + assert np.array_equal(first["10k"], second["10k"]) diff --git a/tests/test_external_residue_benchmark.py b/tests/test_external_residue_benchmark.py new file mode 100644 index 0000000..a6ef820 --- /dev/null +++ b/tests/test_external_residue_benchmark.py @@ -0,0 +1,78 @@ +import numpy as np +import pytest +import torch + +from benchmark.external_residue_models import ( + FrozenResidueDecoder, + FrozenResiduePgenHead, + ResidueArrayDataset, +) +from benchmark.train_external_residue_decoder import levenshtein_distance +from benchmark.fit_external_residue_pca256 import fit_randomized_pca + + +@pytest.mark.parametrize( + ("left", "right", "expected"), + [("", "", 0), ("CASS", "CASS", 0), ("CASS", "CAS", 1), ("CASS", "CATS", 1), ("CA", "CASS", 2)], +) +def test_exact_levenshtein_distance(left, right, expected): + assert levenshtein_distance(left, right) == expected + assert levenshtein_distance(right, left) == expected + + +def test_train_only_flattened_pca_is_finite_and_256_style(): + rng = np.random.default_rng(7) + matrix = rng.normal(size=(30, 4, 5)).astype(np.float32) + train_rows = np.arange(20) + mean, scale, components, explained = fit_randomized_pca( + matrix, train_rows, n_components=6, oversample=2, niter=2, seed=42, + device=torch.device("cpu"), + ) + scores = ((matrix.reshape(30, -1) - mean) / scale) @ components + assert mean.shape == scale.shape == (20,) + assert components.shape == (20, 6) + assert scores.shape == (30, 6) + assert np.isfinite(scores).all() + assert 0 < explained <= 1 + + +def test_residue_dataset_requires_matching_shapes(tmp_path): + features = np.zeros((4, 5, 3), dtype=np.float16) + mask = np.zeros((4, 4), dtype=bool) + np.save(tmp_path / "features.npy", features) + np.save(tmp_path / "mask.npy", mask) + with pytest.raises(ValueError, match="shapes"): + ResidueArrayDataset(tmp_path / "features.npy", tmp_path / "mask.npy", [0], [1]) + + +def test_position_aware_decoder_is_finite_and_order_sensitive(): + torch.manual_seed(7) + model = FrozenResidueDecoder(input_dim=8, max_len=6, hidden_dim=32, num_layers=1, nhead=4).eval() + features = torch.randn(2, 6, 8) + mask = torch.tensor([[1, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 0]], dtype=torch.bool) + with torch.no_grad(): + original = model(features, mask) + reversed_states = model(features.flip(1), mask.flip(1)) + assert original.shape == (2, 6, 25) + assert torch.isfinite(original).all() + assert not torch.allclose(original, reversed_states) + + +def test_position_aware_pgen_head_is_finite(): + torch.manual_seed(9) + model = FrozenResiduePgenHead(input_dim=12, max_len=7, hidden_dim=32, num_layers=1, nhead=4).eval() + features = torch.randn(3, 7, 12) + mask = torch.tensor( + [[1, 1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 0]], + dtype=torch.bool, + ) + with torch.no_grad(): + prediction = model(features, mask) + assert prediction.shape == (3,) + assert torch.isfinite(prediction).all() + + +def test_models_reject_mask_shape_mismatch(): + model = FrozenResidueDecoder(input_dim=4, max_len=5, hidden_dim=16, num_layers=1, nhead=4) + with pytest.raises(ValueError, match="mask"): + model(torch.randn(2, 5, 4), torch.ones(2, 4, dtype=torch.bool)) diff --git a/tests/test_latent_secondary.py b/tests/test_latent_secondary.py new file mode 100644 index 0000000..da473ab --- /dev/null +++ b/tests/test_latent_secondary.py @@ -0,0 +1,82 @@ +import numpy as np +import pandas as pd + +from benchmark.evaluate_latent_secondary import ( + deterministic_substitutions, + joint_relevance, + make_candidate_gallery, + nested_subsets, + project_tcremp, + preregistration, + retrieval_metrics, + ridge_coefficients, + ridge_predict, +) + + +def test_preregistration_covers_tracks_and_does_not_assume_synthetic_source() -> None: + report = preregistration() + assert set(report["models"]) == {"r", "t", "p", "rt", "rp", "tp", "rtp"} + assert set(report["tracks"]) == { + "low_label", "strata", "joint_retrieval", "robustness", "synthetic_discrimination" + } + assert report["tracks"]["synthetic_discrimination"]["status"].startswith("disabled") + assert "No track" in report["no_selection_rule"] + + +def test_nested_subsets_are_deterministic_and_strictly_nested() -> None: + indices = np.arange(1000) + first = nested_subsets(indices, (0.1, 0.25, 1.0), 42) + second = nested_subsets(indices, (0.1, 0.25, 1.0), 42) + assert all(np.array_equal(first[key], second[key]) for key in first) + assert set(first[0.1]).issubset(first[0.25]) + assert set(first[0.25]).issubset(first[1.0]) + + +def test_ridge_fit_uses_only_selected_rows() -> None: + rng = np.random.default_rng(2) + x = rng.normal(size=(40, 3)) + y = x @ np.array([[1.0, 0.0], [0.0, 2.0], [1.0, -1.0]]) + train = np.arange(30) + fit = ridge_coefficients(x, y, train, 0.1) + prediction = ridge_predict(fit, x, np.arange(30, 40)) + assert np.mean((prediction - y[30:]) ** 2) < 0.01 + + +def test_tcremp_projection_is_deterministic_and_finite() -> None: + class Standardizer: + tcremp_mean = np.asarray([1.0, 2.0, 3.0], dtype=np.float32) + tcremp_std = np.asarray([1.0, 2.0, 4.0], dtype=np.float32) + + values = np.arange(18, dtype=np.float32).reshape(6, 3) + first, report = project_tcremp(values, Standardizer(), dimension=2, seed=42, chunk_size=2) + second, _ = project_tcremp(values, Standardizer(), dimension=2, seed=42, chunk_size=3) + assert np.array_equal(first, second) + assert np.isfinite(first).all() + assert report["source_dimension"] == 3 + + +def test_joint_gallery_excludes_query_and_retrieval_is_perfect_when_ranked() -> None: + gallery = make_candidate_gallery(20, 5, 42) + assert gallery.shape == (20, 5) + assert all(query not in gallery[query] for query in range(20)) + relevant = np.zeros_like(gallery, dtype=bool) + relevant[:, 0] = True + distance = np.ones_like(gallery, dtype=float) + distance[:, 0] = 0 + metrics = retrieval_metrics(distance, relevant) + assert metrics["precision_at_1"] == 1.0 + assert metrics["map"] == 1.0 + + +def test_joint_relevance_and_substitutions_are_valid_and_no_indels() -> None: + sequences = pd.Series(["CASSLGQETQYF", "CASSLGQETQFF", "CASSPGQETQYF", "CARDRGNEQFF"]) + tcremp = np.asarray([[1, 0], [0.9, 0.1], [0.8, 0.2], [0, 1]], dtype=np.float32) + pgen = np.asarray([0.0, 0.1, 0.2, 2.0]) + gallery = np.asarray([[1, 2, 3], [0, 2, 3], [0, 1, 3], [0, 1, 2]], dtype=np.int32) + relevant = joint_relevance(sequences, tcremp, pgen, gallery, 0.5) + assert relevant.shape == gallery.shape + conservative, nonconservative = deterministic_substitutions(sequences.iloc[0], 42) + assert len(conservative) == len(nonconservative) == len(sequences.iloc[0]) + assert sum(a != b for a, b in zip(conservative, sequences.iloc[0])) == 1 + assert sum(a != b for a, b in zip(nonconservative, sequences.iloc[0])) == 1 diff --git a/tests/test_latent_sufficiency.py b/tests/test_latent_sufficiency.py new file mode 100644 index 0000000..d57de21 --- /dev/null +++ b/tests/test_latent_sufficiency.py @@ -0,0 +1,59 @@ +import numpy as np +import pandas as pd + +from benchmark.evaluate_latent_sufficiency import ( + EOS_CLASS, + aggregate_losses, + composition_features, + fit_probe, + one_hot_flat, + sequence_metrics, + sequence_targets, +) + + +def test_sequence_target_roundtrip_and_linear_probe_selection(): + sequences = ["CASS", "CASR", "CATS", "CATR"] * 3 + targets = sequence_targets(sequences, 4) + assert np.all(targets[:, 4] == EOS_CLASS) + one_hot = one_hot_flat(targets) + metrics, rows = sequence_metrics(one_hot, targets) + assert metrics["token_accuracy"] == 1.0 + assert metrics["exact_accuracy"] == 1.0 + assert np.all(rows == 0) + + x = np.arange(len(sequences), dtype=np.float32)[:, None] + train = np.arange(0, 8) + val = np.arange(8, 10) + test = np.arange(10, 12) + alpha, val_pred, test_pred, trace = fit_probe( + x, train, val, test, np.arange(len(sequences), dtype=np.float32)[:, None], + [0.01, 1.0], lambda pred, index: np.mean((pred[:, 0] - index) ** 2), + ) + assert alpha in {0.01, 1.0} + assert val_pred.shape == (2, 1) + assert test_pred.shape == (2, 1) + assert set(trace) == {"0.01", "1.0"} + + +def test_controls_and_aggregate_orientation(): + table = pd.DataFrame({ + "junction_aa": ["CASS", "CATS"], + "v_call": ["TRBV1", "TRBV2"], + "j_call": ["TRBJ1", "TRBJ1"], + }) + sequence_only, meta = composition_features(table, include_vj=False) + annotated, annotated_meta = composition_features(table, include_vj=True, fit_indices=np.array([0])) + assert sequence_only.shape == (2, 21) + assert annotated.shape[1] > sequence_only.shape[1] + assert meta["sequence_only"] is True + assert annotated_meta["sequence_only"] is False + + aggregate = aggregate_losses( + {"sequence": 0.2, "tcremp": 0.5, "pgen": 0.4}, + {"sequence": 0.2, "tcremp": 0.4, "pgen": 0.3}, + {"sequence": 0.8, "tcremp": 1.0, "pgen": 1.0}, + ) + assert aggregate["normalized_regret_by_task"]["sequence"] == 0 + assert aggregate["worst_task_normalized_regret"] > 0 + assert 0 <= aggregate["fixed_reference_hypervolume"] <= 1 diff --git a/tests/test_single_aa_challenge.py b/tests/test_single_aa_challenge.py new file mode 100644 index 0000000..91f3894 --- /dev/null +++ b/tests/test_single_aa_challenge.py @@ -0,0 +1,69 @@ +import numpy as np +import pandas as pd + +from benchmark.prepare_single_aa_challenge import choose_parents, generate_mutants, parent_folds +from benchmark.validate_single_aa_targets import align_targets + + +def test_mutants_are_unique_one_substitution_and_parent_split_is_disjoint(): + parents = pd.DataFrame({ + "row_index": [10, 20, 30, 40, 50], + "junction_aa": ["CASSF", "CASRF", "CATQF", "CARGF", "CSAWF"], + "v_call": ["TRBV1"] * 5, + "j_call": ["TRBJ1-1"] * 5, + }) + benchmark = set(parents["junction_aa"]) + mutants = generate_mutants(parents, benchmark, variants_per_parent=3, seed=42) + assert len(mutants) == 15 + assert mutants["junction_aa"].nunique() == len(mutants) + assert not (set(mutants["junction_aa"]) & benchmark) + for row in mutants.itertuples(index=False): + assert len(row.parent_sequence) == len(row.junction_aa) + assert sum(a != b for a, b in zip(row.parent_sequence, row.junction_aa)) == 1 + assert row.mutation_position_zero_based not in (0, len(row.junction_aa) - 1) + folds = parent_folds(mutants["parent_id"].unique(), seed=42) + mutants["fold"] = mutants["parent_id"].map(folds) + by_fold = {fold: set(group["parent_id"]) for fold, group in mutants.groupby("fold")} + assert by_fold["train"].isdisjoint(by_fold["val"]) + assert by_fold["train"].isdisjoint(by_fold["test"]) + assert by_fold["val"].isdisjoint(by_fold["test"]) + + +def test_length_stratified_parent_limit_is_exact_even_with_more_strata_than_limit(): + table = pd.DataFrame({ + "row_index": np.arange(20), + "junction_aa": ["C" + "A" * length + "F" for length in range(2, 22)], + }) + chosen = choose_parents(table, np.arange(20), limit=5, seed=42) + assert len(chosen) == 5 + assert chosen["row_index"].nunique() == 5 + + +def test_validator_accepts_exact_zero_but_requires_finite_1mm_target(tmp_path): + prepared = tmp_path / "prepared" + prepared.mkdir() + mutants = pd.DataFrame({ + "clone_id": ["a", "b"], "junction_aa": ["CASSF", "CASRF"], + "parent_id": ["p1", "p2"], "parent_sequence": ["CASAF", "CASSF"], + }) + mutants.to_csv(prepared / "mutants.tsv", sep="\t", index=False) + pgen = mutants[["clone_id", "junction_aa"]].copy() + pgen["log10_pgen"] = [-np.inf, -5.0] + pgen["log10_pgen_1mm"] = [-4.0, -4.5] + pgen_path = tmp_path / "pgen.tsv" + pgen.to_csv(pgen_path, sep="\t", index=False) + representations = pd.DataFrame({ + "clone_id": ["a", "b"], "cdr3aa_TRB": ["CASSF", "CASRF"], + }) + reps_path = tmp_path / "representations.tsv" + representations.to_csv(reps_path, sep="\t", index=False) + tcremp = pd.DataFrame(np.zeros((2, 9000), dtype=np.float32)) + tcremp.insert(0, "clone_id", ["a", "b"]) + tcremp_path = tmp_path / "tcremp.parquet" + tcremp.to_parquet(tcremp_path, index=False) + report = align_targets(prepared, pgen_path, reps_path, tcremp_path, tmp_path / "targets") + assert report["finite_pgen_target"] is True + assert report["nonfinite_exact_log10_pgen_diagnostic_rows"] == 1 + accepted = pd.read_csv(tmp_path / "targets" / "targets.tsv", sep="\t") + assert "log10_pgen" not in accepted + assert np.isfinite(accepted["log10_pgen_1mm"]).all() diff --git a/tests/test_single_aa_evaluation.py b/tests/test_single_aa_evaluation.py new file mode 100644 index 0000000..ca90733 --- /dev/null +++ b/tests/test_single_aa_evaluation.py @@ -0,0 +1,62 @@ +import numpy as np +import pandas as pd + +from benchmark.evaluate_single_aa_challenge import ( + bootstrap_or_disabled, + evaluate_representation, + identity_features, + ridge_fit, + ridge_predict, +) + + +def test_zero_bootstrap_is_explicitly_disabled_without_resampling(): + frame = pd.DataFrame({"parent_id": ["p1"], "probe_split": ["test"]}) + disabled = bootstrap_or_disabled( + frame, + np.array([0.0]), + np.zeros((1, 2)), + {}, + np.array([True]), + repeats=0, + seed=42, + ) + assert disabled == { + "status": "disabled_by_user", + "repeats": 0, + "uncertainty_available": False, + "significance_claim_permitted": False, + } + + +def test_ridge_and_delta_evaluator_are_finite(): + rng = np.random.default_rng(42) + parents = np.repeat([f"p{i}" for i in range(15)], 3) + split = np.repeat(["train"] * 9 + ["val"] * 3 + ["test"] * 3, 3) + n = len(parents) + frame = pd.DataFrame({ + "parent_id": parents, + "probe_split": split, + "mutation_position_zero_based": np.tile([1, 2, 3], 15), + "from_aa": np.tile(["A", "C", "D"], 15), + "to_aa": np.tile(["G", "H", "I"], 15), + "length": 8, + }) + x = rng.normal(size=(n, 8)) + pgen = x[:, 0] - 0.5 * x[:, 1] + tcremp = x @ rng.normal(size=(8, 12)) + masks = {name: split == name for name in ("train", "val", "test")} + metrics, predictions = evaluate_representation("toy", x, frame, pgen, tcremp, masks) + assert metrics["pgen"]["r2"] > 0.9 + assert metrics["tcremp"]["mean_delta_cosine"] > 0.9 + assert np.isfinite(predictions["tcremp"]).all() + assert identity_features(frame, False).shape == (n, 20) + assert identity_features(frame, True).shape == (n, 100) + + +def test_ridge_preserves_multioutput_shape(): + x = np.arange(40, dtype=float).reshape(10, 4) + y = np.column_stack((x[:, 0], x[:, 1] - x[:, 2])) + pred = ridge_predict(ridge_fit(x, y, 1.0), x) + assert pred.shape == y.shape + assert np.isfinite(pred).all() diff --git a/tests/test_tcremp_geometry_loss.py b/tests/test_tcremp_geometry_loss.py new file mode 100644 index 0000000..e05e005 --- /dev/null +++ b/tests/test_tcremp_geometry_loss.py @@ -0,0 +1,29 @@ +import unittest + +import torch + +from irrm_codec.multitask_losses import IRRMCodecMultiTaskLoss + + +class TCRemPGeometryLossTest(unittest.TestCase): + def test_pairwise_loss_is_zero_for_exact_prediction(self): + target = torch.tensor([[1.0, 2.0, 3.0], [2.0, 1.0, 4.0], [3.0, 4.0, 1.0]]) + loss = IRRMCodecMultiTaskLoss._pairwise_log_cosine_distance(target, target) + self.assertAlmostEqual(float(loss), 0.0, places=7) + + def test_pairwise_loss_detects_collapsed_geometry(self): + target = torch.tensor([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]) + prediction = torch.ones_like(target) + loss = IRRMCodecMultiTaskLoss._pairwise_log_cosine_distance(prediction, target) + self.assertGreater(float(loss), 1.0) + + def test_geometry_weights_are_validated(self): + with self.assertRaises(ValueError): + IRRMCodecMultiTaskLoss( + tcremp_centered_cosine_weight=0.6, + tcremp_pairwise_log_distance_weight=0.5, + ) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/tests/test_vdjdb_cohort.py b/tests/test_vdjdb_cohort.py index 9b84319..49ca16e 100644 --- a/tests/test_vdjdb_cohort.py +++ b/tests/test_vdjdb_cohort.py @@ -1,6 +1,8 @@ import json import unittest +from pathlib import Path +from benchmark.evaluate_vdjdb_frozen import parse_models from benchmark.prepare_vdjdb_epitope_cohort import normalize_vdjdb_row @@ -49,6 +51,14 @@ def test_rejects_missing_donor_and_low_score(self): self.assertIsNone(normalized) self.assertEqual(reason, "low_or_invalid_score") + def test_frozen_evaluator_accepts_full_seven_condition_factorial(self): + values = [f"{name}:{name}.pt:{name}.json" for name in ( + "r", "t", "p", "rt", "rp", "tp", "rtp" + )] + parsed = parse_models(values) + self.assertEqual(set(parsed), {"r", "t", "p", "rt", "rp", "tp", "rtp"}) + self.assertEqual(parsed["tp"], (Path("tp.pt"), Path("tp.json"))) + if __name__ == "__main__": unittest.main() diff --git a/tests/test_vdjdb_epitope_prediction.py b/tests/test_vdjdb_epitope_prediction.py new file mode 100644 index 0000000..af6b476 --- /dev/null +++ b/tests/test_vdjdb_epitope_prediction.py @@ -0,0 +1,47 @@ +import numpy as np +import pandas as pd + +from benchmark.evaluate_vdjdb_epitope_prediction import ( + audit_dataset, + make_splits, + redcea_component_groups, + score_predictions, +) + + +def test_dataset_audit_detects_duplicates_and_label_conflicts(): + frame = pd.DataFrame({"cdr3": ["CASSF", "CASSF", "CASRF"], "label": ["A", "B", "B"]}) + report, sizes = audit_dataset(frame) + assert report["sequences"] == 3 + assert report["epitopes"] == 2 + assert report["duplicate_cdr3_rows"] == 2 + assert report["identical_cdr3_with_different_labels"] == 1 + assert sizes.set_index("label").loc["B", "sequences"] == 2 + + +def test_redcea_components_merge_rows_sharing_any_source_cluster(): + frame = pd.DataFrame({ + "source_cids": ["a|b", "b|c", "d", "e"], + "cid": ["a", "b", "d", "e"], + }) + groups = redcea_component_groups(frame) + assert groups[0] == groups[1] + assert len(np.unique(groups)) == 3 + + +def test_grouped_splits_have_no_group_leakage_and_shared_exact_alias(): + y = np.repeat(np.arange(2), 12) + exact = np.arange(len(y)) + similarity = np.repeat(np.arange(8), 3) + protocols, report = make_splits(y, exact, similarity, [42], 3, True) + assert protocols["sequence_stratified"] == protocols["exact_cdr3_grouped"] + assert report["exact_cdr3_grouped"]["alias_of"] == "sequence_stratified" + for _, _, train, test in protocols["redcea_similarity_grouped"]: + assert not set(similarity[train]).intersection(similarity[test]) + + +def test_multiclass_metrics_are_perfect_for_perfect_probabilities(): + y = np.array([0, 1, 2, 0, 1, 2]) + probabilities = np.eye(3)[y] + result = score_predictions(y, probabilities, np.arange(3)) + assert all(value == 1.0 for value in result.values()) diff --git a/tests/test_vdjdb_redcea_clonotypes.py b/tests/test_vdjdb_redcea_clonotypes.py new file mode 100644 index 0000000..f035cd3 --- /dev/null +++ b/tests/test_vdjdb_redcea_clonotypes.py @@ -0,0 +1,37 @@ +import pandas as pd + +from benchmark.prepare_vdjdb_redcea_clonotypes import prepare_cohort + + +def member(sequence: str, label: str, cid: str, species: str = "HomoSapiens") -> dict: + return { + "species": species, "antigen.epitope": label, "antigen.gene": "g", + "antigen.species": "virus", "mhc.a": "", "mhc.b": "", "mhc.class": "", + "gene": "TRB", "cdr3aa": sequence, "cid": cid, "csz": "5", + "v.segm": "TRBV1", "j.segm": "TRBJ1", + } + + +def test_preparation_deduplicates_removes_ambiguity_overlap_and_applies_support() -> None: + rows = [ + member("CASSAAAFF", "E1", "E1.1"), + member("CASSAAAFF", "E1", "E1.2"), + member("CASSQQQFF", "E1", "E1.1"), + member("CASSCCCFF", "E2", "E2.1"), + member("CASSCCCFF", "E3", "E3.1"), + member("CASSDDDFF", "E2", "E2.1"), + member("CASSEEEXF", "E2", "E2.1"), # invalid AA X + member("CASSFFFYF", "E2", "E2.1"), + ] + benchmark = {"train": {"CASSDDDFF"}, "val": set(), "test": set()} + cohort, summary, report = prepare_cohort(pd.DataFrame(rows), benchmark, 2, 40) + assert cohort[["label", "cdr3"]].to_dict("records") == [ + {"label": "E1", "cdr3": "CASSAAAFF"}, + {"label": "E1", "cdr3": "CASSQQQFF"}, + ] + assert summary.loc[0, "unique_cdr3"] == 2 + assert cohort.loc[0, "source_rows"] == 2 + assert cohort.loc[0, "source_cids"] == "E1.1|E1.2" + assert report["filter_counts"]["ambiguous_multilabel_cdr3"] == 1 + assert report["filter_counts"]["benchmark_overlap_cdr3"] == 1 + assert report["filter_counts"]["invalid_sequence_rows"] == 1 diff --git a/tests/test_vdjdb_redcea_evaluation.py b/tests/test_vdjdb_redcea_evaluation.py new file mode 100644 index 0000000..c51404d --- /dev/null +++ b/tests/test_vdjdb_redcea_evaluation.py @@ -0,0 +1,36 @@ +import numpy as np +import pandas as pd + +from benchmark.evaluate_vdjdb_redcea_clonotypes import ( + build_candidate_gallery, + candidate_distances, + summarize_candidates, +) + + +def test_perfect_epitope_geometry_scores_perfect_retrieval() -> None: + rows = [] + features = [] + for label_id, label in enumerate(("E1", "E2", "E3")): + for index in range(4): + rows.append({ + "label": label, "species": "HomoSapiens", "length": 10, + "v_call": "TRBV1", "j_call": "TRBJ1", "cdr3": f"C{label}{index}F", + }) + vector = np.zeros(3, dtype=np.float32) + vector[label_id] = 10.0 + vector += index * 1e-3 + features.append(vector) + cohort = pd.DataFrame(rows) + candidates, relevant, _, report = build_candidate_gallery(cohort, 2, 1, 42) + distances, _ = candidate_distances(np.asarray(features), candidates, "cosine") + names = report["label_names"] + label_ids = np.array([names.index(value) for value in cohort["label"]], dtype=np.int32) + summary, per_query, _ = summarize_candidates( + distances, candidates, relevant, label_ids, names + ) + assert summary["macro_epitope"]["precision_at_1"] == 1.0 + assert summary["macro_epitope"]["precision_at_5"] > 0.0 + assert summary["macro_epitope"]["within_between_ratio"] < 0.01 + assert summary["knn_classification"]["k_1"]["macro_f1"] == 1.0 + assert per_query["nearest_same_is_closer"].all() diff --git a/tests/test_vdjdb_viral_motif_top10.py b/tests/test_vdjdb_viral_motif_top10.py new file mode 100644 index 0000000..7e8c09c --- /dev/null +++ b/tests/test_vdjdb_viral_motif_top10.py @@ -0,0 +1,79 @@ +import tempfile +from pathlib import Path + +import pandas as pd + +from benchmark.evaluate_vdjdb_viral_motif_top10 import ( + EXPECTED_WEIGHTS, + MODEL_NAMES, + summarize_distribution, +) +from benchmark.prepare_vdjdb_viral_motif_top10 import ( + choose_top10, + rank_epitopes, + read_species_list, +) + + +def test_species_allowlist_is_exact_and_rejects_duplicates() -> None: + with tempfile.TemporaryDirectory() as directory: + path = Path(directory) / "viral.txt" + path.write_text("# pinned exact values\nInfluenzaA\nSARS-CoV-2\n", encoding="utf-8") + assert read_species_list(path) == ["InfluenzaA", "SARS-CoV-2"] + path.write_text("InfluenzaA\nInfluenzaA\n", encoding="utf-8") + try: + read_species_list(path) + except ValueError: + pass + else: + raise AssertionError("Duplicate species values must be rejected.") + + +def test_top10_is_ranked_by_support_and_relaxation_is_explicit() -> None: + records = [] + for index, count in enumerate(range(50, 38, -1)): + for row in range(count): + records.append({ + "cdr3": f"C{index:02d}{row:03d}", + "epitope": f"PEP{index:02d}", + "antigen_species": "VirusExact", + }) + records.append({"cdr3": "OTHER", "epitope": "PEPX", "antigen_species": "Tumor"}) + ranking, inventory = rank_epitopes(records, {"VirusExact"}) + selected, gate = choose_top10(ranking, requested_threshold=45) + assert [row["epitope"] for row in selected] == [f"PEP{i:02d}" for i in range(10)] + assert gate["threshold_transparently_lowered"] is True + assert gate["effective_minimum_unique_cdr3"] == 41 + assert next(row for row in inventory if row["antigen_species"] == "Tumor") \ + ["classified_viral_by_exact_allowlist"] == 0 + + +def test_epitope_count_shortfall_excludes_singleton_targets() -> None: + ranking = [ + {"epitope": f"E{index}", "unique_cdr3": count} + for index, count in enumerate((50, 46, 40, 5, 4, 2, 1, 1)) + ] + selected, gate = choose_top10(ranking, requested_threshold=40) + assert len(selected) == 6 + assert gate["selected_epitopes"] == 6 + assert gate["evaluable_epitope_shortfall"] == 4 + assert gate["effective_minimum_unique_cdr3"] == 2 + assert gate["viral_epitopes_below_distinct_pair_minimum"] == 2 + + +def test_full_factorial_model_labels_and_distribution_summary() -> None: + assert tuple(EXPECTED_WEIGHTS) == MODEL_NAMES + rows = [] + for epitope_index in range(10): + for model_index, model in enumerate(MODEL_NAMES): + rows.append({ + "epitope": f"E{epitope_index}", + "distance": "cosine", + "metric": "same_label_auroc", + "model": model, + "value": 0.5 + model_index / 100, + }) + summary, wins, win_summary = summarize_distribution(pd.DataFrame(rows)) + assert len(summary) == 7 + assert set(wins["model"]) == {"rtp"} + assert win_summary.loc[win_summary["model"] == "rtp", "win_count"].item() == 10 From 461ef56c51915be89e8b2fa9e24d9f283c9beb62 Mon Sep 17 00:00:00 2001 From: Elizaveta Vlasova Date: Sun, 4 Oct 2026 19:38:47 +0300 Subject: [PATCH 66/70] Prepare canonical publication repository and resolve cross-branch compatibility --- .gitattributes | 6 +++ .github/workflows/tests.yml | 18 +++++++ .gitignore | 13 +++++ README.md | 46 ++++++++++++++-- docs/integration_provenance.md | 31 +++++++++++ docs/publication.md | 45 ++++++++++++++++ irrm_codec/train_multitask.py | 52 +++++++++++++++++-- irrm_codec/wordpiece_tokenization.py | 31 ++++++----- requirements-benchmark.txt | 4 ++ requirements-dev.txt | 2 + requirements.txt | 6 +++ requirements_no_mirpy.txt | 6 +++ scripts/run_vdjdb_uniform100.sbatch | 4 +- scripts/run_vdjdb_uniform100_direct.sbatch | 4 +- slurm/benchmark_vdjdb_irrm_cpu.sbatch | 2 +- slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch | 2 +- slurm/benchmark_vdjdb_irrm_gpu.sbatch | 2 +- slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch | 2 +- slurm/benchmark_vdjdb_tcremp_runtime.sbatch | 2 +- slurm/cache_author_global_embeddings.sbatch | 2 +- slurm/cache_author_global_sceptr_cdr3.sbatch | 2 +- slurm/cache_external_model_embeddings.sbatch | 2 +- .../cache_external_residue_embeddings.sbatch | 2 +- slurm/collect_author_global_comparison.sbatch | 2 +- slurm/collect_external_model_benchmark.sbatch | 2 +- slurm/collect_external_pca256_pgen.sbatch | 2 +- ...lect_external_pca256_reconstruction.sbatch | 2 +- .../collect_external_residue_benchmark.sbatch | 2 +- ...collect_external_residue_pca128_all.sbatch | 2 +- ...lect_external_rtp128_reconstruction.sbatch | 2 +- slurm/collect_external_sceptr_pca128.sbatch | 2 +- slurm/evaluate_latent_secondary.sbatch | 6 +-- slurm/evaluate_latent_sufficiency.sbatch | 6 +-- ...luate_rtp_data_anchor_length_errors.sbatch | 8 +-- ...ate_rtp_data_anchor_position_errors.sbatch | 8 +-- ...luate_rtp_data_anchor_substitutions.sbatch | 8 +-- ...te_rtp_data_anchor_substitutions_v2.sbatch | 8 +-- slurm/evaluate_rtp_error_analysis.sbatch | 6 +-- slurm/evaluate_single_aa_challenge.sbatch | 6 +-- slurm/evaluate_tcremp_geometry_biology.sbatch | 6 +-- slurm/evaluate_vdjdb_author_global.sbatch | 2 +- slurm/evaluate_vdjdb_decoded_tcremp.sbatch | 2 +- .../evaluate_vdjdb_epitope_prediction.sbatch | 2 +- slurm/evaluate_vdjdb_frozen.sbatch | 8 +-- slurm/evaluate_vdjdb_redcea_clonotypes.sbatch | 6 +-- ...evaluate_vdjdb_tonly_decoded_tcremp.sbatch | 2 +- slurm/evaluate_vdjdb_uniform100_tcremp.sbatch | 2 +- ...uate_vdjdb_uniform100_tcremp_pca128.sbatch | 2 +- slurm/evaluate_vdjdb_viral_motif_top10.sbatch | 6 +-- slurm/evaluate_vdjdb_ylq_frozen.sbatch | 6 +-- slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch | 6 +-- ...inalize_external_residue_pca128_all.sbatch | 2 +- slurm/finalize_external_residue_pca256.sbatch | 2 +- slurm/finalize_external_sceptr_pca128.sbatch | 2 +- .../finalize_vdjdb_epitope_prediction.sbatch | 2 +- slurm/fit_author_global_bottleneck.sbatch | 2 +- slurm/fit_external_model_bottleneck.sbatch | 2 +- slurm/fit_external_residue_pca128_all.sbatch | 2 +- slurm/fit_external_residue_pca256.sbatch | 2 +- slurm/fit_external_sceptr_pca128.sbatch | 2 +- .../install_external_benchmark_runtime.sbatch | 2 +- slurm/install_wordpiece_dependency.sbatch | 6 +-- .../preflight_author_global_embeddings.sbatch | 2 +- slurm/preflight_data_anchor_factorial.sbatch | 8 +-- slurm/preflight_data_anchor_objectives.sbatch | 8 +-- .../preflight_external_model_benchmark.sbatch | 2 +- ...reflight_external_residue_benchmark.sbatch | 2 +- ...eflight_external_residue_pca128_all.sbatch | 2 +- ...ight_external_rtp128_reconstruction.sbatch | 2 +- slurm/preflight_external_sceptr_pca128.sbatch | 2 +- slurm/preflight_phase1_rq1.sbatch | 2 +- slurm/preflight_rq5_depths.sbatch | 4 +- slurm/preflight_rq5_widths.sbatch | 4 +- slurm/preflight_single_aa_challenge.sbatch | 6 +-- slurm/preflight_vdjdb_epitope.sbatch | 8 +-- slurm/preflight_vdjdb_evaluation.sbatch | 8 +-- slurm/prepare_anchored_tokenizers.sbatch | 8 +-- slurm/prepare_external_model_cohort.sbatch | 2 +- slurm/prepare_single_aa_challenge.sbatch | 6 +-- slurm/prepare_trb_joint.sbatch | 2 +- slurm/prepare_vdjdb_redcea_clonotypes.sbatch | 6 +-- slurm/prepare_vdjdb_viral_motif_top10.sbatch | 6 +-- slurm/prepare_vdjdb_ylq.sbatch | 6 +-- slurm/prepare_vdjdb_ylq_motif_pooled.sbatch | 6 +-- slurm/prepare_wordpiece_rq4.sbatch | 8 +-- slurm/prepare_wordpiece_sweep.sbatch | 8 +-- slurm/smoke_tcremp_geometry_loss.sbatch | 6 +-- slurm/train_anchored_tokenizer.sbatch | 8 +-- slurm/train_author_global_onehot_fixed.sbatch | 2 +- slurm/train_author_global_pgen.sbatch | 2 +- .../train_author_global_pgen_controls.sbatch | 2 +- .../train_author_global_reconstruction.sbatch | 2 +- slurm/train_data_anchor_objective.sbatch | 8 +-- slurm/train_external_pca256_pgen.sbatch | 2 +- ...rain_external_pca256_reconstruction.sbatch | 2 +- ...ternal_pca256_sceptr_reconstruction.sbatch | 2 +- slurm/train_external_pgen.sbatch | 2 +- slurm/train_external_pgen_tfidf.sbatch | 2 +- slurm/train_external_reconstruction.sbatch | 2 +- ...n_external_residue_pca128_remaining.sbatch | 2 +- slurm/train_external_residue_pgen.sbatch | 2 +- ...ain_external_residue_reconstruction.sbatch | 2 +- ...rain_external_rtp128_reconstruction.sbatch | 2 +- .../train_external_sceptr_pca128_heads.sbatch | 2 +- slurm/train_phase1_rq1_char.sbatch | 8 +-- slurm/train_phase2_rq23_char.sbatch | 8 +-- slurm/train_rq4_wordpiece.sbatch | 8 +-- slurm/train_rq5_depth.sbatch | 8 +-- slurm/train_rq5_width.sbatch | 8 +-- slurm/train_tcremp_geometry_ablation.sbatch | 6 +-- slurm/train_wordpiece_sweep.sbatch | 8 +-- slurm/validate_external_model_cohort.sbatch | 2 +- tests/test_integration_compatibility.py | 51 ++++++++++++++++++ 113 files changed, 491 insertions(+), 220 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/tests.yml create mode 100644 docs/integration_provenance.md create mode 100644 docs/publication.md create mode 100644 requirements-benchmark.txt create mode 100644 requirements-dev.txt create mode 100644 tests/test_integration_compatibility.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..266501f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +* text=auto +*.py text eol=lf +*.sh text eol=lf +*.sbatch text eol=lf +*.yml text eol=lf +*.yaml text eol=lf diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..114808f --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,18 @@ +name: CPU tests +on: + push: + pull_request: +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: pip + - run: python -m pip install torch==2.4.1 --index-url https://download.pytorch.org/whl/cpu + - run: python -m pip install -r requirements-dev.txt + - run: python -m compileall -q irrm_codec benchmark scripts tests + - run: python -m pytest -q + - run: find scripts slurm benchmark/slurm -type f \( -name '*.sh' -o -name '*.sbatch' \) -print0 | xargs -0 -n1 bash -n diff --git a/.gitignore b/.gitignore index d579468..1130398 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,16 @@ data/ # Reports reports/ + +# Generated experiments and local publication scratch +.publish-*/ +.tmp*/ +tmp/ +output/ +manuscript/ +*.pt +*.pth +*.npy +*.npz +experiments/**/wandb/ +experiments/**/predictions/ diff --git a/README.md b/README.md index ead456a..50703da 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,51 @@ working with TCR CDR3 amino-acid sequences, TCRemP embeddings, and generation pr - forward model: predicts a TCRemP embedding from CDR3 sequence input - inverse model: reconstructs a CDR3 sequence from a TCRemP embedding -- joint Transformer: maps char- or WordPiece-tokenized CDR3s through one 320-D - bottleneck and jointly predicts TCRemP, `log10(pgen)`, and the original CDR3 +- joint Transformer: maps char- or WordPiece-tokenized CDR3s through a configurable latent + bottleneck (320 dimensions by default; 128 in the DATA-ANCHOR study) and jointly predicts TCRemP, `log10(pgen)`, and the original CDR3 The repository is organized as a small training package with Python entrypoints, Slurm launchers, and analysis notebooks for both single-run and multi-chain workflows. +## Canonical repository and publication workflows + +The maintained repository is [VEK239/irrm-codec](https://github.com/VEK239/irrm-codec). +It combines the original Antigenomics implementation, student contributions, and +Elizaveta Vlasova's joint RTP-CODEC and evaluation work. Original contributor +commits remain in the Git history; see [integration provenance](docs/integration_provenance.md). + +The joint codec uses **R** (sequence reconstruction), **T** (TCRemP prediction), +and **P** (generation-probability prediction) supervision. Input tokenizers include +characters, WordPiece, and sequence-only terminal anchors. Reconstruction always +uses character tokens. Latent width is configurable and is independent of the +Transformer hidden width. + +- Joint codec and matched objective/tokenizer studies: `irrm_codec/train_multitask.py`, + `benchmark/prepare_trb_joint.py`, `experiments/trb/`, and [tokenizer study](docs/anchored_tokenizer_study.md). +- Student reconstruction/Pgen benchmarks: `benchmark/prepare_splits.py`, + `benchmark/train_decoder.py`, `benchmark/train_pgen_arm.py`, and [historical report](REPORT.md). +- Author external-model, residue-PCA, latent, and VDJdb evaluations: `benchmark/` + and their matching launchers in `slurm/`. +- Historical result tables: `results/`. They describe the original runs, not a + new rerun of this integrated revision. + +For a CPU development setup without the Pgen-generation dependency: + +```bash +python -m venv .venv +# Linux/macOS: source .venv/bin/activate +# PowerShell: .\.venv\Scripts\Activate.ps1 +python -m pip install torch==2.4.1 --index-url https://download.pytorch.org/whl/cpu +python -m pip install -r requirements-dev.txt +python -m pytest -q +python -m irrm_codec.train_multitask --help +``` + +Install `requirements.txt` for OLGA/Pgen generation through mirpy. Install +`requirements-benchmark.txt` only when running the optional ESM/TCR-BERT/SCEPTR +encoders; their model weights and external datasets are obtained separately. +See [reproduction and compatibility notes](docs/publication.md) before reusing +historical checkpoints or submitting cluster examples. + ## Repository layout - `irrm_codec/`: package with data loading, tokenization, datasets, models, losses, utilities and training entrypoints @@ -48,7 +88,7 @@ Register the environment as a Jupyter kernel: python -m ipykernel install --user --name irrm-codec --display-name "Python (irrm-codec)" ``` -Project dependencies, including notebook packages, are installed from [requirements.txt](/c:/Users/lizzka239/projects/irrm-codec/requirements.txt). +Project dependencies, including notebook packages, are installed from [requirements.txt](requirements.txt). ## Input data diff --git a/docs/integration_provenance.md b/docs/integration_provenance.md new file mode 100644 index 0000000..800833c --- /dev/null +++ b/docs/integration_provenance.md @@ -0,0 +1,31 @@ +# Integration provenance + +Canonical destination: https://github.com/VEK239/irrm-codec + +The publication integration starts at Antigenomics main `31ccbad1c83a765fdb91a3686cbe31d4fcf6165c`. +Real merge commits preserve the original authors, commit IDs, and parent history: + +1. Maria Demidova's `demidovamaria/main` at `7b0e7f1b82c64490528163210d154fddcb97a290` (45 unique commits). +2. `Consoooomer/benchmark/issue-3-pgen` at `b96f06eb42d9c92e3982103bb903a1dc67d59138` (19 unique commits), including the splits and reconstruction branches. +3. VEK239 main at `aa2589d21428fd59fd34b55d675fc2cb62a6980b`. +4. Antigenomics `agent/multitask-tokenizer-evaluation` at `9abb43c99de96108e178b8bbb5a0ed5d5cf414c6`, authored by Elizaveta Vlasova. +5. Previously uncommitted local author source, test, Slurm, and experiment configuration files. + +Published history is not rewritten and student work is not squashed. The integration +retains both the published VEK239 main and student tips as ancestors. Contributor +identity follows the original Git commits; no author fields were reassigned. + +Resolution decisions: + +- Keep the working single-task training fixes and W&B integration from VEK239 main. +- Combine memory-mapped/clone-ID-aware embedding preparation with the student's V/J + standardization and sequence-keyed Pgen cache. +- Retain student padded/anchored WordPiece APIs together with validated unpadded + WordPiece input and the author's anchored tokenizer implementation. +- Preserve both known WordPiece special-token layouts without renumbering stored vocabularies. +- Retain author gradient-accumulation and resume fixes alongside the experimental + locked standardizer and local TCRemP geometry-loss options. +- Retain historical reports and result tables with their original provenance. + +The original GPL-3.0 license remains in LICENSE. Historical cluster paths and input +hashes in experiment manifests are provenance records and are not rewritten. diff --git a/docs/publication.md b/docs/publication.md new file mode 100644 index 0000000..62e1fe3 --- /dev/null +++ b/docs/publication.md @@ -0,0 +1,45 @@ +# Reproduction and compatibility + +## Data and results + +The repository contains code, tests, experiment configurations, and historical +student result tables. Large TCRemP embeddings, pretrained weights, checkpoints, +raw repertoires, and cluster output are external runtime artifacts. CPU tests use +synthetic fixtures; they do not regenerate the published research results. + +The author's joint preparation (`benchmark.prepare_trb_joint`) validates biological +identity using AIRR, Pgen, and the TCRemP clone-ID sidecar and writer contract. The +student preparation (`benchmark.prepare_splits`) retains its distinct benchmark +workflow and V/J cleaning. Do not interchange split manifests between cohorts. +Normalize targets and fit tokenizer/PCA models using the prescribed training data. + +## Token IDs and historical checkpoints + +The author's character and anchored-tokenizer convention is PAD=0, BOS=1, EOS=2, +UNK=3. Student WordPiece files and the earlier VEK239 main may use PAD=0, UNK=1, +BOS=2, EOS=3. The integrated WordPiece loader accepts both known layouts, preserves +all stored IDs, and checks UNK/EOS using each tokenizer's own vocabulary. The +reconstruction decoder uses the author's character convention. + +A character reconstruction checkpoint trained under the earlier VEK239 special-ID +order is not automatically interchangeable with the author's decoder convention. +Use its original revision or explicitly migrate special-token embedding/output +rows before evaluation. Do not relabel token IDs in existing tokenizer files. +Author DATA-ANCHOR configurations remain compatible with the author convention. + +## Cluster examples + +Slurm examples retain the partitions, accounts, data paths, and environments used +for their historical experiments. Inspect these before submission; #SBATCH paths +are literal and do not expand shell variables. Adapt them to your cluster and use +the Python module entrypoints with explicit CLI paths. Scripts that expose REPO, +SCRATCH, CONDA_ROOT, PYTHON_BIN, or IRRM_ROOT can be configured through those variables. +No cluster jobs are submitted by installing this repository or running its CPU tests. + +## Validation scope + +Run `python -m pytest -q` from the repository root. Tests cover reconstruction, +objective combinations, tokenizers, data identity/alignment, standardizers, metrics, +external benchmark bookkeeping, and VDJdb cohort rules. Optional external encoders +need requirements-benchmark.txt plus model downloads; complete GPU training and +external-data experiments require separately provisioned resources. diff --git a/irrm_codec/train_multitask.py b/irrm_codec/train_multitask.py index 09ddc8b..8631ae2 100644 --- a/irrm_codec/train_multitask.py +++ b/irrm_codec/train_multitask.py @@ -174,6 +174,36 @@ def _batch_limit(loader, requested: int) -> int: return min(len(loader), requested) if requested > 0 else len(loader) +def _gradient_accumulation_group_size( + step: int, + total_steps: int, + accumulation_steps: int, +) -> int: + """Return the actual size of the accumulation group containing ``step``.""" + group_start = ((step - 1) // accumulation_steps) * accumulation_steps + return min(accumulation_steps, total_steps - group_start) + + +def _resolve_best_checkpoint(output_dir: Path, resume: str | None) -> Path: + """Find the best available checkpoint after a fresh or resumed run.""" + candidates = [output_dir / "best.pt"] + if resume: + resume_path = Path(resume) + sibling_best = resume_path.parent / "best.pt" + if sibling_best not in candidates: + candidates.append(sibling_best) + if resume_path not in candidates: + candidates.append(resume_path) + for candidate in candidates: + if candidate.exists(): + return candidate + raise FileNotFoundError( + "No best checkpoint is available. Expected one of: " + + ", ".join(str(candidate) for candidate in candidates) + ) + + + def run_epoch( *, model: IRRMCodecTransformer, @@ -240,7 +270,10 @@ def run_epoch( ) if is_train: - scaled_loss = losses["loss"] / gradient_accumulation_steps + accumulation_group_size = _gradient_accumulation_group_size( + step, limit, gradient_accumulation_steps + ) + scaled_loss = losses["loss"] / accumulation_group_size scaler.scale(scaled_loss).backward() should_step = ( step % gradient_accumulation_steps == 0 or step == limit @@ -378,7 +411,19 @@ def main() -> None: if args.standardizer_path else Path(args.data_dir) / "target_standardizer.npz" ) - if args.resume and output_standardizer_path.exists(): + resume_standardizer_path = ( + Path(args.resume).parent / "target_standardizer.npz" if args.resume else None + ) + if resume_standardizer_path is not None and resume_standardizer_path.exists(): + standardizer = TargetStandardizer.load(resume_standardizer_path) + standardizer.save(output_standardizer_path) + if standardizer.pgen_target != args.pgen_target: + raise ValueError("Resume checkpoint and requested pgen target do not match.") + if standardizer.train_rows != len(train_indices): + raise ValueError("Resume standardizer and requested train subset do not match.") + if len(standardizer.tcremp_mean) != embeddings.shape[1]: + raise ValueError("Resume standardizer and TCRemP dimension do not match.") + elif args.resume and output_standardizer_path.exists(): standardizer = TargetStandardizer.load(output_standardizer_path) if standardizer.pgen_target != args.pgen_target: raise ValueError("Resume checkpoint and requested pgen target do not match.") @@ -660,7 +705,8 @@ def main() -> None: logger.info("early stopping at epoch=%d", epoch) break - best_checkpoint = torch.load(output_dir / "best.pt", map_location=device) + best_checkpoint_path = _resolve_best_checkpoint(output_dir, args.resume) + best_checkpoint = torch.load(best_checkpoint_path, map_location=device) model.load_state_dict(best_checkpoint["model_state"]) test_metrics = run_epoch( model=model, diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py index 78e9719..dc83099 100644 --- a/irrm_codec/wordpiece_tokenization.py +++ b/irrm_codec/wordpiece_tokenization.py @@ -1,8 +1,8 @@ """WordPiece tokenizer for CDR3 sequences, as an alternative to the char-level one. Requires: pip install tokenizers -Requires a tokenizer.json with special tokens at [PAD]=0, [UNK]=1, [BOS]=2, [EOS]=3 — -same ids irrm_codec.tokenization uses. A mismatched file raises ValueError. +Requires a tokenizer.json with special tokens at [PAD]=0, [UNK]=1, [BOS]=2, [EOS]=3 — +The author layout [PAD]/[BOS]/[EOS]/[UNK]=0/1/2/3 is also accepted. IDs are never remapped. """ from pathlib import Path @@ -14,18 +14,20 @@ _EXPECTED_SPECIAL_IDS = {"[PAD]": PAD_ID, "[UNK]": UNK_ID, "[BOS]": BOS_ID, "[EOS]": EOS_ID} -def _validate_special_ids(tokenizer, tokenizer_path): - """Check PAD/UNK/BOS/EOS ids match, since ForwardModel/InverseModel assume padding_idx=0.""" - for token, expected_id in _EXPECTED_SPECIAL_IDS.items(): - actual_id = tokenizer.token_to_id(token) - if actual_id != expected_id: - raise ValueError( - f"Tokenizer at {tokenizer_path} has {token}={actual_id}, expected {expected_id}." - ) +def validate_wordpiece_tokenizer(tokenizer, source): + """Accept the published author and student special-token layouts without remapping IDs.""" + observed = {token: tokenizer.token_to_id(token) for token in _EXPECTED_SPECIAL_IDS} + author = {"[PAD]": 0, "[BOS]": 1, "[EOS]": 2, "[UNK]": 3} + student = {"[PAD]": 0, "[UNK]": 1, "[BOS]": 2, "[EOS]": 3} + if observed not in (author, student): + raise ValueError(f"Tokenizer at {source} has unsupported special IDs: {observed}.") + +def _validate_special_ids(tokenizer, tokenizer_path): + validate_wordpiece_tokenizer(tokenizer, tokenizer_path) def load_wordpiece_tokenizer(path) -> Tokenizer: - """Load and validate a tokenizer.json. Returns the Tokenizer itself — it's picklable, + """Load and validate a tokenizer.json. Returns the Tokenizer itself — it's picklable, so it can go straight into a DataLoader worker.""" tokenizer = Tokenizer.from_file(str(Path(path))) _validate_special_ids(tokenizer, path) @@ -62,7 +64,7 @@ def encode_wordpiece_unpadded( token_ids = tokenizer.encode(sequence).ids if not token_ids: raise ValueError("WordPiece encoding must contain at least one token.") - if UNK_ID in token_ids: + if tokenizer.token_to_id("[UNK]") in token_ids: raise ValueError(f"WordPiece encoding contains [UNK] for sequence {sequence!r}.") if len(token_ids) > max_len: raise ValueError( @@ -121,8 +123,9 @@ def encode_wordpiece_anchored(seq, tokenizer, max_len, left_anchor=1, right_anch def decode_wordpiece(token_ids, tokenizer, stop_at_eos=True): """Decode ids back to an amino-acid string, stopping at the first EOS by default.""" ids = list(token_ids) - if stop_at_eos and EOS_ID in ids: - ids = ids[: ids.index(EOS_ID)] + eos_id = tokenizer.token_to_id("[EOS]") + if stop_at_eos and eos_id in ids: + ids = ids[: ids.index(eos_id)] return tokenizer.decode(ids, skip_special_tokens=True) diff --git a/requirements-benchmark.txt b/requirements-benchmark.txt new file mode 100644 index 0000000..6be1846 --- /dev/null +++ b/requirements-benchmark.txt @@ -0,0 +1,4 @@ +# Optional external representation encoders; install after requirements.txt. +fair-esm +transformers +sceptr diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..aa395c5 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,2 @@ +-r requirements_no_mirpy.txt +pytest>=8,<9 diff --git a/requirements.txt b/requirements.txt index 394cc7c..e7a17c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,3 +15,9 @@ tokenizers>=0.20,<1 wandb torch==2.4.1 mirpy-lib @ git+https://github.com/antigenomics/mirpy.git@11a5fd1ac12edd22e12a2bb167ab9dfb55ccefd4 + +scipy +joblib +tidytcells>=2,<3 +rapidfuzz>=3,<4 +biopython diff --git a/requirements_no_mirpy.txt b/requirements_no_mirpy.txt index 7df91da..5ec5a69 100644 --- a/requirements_no_mirpy.txt +++ b/requirements_no_mirpy.txt @@ -13,3 +13,9 @@ ipywidgets tqdm tokenizers>=0.20,<1 torch==2.4.1 + +scipy +joblib +tidytcells>=2,<3 +rapidfuzz>=3,<4 +biopython diff --git a/scripts/run_vdjdb_uniform100.sbatch b/scripts/run_vdjdb_uniform100.sbatch index 5ff14ba..238fb25 100644 --- a/scripts/run_vdjdb_uniform100.sbatch +++ b/scripts/run_vdjdb_uniform100.sbatch @@ -5,8 +5,8 @@ #SBATCH --cpus-per-task=16 #SBATCH --mem=64G #SBATCH --time=04:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.err +#SBATCH --output=slurm-%j.out +#SBATCH --error=slurm-%j.err set -euo pipefail diff --git a/scripts/run_vdjdb_uniform100_direct.sbatch b/scripts/run_vdjdb_uniform100_direct.sbatch index 9159b5f..da2db2a 100644 --- a/scripts/run_vdjdb_uniform100_direct.sbatch +++ b/scripts/run_vdjdb_uniform100_direct.sbatch @@ -5,8 +5,8 @@ #SBATCH --cpus-per-task=16 #SBATCH --mem=64G #SBATCH --time=04:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-uniform100-v1/slurm-%j.err +#SBATCH --output=slurm-%j.out +#SBATCH --error=slurm-%j.err set -euo pipefail diff --git a/slurm/benchmark_vdjdb_irrm_cpu.sbatch b/slurm/benchmark_vdjdb_irrm_cpu.sbatch index c71fb29..4ffa90e 100644 --- a/slurm/benchmark_vdjdb_irrm_cpu.sbatch +++ b/slurm/benchmark_vdjdb_irrm_cpu.sbatch @@ -7,7 +7,7 @@ #SBATCH --time=2:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-cpu-${SLURM_JOB_ID}" mkdir -p "$OUT" cd "$ROOT" diff --git a/slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch b/slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch index 644620b..57bb086 100644 --- a/slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch +++ b/slurm/benchmark_vdjdb_irrm_cpu_fixed.sbatch @@ -6,7 +6,7 @@ #SBATCH --mem=32G #SBATCH --time=2:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-cpu-${SLURM_JOB_ID}" mkdir -p "$OUT" cd "$ROOT" diff --git a/slurm/benchmark_vdjdb_irrm_gpu.sbatch b/slurm/benchmark_vdjdb_irrm_gpu.sbatch index dd5f669..76931a9 100644 --- a/slurm/benchmark_vdjdb_irrm_gpu.sbatch +++ b/slurm/benchmark_vdjdb_irrm_gpu.sbatch @@ -8,7 +8,7 @@ #SBATCH --time=2:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-gpu-${SLURM_JOB_ID}" mkdir -p "$OUT" cd "$ROOT" diff --git a/slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch b/slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch index deee79e..2836eba 100644 --- a/slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch +++ b/slurm/benchmark_vdjdb_irrm_gpu_fixed.sbatch @@ -7,7 +7,7 @@ #SBATCH --mem=32G #SBATCH --time=2:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/irrm-gpu-${SLURM_JOB_ID}" mkdir -p "$OUT" cd "$ROOT" diff --git a/slurm/benchmark_vdjdb_tcremp_runtime.sbatch b/slurm/benchmark_vdjdb_tcremp_runtime.sbatch index d22a274..abe1cff 100644 --- a/slurm/benchmark_vdjdb_tcremp_runtime.sbatch +++ b/slurm/benchmark_vdjdb_tcremp_runtime.sbatch @@ -9,7 +9,7 @@ set -euo pipefail THREADS="${1:?Pass the requested TCRemP worker count (1 or 16)}" case "$THREADS" in 1|16) ;; *) echo "threads must be 1 or 16" >&2; exit 2;; esac -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb-runtime-benchmark/tcremp-${THREADS}cpu-${SLURM_JOB_ID}" TCREMP_ROOT=/home/evlasova/tcremp-git/tcremp PYTHON=/home/evlasova/.conda/envs/vdjdb-redcea/bin/python diff --git a/slurm/cache_author_global_embeddings.sbatch b/slurm/cache_author_global_embeddings.sbatch index 876a9f7..075ff14 100644 --- a/slurm/cache_author_global_embeddings.sbatch +++ b/slurm/cache_author_global_embeddings.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/cache-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-global-author-v1" RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" diff --git a/slurm/cache_author_global_sceptr_cdr3.sbatch b/slurm/cache_author_global_sceptr_cdr3.sbatch index 8bcda81..0b19c3b 100644 --- a/slurm/cache_author_global_sceptr_cdr3.sbatch +++ b/slurm/cache_author_global_sceptr_cdr3.sbatch @@ -10,7 +10,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/sceptr-cdr3-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-global-author-v1" RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" diff --git a/slurm/cache_external_model_embeddings.sbatch b/slurm/cache_external_model_embeddings.sbatch index cefc4b9..9ef52ae 100644 --- a/slurm/cache_external_model_embeddings.sbatch +++ b/slurm/cache_external_model_embeddings.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/cache-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" COHORT="$REPO/experiments/trb/external-model-benchmark/cohort" diff --git a/slurm/cache_external_residue_embeddings.sbatch b/slurm/cache_external_residue_embeddings.sbatch index 745d802..3180f62 100644 --- a/slurm/cache_external_residue_embeddings.sbatch +++ b/slurm/cache_external_residue_embeddings.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/cache-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-v1" diff --git a/slurm/collect_author_global_comparison.sbatch b/slurm/collect_author_global_comparison.sbatch index a3754bc..b79e414 100644 --- a/slurm/collect_author_global_comparison.sbatch +++ b/slurm/collect_author_global_comparison.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/final-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python OLD="$REPO/experiments/trb/external-model-benchmark" BASE="$REPO/experiments/trb/external-global-author-v1" diff --git a/slurm/collect_external_model_benchmark.sbatch b/slurm/collect_external_model_benchmark.sbatch index eaa6754..06a1ded 100644 --- a/slurm/collect_external_model_benchmark.sbatch +++ b/slurm/collect_external_model_benchmark.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/collect-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/collect_external_pca256_pgen.sbatch b/slurm/collect_external_pca256_pgen.sbatch index be60e06..b1e8596 100644 --- a/slurm/collect_external_pca256_pgen.sbatch +++ b/slurm/collect_external_pca256_pgen.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pgen-summary-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca256-v1" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/collect_external_pca256_reconstruction.sbatch b/slurm/collect_external_pca256_reconstruction.sbatch index 55bf223..d4c9cdb 100644 --- a/slurm/collect_external_pca256_reconstruction.sbatch +++ b/slurm/collect_external_pca256_reconstruction.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-summary-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca256-v1" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/collect_external_residue_benchmark.sbatch b/slurm/collect_external_residue_benchmark.sbatch index ac789f5..a0c4636 100644 --- a/slurm/collect_external_residue_benchmark.sbatch +++ b/slurm/collect_external_residue_benchmark.sbatch @@ -9,7 +9,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/collect-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/residue-v1" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/collect_external_residue_pca128_all.sbatch b/slurm/collect_external_residue_pca128_all.sbatch index 28416c2..6fbc049 100644 --- a/slurm/collect_external_residue_pca128_all.sbatch +++ b/slurm/collect_external_residue_pca128_all.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/summary-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca128-v1" diff --git a/slurm/collect_external_rtp128_reconstruction.sbatch b/slurm/collect_external_rtp128_reconstruction.sbatch index f5a86c8..c739dcf 100644 --- a/slurm/collect_external_rtp128_reconstruction.sbatch +++ b/slurm/collect_external_rtp128_reconstruction.sbatch @@ -9,7 +9,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/summary-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/native-rtp128-v1" diff --git a/slurm/collect_external_sceptr_pca128.sbatch b/slurm/collect_external_sceptr_pca128.sbatch index 302c72b..6f9c995 100644 --- a/slurm/collect_external_sceptr_pca128.sbatch +++ b/slurm/collect_external_sceptr_pca128.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/summary-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/evaluate_latent_secondary.sbatch b/slurm/evaluate_latent_secondary.sbatch index 940e074..cbed559 100644 --- a/slurm/evaluate_latent_secondary.sbatch +++ b/slurm/evaluate_latent_secondary.sbatch @@ -5,13 +5,13 @@ #SBATCH --cpus-per-task=32 #SBATCH --mem=128G #SBATCH --time=16:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/latent-secondary/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/latent-secondary/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail MODE="${1:?mode must be preflight or evaluate}" PREFLIGHT_ROOT="${2:-}" -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" BASE="$ROOT/experiments/trb/latent-secondary" OUTPUT="$BASE/${MODE}-${SLURM_JOB_ID}" DATA="$ROOT/data/benchmark/trb" diff --git a/slurm/evaluate_latent_sufficiency.sbatch b/slurm/evaluate_latent_sufficiency.sbatch index 9ae6551..2fff4b4 100644 --- a/slurm/evaluate_latent_sufficiency.sbatch +++ b/slurm/evaluate_latent_sufficiency.sbatch @@ -5,11 +5,11 @@ #SBATCH --cpus-per-task=32 #SBATCH --mem=192G #SBATCH --time=16:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/latent-sufficiency/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/latent-sufficiency/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" BASE="$ROOT/experiments/trb/latent-sufficiency" OUTPUT="$BASE/evaluation-${SLURM_JOB_ID}" DATA="$ROOT/data/benchmark/trb" diff --git a/slurm/evaluate_rtp_data_anchor_length_errors.sbatch b/slurm/evaluate_rtp_data_anchor_length_errors.sbatch index 7417e60..94d1e13 100644 --- a/slurm/evaluate_rtp_data_anchor_length_errors.sbatch +++ b/slurm/evaluate_rtp_data_anchor_length_errors.sbatch @@ -6,16 +6,16 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=04:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-length-errors-$SLURM_JOB_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/evaluate_rtp_data_anchor_position_errors.sbatch b/slurm/evaluate_rtp_data_anchor_position_errors.sbatch index 5da2eb7..c42323c 100644 --- a/slurm/evaluate_rtp_data_anchor_position_errors.sbatch +++ b/slurm/evaluate_rtp_data_anchor_position_errors.sbatch @@ -6,16 +6,16 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=04:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-position-errors-$SLURM_JOB_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/evaluate_rtp_data_anchor_substitutions.sbatch b/slurm/evaluate_rtp_data_anchor_substitutions.sbatch index 61e6954..670c803 100644 --- a/slurm/evaluate_rtp_data_anchor_substitutions.sbatch +++ b/slurm/evaluate_rtp_data_anchor_substitutions.sbatch @@ -6,17 +6,17 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=04:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-substitutions-$SLURM_JOB_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch b/slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch index e1b4ffd..8959f3a 100644 --- a/slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch +++ b/slurm/evaluate_rtp_data_anchor_substitutions_v2.sbatch @@ -6,17 +6,17 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=04:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" CHECKPOINT="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" OUTPUT_DIR="$ROOT_DIR/experiments/trb/rtp-data-anchor-substitutions-$SLURM_JOB_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/evaluate_rtp_error_analysis.sbatch b/slurm/evaluate_rtp_error_analysis.sbatch index 8a634c4..762a559 100644 --- a/slurm/evaluate_rtp_error_analysis.sbatch +++ b/slurm/evaluate_rtp_error_analysis.sbatch @@ -6,9 +6,9 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=04:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR=/home/evlasova/irrm-codec +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" cd "$ROOT_DIR"; export PYTHONPATH="$ROOT_DIR${PYTHONPATH:+:$PYTHONPATH}" /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_rtp_error_analysis.py --data-dir "$ROOT_DIR/data/benchmark/trb" --tokenizer "$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" --checkpoint "$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/best.pt" --output-dir "$ROOT_DIR/experiments/trb/rtp-data-anchor-error-analysis-$SLURM_JOB_ID" --batch-size 64 --num-workers 8 --device cuda diff --git a/slurm/evaluate_single_aa_challenge.sbatch b/slurm/evaluate_single_aa_challenge.sbatch index ddd32e8..10d440d 100644 --- a/slurm/evaluate_single_aa_challenge.sbatch +++ b/slurm/evaluate_single_aa_challenge.sbatch @@ -5,12 +5,12 @@ #SBATCH --cpus-per-task=32 #SBATCH --mem=192G #SBATCH --time=16:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail TARGET_ROOT="${1:?Validated target job directory required}" -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" BASE="$ROOT/experiments/trb/single-aa-challenge" OUT="$BASE/evaluation-${SLURM_JOB_ID}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python diff --git a/slurm/evaluate_tcremp_geometry_biology.sbatch b/slurm/evaluate_tcremp_geometry_biology.sbatch index 1200e62..f8f1cf8 100644 --- a/slurm/evaluate_tcremp_geometry_biology.sbatch +++ b/slurm/evaluate_tcremp_geometry_biology.sbatch @@ -6,12 +6,12 @@ #SBATCH --cpus-per-task=16 #SBATCH --mem=64G #SBATCH --time=16:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail VARIANT="${1:?Variant centered or relational required}" case "$VARIANT" in centered|relational) ;; *) exit 2 ;; esac -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" MODEL="$ROOT/experiments/trb/tcremp-geometry-t-${VARIANT}-seed42" OUT="$ROOT/experiments/trb/vdjdb-tcremp-geometry-${VARIANT}-${SLURM_JOB_ID}" COHORT="$ROOT/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" diff --git a/slurm/evaluate_vdjdb_author_global.sbatch b/slurm/evaluate_vdjdb_author_global.sbatch index b290746..6df8a01 100644 --- a/slurm/evaluate_vdjdb_author_global.sbatch +++ b/slurm/evaluate_vdjdb_author_global.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/vdjdb-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-global-author-v1" COHORT="$REPO/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" diff --git a/slurm/evaluate_vdjdb_decoded_tcremp.sbatch b/slurm/evaluate_vdjdb_decoded_tcremp.sbatch index 4bd87ee..a612a96 100644 --- a/slurm/evaluate_vdjdb_decoded_tcremp.sbatch +++ b/slurm/evaluate_vdjdb_decoded_tcremp.sbatch @@ -7,7 +7,7 @@ #SBATCH --time=16:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb_decoded_tcremp/${SLURM_JOB_ID}" cd "$ROOT" PYTHONPATH="$ROOT" /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_vdjdb_decoded_tcremp.py \ diff --git a/slurm/evaluate_vdjdb_epitope_prediction.sbatch b/slurm/evaluate_vdjdb_epitope_prediction.sbatch index 179a6ee..3e6f023 100644 --- a/slurm/evaluate_vdjdb_epitope_prediction.sbatch +++ b/slurm/evaluate_vdjdb_epitope_prediction.sbatch @@ -9,7 +9,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/epitope-prediction-v1/logs/run-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/epitope-prediction-v1" COHORT="$REPO/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" diff --git a/slurm/evaluate_vdjdb_frozen.sbatch b/slurm/evaluate_vdjdb_frozen.sbatch index bf92e2d..743a604 100644 --- a/slurm/evaluate_vdjdb_frozen.sbatch +++ b/slurm/evaluate_vdjdb_frozen.sbatch @@ -5,16 +5,16 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=64G #SBATCH --time=08:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" VALIDATION_ROOT="$ROOT_DIR/experiments/trb/vdjdb-data-anchor-validation" COHORT_DIR="$VALIDATION_ROOT/cohort-preflight-1426341" OUTPUT_DIR="$VALIDATION_ROOT/evaluation-${SLURM_JOB_ID}" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" for condition in r p rp; do diff --git a/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch b/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch index 92aa85c..181bf9e 100644 --- a/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch +++ b/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch @@ -5,12 +5,12 @@ #SBATCH --cpus-per-task=32 #SBATCH --mem=128G #SBATCH --time=16:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail PREFLIGHT_ROOT="${1:?Preflight job directory is required}" -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" BASE="$ROOT/experiments/trb/vdjdb-redcea-clonotypes" OUTPUT="$BASE/evaluation-${SLURM_JOB_ID}" TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" diff --git a/slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch b/slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch index dcbde96..c04c729 100644 --- a/slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch +++ b/slurm/evaluate_vdjdb_tonly_decoded_tcremp.sbatch @@ -6,7 +6,7 @@ #SBATCH --mem=64G #SBATCH --time=16:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb_tonly_decoded_tcremp/${SLURM_JOB_ID}" cd "$ROOT" PYTHONPATH="$ROOT" /home/evlasova/.conda/envs/irrm-codec/bin/python benchmark/evaluate_vdjdb_decoded_tcremp.py \ diff --git a/slurm/evaluate_vdjdb_uniform100_tcremp.sbatch b/slurm/evaluate_vdjdb_uniform100_tcremp.sbatch index b963e67..b7993da 100644 --- a/slurm/evaluate_vdjdb_uniform100_tcremp.sbatch +++ b/slurm/evaluate_vdjdb_uniform100_tcremp.sbatch @@ -7,7 +7,7 @@ #SBATCH --time=16:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-${SLURM_JOB_ID}" COHORT="$ROOT/experiments/trb/vdjdb-redcea-clonotypes/preflight-1426719/cohort/cohort.tsv" PAIRS="$ROOT/experiments/trb/vdjdb-uniform100-v1/evaluation-1427813/uniform_pairs.npz" diff --git a/slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch b/slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch index e1b1c55..2df132b 100644 --- a/slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch +++ b/slurm/evaluate_vdjdb_uniform100_tcremp_pca128.sbatch @@ -7,7 +7,7 @@ #SBATCH --time=16:00:00 set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/vdjdb-uniform100-v1/tcremp-pca128-${SLURM_JOB_ID}" TRAIN_DATA="$ROOT/experiments/trb/external-model-benchmark/cohort" TRAIN_TCREMP="$TRAIN_DATA/representations/tcremp.npy" diff --git a/slurm/evaluate_vdjdb_viral_motif_top10.sbatch b/slurm/evaluate_vdjdb_viral_motif_top10.sbatch index 7e345c3..51de588 100644 --- a/slurm/evaluate_vdjdb_viral_motif_top10.sbatch +++ b/slurm/evaluate_vdjdb_viral_motif_top10.sbatch @@ -5,12 +5,12 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=64G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail PREFLIGHT_DIR="${1:?Top-10 preflight directory is required}" -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUTPUT="$ROOT/experiments/trb/vdjdb-viral-motif-top10/evaluation-${SLURM_JOB_ID}" TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" diff --git a/slurm/evaluate_vdjdb_ylq_frozen.sbatch b/slurm/evaluate_vdjdb_ylq_frozen.sbatch index 268dcf0..49fa542 100644 --- a/slurm/evaluate_vdjdb_ylq_frozen.sbatch +++ b/slurm/evaluate_vdjdb_ylq_frozen.sbatch @@ -5,12 +5,12 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=64G #SBATCH --time=08:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail PREFLIGHT_DIR="${1:?YLQ preflight directory is required}" -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-data-anchor-validation/evaluation-${SLURM_JOB_ID}" TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" diff --git a/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch b/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch index cb51dfa..eab1504 100644 --- a/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch +++ b/slurm/evaluate_vdjdb_ylq_motif_pooled.sbatch @@ -5,12 +5,12 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=64G #SBATCH --time=08:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail PREFLIGHT_DIR="${1:?Official-motif pooled preflight directory is required}" -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-official-motif-pooled/evaluation-${SLURM_JOB_ID}" TOKENIZER="$ROOT/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" diff --git a/slurm/finalize_external_residue_pca128_all.sbatch b/slurm/finalize_external_residue_pca128_all.sbatch index bb22016..538ccc4 100644 --- a/slurm/finalize_external_residue_pca128_all.sbatch +++ b/slurm/finalize_external_residue_pca128_all.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/gate-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca128-v1" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/finalize_external_residue_pca256.sbatch b/slurm/finalize_external_residue_pca256.sbatch index ee75687..c49abf6 100644 --- a/slurm/finalize_external_residue_pca256.sbatch +++ b/slurm/finalize_external_residue_pca256.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/finalize-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca256-v1" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/finalize_external_sceptr_pca128.sbatch b/slurm/finalize_external_sceptr_pca128.sbatch index c2cf9fb..6c1830e 100644 --- a/slurm/finalize_external_sceptr_pca128.sbatch +++ b/slurm/finalize_external_sceptr_pca128.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/gate-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/finalize_vdjdb_epitope_prediction.sbatch b/slurm/finalize_vdjdb_epitope_prediction.sbatch index 9782b12..d6d55a1 100644 --- a/slurm/finalize_vdjdb_epitope_prediction.sbatch +++ b/slurm/finalize_vdjdb_epitope_prediction.sbatch @@ -9,7 +9,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/epitope-prediction-v1/logs/finalize-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python OUT="${EPITOPE_PREDICTION_OUT:-$REPO/experiments/trb/epitope-prediction-v1/evaluation-1429982}" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/fit_author_global_bottleneck.sbatch b/slurm/fit_author_global_bottleneck.sbatch index 90c3eb6..982211b 100644 --- a/slurm/fit_author_global_bottleneck.sbatch +++ b/slurm/fit_author_global_bottleneck.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pca-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python OLD="$REPO/experiments/trb/external-model-benchmark" BASE="$REPO/experiments/trb/external-global-author-v1" diff --git a/slurm/fit_external_model_bottleneck.sbatch b/slurm/fit_external_model_bottleneck.sbatch index cb833b5..629b999 100644 --- a/slurm/fit_external_model_bottleneck.sbatch +++ b/slurm/fit_external_model_bottleneck.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/pca-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark" COHORT="$ROOT/cohort" diff --git a/slurm/fit_external_residue_pca128_all.sbatch b/slurm/fit_external_residue_pca128_all.sbatch index 09e8c5e..c29f50f 100644 --- a/slurm/fit_external_residue_pca128_all.sbatch +++ b/slurm/fit_external_residue_pca128_all.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/pca-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca128-v1" diff --git a/slurm/fit_external_residue_pca256.sbatch b/slurm/fit_external_residue_pca256.sbatch index afc255d..dccd9a0 100644 --- a/slurm/fit_external_residue_pca256.sbatch +++ b/slurm/fit_external_residue_pca256.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pca-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca256-v1" diff --git a/slurm/fit_external_sceptr_pca128.sbatch b/slurm/fit_external_sceptr_pca128.sbatch index 7ee5dd5..1bfc27e 100644 --- a/slurm/fit_external_sceptr_pca128.sbatch +++ b/slurm/fit_external_sceptr_pca128.sbatch @@ -10,7 +10,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/pca-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca128-sceptr-v1" diff --git a/slurm/install_external_benchmark_runtime.sbatch b/slurm/install_external_benchmark_runtime.sbatch index e78f6cb..c949951 100644 --- a/slurm/install_external_benchmark_runtime.sbatch +++ b/slurm/install_external_benchmark_runtime.sbatch @@ -9,7 +9,7 @@ set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark/runtime-v2" SITE="$ROOT/site-packages" diff --git a/slurm/install_wordpiece_dependency.sbatch b/slurm/install_wordpiece_dependency.sbatch index c4fb239..16029c5 100644 --- a/slurm/install_wordpiece_dependency.sbatch +++ b/slurm/install_wordpiece_dependency.sbatch @@ -5,10 +5,10 @@ #SBATCH --cpus-per-task=1 #SBATCH --mem=4G #SBATCH --time=00:20:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" "$PYTHON_BIN" -m pip install --disable-pip-version-check "tokenizers==0.23.1" "$PYTHON_BIN" -c 'import tokenizers; assert tokenizers.__version__ == "0.23.1"; print(tokenizers.__version__)' diff --git a/slurm/preflight_author_global_embeddings.sbatch b/slurm/preflight_author_global_embeddings.sbatch index 01f9b17..6fb6631 100644 --- a/slurm/preflight_author_global_embeddings.sbatch +++ b/slurm/preflight_author_global_embeddings.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/preflight-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-global-author-v1" RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" diff --git a/slurm/preflight_data_anchor_factorial.sbatch b/slurm/preflight_data_anchor_factorial.sbatch index f753c8d..644bf26 100644 --- a/slurm/preflight_data_anchor_factorial.sbatch +++ b/slurm/preflight_data_anchor_factorial.sbatch @@ -5,16 +5,16 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/data-anchor-full-factorial-gate/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/data-anchor-full-factorial-gate/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" REFERENCE="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/run_config.json" OUTPUT_ROOT="$ROOT_DIR/experiments/trb/data-anchor-full-factorial-gate" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/preflight_data_anchor_objectives.sbatch b/slurm/preflight_data_anchor_objectives.sbatch index 3ec90c4..3e02ac1 100644 --- a/slurm/preflight_data_anchor_objectives.sbatch +++ b/slurm/preflight_data_anchor_objectives.sbatch @@ -5,16 +5,16 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/data-anchor-objective-matrix/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/data-anchor-objective-matrix/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" REFERENCE="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42/run_config.json" OUTPUT_ROOT="$ROOT_DIR/experiments/trb/data-anchor-objective-matrix" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/preflight_external_model_benchmark.sbatch b/slurm/preflight_external_model_benchmark.sbatch index 95f13d5..12e36f4 100644 --- a/slurm/preflight_external_model_benchmark.sbatch +++ b/slurm/preflight_external_model_benchmark.sbatch @@ -9,7 +9,7 @@ set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python DATASET="$REPO/data/benchmark/trb" RTP="$REPO/experiments/trb/latent-sufficiency/evaluation-1426737/embeddings_rtp.npy" diff --git a/slurm/preflight_external_residue_benchmark.sbatch b/slurm/preflight_external_residue_benchmark.sbatch index bc6845b..673fe1a 100644 --- a/slurm/preflight_external_residue_benchmark.sbatch +++ b/slurm/preflight_external_residue_benchmark.sbatch @@ -9,7 +9,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/preflight-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-v1" diff --git a/slurm/preflight_external_residue_pca128_all.sbatch b/slurm/preflight_external_residue_pca128_all.sbatch index 701a6fd..8a822c2 100644 --- a/slurm/preflight_external_residue_pca128_all.sbatch +++ b/slurm/preflight_external_residue_pca128_all.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/preflight-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca128-v1" diff --git a/slurm/preflight_external_rtp128_reconstruction.sbatch b/slurm/preflight_external_rtp128_reconstruction.sbatch index f71ca2b..6b84b62 100644 --- a/slurm/preflight_external_rtp128_reconstruction.sbatch +++ b/slurm/preflight_external_rtp128_reconstruction.sbatch @@ -9,7 +9,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/preflight-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/native-rtp128-v1" diff --git a/slurm/preflight_external_sceptr_pca128.sbatch b/slurm/preflight_external_sceptr_pca128.sbatch index 491f13f..160a8a4 100644 --- a/slurm/preflight_external_sceptr_pca128.sbatch +++ b/slurm/preflight_external_sceptr_pca128.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/preflight-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca128-sceptr-v1" diff --git a/slurm/preflight_phase1_rq1.sbatch b/slurm/preflight_phase1_rq1.sbatch index 9b21d16..7277147 100644 --- a/slurm/preflight_phase1_rq1.sbatch +++ b/slurm/preflight_phase1_rq1.sbatch @@ -10,7 +10,7 @@ set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" cd "$ROOT_DIR" export PYTHONPATH="$ROOT_DIR${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/preflight_rq5_depths.sbatch b/slurm/preflight_rq5_depths.sbatch index 75ea2d3..76eff19 100644 --- a/slurm/preflight_rq5_depths.sbatch +++ b/slurm/preflight_rq5_depths.sbatch @@ -9,8 +9,8 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-depths-seed42/preflight-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" cd "$ROOT_DIR" "$PYTHON_BIN" -m scripts.preflight_rq5_depths \ --baseline-run-config "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-seed42/run_config.json" \ diff --git a/slurm/preflight_rq5_widths.sbatch b/slurm/preflight_rq5_widths.sbatch index 4767e3f..b878e2a 100644 --- a/slurm/preflight_rq5_widths.sbatch +++ b/slurm/preflight_rq5_widths.sbatch @@ -9,8 +9,8 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-widths-seed42/preflight-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" cd "$ROOT_DIR" "$PYTHON_BIN" -m scripts.preflight_rq5_widths \ --baseline-run-config "$ROOT_DIR/experiments/trb/rq1-char-rtp-seed42/run_config.json" \ diff --git a/slurm/preflight_single_aa_challenge.sbatch b/slurm/preflight_single_aa_challenge.sbatch index 61c8beb..c7051e3 100644 --- a/slurm/preflight_single_aa_challenge.sbatch +++ b/slurm/preflight_single_aa_challenge.sbatch @@ -5,11 +5,11 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" BASE="$ROOT/experiments/trb/single-aa-challenge" OUT="$BASE/preflight-${SLURM_JOB_ID}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python diff --git a/slurm/preflight_vdjdb_epitope.sbatch b/slurm/preflight_vdjdb_epitope.sbatch index 9caa497..560de05 100644 --- a/slurm/preflight_vdjdb_epitope.sbatch +++ b/slurm/preflight_vdjdb_epitope.sbatch @@ -5,18 +5,18 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUTPUT_ROOT="$ROOT_DIR/experiments/trb/vdjdb-data-anchor-validation" OUTPUT_DIR="$OUTPUT_ROOT/cohort-preflight-${SLURM_JOB_ID}" VDJDB_SOURCE="/projects/immunestatus/vdjdb/vdjdb-2025-07-30/vdjdb.txt" BENCHMARK_DIR="$ROOT_DIR/data/benchmark/trb" EXPERIMENT_DIR="$ROOT_DIR/experiments/trb/anchor-data-rtp-seed42" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$VDJDB_SOURCE" diff --git a/slurm/preflight_vdjdb_evaluation.sbatch b/slurm/preflight_vdjdb_evaluation.sbatch index 316db21..77762bf 100644 --- a/slurm/preflight_vdjdb_evaluation.sbatch +++ b/slurm/preflight_vdjdb_evaluation.sbatch @@ -5,14 +5,14 @@ #SBATCH --cpus-per-task=4 #SBATCH --mem=16G #SBATCH --time=01:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-data-anchor-validation/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" VALIDATION_ROOT="$ROOT_DIR/experiments/trb/vdjdb-data-anchor-validation" COHORT_DIR="$VALIDATION_ROOT/cohort-preflight-1426341" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" OUTPUT="$VALIDATION_ROOT/evaluation-code-preflight-${SLURM_JOB_ID}.json" test -x "$PYTHON_BIN" diff --git a/slurm/prepare_anchored_tokenizers.sbatch b/slurm/prepare_anchored_tokenizers.sbatch index 68722a5..29f3983 100644 --- a/slurm/prepare_anchored_tokenizers.sbatch +++ b/slurm/prepare_anchored_tokenizers.sbatch @@ -5,15 +5,15 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=64G #SBATCH --time=08:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/anchored-seed42/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/anchored-seed42/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42" SOURCE_ROOT="/projects/immunestatus/vdjrearm" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/prepare_external_model_cohort.sbatch b/slurm/prepare_external_model_cohort.sbatch index 133121a..178de9d 100644 --- a/slurm/prepare_external_model_cohort.sbatch +++ b/slurm/prepare_external_model_cohort.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/cohort-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" SOURCE="$REPO/data/benchmark/trb" diff --git a/slurm/prepare_single_aa_challenge.sbatch b/slurm/prepare_single_aa_challenge.sbatch index 9f39915..5a30f71 100644 --- a/slurm/prepare_single_aa_challenge.sbatch +++ b/slurm/prepare_single_aa_challenge.sbatch @@ -5,12 +5,12 @@ #SBATCH --cpus-per-task=32 #SBATCH --mem=96G #SBATCH --time=16:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/single-aa-challenge/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail PREFLIGHT="${1:?Accepted preflight directory required}" -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" BASE="$ROOT/experiments/trb/single-aa-challenge" OUT="$BASE/targets-${SLURM_JOB_ID}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python diff --git a/slurm/prepare_trb_joint.sbatch b/slurm/prepare_trb_joint.sbatch index 7fbdc23..9292356 100644 --- a/slurm/prepare_trb_joint.sbatch +++ b/slurm/prepare_trb_joint.sbatch @@ -10,7 +10,7 @@ set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUTPUT_DIR="$ROOT_DIR/data/benchmark/trb" cd "$ROOT_DIR" diff --git a/slurm/prepare_vdjdb_redcea_clonotypes.sbatch b/slurm/prepare_vdjdb_redcea_clonotypes.sbatch index 255c61d..4d498cf 100644 --- a/slurm/prepare_vdjdb_redcea_clonotypes.sbatch +++ b/slurm/prepare_vdjdb_redcea_clonotypes.sbatch @@ -5,11 +5,11 @@ #SBATCH --cpus-per-task=4 #SBATCH --mem=16G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" BASE="$ROOT/experiments/trb/vdjdb-redcea-clonotypes" OUTPUT="$BASE/preflight-${SLURM_JOB_ID}" SOURCE="$OUTPUT/cluster_members_TRB.txt" diff --git a/slurm/prepare_vdjdb_viral_motif_top10.sbatch b/slurm/prepare_vdjdb_viral_motif_top10.sbatch index 5d8ffdf..10065a7 100644 --- a/slurm/prepare_vdjdb_viral_motif_top10.sbatch +++ b/slurm/prepare_vdjdb_viral_motif_top10.sbatch @@ -5,12 +5,12 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail MODE="${1:-prepare}" -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" SNAPSHOT="/projects/immunestatus/vdjdb/vdjdb-2025-07-30" OUTPUT="$ROOT/experiments/trb/vdjdb-viral-motif-top10/${MODE}-${SLURM_JOB_ID}" SPECIES="$ROOT/benchmark/viral_antigen_species_2025_07_30.txt" diff --git a/slurm/prepare_vdjdb_ylq.sbatch b/slurm/prepare_vdjdb_ylq.sbatch index 0a24613..f01d7fa 100644 --- a/slurm/prepare_vdjdb_ylq.sbatch +++ b/slurm/prepare_vdjdb_ylq.sbatch @@ -5,11 +5,11 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-data-anchor-validation/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-data-anchor-validation/preflight-${SLURM_JOB_ID}" PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" mkdir -p "$ROOT/experiments/trb/vdjdb-ylq-data-anchor-validation" diff --git a/slurm/prepare_vdjdb_ylq_motif_pooled.sbatch b/slurm/prepare_vdjdb_ylq_motif_pooled.sbatch index e821345..43dcde5 100644 --- a/slurm/prepare_vdjdb_ylq_motif_pooled.sbatch +++ b/slurm/prepare_vdjdb_ylq_motif_pooled.sbatch @@ -5,11 +5,11 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/vdjdb-ylq-official-motif-pooled/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT="/home/evlasova/irrm-codec" +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" SNAPSHOT="/projects/immunestatus/vdjdb/vdjdb-2025-07-30" OUTPUT="$ROOT/experiments/trb/vdjdb-ylq-official-motif-pooled/preflight-${SLURM_JOB_ID}" PYTHON="/home/evlasova/.conda/envs/irrm-codec/bin/python" diff --git a/slurm/prepare_wordpiece_rq4.sbatch b/slurm/prepare_wordpiece_rq4.sbatch index 6ec7cee..dcc3959 100644 --- a/slurm/prepare_wordpiece_rq4.sbatch +++ b/slurm/prepare_wordpiece_rq4.sbatch @@ -5,14 +5,14 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=01:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-seed42/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER_DIR="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-seed42" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$DATA_DIR/READY.json" test ! -e "$TOKENIZER_DIR/tokenizer.json" diff --git a/slurm/prepare_wordpiece_sweep.sbatch b/slurm/prepare_wordpiece_sweep.sbatch index eb63c9e..613bfeb 100644 --- a/slurm/prepare_wordpiece_sweep.sbatch +++ b/slurm/prepare_wordpiece_sweep.sbatch @@ -5,14 +5,14 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=32G #SBATCH --time=02:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-sweep-seed42/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/tokenizers/wordpiece-sweep-seed42/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-sweep-seed42" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$DATA_DIR/READY.json" test ! -e "$TOKENIZER_ROOT/sweep_manifest.json" diff --git a/slurm/smoke_tcremp_geometry_loss.sbatch b/slurm/smoke_tcremp_geometry_loss.sbatch index 3a9ccc6..0b7ef9b 100644 --- a/slurm/smoke_tcremp_geometry_loss.sbatch +++ b/slurm/smoke_tcremp_geometry_loss.sbatch @@ -6,10 +6,10 @@ #SBATCH --cpus-per-task=4 #SBATCH --mem=32G #SBATCH --time=00:30:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/tcremp-geometry-smoke-${SLURM_JOB_ID}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python cd "$ROOT" diff --git a/slurm/train_anchored_tokenizer.sbatch b/slurm/train_anchored_tokenizer.sbatch index 728bb29..177c06e 100644 --- a/slurm/train_anchored_tokenizer.sbatch +++ b/slurm/train_anchored_tokenizer.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail KIND="${1:?Tokenizer kind is required}" @@ -16,11 +16,11 @@ case "$KIND" in *) echo "Refusing unregistered anchored tokenizer" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42" TOKENIZER_PATH="$TOKENIZER_ROOT/$KIND/anchored_tokenizer.json" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" case "$KIND" in edge_k) EXPERIMENT_ID="anchor-edge3-rtp-seed42" ;; data_anchor) EXPERIMENT_ID="anchor-data-rtp-seed42" ;; diff --git a/slurm/train_author_global_onehot_fixed.sbatch b/slurm/train_author_global_onehot_fixed.sbatch index a5499ad..feb9f9c 100644 --- a/slurm/train_author_global_onehot_fixed.sbatch +++ b/slurm/train_author_global_onehot_fixed.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-onehot-fixed-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python OLD="$REPO/experiments/trb/external-model-benchmark" BASE="$REPO/experiments/trb/external-global-author-v1" diff --git a/slurm/train_author_global_pgen.sbatch b/slurm/train_author_global_pgen.sbatch index be973cb..9d08180 100644 --- a/slurm/train_author_global_pgen.sbatch +++ b/slurm/train_author_global_pgen.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python OLD="$REPO/experiments/trb/external-model-benchmark" BASE="$REPO/experiments/trb/external-global-author-v1" diff --git a/slurm/train_author_global_pgen_controls.sbatch b/slurm/train_author_global_pgen_controls.sbatch index a1078ec..8ccf296 100644 --- a/slurm/train_author_global_pgen_controls.sbatch +++ b/slurm/train_author_global_pgen_controls.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/pgen-controls-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python OLD="$REPO/experiments/trb/external-model-benchmark" BASE="$REPO/experiments/trb/external-global-author-v1" diff --git a/slurm/train_author_global_reconstruction.sbatch b/slurm/train_author_global_reconstruction.sbatch index 6964911..58c02fa 100644 --- a/slurm/train_author_global_reconstruction.sbatch +++ b/slurm/train_author_global_reconstruction.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/logs/recon-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python OLD="$REPO/experiments/trb/external-model-benchmark" BASE="$REPO/experiments/trb/external-global-author-v1" diff --git a/slurm/train_data_anchor_objective.sbatch b/slurm/train_data_anchor_objective.sbatch index 11faf10..980f30a 100644 --- a/slurm/train_data_anchor_objective.sbatch +++ b/slurm/train_data_anchor_objective.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail CONDITION="${1:?Condition t, rt, or tp is required}" @@ -18,14 +18,14 @@ case "$CONDITION" in *) echo "Refusing unregistered DATA-ANCHOR objective condition" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER="$ROOT_DIR/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json" MATRIX_ROOT="$ROOT_DIR/experiments/trb/data-anchor-full-factorial-gate" PREFLIGHT="$MATRIX_ROOT/PREFLIGHT.json" CONDITION_CONFIG="$MATRIX_ROOT/configs/$CONDITION.json" OUTPUT_DIR="$ROOT_DIR/experiments/trb/data-anchor-$CONDITION-seed42" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -x "$PYTHON_BIN" test -f "$DATA_DIR/READY.json" diff --git a/slurm/train_external_pca256_pgen.sbatch b/slurm/train_external_pca256_pgen.sbatch index e8cf0b9..061059b 100644 --- a/slurm/train_external_pca256_pgen.sbatch +++ b/slurm/train_external_pca256_pgen.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/pgen-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca256-v1" diff --git a/slurm/train_external_pca256_reconstruction.sbatch b/slurm/train_external_pca256_reconstruction.sbatch index 2aeb97b..7a78ecb 100644 --- a/slurm/train_external_pca256_reconstruction.sbatch +++ b/slurm/train_external_pca256_reconstruction.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca256-v1" diff --git a/slurm/train_external_pca256_sceptr_reconstruction.sbatch b/slurm/train_external_pca256_sceptr_reconstruction.sbatch index 0d100d1..c16c479 100644 --- a/slurm/train_external_pca256_sceptr_reconstruction.sbatch +++ b/slurm/train_external_pca256_sceptr_reconstruction.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca256-v1/logs/recon-sceptr-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca256-v1" diff --git a/slurm/train_external_pgen.sbatch b/slurm/train_external_pgen.sbatch index 51cc1e9..52d8eb9 100644 --- a/slurm/train_external_pgen.sbatch +++ b/slurm/train_external_pgen.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/pgen-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark" ARMS=(sceptr_mlp tcr_bert_mlp esm2_8m_mlp rtp_mlp) diff --git a/slurm/train_external_pgen_tfidf.sbatch b/slurm/train_external_pgen_tfidf.sbatch index df70ac4..37fdfc0 100644 --- a/slurm/train_external_pgen_tfidf.sbatch +++ b/slurm/train_external_pgen_tfidf.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/tfidf-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark" export PYTHONPATH="$REPO${PYTHONPATH:+:$PYTHONPATH}" diff --git a/slurm/train_external_reconstruction.sbatch b/slurm/train_external_reconstruction.sbatch index 940a6e7..8d6f093 100644 --- a/slurm/train_external_reconstruction.sbatch +++ b/slurm/train_external_reconstruction.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/recon-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python ROOT="$REPO/experiments/trb/external-model-benchmark" RUNTIME="$ROOT/runtime-v2" diff --git a/slurm/train_external_residue_pca128_remaining.sbatch b/slurm/train_external_residue_pca128_remaining.sbatch index ad99aec..2ee199d 100644 --- a/slurm/train_external_residue_pca128_remaining.sbatch +++ b/slurm/train_external_residue_pca128_remaining.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-v1/logs/head-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca128-v1" diff --git a/slurm/train_external_residue_pgen.sbatch b/slurm/train_external_residue_pgen.sbatch index 26289b2..e1207eb 100644 --- a/slurm/train_external_residue_pgen.sbatch +++ b/slurm/train_external_residue_pgen.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/pgen-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-v1" diff --git a/slurm/train_external_residue_reconstruction.sbatch b/slurm/train_external_residue_reconstruction.sbatch index 7f3b740..ede23d8 100644 --- a/slurm/train_external_residue_reconstruction.sbatch +++ b/slurm/train_external_residue_reconstruction.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-v1/logs/recon-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-v1" diff --git a/slurm/train_external_rtp128_reconstruction.sbatch b/slurm/train_external_rtp128_reconstruction.sbatch index bdaa06d..d2fbe32 100644 --- a/slurm/train_external_rtp128_reconstruction.sbatch +++ b/slurm/train_external_rtp128_reconstruction.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/native-rtp128-v1/logs/recon-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/native-rtp128-v1" diff --git a/slurm/train_external_sceptr_pca128_heads.sbatch b/slurm/train_external_sceptr_pca128_heads.sbatch index e977fd0..e21be11 100644 --- a/slurm/train_external_sceptr_pca128_heads.sbatch +++ b/slurm/train_external_sceptr_pca128_heads.sbatch @@ -11,7 +11,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/residue-pca128-sceptr-v1/logs/head-%A-%a.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python BASE="$REPO/experiments/trb/external-model-benchmark" ROOT="$BASE/residue-pca128-sceptr-v1" diff --git a/slurm/train_phase1_rq1_char.sbatch b/slurm/train_phase1_rq1_char.sbatch index 61550a5..1a5c336 100644 --- a/slurm/train_phase1_rq1_char.sbatch +++ b/slurm/train_phase1_rq1_char.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail @@ -21,11 +21,11 @@ case "$EXPERIMENT_ID:$TCREMP_WEIGHT:$PGEN_WEIGHT:$RECONSTRUCTION_WEIGHT" in *) echo "Refusing unregistered Phase-1 configuration" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" CONFIG_PATH="$OUTPUT_DIR/experiment_config.json" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$DATA_DIR/READY.json" test -f "$DATA_DIR/target_standardizer.npz" diff --git a/slurm/train_phase2_rq23_char.sbatch b/slurm/train_phase2_rq23_char.sbatch index 2465c74..aa8eb16 100644 --- a/slurm/train_phase2_rq23_char.sbatch +++ b/slurm/train_phase2_rq23_char.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail @@ -21,11 +21,11 @@ case "$EXPERIMENT_ID:$TCREMP_WEIGHT:$PGEN_WEIGHT:$RECONSTRUCTION_WEIGHT" in *) echo "Refusing unregistered Phase-2 configuration" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" CONFIG_PATH="$OUTPUT_DIR/experiment_config.json" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$DATA_DIR/READY.json" test -f "$DATA_DIR/target_standardizer.npz" diff --git a/slurm/train_rq4_wordpiece.sbatch b/slurm/train_rq4_wordpiece.sbatch index fdfd73d..c67242e 100644 --- a/slurm/train_rq4_wordpiece.sbatch +++ b/slurm/train_rq4_wordpiece.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail @@ -20,12 +20,12 @@ case "$EXPERIMENT_ID:$TCREMP_WEIGHT:$PGEN_WEIGHT:$RECONSTRUCTION_WEIGHT" in *) echo "Refusing unregistered RQ4 configuration" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER_DIR="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-seed42" TOKENIZER_PATH="$TOKENIZER_DIR/tokenizer.json" OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$DATA_DIR/READY.json" test -f "$TOKENIZER_DIR/preflight.json" diff --git a/slurm/train_rq5_depth.sbatch b/slurm/train_rq5_depth.sbatch index ff80d86..8f6671e 100644 --- a/slurm/train_rq5_depth.sbatch +++ b/slurm/train_rq5_depth.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail EXPERIMENT_ID="${1:?experiment id is required}" @@ -17,10 +17,10 @@ case "$EXPERIMENT_ID:$ENCODER_LAYERS" in *) echo "Refusing unregistered RQ5 depth" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$ROOT_DIR/experiments/trb/rq5-char-rtp-d128-depths-seed42/preflight.json" test -f "$DATA_DIR/READY.json" test -f "$OUTPUT_DIR/experiment_config.json" diff --git a/slurm/train_rq5_width.sbatch b/slurm/train_rq5_width.sbatch index 84a2bd7..83d37e7 100644 --- a/slurm/train_rq5_width.sbatch +++ b/slurm/train_rq5_width.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail EXPERIMENT_ID="${1:?experiment id is required}" @@ -17,10 +17,10 @@ case "$EXPERIMENT_ID:$LATENT_DIM" in *) echo "Refusing unregistered RQ5 width" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$ROOT_DIR/experiments/trb/rq5-char-rtp-widths-seed42/preflight.json" test -f "$DATA_DIR/READY.json" test -f "$OUTPUT_DIR/experiment_config.json" diff --git a/slurm/train_tcremp_geometry_ablation.sbatch b/slurm/train_tcremp_geometry_ablation.sbatch index 331fdea..9d32e91 100644 --- a/slurm/train_tcremp_geometry_ablation.sbatch +++ b/slurm/train_tcremp_geometry_ablation.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=16:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail VARIANT="${1:?Variant centered or relational required}" case "$VARIANT" in @@ -15,7 +15,7 @@ case "$VARIANT" in relational) C=0.15; P=0.35 ;; *) echo "Unknown variant: $VARIANT" >&2; exit 2 ;; esac -ROOT=/home/evlasova/irrm-codec +ROOT="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" OUT="$ROOT/experiments/trb/tcremp-geometry-t-${VARIANT}-seed42" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python test ! -e "$OUT/best.pt" diff --git a/slurm/train_wordpiece_sweep.sbatch b/slurm/train_wordpiece_sweep.sbatch index bfc4c6a..cd87db7 100644 --- a/slurm/train_wordpiece_sweep.sbatch +++ b/slurm/train_wordpiece_sweep.sbatch @@ -6,8 +6,8 @@ #SBATCH --cpus-per-task=8 #SBATCH --mem=48G #SBATCH --time=12:00:00 -#SBATCH --output=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.out -#SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/slurm-%x-%j.err +#SBATCH --output=slurm-%x-%j.out +#SBATCH --error=slurm-%x-%j.err set -euo pipefail VOCAB_SIZE="${1:?WordPiece vocabulary size is required}" @@ -16,14 +16,14 @@ case "$VOCAB_SIZE" in *) echo "Refusing unregistered WordPiece vocabulary size" >&2; exit 2 ;; esac -ROOT_DIR="/home/evlasova/irrm-codec" +ROOT_DIR="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" DATA_DIR="$ROOT_DIR/data/benchmark/trb" TOKENIZER_ROOT="$ROOT_DIR/experiments/trb/tokenizers/wordpiece-sweep-seed42" TOKENIZER_DIR="$TOKENIZER_ROOT/v${VOCAB_SIZE}-seed42" TOKENIZER_PATH="$TOKENIZER_DIR/tokenizer.json" EXPERIMENT_ID="wp-sweep-v${VOCAB_SIZE}-rtp-seed42" OUTPUT_DIR="$ROOT_DIR/experiments/trb/$EXPERIMENT_ID" -PYTHON_BIN="/home/evlasova/.conda/envs/irrm-codec/bin/python" +PYTHON_BIN="${IRRM_PYTHON:-$(command -v python)}" test -f "$DATA_DIR/READY.json" test -f "$TOKENIZER_ROOT/preflight.json" diff --git a/slurm/validate_external_model_cohort.sbatch b/slurm/validate_external_model_cohort.sbatch index 87c3268..a9a6df2 100644 --- a/slurm/validate_external_model_cohort.sbatch +++ b/slurm/validate_external_model_cohort.sbatch @@ -8,7 +8,7 @@ #SBATCH --error=/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/logs/validate-%j.err set -euo pipefail -REPO=/home/evlasova/irrm-codec +REPO="${IRRM_ROOT:-${SLURM_SUBMIT_DIR:-$PWD}}" PYTHON=/home/evlasova/.conda/envs/irrm-codec/bin/python RUNTIME="$REPO/experiments/trb/external-model-benchmark/runtime-v2" ROOT="$REPO/experiments/trb/external-model-benchmark" diff --git a/tests/test_integration_compatibility.py b/tests/test_integration_compatibility.py new file mode 100644 index 0000000..588f619 --- /dev/null +++ b/tests/test_integration_compatibility.py @@ -0,0 +1,51 @@ +"""Regression coverage for formats brought together by the publication merge.""" +import tempfile +from pathlib import Path + +import pytest +from tokenizers import Tokenizer +from tokenizers.decoders import WordPiece as WordPieceDecoder +from tokenizers.models import WordPiece + +from irrm_codec.wordpiece_tokenization import ( + decode_wordpiece, encode_wordpiece_unpadded, filter_vocab_by_max_token_length, + load_wordpiece_tokenizer, +) + + +@pytest.mark.parametrize("specials", [ + ["[PAD]", "[BOS]", "[EOS]", "[UNK]"], + ["[PAD]", "[UNK]", "[BOS]", "[EOS]"], +]) +def test_author_and_student_vocabularies_preserve_ids_and_decode(specials): + vocab = {token: i for i, token in enumerate(specials + ["C", "##A", "CASS"])} + tokenizer = Tokenizer(WordPiece(vocab=vocab, unk_token="[UNK]")) + tokenizer.decoder = WordPieceDecoder(prefix="##") + tokenizer.add_special_tokens(specials) + with tempfile.TemporaryDirectory() as temporary: + path = Path(temporary) / "tokenizer.json" + tokenizer.save(str(path)) + restored = load_wordpiece_tokenizer(path) + assert restored.get_vocab() == vocab + ids = encode_wordpiece_unpadded("CA", restored, 40) + assert ids == [vocab["C"], vocab["##A"]] + assert decode_wordpiece(ids + [vocab["[EOS]"], vocab["C"]], restored) == "CA" + filtered = filter_vocab_by_max_token_length(restored, 1) + assert {s: filtered.token_to_id(s) for s in specials} == {s: vocab[s] for s in specials} + assert decode_wordpiece(encode_wordpiece_unpadded("CA", filtered, 40), filtered) == "CA" + with pytest.raises(ValueError, match="UNK"): + encode_wordpiece_unpadded("CY", restored, 40) + + +def test_sequence_keyed_pgen_cache_survives_row_filtering(tmp_path): + import pandas as pd + from benchmark.prepare_splits import _pgen_lookup + path = tmp_path / "pgen.tsv" + pd.DataFrame({ + "junction_aa": ["CASSF", "CASRF", "CATGF"], + "log10_pgen": [-5., -6., -7.], + "log10_pgen_1mm": [-4., -5., -6.], + }).to_csv(path, sep="\t", index=False) + result = _pgen_lookup(path, pd.Series(["CATGF", "CASSF"])) + assert result.log10_pgen.tolist() == [-7., -5.] + assert _pgen_lookup(path, pd.Series(["CQQF"])) is None From 27ac824b8b0b0599b77f2a216d0f89caca1b06d2 Mon Sep 17 00:00:00 2001 From: Elizaveta Vlasova Date: Sun, 4 Oct 2026 19:39:46 +0300 Subject: [PATCH 67/70] Normalize publication file endings --- benchmark/collect_external_reconstruction.py | 3 +-- benchmark/fit_external_model_bottleneck.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/benchmark/collect_external_reconstruction.py b/benchmark/collect_external_reconstruction.py index 191125a..11f5dc8 100644 --- a/benchmark/collect_external_reconstruction.py +++ b/benchmark/collect_external_reconstruction.py @@ -96,7 +96,7 @@ def to_markdown(summary, bottleneck_dim): def cell(row, name): std = row[f"{name}_std"] - spread = f" ± {std:.4f}" if pd.notna(std) else "" + spread = f" ± {std:.4f}" if pd.notna(std) else "" return f"{row[f'{name}_mean']:.4f}{spread}" lines = [] @@ -146,4 +146,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/benchmark/fit_external_model_bottleneck.py b/benchmark/fit_external_model_bottleneck.py index 3b3a727..20f7d22 100644 --- a/benchmark/fit_external_model_bottleneck.py +++ b/benchmark/fit_external_model_bottleneck.py @@ -158,4 +158,3 @@ def main(): if __name__ == "__main__": main() - From 2aa33a0697a93655ff483a3affd3c9958c334fb1 Mon Sep 17 00:00:00 2001 From: Elizaveta Vlasova Date: Sun, 4 Oct 2026 19:40:56 +0300 Subject: [PATCH 68/70] Preserve author result summaries and normalize UTF-8 release text --- README.md | 2 +- benchmark/collect_external_reconstruction.py | 2 +- irrm_codec/wordpiece_tokenization.py | 4 ++-- results/author/README.md | 8 ++++++++ results/pgen/pgen_summary.md | 1 - results/pgen_constlr/pgen_summary.md | 1 - slurm/evaluate_vdjdb_redcea_clonotypes.sbatch | 1 - 7 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 results/author/README.md diff --git a/README.md b/README.md index 50703da..e7106a6 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Transformer hidden width. `benchmark/train_decoder.py`, `benchmark/train_pgen_arm.py`, and [historical report](REPORT.md). - Author external-model, residue-PCA, latent, and VDJdb evaluations: `benchmark/` and their matching launchers in `slurm/`. -- Historical result tables: `results/`. They describe the original runs, not a +- Historical result tables: `results/` (student runs) and `results/author/` (author runs). They describe the original runs, not a new rerun of this integrated revision. For a CPU development setup without the Pgen-generation dependency: diff --git a/benchmark/collect_external_reconstruction.py b/benchmark/collect_external_reconstruction.py index 11f5dc8..0c41543 100644 --- a/benchmark/collect_external_reconstruction.py +++ b/benchmark/collect_external_reconstruction.py @@ -96,7 +96,7 @@ def to_markdown(summary, bottleneck_dim): def cell(row, name): std = row[f"{name}_std"] - spread = f" ± {std:.4f}" if pd.notna(std) else "" + spread = f" ± {std:.4f}" if pd.notna(std) else "" return f"{row[f'{name}_mean']:.4f}{spread}" lines = [] diff --git a/irrm_codec/wordpiece_tokenization.py b/irrm_codec/wordpiece_tokenization.py index dc83099..351a3fa 100644 --- a/irrm_codec/wordpiece_tokenization.py +++ b/irrm_codec/wordpiece_tokenization.py @@ -1,7 +1,7 @@ """WordPiece tokenizer for CDR3 sequences, as an alternative to the char-level one. Requires: pip install tokenizers -Requires a tokenizer.json with special tokens at [PAD]=0, [UNK]=1, [BOS]=2, [EOS]=3 — +Requires a tokenizer.json with special tokens at [PAD]=0, [UNK]=1, [BOS]=2, [EOS]=3 — The author layout [PAD]/[BOS]/[EOS]/[UNK]=0/1/2/3 is also accepted. IDs are never remapped. """ from pathlib import Path @@ -27,7 +27,7 @@ def _validate_special_ids(tokenizer, tokenizer_path): validate_wordpiece_tokenizer(tokenizer, tokenizer_path) def load_wordpiece_tokenizer(path) -> Tokenizer: - """Load and validate a tokenizer.json. Returns the Tokenizer itself — it's picklable, + """Load and validate a tokenizer.json. Returns the Tokenizer itself — it's picklable, so it can go straight into a DataLoader worker.""" tokenizer = Tokenizer.from_file(str(Path(path))) _validate_special_ids(tokenizer, path) diff --git a/results/author/README.md b/results/author/README.md new file mode 100644 index 0000000..d6686fe --- /dev/null +++ b/results/author/README.md @@ -0,0 +1,8 @@ +# Author result archive + +These tables were recovered from the local manuscript/results directory during +publication integration. They record the original author experiments, including +R/T/P factorial, tokenization/architecture comparisons, external models, latent +sufficiency, reconstruction errors, and downstream evaluation. They were not +regenerated by the integration CPU tests. Preserve the recorded hashes and run +provenance when reproducing or comparing these results. diff --git a/results/pgen/pgen_summary.md b/results/pgen/pgen_summary.md index 1730a22..a0f87e6 100644 --- a/results/pgen/pgen_summary.md +++ b/results/pgen/pgen_summary.md @@ -67,4 +67,3 @@ | sceptr_mlp | 0.4465 ± 0.0060 | 0.2510 | 0.9233 | 0.9621 | 0.9783 | +0.0642 | 58 | 1043629 | 1193 | | esm2_8m_mlp | 0.4539 ± 0.0015 | 0.2655 | 0.9208 | 0.9607 | 0.9762 | +0.0549 | 68 | 726936 | 1295 | | tfidf_ridge | 0.5542 | 0.3671 | 0.8819 | 0.9391 | 0.9566 | +0.0035 | 9 | 67435 | 717 | - diff --git a/results/pgen_constlr/pgen_summary.md b/results/pgen_constlr/pgen_summary.md index f5572ce..b8227f3 100644 --- a/results/pgen_constlr/pgen_summary.md +++ b/results/pgen_constlr/pgen_summary.md @@ -67,4 +67,3 @@ | sceptr_mlp | 0.4560 ± 0.0080 | 0.2636 | 0.9200 | 0.9599 | 0.9754 | +0.0484 | 53 | 912996 | 1197 | | esm2_8m_mlp | 0.4794 ± 0.0092 | 0.2868 | 0.9116 | 0.9561 | 0.9721 | +0.0650 | 68 | 543945 | 1301 | | tfidf_ridge | 0.5542 | 0.3671 | 0.8819 | 0.9391 | 0.9566 | +0.0035 | 10 | 44727 | 716 | - diff --git a/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch b/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch index 181bf9e..8313c8e 100644 --- a/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch +++ b/slurm/evaluate_vdjdb_redcea_clonotypes.sbatch @@ -42,4 +42,3 @@ cd "$ROOT" --bootstrap 2000 \ --silhouette-sample 10000 \ --seed 42 - From 436cf4e4c87bee83ecbb29620931596b09b77a6c Mon Sep 17 00:00:00 2001 From: Elizaveta Vlasova Date: Sun, 4 Oct 2026 19:41:48 +0300 Subject: [PATCH 69/70] Archive author publication tables with their recorded provenance --- results/author/README.md | 2 +- results/author/architecture_results.tsv | 6 + .../downstream_distribution_summary.tsv | 85 +++ .../downstream_per_epitope_controls.tsv | 97 ++++ .../author/downstream_per_epitope_metrics.tsv | 505 ++++++++++++++++++ .../downstream_rtp_minus_rp_effects.tsv | 73 +++ .../external_author_global_comparison.md | 10 + .../external_author_global_comparison.tsv | 9 + ...nal_author_global_comparison_manifest.json | 25 + results/author/external_pgen_results.tsv | 6 + results/author/external_pgen_runs.tsv | 14 + .../external_reconstruction_results.tsv | 7 + .../author/external_reconstruction_runs.tsv | 19 + results/author/factorial_results.tsv | 8 + results/author/latent_sufficiency_summary.tsv | 10 + results/author/low_label_sequence_summary.tsv | 43 ++ results/author/provenance_and_hashes.tsv | 16 + ...p_data_anchor_error_analysis_by_length.tsv | 23 + ...ta_anchor_error_rates_by_target_length.tsv | 23 + .../rtp_data_anchor_region_error_rates.tsv | 4 + .../rtp_data_anchor_substitution_matrix.tsv | 21 + .../rtp_data_anchor_substitution_results.json | 47 ++ results/author/tokenizer_results.tsv | 13 + 23 files changed, 1065 insertions(+), 1 deletion(-) create mode 100644 results/author/architecture_results.tsv create mode 100644 results/author/downstream_distribution_summary.tsv create mode 100644 results/author/downstream_per_epitope_controls.tsv create mode 100644 results/author/downstream_per_epitope_metrics.tsv create mode 100644 results/author/downstream_rtp_minus_rp_effects.tsv create mode 100644 results/author/external_author_global_comparison.md create mode 100644 results/author/external_author_global_comparison.tsv create mode 100644 results/author/external_author_global_comparison_manifest.json create mode 100644 results/author/external_pgen_results.tsv create mode 100644 results/author/external_pgen_runs.tsv create mode 100644 results/author/external_reconstruction_results.tsv create mode 100644 results/author/external_reconstruction_runs.tsv create mode 100644 results/author/factorial_results.tsv create mode 100644 results/author/latent_sufficiency_summary.tsv create mode 100644 results/author/low_label_sequence_summary.tsv create mode 100644 results/author/provenance_and_hashes.tsv create mode 100644 results/author/rtp_data_anchor_error_analysis_by_length.tsv create mode 100644 results/author/rtp_data_anchor_error_rates_by_target_length.tsv create mode 100644 results/author/rtp_data_anchor_region_error_rates.tsv create mode 100644 results/author/rtp_data_anchor_substitution_matrix.tsv create mode 100644 results/author/rtp_data_anchor_substitution_results.json create mode 100644 results/author/tokenizer_results.tsv diff --git a/results/author/README.md b/results/author/README.md index d6686fe..c26c2c8 100644 --- a/results/author/README.md +++ b/results/author/README.md @@ -1,6 +1,6 @@ # Author result archive -These tables were recovered from the local manuscript/results directory during +These tables were recovered from the local manuscript/tables directory during publication integration. They record the original author experiments, including R/T/P factorial, tokenization/architecture comparisons, external models, latent sufficiency, reconstruction errors, and downstream evaluation. They were not diff --git a/results/author/architecture_results.tsv b/results/author/architecture_results.tsv new file mode 100644 index 0000000..ed1f2ad --- /dev/null +++ b/results/author/architecture_results.tsv @@ -0,0 +1,6 @@ +condition latent_dim encoder_layers decoder_layers best_epoch best_validation_joint_loss test_reconstruction_exact_match test_tcremp_cosine test_pgen_rmse parameters remote_output +d128-e4d4 128 4 4 30 0.19693734171098476 0.9815950920245399 0.992289113360584 0.343395136972041 21142953 /home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-seed42 +d320-e4d4 320 4 4 28 0.20322377112032147 0.971236045459117 0.9922739834801287 0.3678781484793622 21697257 /home/evlasova/irrm-codec/experiments/trb/rq1-char-rtp-seed42 +d512-e4d4 512 4 4 28 0.2087959912276347 0.9676154078246002 0.9919841033189718 0.3447591167246714 22251561 /home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d512-seed42 +d128-e2d4 128 2 4 38 0.2047392800008221 0.9614804384994469 0.9922445351528616 0.3915365453431801 18677033 /home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-e2d4-seed42 +d128-e6d4 128 6 4 28 0.20005685247478622 0.9690234335713568 0.992220890590342 0.3328977050320967 23608873 /home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-e6d4-seed42 diff --git a/results/author/downstream_distribution_summary.tsv b/results/author/downstream_distribution_summary.tsv new file mode 100644 index 0000000..2aec099 --- /dev/null +++ b/results/author/downstream_distribution_summary.tsv @@ -0,0 +1,85 @@ +distance metric model epitopes median q1 q3 +cosine between_minus_within p 6 0.0145443152895451 -0.0001492005485736 0.0223180058645856 +cosine between_minus_within r 6 0.1578570451716967 0.0660611825275395 0.2059822047681393 +cosine between_minus_within rp 6 0.1482288745391226 0.0703371563373106 0.1812976137030069 +cosine between_minus_within rt 6 0.1485969787030767 0.1105945336383283 0.1936926422338269 +cosine between_minus_within rtp 6 0.1181646810375563 0.1091203728571297 0.1666706381533964 +cosine between_minus_within t 6 0.1445365267388816 0.0487515996728354 0.1554817927078322 +cosine between_minus_within tp 6 0.0558434676762929 0.0177303851753551 0.1254538239660743 +cosine map_at_r p 6 0.1072723899090958 0.0499999999999999 0.3327528171366436 +cosine map_at_r r 6 0.567181302109368 0.2961775566854647 0.9219392854417802 +cosine map_at_r rp 6 0.5712887961220562 0.3008174984726075 0.8470631754505331 +cosine map_at_r rt 6 0.5785180537443047 0.394076685303714 0.8092542051437623 +cosine map_at_r rtp 6 0.5720908539934587 0.3674453785075067 0.8205274195292898 +cosine map_at_r t 6 0.4102288717786875 0.241837828946378 0.5799432736096324 +cosine map_at_r tp 6 0.3849056822155335 0.2746976756621377 0.617755165445629 +cosine precision_at_1 p 6 0.15 0.0 0.6293478260869565 +cosine precision_at_1 r 6 0.997835497835498 0.982613401091662 1.0 +cosine precision_at_1 rp 6 0.9967532467532468 0.9820722755505364 1.0 +cosine precision_at_1 rt 6 0.9869659326181066 0.9758152173913044 0.998917748917749 +cosine precision_at_1 rtp 6 0.9826369282891022 0.9758152173913044 0.9967532467532468 +cosine precision_at_1 t 6 0.8125 0.7625 0.9073369565217392 +cosine precision_at_1 tp 6 0.879891304347826 0.80625 0.97557876905703 +cosine same_label_auprc_balanced p 6 0.539248199520719 0.5053728183074511 0.5879886551902822 +cosine same_label_auprc_balanced r 6 0.8475517022311078 0.6490237688365724 0.9912878787878788 +cosine same_label_auprc_balanced rp 6 0.8210715594987712 0.6474908672137286 0.9811625874125874 +cosine same_label_auprc_balanced rt 6 0.8034531209606439 0.7060939707370587 0.974431818181818 +cosine same_label_auprc_balanced rtp 6 0.7985890749138258 0.7036019824914448 0.9706818181818182 +cosine same_label_auprc_balanced t 6 0.7141583539785815 0.6082069732618179 0.920682486972982 +cosine same_label_auprc_balanced tp 6 0.7098644847055979 0.6231296867497326 0.8973546314400598 +cosine same_label_auroc p 6 0.504926571111111 0.4405555555555555 0.5609014279785969 +cosine same_label_auroc r 6 0.8457943800000001 0.6161970710939357 0.99 +cosine same_label_auroc rp 6 0.81789524 0.604472590273484 0.9775 +cosine same_label_auroc rt 6 0.78903498 0.6648428768234964 0.9675 +cosine same_label_auroc rtp 6 0.77995546 0.665116706405517 0.96 +cosine same_label_auroc t 6 0.7309987030273752 0.5775910405350774 0.9163325281803544 +cosine same_label_auroc tp 6 0.7320116917146258 0.5748606921593343 0.8970451933333334 +cosine within_between_ratio p 6 0.8179821629283468 0.7973325641955162 1.0103488838501615 +cosine within_between_ratio r 6 0.7461820844136712 0.5318130153584926 0.896319378478054 +cosine within_between_ratio rp 6 0.7360651990271578 0.5343375419702201 0.8872807430525629 +cosine within_between_ratio rt 6 0.7598338444758671 0.604724903085157 0.8425857353682646 +cosine within_between_ratio rtp 6 0.7715636576640352 0.6536983166194029 0.8369475654044015 +cosine within_between_ratio t 6 0.7699551601043487 0.7099430371505517 0.9071517773056192 +cosine within_between_ratio tp 6 0.8493645602381839 0.7302541305366014 0.9526920339881136 +euclidean between_minus_within p 6 0.2757123701977926 -0.059618771315719 0.6019926425050299 +euclidean between_minus_within r 6 1.6116113735004554 0.7905967767468112 2.6223420450288786 +euclidean between_minus_within rp 6 1.5069047169069432 0.8281081652673254 2.4094358188863936 +euclidean between_minus_within rt 6 1.712747171445943 1.1221761363938518 2.3251597072080803 +euclidean between_minus_within rtp 6 1.5569426077436344 1.1079599161060276 1.7965944639688614 +euclidean between_minus_within t 6 1.7479573007303433 0.738132089438619 2.701660348818735 +euclidean between_minus_within tp 6 1.0889405252505675 0.3118886026511105 1.9733571716059028 +euclidean map_at_r p 6 0.1069136915349483 0.0499999999999999 0.3323742775309038 +euclidean map_at_r r 6 0.5686769709072258 0.296089041743911 0.9225953504042612 +euclidean map_at_r rp 6 0.5738011794219053 0.301259424271951 0.8472519876707403 +euclidean map_at_r rt 6 0.5801873236682918 0.4032949812936193 0.8079024354126133 +euclidean map_at_r rtp 6 0.5800994521465858 0.3816460500084527 0.8178226775033324 +euclidean map_at_r t 6 0.4067968767490306 0.2407373145960313 0.5793277904451506 +euclidean map_at_r tp 6 0.3811436671924311 0.2747485823983004 0.6158232511979151 +euclidean precision_at_1 p 6 0.1375 0.0 0.6230978260869565 +euclidean precision_at_1 r 6 0.997835497835498 0.982613401091662 1.0 +euclidean precision_at_1 rp 6 0.997835497835498 0.982613401091662 1.0 +euclidean precision_at_1 rt 6 0.9869659326181066 0.9758152173913044 0.998917748917749 +euclidean precision_at_1 rtp 6 0.9826369282891022 0.9758152173913044 0.9967532467532468 +euclidean precision_at_1 t 6 0.8125 0.7625 0.9073369565217392 +euclidean precision_at_1 tp 6 0.879891304347826 0.80625 0.97557876905703 +euclidean same_label_auprc_balanced p 6 0.5193031996501787 0.5037457912457912 0.5462770451630575 +euclidean same_label_auprc_balanced r 6 0.850156124431406 0.6546985430978252 0.9912878787878788 +euclidean same_label_auprc_balanced rp 6 0.8228910796395241 0.6550536252738018 0.9811625874125874 +euclidean same_label_auprc_balanced rt 6 0.8085321068617215 0.7101054409871914 0.9740311771561772 +euclidean same_label_auprc_balanced rtp 6 0.8005937366322124 0.712261035132749 0.9706818181818182 +euclidean same_label_auprc_balanced t 6 0.7141135767918775 0.606869109378777 0.9199743118632536 +euclidean same_label_auprc_balanced tp 6 0.708716250339988 0.6232321985930138 0.8963979330461858 +euclidean same_label_auroc p 6 0.4924432822222222 0.4336111111111111 0.5602215882639715 +euclidean same_label_auroc r 6 0.84832026 0.6218091192984543 0.99 +euclidean same_label_auroc rp 6 0.8188651 0.6075487212247325 0.9775 +euclidean same_label_auroc rt 6 0.78825486 0.6805495752075895 0.9675 +euclidean same_label_auroc rtp 6 0.7754911 0.6878897774032066 0.96 +euclidean same_label_auroc t 6 0.7301146150906672 0.5756820298335315 0.9150484842120004 +euclidean same_label_auroc tp 6 0.730726850510397 0.5733397310340332 0.8974585733333333 +euclidean within_between_ratio p 6 0.9349746031223288 0.8766179889749843 1.0221335500292326 +euclidean within_between_ratio r 6 0.8656682254017987 0.7232751133175406 0.9347943555106916 +euclidean within_between_ratio rp 6 0.858484774291782 0.7266690133104422 0.9261933907546518 +euclidean within_between_ratio rt 6 0.8595267247842686 0.7694552586796968 0.9104275665656826 +euclidean within_between_ratio rtp 6 0.8676658082373783 0.8053474848489822 0.9064168776507302 +euclidean within_between_ratio t 6 0.8669592497804925 0.8033823364614108 0.936983570542994 +euclidean within_between_ratio tp 6 0.8990771644752427 0.8353543721278662 0.9696957552483164 diff --git a/results/author/downstream_per_epitope_controls.tsv b/results/author/downstream_per_epitope_controls.tsv new file mode 100644 index 0000000..7122789 --- /dev/null +++ b/results/author/downstream_per_epitope_controls.tsv @@ -0,0 +1,97 @@ +rank epitope distance control metric value +1 GILGFVFTL absolute exact_cdr3_length within_between_ratio 1.0 +1 GILGFVFTL absolute exact_cdr3_length between_minus_within 0.0 +1 GILGFVFTL absolute exact_cdr3_length same_label_auroc 0.5 +1 GILGFVFTL absolute exact_cdr3_length same_label_auprc_balanced 0.5 +1 GILGFVFTL cosine amino_acid_composition within_between_ratio 0.917498976188238 +1 GILGFVFTL cosine amino_acid_composition between_minus_within 0.0227998023803722 +1 GILGFVFTL cosine amino_acid_composition same_label_auroc 0.55205354 +1 GILGFVFTL cosine amino_acid_composition same_label_auprc_balanced 0.5690443818486688 +1 GILGFVFTL euclidean amino_acid_composition within_between_ratio 0.963622217536067 +1 GILGFVFTL euclidean amino_acid_composition between_minus_within 0.009632094464311 +1 GILGFVFTL euclidean amino_acid_composition same_label_auroc 0.54093074 +1 GILGFVFTL euclidean amino_acid_composition same_label_auprc_balanced 0.5540953848468919 +1 GILGFVFTL mismatch_fraction v_j_identity within_between_ratio 0.5486555697823303 +1 GILGFVFTL mismatch_fraction v_j_identity between_minus_within 0.423 +1 GILGFVFTL mismatch_fraction v_j_identity same_label_auroc 0.8715852800000001 +1 GILGFVFTL mismatch_fraction v_j_identity same_label_auprc_balanced 0.8325820334830544 +2 GLCTLVAML absolute exact_cdr3_length within_between_ratio 1.0 +2 GLCTLVAML absolute exact_cdr3_length between_minus_within 0.0 +2 GLCTLVAML absolute exact_cdr3_length same_label_auroc 0.5 +2 GLCTLVAML absolute exact_cdr3_length same_label_auprc_balanced 0.5 +2 GLCTLVAML cosine amino_acid_composition within_between_ratio 0.954935606190231 +2 GLCTLVAML cosine amino_acid_composition between_minus_within 0.0128782543677601 +2 GLCTLVAML cosine amino_acid_composition same_label_auroc 0.5206604588205093 +2 GLCTLVAML cosine amino_acid_composition same_label_auprc_balanced 0.5860336166083757 +2 GLCTLVAML euclidean amino_acid_composition within_between_ratio 0.9648202050628965 +2 GLCTLVAML euclidean amino_acid_composition between_minus_within 0.0089334411397177 +2 GLCTLVAML euclidean amino_acid_composition same_label_auroc 0.5192853975588696 +2 GLCTLVAML euclidean amino_acid_composition same_label_auprc_balanced 0.5944189527018383 +2 GLCTLVAML mismatch_fraction v_j_identity within_between_ratio 0.8186555497655029 +2 GLCTLVAML mismatch_fraction v_j_identity between_minus_within 0.1681159420289855 +2 GLCTLVAML mismatch_fraction v_j_identity same_label_auroc 0.6016854535695115 +2 GLCTLVAML mismatch_fraction v_j_identity same_label_auprc_balanced 0.6104768679055156 +3 YLQPRTFLL absolute exact_cdr3_length within_between_ratio 1.0 +3 YLQPRTFLL absolute exact_cdr3_length between_minus_within 0.0 +3 YLQPRTFLL absolute exact_cdr3_length same_label_auroc 0.4999999999999999 +3 YLQPRTFLL absolute exact_cdr3_length same_label_auprc_balanced 0.5 +3 YLQPRTFLL cosine amino_acid_composition within_between_ratio 0.9531587680806616 +3 YLQPRTFLL cosine amino_acid_composition between_minus_within 0.0114973732487685 +3 YLQPRTFLL cosine amino_acid_composition same_label_auroc 0.5639429250891795 +3 YLQPRTFLL cosine amino_acid_composition same_label_auprc_balanced 0.596767984185325 +3 YLQPRTFLL euclidean amino_acid_composition within_between_ratio 0.9119303437002227 +3 YLQPRTFLL euclidean amino_acid_composition between_minus_within 0.0221158269223845 +3 YLQPRTFLL euclidean amino_acid_composition same_label_auroc 0.6133992865636146 +3 YLQPRTFLL euclidean amino_acid_composition same_label_auprc_balanced 0.6361629629451064 +3 YLQPRTFLL mismatch_fraction v_j_identity within_between_ratio 0.8848996832101372 +3 YLQPRTFLL mismatch_fraction v_j_identity between_minus_within 0.0751724137931034 +3 YLQPRTFLL mismatch_fraction v_j_identity same_label_auroc 0.5652775267538646 +3 YLQPRTFLL mismatch_fraction v_j_identity same_label_auprc_balanced 0.5440484630600354 +4 SLYNTVATL absolute exact_cdr3_length within_between_ratio 1.0 +4 SLYNTVATL absolute exact_cdr3_length between_minus_within 0.0 +4 SLYNTVATL absolute exact_cdr3_length same_label_auroc 0.5 +4 SLYNTVATL absolute exact_cdr3_length same_label_auprc_balanced 0.5 +4 SLYNTVATL cosine amino_acid_composition within_between_ratio 0.4896836516369041 +4 SLYNTVATL cosine amino_acid_composition between_minus_within 0.0630725596060895 +4 SLYNTVATL cosine amino_acid_composition same_label_auroc 0.88 +4 SLYNTVATL cosine amino_acid_composition same_label_auprc_balanced 0.9102272727272728 +4 SLYNTVATL euclidean amino_acid_composition within_between_ratio 0.7248228937768533 +4 SLYNTVATL euclidean amino_acid_composition between_minus_within 0.0564259005060354 +4 SLYNTVATL euclidean amino_acid_composition same_label_auroc 0.84 +4 SLYNTVATL euclidean amino_acid_composition same_label_auprc_balanced 0.8726984126984126 +4 SLYNTVATL mismatch_fraction v_j_identity within_between_ratio 0.4615384615384615 +4 SLYNTVATL mismatch_fraction v_j_identity between_minus_within 0.35 +4 SLYNTVATL mismatch_fraction v_j_identity same_label_auroc 0.79 +4 SLYNTVATL mismatch_fraction v_j_identity same_label_auprc_balanced 0.7529411764705882 +5 ALSKGVHFV absolute exact_cdr3_length within_between_ratio 1.0 +5 ALSKGVHFV absolute exact_cdr3_length between_minus_within 0.0 +5 ALSKGVHFV absolute exact_cdr3_length same_label_auroc 0.5 +5 ALSKGVHFV absolute exact_cdr3_length same_label_auprc_balanced 0.5 +5 ALSKGVHFV cosine amino_acid_composition within_between_ratio 0.43903884813344 +5 ALSKGVHFV cosine amino_acid_composition between_minus_within 0.0618176669520792 +5 ALSKGVHFV cosine amino_acid_composition same_label_auroc 0.7916666666666667 +5 ALSKGVHFV cosine amino_acid_composition same_label_auprc_balanced 0.7500000000000001 +5 ALSKGVHFV euclidean amino_acid_composition within_between_ratio 0.6709093005374359 +5 ALSKGVHFV euclidean amino_acid_composition between_minus_within 0.0494387749198131 +5 ALSKGVHFV euclidean amino_acid_composition same_label_auroc 0.8194444444444445 +5 ALSKGVHFV euclidean amino_acid_composition same_label_auprc_balanced 0.763888888888889 +5 ALSKGVHFV mismatch_fraction v_j_identity within_between_ratio 0.0 +5 ALSKGVHFV mismatch_fraction v_j_identity between_minus_within 0.5 +5 ALSKGVHFV mismatch_fraction v_j_identity same_label_auroc 1.0 +5 ALSKGVHFV mismatch_fraction v_j_identity same_label_auprc_balanced 1.0 +6 FLYALALLL absolute exact_cdr3_length within_between_ratio 1.0 +6 FLYALALLL absolute exact_cdr3_length between_minus_within 0.0 +6 FLYALALLL absolute exact_cdr3_length same_label_auroc 0.5 +6 FLYALALLL absolute exact_cdr3_length same_label_auprc_balanced 0.5 +6 FLYALALLL cosine amino_acid_composition within_between_ratio 0.8643636499681533 +6 FLYALALLL cosine amino_acid_composition between_minus_within 0.0276565312034742 +6 FLYALALLL cosine amino_acid_composition same_label_auroc 1.0 +6 FLYALALLL cosine amino_acid_composition same_label_auprc_balanced 1.0 +6 FLYALALLL euclidean amino_acid_composition within_between_ratio 0.983532756656882 +6 FLYALALLL euclidean amino_acid_composition between_minus_within 0.0036101150869386 +6 FLYALALLL euclidean amino_acid_composition same_label_auroc 1.0 +6 FLYALALLL euclidean amino_acid_composition same_label_auprc_balanced 1.0 +6 FLYALALLL mismatch_fraction v_j_identity within_between_ratio 1.0 +6 FLYALALLL mismatch_fraction v_j_identity between_minus_within 0.0 +6 FLYALALLL mismatch_fraction v_j_identity same_label_auroc 0.5 +6 FLYALALLL mismatch_fraction v_j_identity same_label_auprc_balanced 0.5 diff --git a/results/author/downstream_per_epitope_metrics.tsv b/results/author/downstream_per_epitope_metrics.tsv new file mode 100644 index 0000000..c657e1d --- /dev/null +++ b/results/author/downstream_per_epitope_metrics.tsv @@ -0,0 +1,505 @@ +rank epitope distance model metric value +1 GILGFVFTL cosine r within_between_ratio 0.814834956105159 +1 GILGFVFTL cosine r between_minus_within 0.1233428152129985 +1 GILGFVFTL cosine r same_label_auroc 0.73158876 +1 GILGFVFTL cosine r same_label_auprc_balanced 0.7299518893107003 +1 GILGFVFTL cosine r precision_at_1 0.9956709956709956 +1 GILGFVFTL cosine r map_at_r 0.8377571417671207 +1 GILGFVFTL cosine t within_between_ratio 0.7684862592239499 +1 GILGFVFTL cosine t between_minus_within 0.1538348010838437 +1 GILGFVFTL cosine t same_label_auroc 0.71333396 +1 GILGFVFTL cosine t same_label_auprc_balanced 0.674158188636663 +1 GILGFVFTL cosine t precision_at_1 0.9913419913419912 +1 GILGFVFTL cosine t map_at_r 0.8391364170281714 +1 GILGFVFTL cosine p within_between_ratio 0.8230982847313358 +1 GILGFVFTL cosine p between_minus_within 0.0206568423984859 +1 GILGFVFTL cosine p same_label_auroc 0.53763092 +1 GILGFVFTL cosine p same_label_auprc_balanced 0.521491273229804 +1 GILGFVFTL cosine p precision_at_1 0.8982683982683982 +1 GILGFVFTL cosine p map_at_r 0.7469039220366203 +1 GILGFVFTL cosine rt within_between_ratio 0.8470954060378486 +1 GILGFVFTL cosine rt between_minus_within 0.1070347350523491 +1 GILGFVFTL cosine rt same_label_auroc 0.70806996 +1 GILGFVFTL cosine rt same_label_auprc_balanced 0.7050656379180732 +1 GILGFVFTL cosine rt precision_at_1 0.9956709956709956 +1 GILGFVFTL cosine rt map_at_r 0.8290056068583498 +1 GILGFVFTL cosine rp within_between_ratio 0.8013631708826814 +1 GILGFVFTL cosine rp between_minus_within 0.1202215255443032 +1 GILGFVFTL cosine rp same_label_auroc 0.7257904800000001 +1 GILGFVFTL cosine rp same_label_auprc_balanced 0.7174927693471926 +1 GILGFVFTL cosine rp precision_at_1 0.9935064935064936 +1 GILGFVFTL cosine rp map_at_r 0.8382527018021324 +1 GILGFVFTL cosine tp within_between_ratio 0.7243638016662785 +1 GILGFVFTL cosine tp between_minus_within 0.137600465097264 +1 GILGFVFTL cosine tp same_label_auroc 0.75484744 +1 GILGFVFTL cosine tp same_label_auprc_balanced 0.7053104436509567 +1 GILGFVFTL cosine tp precision_at_1 0.9891774891774892 +1 GILGFVFTL cosine tp map_at_r 0.8556084509363918 +1 GILGFVFTL cosine rtp within_between_ratio 0.829036865860044 +1 GILGFVFTL cosine rtp between_minus_within 0.110323732416114 +1 GILGFVFTL cosine rtp same_label_auroc 0.71991092 +1 GILGFVFTL cosine rtp same_label_auprc_balanced 0.7144508771003788 +1 GILGFVFTL cosine rtp precision_at_1 0.987012987012987 +1 GILGFVFTL cosine rtp map_at_r 0.835703226039053 +1 GILGFVFTL euclidean r within_between_ratio 0.8980290222030745 +1 GILGFVFTL euclidean r between_minus_within 1.2324917821683776 +1 GILGFVFTL euclidean r same_label_auroc 0.73664052 +1 GILGFVFTL euclidean r same_label_auprc_balanced 0.7351607337112969 +1 GILGFVFTL euclidean r precision_at_1 0.9956709956709956 +1 GILGFVFTL euclidean r map_at_r 0.8403814016170456 +1 GILGFVFTL euclidean t within_between_ratio 0.8627014070154413 +1 GILGFVFTL euclidean t between_minus_within 1.7771783413246125 +1 GILGFVFTL euclidean t same_label_auroc 0.71670196 +1 GILGFVFTL euclidean t same_label_auprc_balanced 0.6769013347021693 +1 GILGFVFTL euclidean t precision_at_1 0.9913419913419912 +1 GILGFVFTL euclidean t map_at_r 0.8439129645545131 +1 GILGFVFTL euclidean p within_between_ratio 0.8973830858007207 +1 GILGFVFTL euclidean p between_minus_within 0.4762456869122298 +1 GILGFVFTL euclidean p same_label_auroc 0.54044212 +1 GILGFVFTL euclidean p same_label_auprc_balanced 0.5236232343171925 +1 GILGFVFTL euclidean p precision_at_1 0.8982683982683982 +1 GILGFVFTL euclidean p map_at_r 0.7478342545035729 +1 GILGFVFTL euclidean rt within_between_ratio 0.9181802458439324 +1 GILGFVFTL euclidean rt between_minus_within 1.0255226173407426 +1 GILGFVFTL euclidean rt same_label_auroc 0.70650972 +1 GILGFVFTL euclidean rt same_label_auprc_balanced 0.7064940862833436 +1 GILGFVFTL euclidean rt precision_at_1 0.9956709956709956 +1 GILGFVFTL euclidean rt map_at_r 0.8272032472168177 +1 GILGFVFTL euclidean rp within_between_ratio 0.8919376258759846 +1 GILGFVFTL euclidean rp between_minus_within 1.1943521196618183 +1 GILGFVFTL euclidean rp same_label_auroc 0.7277302 +1 GILGFVFTL euclidean rp same_label_auprc_balanced 0.7211318096286985 +1 GILGFVFTL euclidean rp precision_at_1 0.9956709956709956 +1 GILGFVFTL euclidean rp map_at_r 0.8390079506829614 +1 GILGFVFTL euclidean tp within_between_ratio 0.8430098768730618 +1 GILGFVFTL euclidean tp between_minus_within 1.764684817162717 +1 GILGFVFTL euclidean tp same_label_auroc 0.75650096 +1 GILGFVFTL euclidean tp same_label_auprc_balanced 0.7068407684952329 +1 GILGFVFTL euclidean tp precision_at_1 0.9891774891774892 +1 GILGFVFTL euclidean tp map_at_r 0.8574148540779141 +1 GILGFVFTL euclidean rtp within_between_ratio 0.9120983001562664 +1 GILGFVFTL euclidean rtp between_minus_within 1.0340184856414627 +1 GILGFVFTL euclidean rtp same_label_auroc 0.7109821999999999 +1 GILGFVFTL euclidean rtp same_label_auprc_balanced 0.7101946466646145 +1 GILGFVFTL euclidean rtp precision_at_1 0.987012987012987 +1 GILGFVFTL euclidean rtp map_at_r 0.8320969033377764 +2 GLCTLVAML cosine r within_between_ratio 0.9304252886506998 +2 GLCTLVAML cosine r between_minus_within 0.0469673049657198 +2 GLCTLVAML cosine r same_label_auroc 0.5325370487059209 +2 GLCTLVAML cosine r same_label_auprc_balanced 0.6220477286785298 +2 GLCTLVAML cosine r precision_at_1 0.9782608695652174 +2 GLCTLVAML cosine r map_at_r 0.2960349214300812 +2 GLCTLVAML cosine t within_between_ratio 0.6904286297927523 +2 GLCTLVAML cosine t between_minus_within 0.2327473467424893 +2 GLCTLVAML cosine t same_label_auroc 0.7486634460547503 +2 GLCTLVAML cosine t same_label_auprc_balanced 0.7541585193205 +2 GLCTLVAML cosine t precision_at_1 0.9347826086956522 +2 GLCTLVAML cosine t map_at_r 0.5281064277718629 +2 GLCTLVAML cosine p within_between_ratio 0.2016262709941349 +2 GLCTLVAML cosine p between_minus_within 0.1346310777629427 +2 GLCTLVAML cosine p same_label_auroc 0.8133053280123224 +2 GLCTLVAML cosine p same_label_auprc_balanced 0.764362746527017 +2 GLCTLVAML cosine p precision_at_1 0.7391304347826086 +2 GLCTLVAML cosine p map_at_r 0.3971554962427943 +2 GLCTLVAML cosine rt within_between_ratio 0.8290567233595127 +2 GLCTLVAML cosine rt between_minus_within 0.1212739293962659 +2 GLCTLVAML cosine rt same_label_auroc 0.6504338490979953 +2 GLCTLVAML cosine rt same_label_auprc_balanced 0.7091789691940154 +2 GLCTLVAML cosine rt precision_at_1 0.9782608695652174 +2 GLCTLVAML cosine rt map_at_r 0.3897568779087489 +2 GLCTLVAML cosine rp within_between_ratio 0.9159199337758568 +2 GLCTLVAML cosine rp between_minus_within 0.0537090332683131 +2 GLCTLVAML cosine rp same_label_auroc 0.5408042194683657 +2 GLCTLVAML cosine rp same_label_auprc_balanced 0.6241568998359073 +2 GLCTLVAML cosine rp precision_at_1 0.9782608695652174 +2 GLCTLVAML cosine rp map_at_r 0.30432489044198 +2 GLCTLVAML cosine tp within_between_ratio 0.7479251171475703 +2 GLCTLVAML cosine tp between_minus_within 0.1461652305207085 +2 GLCTLVAML cosine tp same_label_auroc 0.7091759434292515 +2 GLCTLVAML cosine tp same_label_auprc_balanced 0.7144185257602391 +2 GLCTLVAML cosine tp precision_at_1 0.9347826086956522 +2 GLCTLVAML cosine tp map_at_r 0.4710206617825163 +2 GLCTLVAML cosine rtp within_between_ratio 0.8395844652525207 +2 GLCTLVAML cosine rtp between_minus_within 0.1087192530041349 +2 GLCTLVAML cosine rtp same_label_auroc 0.6468519685406894 +2 GLCTLVAML cosine rtp same_label_auprc_balanced 0.6999856842884669 +2 GLCTLVAML cosine rtp precision_at_1 0.9782608695652174 +2 GLCTLVAML cosine rtp map_at_r 0.3668666020143697 +2 GLCTLVAML euclidean r within_between_ratio 0.9470494666132306 +2 GLCTLVAML euclidean r between_minus_within 0.643298441606289 +2 GLCTLVAML euclidean r same_label_auroc 0.543551541459544 +2 GLCTLVAML euclidean r same_label_auprc_balanced 0.6278778128933347 +2 GLCTLVAML euclidean r precision_at_1 0.9782608695652174 +2 GLCTLVAML euclidean r map_at_r 0.2969725401974061 +2 GLCTLVAML euclidean t within_between_ratio 0.7836093129434006 +2 GLCTLVAML euclidean t between_minus_within 3.009821017983443 +2 GLCTLVAML euclidean t same_label_auroc 0.7435272701813344 +2 GLCTLVAML euclidean t same_label_auprc_balanced 0.7513258188815857 +2 GLCTLVAML euclidean t precision_at_1 0.9347826086956522 +2 GLCTLVAML euclidean t map_at_r 0.525644495113936 +2 GLCTLVAML euclidean p within_between_ratio 0.4021732315244646 +2 GLCTLVAML euclidean p between_minus_within 3.49534116615842 +2 GLCTLVAML euclidean p same_label_auroc 0.810628952834372 +2 GLCTLVAML euclidean p same_label_auprc_balanced 0.7625697321880942 +2 GLCTLVAML euclidean p precision_at_1 0.7391304347826086 +2 GLCTLVAML euclidean p map_at_r 0.3968899090179063 +2 GLCTLVAML euclidean rt within_between_ratio 0.8871695287309327 +2 GLCTLVAML euclidean rt between_minus_within 1.4121366935531796 +2 GLCTLVAML euclidean rt same_label_auroc 0.6718961936101193 +2 GLCTLVAML euclidean rt same_label_auprc_balanced 0.7209395050987346 +2 GLCTLVAML euclidean rt precision_at_1 0.9782608695652174 +2 GLCTLVAML euclidean rt map_at_r 0.4009350926126311 +2 GLCTLVAML euclidean rp within_between_ratio 0.9376119790475408 +2 GLCTLVAML euclidean rp between_minus_within 0.7060268471358278 +2 GLCTLVAML euclidean rp same_label_auroc 0.5572181381129082 +2 GLCTLVAML euclidean rp same_label_auprc_balanced 0.6330275638221696 +2 GLCTLVAML euclidean rp precision_at_1 0.9782608695652174 +2 GLCTLVAML euclidean rp map_at_r 0.3085944081608493 +2 GLCTLVAML euclidean tp within_between_ratio 0.832802537212801 +2 GLCTLVAML euclidean tp between_minus_within 2.042914623086965 +2 GLCTLVAML euclidean tp same_label_auroc 0.7049527410207939 +2 GLCTLVAML euclidean tp same_label_auprc_balanced 0.710591732184743 +2 GLCTLVAML euclidean tp precision_at_1 0.9347826086956522 +2 GLCTLVAML euclidean tp map_at_r 0.4632930047916605 +2 GLCTLVAML euclidean rtp within_between_ratio 0.8893726101341216 +2 GLCTLVAML euclidean rtp between_minus_within 1.3297842074997224 +2 GLCTLVAML euclidean rtp same_label_auroc 0.6801923032042755 +2 GLCTLVAML euclidean rtp same_label_auprc_balanced 0.7184602005371521 +2 GLCTLVAML euclidean rtp precision_at_1 0.9782608695652174 +2 GLCTLVAML euclidean rtp map_at_r 0.3851989042931715 +3 YLQPRTFLL cosine r within_between_ratio 0.9234808526023524 +3 YLQPRTFLL cosine r between_minus_within 0.0446161337209015 +3 YLQPRTFLL cosine r same_label_auroc 0.5777331747919143 +3 YLQPRTFLL cosine r same_label_auprc_balanced 0.6199786587907083 +3 YLQPRTFLL cosine r precision_at_1 1.0 +3 YLQPRTFLL cosine r map_at_r 0.2966054624516153 +3 YLQPRTFLL cosine t within_between_ratio 0.9523943494125764 +3 YLQPRTFLL cosine t between_minus_within 0.019922715432474 +3 YLQPRTFLL cosine t same_label_auroc 0.5323434007134364 +3 YLQPRTFLL cosine t same_label_auprc_balanced 0.5862232348035362 +3 YLQPRTFLL cosine t precision_at_1 0.825 +3 YLQPRTFLL cosine t map_at_r 0.292351315785512 +3 YLQPRTFLL cosine p within_between_ratio 0.8128660411253578 +3 YLQPRTFLL cosine p between_minus_within 0.0228717270199522 +3 YLQPRTFLL cosine p same_label_auroc 0.5686582639714625 +3 YLQPRTFLL cosine p same_label_auprc_balanced 0.557005125811634 +3 YLQPRTFLL cosine p precision_at_1 0.3 +3 YLQPRTFLL cosine p map_at_r 0.1395447798181916 +3 YLQPRTFLL cosine rt within_between_ratio 0.8632042895855496 +3 YLQPRTFLL cosine rt between_minus_within 0.0844520133839246 +3 YLQPRTFLL cosine rt same_label_auroc 0.6346615933412604 +3 YLQPRTFLL cosine rt same_label_auprc_balanced 0.6779547121190657 +3 YLQPRTFLL cosine rt precision_at_1 0.975 +3 YLQPRTFLL cosine rt map_at_r 0.4070361074886092 +3 YLQPRTFLL cosine rp within_between_ratio 0.9310489264658908 +3 YLQPRTFLL cosine rp between_minus_within 0.0366156392001849 +3 YLQPRTFLL cosine rp same_label_auroc 0.5640332936979786 +3 YLQPRTFLL cosine rp same_label_auprc_balanced 0.5943170885404121 +3 YLQPRTFLL cosine rp precision_at_1 1.0 +3 YLQPRTFLL cosine rp map_at_r 0.29964836781615 +3 YLQPRTFLL cosine tp within_between_ratio 0.9533213775412188 +3 YLQPRTFLL cosine tp between_minus_within 0.0160828353071133 +3 YLQPRTFLL cosine tp same_label_auroc 0.5300889417360286 +3 YLQPRTFLL cosine tp same_label_auprc_balanced 0.5957361011159912 +3 YLQPRTFLL cosine tp precision_at_1 0.825 +3 YLQPRTFLL cosine tp map_at_r 0.2987907026485508 +3 YLQPRTFLL cosine rtp within_between_ratio 0.9120239325822764 +3 YLQPRTFLL cosine rtp between_minus_within 0.0486971483198341 +3 YLQPRTFLL cosine rtp same_label_auroc 0.5801588585017836 +3 YLQPRTFLL cosine rtp same_label_auprc_balanced 0.6137564655276165 +3 YLQPRTFLL cosine rtp precision_at_1 0.975 +3 YLQPRTFLL cosine rtp map_at_r 0.3691817079869173 +3 YLQPRTFLL euclidean r within_between_ratio 0.9530694427510062 +3 YLQPRTFLL euclidean r between_minus_within 0.5335972980226611 +3 YLQPRTFLL euclidean r same_label_auroc 0.5835319857312723 +3 YLQPRTFLL euclidean r same_label_auprc_balanced 0.6232151785513477 +3 YLQPRTFLL euclidean r precision_at_1 1.0 +3 YLQPRTFLL euclidean r map_at_r 0.2957945422594127 +3 YLQPRTFLL euclidean t within_between_ratio 0.9589057298754774 +3 YLQPRTFLL euclidean t between_minus_within 0.4112640325394672 +3 YLQPRTFLL euclidean t same_label_auroc 0.5286753864447087 +3 YLQPRTFLL euclidean t same_label_auprc_balanced 0.5835250342709797 +3 YLQPRTFLL euclidean t precision_at_1 0.825 +3 YLQPRTFLL euclidean t map_at_r 0.2879492583841253 +3 YLQPRTFLL euclidean p within_between_ratio 0.8696962900330723 +3 YLQPRTFLL euclidean p between_minus_within 0.6439082943692966 +3 YLQPRTFLL euclidean p same_label_auroc 0.566814744351962 +3 YLQPRTFLL euclidean p same_label_auprc_balanced 0.5538283154450125 +3 YLQPRTFLL euclidean p precision_at_1 0.275 +3 YLQPRTFLL euclidean p map_at_r 0.1388273830698967 +3 YLQPRTFLL euclidean rt within_between_ratio 0.9200626838923368 +3 YLQPRTFLL euclidean rt between_minus_within 0.9411507264122356 +3 YLQPRTFLL euclidean rt same_label_auroc 0.6455286563614744 +3 YLQPRTFLL euclidean rt same_label_auprc_balanced 0.6898694962560761 +3 YLQPRTFLL euclidean rt precision_at_1 0.975 +3 YLQPRTFLL euclidean rt map_at_r 0.4103746473365836 +3 YLQPRTFLL euclidean rp within_between_ratio 0.9583005918155642 +3 YLQPRTFLL euclidean rp between_minus_within 0.4338869883892666 +3 YLQPRTFLL euclidean rp same_label_auroc 0.5674882282996433 +3 YLQPRTFLL euclidean rp same_label_auprc_balanced 0.5968576844192361 +3 YLQPRTFLL euclidean rp precision_at_1 1.0 +3 YLQPRTFLL euclidean rp map_at_r 0.2988144296423183 +3 YLQPRTFLL euclidean tp within_between_ratio 0.9551444520774234 +3 YLQPRTFLL euclidean tp between_minus_within 0.413196233338418 +3 YLQPRTFLL euclidean tp same_label_auroc 0.529468727705113 +3 YLQPRTFLL euclidean tp same_label_auprc_balanced 0.595362675292274 +3 YLQPRTFLL euclidean tp precision_at_1 0.825 +3 YLQPRTFLL euclidean tp map_at_r 0.2989943295932016 +3 YLQPRTFLL euclidean rtp within_between_ratio 0.9433479558101976 +3 YLQPRTFLL euclidean rtp between_minus_within 0.6197374939630098 +3 YLQPRTFLL euclidean rtp same_label_auroc 0.596221640903686 +3 YLQPRTFLL euclidean rtp same_label_auprc_balanced 0.6267377767138391 +3 YLQPRTFLL euclidean rtp precision_at_1 0.975 +3 YLQPRTFLL euclidean rtp map_at_r 0.3804617652468797 +4 SLYNTVATL cosine r within_between_ratio 0.4832409495705956 +4 SLYNTVATL cosine r between_minus_within 0.1923712751303949 +4 SLYNTVATL cosine r same_label_auroc 0.96 +4 SLYNTVATL cosine r same_label_auprc_balanced 0.9651515151515152 +4 SLYNTVATL cosine r precision_at_1 1.0 +4 SLYNTVATL cosine r map_at_r 0.95 +4 SLYNTVATL cosine t within_between_ratio 1.1742857931789124 +4 SLYNTVATL cosine t between_minus_within -0.0485228913031524 +4 SLYNTVATL cosine t same_label_auroc 0.42 +4 SLYNTVATL cosine t same_label_auprc_balanced 0.5704667116509221 +4 SLYNTVATL cosine t precision_at_1 0.8 +4 SLYNTVATL cosine t map_at_r 0.225 +4 SLYNTVATL cosine p within_between_ratio 1.0727657502231038 +4 SLYNTVATL cosine p between_minus_within -0.0030095301249663 +4 SLYNTVATL cosine p same_label_auroc 0.43 +4 SLYNTVATL cosine p same_label_auprc_balanced 0.4691727278569384 +4 SLYNTVATL cosine p precision_at_1 0.0 +4 SLYNTVATL cosine p map_at_r 0.0749999999999999 +4 SLYNTVATL cosine rt within_between_ratio 0.5760962155828022 +4 SLYNTVATL cosine rt between_minus_within 0.1759200280098875 +4 SLYNTVATL cosine rt same_label_auroc 0.8700000000000001 +4 SLYNTVATL cosine rt same_label_auprc_balanced 0.8977272727272726 +4 SLYNTVATL cosine rt precision_at_1 1.0 +4 SLYNTVATL cosine rt map_at_r 0.75 +4 SLYNTVATL cosine rp within_between_ratio 0.4888609802364154 +4 SLYNTVATL cosine rp between_minus_within 0.1829847437593619 +4 SLYNTVATL cosine rp same_label_auroc 0.91 +4 SLYNTVATL cosine rp same_label_auprc_balanced 0.9246503496503496 +4 SLYNTVATL cosine rp precision_at_1 1.0 +4 SLYNTVATL cosine rp map_at_r 0.85 +4 SLYNTVATL cosine tp within_between_ratio 1.030978839230196 +4 SLYNTVATL cosine tp between_minus_within -0.0053958569484331 +4 SLYNTVATL cosine tp same_label_auroc 0.44 +4 SLYNTVATL cosine tp same_label_auprc_balanced 0.5771453108295213 +4 SLYNTVATL cosine tp precision_at_1 0.8 +4 SLYNTVATL cosine tp map_at_r 0.2666666666666666 +4 SLYNTVATL cosine rtp within_between_ratio 0.6335676056698618 +4 SLYNTVATL cosine rtp between_minus_within 0.1260056296589986 +4 SLYNTVATL cosine rtp same_label_auroc 0.8400000000000001 +4 SLYNTVATL cosine rtp same_label_auprc_balanced 0.8827272727272727 +4 SLYNTVATL cosine rtp precision_at_1 1.0 +4 SLYNTVATL cosine rtp map_at_r 0.775 +4 SLYNTVATL euclidean r within_between_ratio 0.6865976748898798 +4 SLYNTVATL euclidean r between_minus_within 2.8328790717609937 +4 SLYNTVATL euclidean r same_label_auroc 0.96 +4 SLYNTVATL euclidean r same_label_auprc_balanced 0.9651515151515152 +4 SLYNTVATL euclidean r precision_at_1 1.0 +4 SLYNTVATL euclidean r map_at_r 0.95 +4 SLYNTVATL euclidean t within_between_ratio 1.0462181651429443 +4 SLYNTVATL euclidean t between_minus_within -0.3722083127557116 +4 SLYNTVATL euclidean t same_label_auroc 0.42 +4 SLYNTVATL euclidean t same_label_auprc_balanced 0.5704667116509221 +4 SLYNTVATL euclidean t precision_at_1 0.8 +4 SLYNTVATL euclidean t map_at_r 0.225 +4 SLYNTVATL euclidean p within_between_ratio 1.0386560265576643 +4 SLYNTVATL euclidean p between_minus_within -0.1045513795820771 +4 SLYNTVATL euclidean p same_label_auroc 0.43 +4 SLYNTVATL euclidean p same_label_auprc_balanced 0.4691727278569384 +4 SLYNTVATL euclidean p precision_at_1 0.0 +4 SLYNTVATL euclidean p map_at_r 0.0749999999999999 +4 SLYNTVATL euclidean rt within_between_ratio 0.7486457046270609 +4 SLYNTVATL euclidean rt between_minus_within 2.429093726497872 +4 SLYNTVATL euclidean rt same_label_auroc 0.87 +4 SLYNTVATL euclidean rt same_label_auprc_balanced 0.8961247086247085 +4 SLYNTVATL euclidean rt precision_at_1 1.0 +4 SLYNTVATL euclidean rt map_at_r 0.75 +4 SLYNTVATL euclidean rp within_between_ratio 0.6938813768447298 +4 SLYNTVATL euclidean rp between_minus_within 2.606095320464502 +4 SLYNTVATL euclidean rp same_label_auroc 0.91 +4 SLYNTVATL euclidean rp same_label_auprc_balanced 0.9246503496503496 +4 SLYNTVATL euclidean rp precision_at_1 1.0 +4 SLYNTVATL euclidean rp map_at_r 0.85 +4 SLYNTVATL euclidean tp within_between_ratio 0.9867719221564634 +4 SLYNTVATL euclidean tp between_minus_within 0.0847202375826423 +4 SLYNTVATL euclidean tp same_label_auroc 0.44 +4 SLYNTVATL euclidean tp same_label_auprc_balanced 0.5771453108295213 +4 SLYNTVATL euclidean tp precision_at_1 0.8 +4 SLYNTVATL euclidean tp map_at_r 0.2666666666666666 +4 SLYNTVATL euclidean rtp within_between_ratio 0.7918103110184312 +4 SLYNTVATL euclidean rtp between_minus_within 1.7841010079875463 +4 SLYNTVATL euclidean rtp same_label_auroc 0.8400000000000001 +4 SLYNTVATL euclidean rtp same_label_auprc_balanced 0.8827272727272727 +4 SLYNTVATL euclidean rtp precision_at_1 1.0 +4 SLYNTVATL euclidean rtp map_at_r 0.775 +5 ALSKGVHFV cosine r within_between_ratio 0.3866865701359755 +5 ALSKGVHFV cosine r between_minus_within 0.2910739948539576 +5 ALSKGVHFV cosine r same_label_auroc 1.0 +5 ALSKGVHFV cosine r same_label_auprc_balanced 1.0 +5 ALSKGVHFV cosine r precision_at_1 1.0 +5 ALSKGVHFV cosine r map_at_r 1.0 +5 ALSKGVHFV cosine t within_between_ratio 0.2201952872084881 +5 ALSKGVHFV cosine t between_minus_within 0.1352382523939194 +5 ALSKGVHFV cosine t same_label_auroc 0.9722222222222224 +5 ALSKGVHFV cosine t same_label_auprc_balanced 0.976190476190476 +5 ALSKGVHFV cosine t precision_at_1 0.75 +5 ALSKGVHFV cosine t map_at_r 0.5972222222222222 +5 ALSKGVHFV cosine p within_between_ratio 0.7921547385522357 +5 ALSKGVHFV cosine p between_minus_within 0.0084317881806044 +5 ALSKGVHFV cosine p same_label_auroc 0.4722222222222222 +5 ALSKGVHFV cosine p same_label_auprc_balanced 0.5983164983164984 +5 ALSKGVHFV cosine p precision_at_1 0.0 +5 ALSKGVHFV cosine p map_at_r 0.0416666666666666 +5 ALSKGVHFV cosine rt within_between_ratio 0.3962952790798194 +5 ALSKGVHFV cosine rt between_minus_within 0.2712548608840007 +5 ALSKGVHFV cosine rt same_label_auroc 1.0 +5 ALSKGVHFV cosine rt same_label_auprc_balanced 1.0 +5 ALSKGVHFV cosine rt precision_at_1 1.0 +5 ALSKGVHFV cosine rt map_at_r 1.0 +5 ALSKGVHFV cosine rp within_between_ratio 0.3960752750678162 +5 ALSKGVHFV cosine rp between_minus_within 0.2488982920455894 +5 ALSKGVHFV cosine rp same_label_auroc 1.0 +5 ALSKGVHFV cosine rp same_label_auprc_balanced 1.0 +5 ALSKGVHFV cosine rp precision_at_1 1.0 +5 ALSKGVHFV cosine rp map_at_r 1.0 +5 ALSKGVHFV cosine tp within_between_ratio 0.3950118209766391 +5 ALSKGVHFV cosine tp between_minus_within 0.0890139005725051 +5 ALSKGVHFV cosine tp same_label_auroc 0.9444444444444444 +5 ALSKGVHFV cosine tp same_label_auprc_balanced 0.9583333333333331 +5 ALSKGVHFV cosine tp precision_at_1 1.0 +5 ALSKGVHFV cosine tp map_at_r 0.6666666666666666 +5 ALSKGVHFV cosine rtp within_between_ratio 0.4186267993922287 +5 ALSKGVHFV cosine rtp between_minus_within 0.2138412621092893 +5 ALSKGVHFV cosine rtp same_label_auroc 1.0 +5 ALSKGVHFV cosine rtp same_label_auprc_balanced 1.0 +5 ALSKGVHFV cosine rtp precision_at_1 1.0 +5 ALSKGVHFV cosine rtp map_at_r 1.0 +5 ALSKGVHFV euclidean r within_between_ratio 0.6251015024335775 +5 ALSKGVHFV euclidean r between_minus_within 3.838027858236756 +5 ALSKGVHFV euclidean r same_label_auroc 1.0 +5 ALSKGVHFV euclidean r same_label_auprc_balanced 1.0 +5 ALSKGVHFV euclidean r precision_at_1 1.0 +5 ALSKGVHFV euclidean r map_at_r 1.0 +5 ALSKGVHFV euclidean t within_between_ratio 0.4450798133529459 +5 ALSKGVHFV euclidean t between_minus_within 3.637365859970788 +5 ALSKGVHFV euclidean t same_label_auroc 0.9722222222222224 +5 ALSKGVHFV euclidean t same_label_auprc_balanced 0.976190476190476 +5 ALSKGVHFV euclidean t precision_at_1 0.75 +5 ALSKGVHFV euclidean t map_at_r 0.5972222222222222 +5 ALSKGVHFV euclidean p within_between_ratio 0.9725661204439372 +5 ALSKGVHFV euclidean p between_minus_within 0.0751790534833554 +5 ALSKGVHFV euclidean p same_label_auroc 0.4444444444444444 +5 ALSKGVHFV euclidean p same_label_auprc_balanced 0.514983164983165 +5 ALSKGVHFV euclidean p precision_at_1 0.0 +5 ALSKGVHFV euclidean p map_at_r 0.0416666666666666 +5 ALSKGVHFV euclidean rt within_between_ratio 0.6210177573640201 +5 ALSKGVHFV euclidean rt between_minus_within 3.774737004163465 +5 ALSKGVHFV euclidean rt same_label_auroc 1.0 +5 ALSKGVHFV euclidean rt same_label_auprc_balanced 1.0 +5 ALSKGVHFV euclidean rt precision_at_1 1.0 +5 ALSKGVHFV euclidean rt map_at_r 1.0 +5 ALSKGVHFV euclidean rp within_between_ratio 0.6226201452868303 +5 ALSKGVHFV euclidean rp between_minus_within 3.4502983786053063 +5 ALSKGVHFV euclidean rp same_label_auroc 1.0 +5 ALSKGVHFV euclidean rp same_label_auprc_balanced 1.0 +5 ALSKGVHFV euclidean rp precision_at_1 1.0 +5 ALSKGVHFV euclidean rp map_at_r 1.0 +5 ALSKGVHFV euclidean tp within_between_ratio 0.6149599833028031 +5 ALSKGVHFV euclidean tp between_minus_within 2.342975754521881 +5 ALSKGVHFV euclidean tp same_label_auroc 0.9444444444444444 +5 ALSKGVHFV euclidean tp same_label_auprc_balanced 0.9583333333333331 +5 ALSKGVHFV euclidean tp precision_at_1 1.0 +5 ALSKGVHFV euclidean tp map_at_r 0.6666666666666666 +5 ALSKGVHFV euclidean rtp within_between_ratio 0.642568503402784 +5 ALSKGVHFV euclidean rtp between_minus_within 3.1288563750265324 +5 ALSKGVHFV euclidean rtp same_label_auroc 1.0 +5 ALSKGVHFV euclidean rtp same_label_auprc_balanced 1.0 +5 ALSKGVHFV euclidean rtp precision_at_1 1.0 +5 ALSKGVHFV euclidean rtp map_at_r 1.0 +6 FLYALALLL cosine r within_between_ratio 0.6775292127221834 +6 FLYALALLL cosine r between_minus_within 0.2105191813140541 +6 FLYALALLL cosine r same_label_auroc 1.0 +6 FLYALALLL cosine r same_label_auprc_balanced 1.0 +6 FLYALALLL cosine r precision_at_1 0.0 +6 FLYALALLL cosine r map_at_r 0.0 +6 FLYALALLL cosine t within_between_ratio 0.7714240609847476 +6 FLYALALLL cosine t between_minus_within 0.1560307899158284 +6 FLYALALLL cosine t same_label_auroc 1.0 +6 FLYALALLL cosine t same_label_auprc_balanced 1.0 +6 FLYALALLL cosine t precision_at_1 0.0 +6 FLYALALLL cosine t map_at_r 0.0 +6 FLYALALLL cosine p within_between_ratio 1.7646471937707764 +6 FLYALALLL cosine p between_minus_within -0.0382589357909233 +6 FLYALALLL cosine p same_label_auroc 0.0 +6 FLYALALLL cosine p same_label_auprc_balanced 0.5 +6 FLYALALLL cosine p precision_at_1 0.0 +6 FLYALALLL cosine p map_at_r 0.0 +6 FLYALALLL cosine rt within_between_ratio 0.6906109655922215 +6 FLYALALLL cosine rt between_minus_within 0.1996168469751401 +6 FLYALALLL cosine rt same_label_auroc 1.0 +6 FLYALALLL cosine rt same_label_auprc_balanced 1.0 +6 FLYALALLL cosine rt precision_at_1 0.0 +6 FLYALALLL cosine rt map_at_r 0.0 +6 FLYALALLL cosine rp within_between_ratio 0.6707672271716343 +6 FLYALALLL cosine rp between_minus_within 0.1762362235339419 +6 FLYALALLL cosine rp same_label_auroc 1.0 +6 FLYALALLL cosine rp same_label_auprc_balanced 1.0 +6 FLYALALLL cosine rp precision_at_1 0.0 +6 FLYALALLL cosine rp map_at_r 0.0 +6 FLYALALLL cosine tp within_between_ratio 0.9508040033287974 +6 FLYALALLL cosine tp between_minus_within 0.0226730347800806 +6 FLYALALLL cosine tp same_label_auroc 1.0 +6 FLYALALLL cosine tp same_label_auprc_balanced 1.0 +6 FLYALALLL cosine tp precision_at_1 0.0 +6 FLYALALLL cosine tp map_at_r 0.0 +6 FLYALALLL cosine rtp within_between_ratio 0.7140904494680264 +6 FLYALALLL cosine rtp between_minus_within 0.1802256409848623 +6 FLYALALLL cosine rtp same_label_auroc 1.0 +6 FLYALALLL cosine rtp same_label_auprc_balanced 1.0 +6 FLYALALLL cosine rtp precision_at_1 0.0 +6 FLYALALLL cosine rtp map_at_r 0.0 +6 FLYALALLL euclidean r within_between_ratio 0.833307428600523 +6 FLYALALLL euclidean r between_minus_within 1.990730964832533 +6 FLYALALLL euclidean r same_label_auroc 1.0 +6 FLYALALLL euclidean r same_label_auprc_balanced 1.0 +6 FLYALALLL euclidean r precision_at_1 0.0 +6 FLYALALLL euclidean r map_at_r 0.0 +6 FLYALALLL euclidean t within_between_ratio 0.8712170925455438 +6 FLYALALLL euclidean t between_minus_within 1.7187362601360745 +6 FLYALALLL euclidean t same_label_auroc 1.0 +6 FLYALALLL euclidean t same_label_auprc_balanced 1.0 +6 FLYALALLL euclidean t precision_at_1 0.0 +6 FLYALALLL euclidean t map_at_r 0.0 +6 FLYALALLL euclidean p within_between_ratio 1.3238794339624518 +6 FLYALALLL euclidean p between_minus_within -1.1806467313926985 +6 FLYALALLL euclidean p same_label_auroc 0.0 +6 FLYALALLL euclidean p same_label_auprc_balanced 0.5 +6 FLYALALLL euclidean p precision_at_1 0.0 +6 FLYALALLL euclidean p map_at_r 0.0 +6 FLYALALLL euclidean rt within_between_ratio 0.8318839208376045 +6 FLYALALLL euclidean rt between_minus_within 2.0133576493387064 +6 FLYALALLL euclidean rt same_label_auroc 1.0 +6 FLYALALLL euclidean rt same_label_auprc_balanced 1.0 +6 FLYALALLL euclidean rt precision_at_1 0.0 +6 FLYALALLL euclidean rt map_at_r 0.0 +6 FLYALALLL euclidean rp within_between_ratio 0.8250319227075794 +6 FLYALALLL euclidean rp between_minus_within 1.819457314152068 +6 FLYALALLL euclidean rp same_label_auroc 1.0 +6 FLYALALLL euclidean rp same_label_auprc_balanced 1.0 +6 FLYALALLL euclidean rp precision_at_1 0.0 +6 FLYALALLL euclidean rp map_at_r 0.0 +6 FLYALALLL euclidean tp within_between_ratio 0.9745461896386142 +6 FLYALALLL euclidean tp between_minus_within 0.278119392422008 +6 FLYALALLL euclidean tp same_label_auroc 1.0 +6 FLYALALLL euclidean tp same_label_auprc_balanced 1.0 +6 FLYALALLL euclidean tp precision_at_1 0.0 +6 FLYALALLL euclidean tp map_at_r 0.0 +6 FLYALALLL euclidean rtp within_between_ratio 0.845959006340635 +6 FLYALALLL euclidean rtp between_minus_within 1.8007589492959664 +6 FLYALALLL euclidean rtp same_label_auroc 1.0 +6 FLYALALLL euclidean rtp same_label_auprc_balanced 1.0 +6 FLYALALLL euclidean rtp precision_at_1 0.0 +6 FLYALALLL euclidean rtp map_at_r 0.0 diff --git a/results/author/downstream_rtp_minus_rp_effects.tsv b/results/author/downstream_rtp_minus_rp_effects.tsv new file mode 100644 index 0000000..af9ab26 --- /dev/null +++ b/results/author/downstream_rtp_minus_rp_effects.tsv @@ -0,0 +1,73 @@ +rank epitope distance metric p r rp rt rtp t tp rtp_minus_rp +1 GILGFVFTL cosine between_minus_within 0.0206568423984859 0.1233428152129985 0.1202215255443032 0.1070347350523491 0.110323732416114 0.1538348010838437 0.137600465097264 -0.0098977931281891 +1 GILGFVFTL cosine map_at_r 0.7469039220366203 0.8377571417671207 0.8382527018021324 0.8290056068583498 0.835703226039053 0.8391364170281714 0.8556084509363918 -0.0025494757630794 +1 GILGFVFTL cosine precision_at_1 0.8982683982683982 0.9956709956709956 0.9935064935064936 0.9956709956709956 0.987012987012987 0.9913419913419912 0.9891774891774892 -0.0064935064935065 +1 GILGFVFTL cosine same_label_auprc_balanced 0.521491273229804 0.7299518893107003 0.7174927693471926 0.7050656379180732 0.7144508771003788 0.674158188636663 0.7053104436509567 -0.0030418922468138 +1 GILGFVFTL cosine same_label_auroc 0.53763092 0.73158876 0.7257904800000001 0.70806996 0.71991092 0.71333396 0.75484744 -0.0058795600000001 +1 GILGFVFTL cosine within_between_ratio 0.8230982847313358 0.814834956105159 0.8013631708826814 0.8470954060378486 0.829036865860044 0.7684862592239499 0.7243638016662785 0.0276736949773626 +1 GILGFVFTL euclidean between_minus_within 0.4762456869122298 1.2324917821683776 1.1943521196618183 1.0255226173407426 1.0340184856414627 1.7771783413246125 1.764684817162717 -0.1603336340203558 +1 GILGFVFTL euclidean map_at_r 0.7478342545035729 0.8403814016170456 0.8390079506829614 0.8272032472168177 0.8320969033377764 0.8439129645545131 0.8574148540779141 -0.0069110473451849 +1 GILGFVFTL euclidean precision_at_1 0.8982683982683982 0.9956709956709956 0.9956709956709956 0.9956709956709956 0.987012987012987 0.9913419913419912 0.9891774891774892 -0.0086580086580086 +1 GILGFVFTL euclidean same_label_auprc_balanced 0.5236232343171925 0.7351607337112969 0.7211318096286985 0.7064940862833436 0.7101946466646145 0.6769013347021693 0.7068407684952329 -0.0109371629640839 +1 GILGFVFTL euclidean same_label_auroc 0.54044212 0.73664052 0.7277302 0.70650972 0.7109821999999999 0.71670196 0.75650096 -0.016748 +1 GILGFVFTL euclidean within_between_ratio 0.8973830858007207 0.8980290222030745 0.8919376258759846 0.9181802458439324 0.9120983001562664 0.8627014070154413 0.8430098768730618 0.0201606742802817 +2 GLCTLVAML cosine between_minus_within 0.1346310777629427 0.0469673049657198 0.0537090332683131 0.1212739293962659 0.1087192530041349 0.2327473467424893 0.1461652305207085 0.0550102197358218 +2 GLCTLVAML cosine map_at_r 0.3971554962427943 0.2960349214300812 0.30432489044198 0.3897568779087489 0.3668666020143697 0.5281064277718629 0.4710206617825163 0.0625417115723897 +2 GLCTLVAML cosine precision_at_1 0.7391304347826086 0.9782608695652174 0.9782608695652174 0.9782608695652174 0.9782608695652174 0.9347826086956522 0.9347826086956522 0.0 +2 GLCTLVAML cosine same_label_auprc_balanced 0.764362746527017 0.6220477286785298 0.6241568998359073 0.7091789691940154 0.6999856842884669 0.7541585193205 0.7144185257602391 0.0758287844525595 +2 GLCTLVAML cosine same_label_auroc 0.8133053280123224 0.5325370487059209 0.5408042194683657 0.6504338490979953 0.6468519685406894 0.7486634460547503 0.7091759434292515 0.1060477490723237 +2 GLCTLVAML cosine within_between_ratio 0.2016262709941349 0.9304252886506998 0.9159199337758568 0.8290567233595127 0.8395844652525207 0.6904286297927523 0.7479251171475703 -0.076335468523336 +2 GLCTLVAML euclidean between_minus_within 3.49534116615842 0.643298441606289 0.7060268471358278 1.4121366935531796 1.3297842074997224 3.009821017983443 2.042914623086965 0.6237573603638946 +2 GLCTLVAML euclidean map_at_r 0.3968899090179063 0.2969725401974061 0.3085944081608493 0.4009350926126311 0.3851989042931715 0.525644495113936 0.4632930047916605 0.0766044961323221 +2 GLCTLVAML euclidean precision_at_1 0.7391304347826086 0.9782608695652174 0.9782608695652174 0.9782608695652174 0.9782608695652174 0.9347826086956522 0.9347826086956522 0.0 +2 GLCTLVAML euclidean same_label_auprc_balanced 0.7625697321880942 0.6278778128933347 0.6330275638221696 0.7209395050987346 0.7184602005371521 0.7513258188815857 0.710591732184743 0.0854326367149824 +2 GLCTLVAML euclidean same_label_auroc 0.810628952834372 0.543551541459544 0.5572181381129082 0.6718961936101193 0.6801923032042755 0.7435272701813344 0.7049527410207939 0.1229741650913672 +2 GLCTLVAML euclidean within_between_ratio 0.4021732315244646 0.9470494666132306 0.9376119790475408 0.8871695287309327 0.8893726101341216 0.7836093129434006 0.832802537212801 -0.0482393689134192 +3 YLQPRTFLL cosine between_minus_within 0.0228717270199522 0.0446161337209015 0.0366156392001849 0.0844520133839246 0.0486971483198341 0.019922715432474 0.0160828353071133 0.0120815091196492 +3 YLQPRTFLL cosine map_at_r 0.1395447798181916 0.2966054624516153 0.29964836781615 0.4070361074886092 0.3691817079869173 0.292351315785512 0.2987907026485508 0.0695333401707673 +3 YLQPRTFLL cosine precision_at_1 0.3 1.0 1.0 0.975 0.975 0.825 0.825 -0.025 +3 YLQPRTFLL cosine same_label_auprc_balanced 0.557005125811634 0.6199786587907083 0.5943170885404121 0.6779547121190657 0.6137564655276165 0.5862232348035362 0.5957361011159912 0.0194393769872044 +3 YLQPRTFLL cosine same_label_auroc 0.5686582639714625 0.5777331747919143 0.5640332936979786 0.6346615933412604 0.5801588585017836 0.5323434007134364 0.5300889417360286 0.016125564803805 +3 YLQPRTFLL cosine within_between_ratio 0.8128660411253578 0.9234808526023524 0.9310489264658908 0.8632042895855496 0.9120239325822764 0.9523943494125764 0.9533213775412188 -0.0190249938836142 +3 YLQPRTFLL euclidean between_minus_within 0.6439082943692966 0.5335972980226611 0.4338869883892666 0.9411507264122356 0.6197374939630098 0.4112640325394672 0.413196233338418 0.1858505055737431 +3 YLQPRTFLL euclidean map_at_r 0.1388273830698967 0.2957945422594127 0.2988144296423183 0.4103746473365836 0.3804617652468797 0.2879492583841253 0.2989943295932016 0.0816473356045614 +3 YLQPRTFLL euclidean precision_at_1 0.275 1.0 1.0 0.975 0.975 0.825 0.825 -0.025 +3 YLQPRTFLL euclidean same_label_auprc_balanced 0.5538283154450125 0.6232151785513477 0.5968576844192361 0.6898694962560761 0.6267377767138391 0.5835250342709797 0.595362675292274 0.0298800922946029 +3 YLQPRTFLL euclidean same_label_auroc 0.566814744351962 0.5835319857312723 0.5674882282996433 0.6455286563614744 0.596221640903686 0.5286753864447087 0.529468727705113 0.0287334126040427 +3 YLQPRTFLL euclidean within_between_ratio 0.8696962900330723 0.9530694427510062 0.9583005918155642 0.9200626838923368 0.9433479558101976 0.9589057298754774 0.9551444520774234 -0.0149526360053664 +4 SLYNTVATL cosine between_minus_within -0.0030095301249663 0.1923712751303949 0.1829847437593619 0.1759200280098875 0.1260056296589986 -0.0485228913031524 -0.0053958569484331 -0.0569791141003633 +4 SLYNTVATL cosine map_at_r 0.0749999999999999 0.95 0.85 0.75 0.775 0.225 0.2666666666666666 -0.0749999999999999 +4 SLYNTVATL cosine precision_at_1 0.0 1.0 1.0 1.0 1.0 0.8 0.8 0.0 +4 SLYNTVATL cosine same_label_auprc_balanced 0.4691727278569384 0.9651515151515152 0.9246503496503496 0.8977272727272726 0.8827272727272727 0.5704667116509221 0.5771453108295213 -0.0419230769230769 +4 SLYNTVATL cosine same_label_auroc 0.43 0.96 0.91 0.8700000000000001 0.8400000000000001 0.42 0.44 -0.0699999999999998 +4 SLYNTVATL cosine within_between_ratio 1.0727657502231038 0.4832409495705956 0.4888609802364154 0.5760962155828022 0.6335676056698618 1.1742857931789124 1.030978839230196 0.1447066254334464 +4 SLYNTVATL euclidean between_minus_within -0.1045513795820771 2.8328790717609937 2.606095320464502 2.429093726497872 1.7841010079875463 -0.3722083127557116 0.0847202375826423 -0.8219943124769555 +4 SLYNTVATL euclidean map_at_r 0.0749999999999999 0.95 0.85 0.75 0.775 0.225 0.2666666666666666 -0.0749999999999999 +4 SLYNTVATL euclidean precision_at_1 0.0 1.0 1.0 1.0 1.0 0.8 0.8 0.0 +4 SLYNTVATL euclidean same_label_auprc_balanced 0.4691727278569384 0.9651515151515152 0.9246503496503496 0.8961247086247085 0.8827272727272727 0.5704667116509221 0.5771453108295213 -0.0419230769230769 +4 SLYNTVATL euclidean same_label_auroc 0.43 0.96 0.91 0.87 0.8400000000000001 0.42 0.44 -0.0699999999999998 +4 SLYNTVATL euclidean within_between_ratio 1.0386560265576643 0.6865976748898798 0.6938813768447298 0.7486457046270609 0.7918103110184312 1.0462181651429443 0.9867719221564634 0.0979289341737014 +5 ALSKGVHFV cosine between_minus_within 0.0084317881806044 0.2910739948539576 0.2488982920455894 0.2712548608840007 0.2138412621092893 0.1352382523939194 0.0890139005725051 -0.0350570299363 +5 ALSKGVHFV cosine map_at_r 0.0416666666666666 1.0 1.0 1.0 1.0 0.5972222222222222 0.6666666666666666 0.0 +5 ALSKGVHFV cosine precision_at_1 0.0 1.0 1.0 1.0 1.0 0.75 1.0 0.0 +5 ALSKGVHFV cosine same_label_auprc_balanced 0.5983164983164984 1.0 1.0 1.0 1.0 0.976190476190476 0.9583333333333331 0.0 +5 ALSKGVHFV cosine same_label_auroc 0.4722222222222222 1.0 1.0 1.0 1.0 0.9722222222222224 0.9444444444444444 0.0 +5 ALSKGVHFV cosine within_between_ratio 0.7921547385522357 0.3866865701359755 0.3960752750678162 0.3962952790798194 0.4186267993922287 0.2201952872084881 0.3950118209766391 0.0225515243244124 +5 ALSKGVHFV euclidean between_minus_within 0.0751790534833554 3.838027858236756 3.4502983786053063 3.774737004163465 3.1288563750265324 3.637365859970788 2.342975754521881 -0.3214420035787739 +5 ALSKGVHFV euclidean map_at_r 0.0416666666666666 1.0 1.0 1.0 1.0 0.5972222222222222 0.6666666666666666 0.0 +5 ALSKGVHFV euclidean precision_at_1 0.0 1.0 1.0 1.0 1.0 0.75 1.0 0.0 +5 ALSKGVHFV euclidean same_label_auprc_balanced 0.514983164983165 1.0 1.0 1.0 1.0 0.976190476190476 0.9583333333333331 0.0 +5 ALSKGVHFV euclidean same_label_auroc 0.4444444444444444 1.0 1.0 1.0 1.0 0.9722222222222224 0.9444444444444444 0.0 +5 ALSKGVHFV euclidean within_between_ratio 0.9725661204439372 0.6251015024335775 0.6226201452868303 0.6210177573640201 0.642568503402784 0.4450798133529459 0.6149599833028031 0.0199483581159537 +6 FLYALALLL cosine between_minus_within -0.0382589357909233 0.2105191813140541 0.1762362235339419 0.1996168469751401 0.1802256409848623 0.1560307899158284 0.0226730347800806 0.0039894174509204 +6 FLYALALLL cosine map_at_r 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6 FLYALALLL cosine precision_at_1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6 FLYALALLL cosine same_label_auprc_balanced 0.5 1.0 1.0 1.0 1.0 1.0 1.0 0.0 +6 FLYALALLL cosine same_label_auroc 0.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 +6 FLYALALLL cosine within_between_ratio 1.7646471937707764 0.6775292127221834 0.6707672271716343 0.6906109655922215 0.7140904494680264 0.7714240609847476 0.9508040033287974 0.043323222296392 +6 FLYALALLL euclidean between_minus_within -1.1806467313926985 1.990730964832533 1.819457314152068 2.0133576493387064 1.8007589492959664 1.7187362601360745 0.278119392422008 -0.0186983648561014 +6 FLYALALLL euclidean map_at_r 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6 FLYALALLL euclidean precision_at_1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6 FLYALALLL euclidean same_label_auprc_balanced 0.5 1.0 1.0 1.0 1.0 1.0 1.0 0.0 +6 FLYALALLL euclidean same_label_auroc 0.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 +6 FLYALALLL euclidean within_between_ratio 1.3238794339624518 0.833307428600523 0.8250319227075794 0.8318839208376045 0.845959006340635 0.8712170925455438 0.9745461896386142 0.0209270836330556 diff --git a/results/author/external_author_global_comparison.md b/results/author/external_author_global_comparison.md new file mode 100644 index 0000000..e23a9fe --- /dev/null +++ b/results/author/external_author_global_comparison.md @@ -0,0 +1,10 @@ +| Method | Modality | Reconstruction exact | pgen RMSE | VDJdb P@1 | P@5 | P@10 | MAP | Within/between | +|---|---|---|---|---|---|---|---|---| +| DATA-ANCHOR RTP | sequence-only | 0.8831 +/- 0.0058 | 0.2375 +/- 0.0008 | 0.3879 | 0.3272 | 0.2940 | 0.3136 | 0.9526 | +| TCRemP prototype distances | sequence-derived alignment | 0.5181 +/- 0.0024 | 0.6038 +/- 0.0019 | NA | NA | NA | NA | NA | +| TCR-BERT final residue mean | sequence-only | 0.4778 +/- 0.0179 | 0.4299 +/- 0.0022 | 0.3590 | 0.3053 | 0.2735 | 0.2999 | 0.9722 | +| ESM2-35M final residue mean | sequence-only | 0.2042 +/- 0.0132 | 0.7086 +/- 0.0033 | 0.3597 | 0.3081 | 0.2782 | 0.2968 | 0.9410 | +| ESM2-8M final residue mean | sequence-only sensitivity | 0.2179 +/- 0.0075 | 0.7439 +/- 0.0012 | NA | NA | NA | NA | NA | +| SCEPTR CDR3-only native CLS | sequence-only | 0.8213 +/- 0.0043 | 0.6637 +/- 0.0062 | 0.3553 | 0.2778 | 0.2366 | 0.2651 | 1.0469 | +| SCEPTR default native CLS | annotation-aware V+CDR3+J | 0.7263 +/- 0.0125 | 0.8073 +/- 0.0084 | NA | NA | NA | NA | NA | +| CDR3 TF-IDF ridge | sequence control | NA | 0.7860 | NA | NA | NA | NA | NA | diff --git a/results/author/external_author_global_comparison.tsv b/results/author/external_author_global_comparison.tsv new file mode 100644 index 0000000..418179b --- /dev/null +++ b/results/author/external_author_global_comparison.tsv @@ -0,0 +1,9 @@ +condition method modality native_global_dim reconstruction_common_dim reconstruction_exact_mean reconstruction_exact_std reconstruction_token_accuracy_mean pgen_rmse_mean pgen_rmse_std pgen_r2_mean pgen_spearman_mean vdjdb_cosine_precision_at_1 vdjdb_cosine_precision_at_5 vdjdb_cosine_precision_at_10 vdjdb_cosine_map vdjdb_cosine_within_between_ratio vdjdb_cosine_knn_macro_f1_at_5 reconstruction_exact pgen_rmse vdjdb_p_at_1 vdjdb_p_at_5 vdjdb_p_at_10 vdjdb_map vdjdb_within_between_ratio +rtp DATA-ANCHOR RTP sequence-only 128.0 64.0 0.8831338630192095 0.0058150137887855 0.9810685896331252 0.2375036700301933 0.0007641427238683 0.9910726990213594 0.9958299890234856 0.38789317660994344 0.32720557444226145 0.2939801617089443 0.31364862922705045 0.9525868556453406 0.2744565109481644 0.8831 +/- 0.0058 0.2375 +/- 0.0008 0.3879 0.3272 0.2940 0.3136 0.9526 +tcremp TCRemP prototype distances sequence-derived alignment 9000.0 64.0 0.518052901538771 0.0024158527908004 0.9371434757441994 0.6038112324768586 0.0019115151879035455 0.9422992036297707 0.9650743522262878 0.5181 +/- 0.0024 0.6038 +/- 0.0019 NA NA NA NA NA +tcr_bert TCR-BERT final residue mean sequence-only 768.0 64.0 0.4777565456435013 0.0178585766284086 0.90975931989201 0.4298724150079793 0.0022051496033906 0.9707542136303974 0.9863067900009792 0.358981305173744 0.3053478420625738 0.2734693644304071 0.2998904226736852 0.9721619846959844 0.2582267395006297 0.4778 +/- 0.0179 0.4299 +/- 0.0022 0.3590 0.3053 0.2735 0.2999 0.9722 +esm2_35m ESM2-35M final residue mean sequence-only 480.0 64.0 0.20416373327969425 0.013152045845910268 0.8082159095428093 0.7086315695015749 0.0033364098056348564 0.9205262070492487 0.9632367899599094 0.3597203532617486 0.3080627550986812 0.2781556804093438 0.2968139690814502 0.9410002050511648 0.2406928227557169 0.2042 +/- 0.0132 0.7086 +/- 0.0033 0.3597 0.3081 0.2782 0.2968 0.9410 +esm2_8m ESM2-8M final residue mean sequence-only sensitivity 320.0 64.0 0.2179087465218411 0.0075197155491379 0.8092609039533044 0.7439029042798556 0.0012426103217311 0.9124190107532284 0.9588768535120026 0.2179 +/- 0.0075 0.7439 +/- 0.0012 NA NA NA NA NA +sceptr_cdr3 SCEPTR CDR3-only native CLS sequence-only 64.0 64.0 0.8213148278520902 0.004335551696797592 0.9707998073498677 0.6636995360955414 0.006248417396838993 0.9302819519415871 0.9732935578951564 0.355322581407025 0.2777975134354664 0.2366489373866297 0.2651021244243266 1.0469384621629017 0.217804653528936 0.8213 +/- 0.0043 0.6637 +/- 0.0062 0.3553 0.2778 0.2366 0.2651 1.0469 +sceptr SCEPTR default native CLS annotation-aware V+CDR3+J 64.0 64.0 0.7263401387911094 0.0125148065817577 0.9556794231100624 0.8072807829525773 0.0083542304525543 0.8968529612267799 0.95929616602314 0.7263 +/- 0.0125 0.8073 +/- 0.0084 NA NA NA NA NA +tfidf CDR3 TF-IDF ridge sequence control 0.785974434572495 0.9022327566653896 0.9653913662774836 NA 0.7860 NA NA NA NA NA diff --git a/results/author/external_author_global_comparison_manifest.json b/results/author/external_author_global_comparison_manifest.json new file mode 100644 index 0000000..8f43089 --- /dev/null +++ b/results/author/external_author_global_comparison_manifest.json @@ -0,0 +1,25 @@ +{ + "inputs": { + "/home/evlasova/irrm-codec/experiments/trb/external-global-author-v1/vdjdb/evaluation-1427581/external_retrieval_summary.tsv": "58ec7b647ea881689495770f1a2bbe94b90184bd8e67f143aca96ada4909393a", + "/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/results/pgen/pgen_summary.csv": "1be5e255e91c0b55f2c7429aeb48b75ce332af524fee17779f43070a88b8a362", + "/home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/results/reconstruction/reconstruction_summary.csv": "5f15ae270e153ef179cddb8651d8e7f75d5ceb3b77aa8c66c48c66fc5d0739d4", + "/home/evlasova/irrm-codec/experiments/trb/vdjdb-redcea-clonotypes/evaluation-1426728/metrics.json": "8a460d8f870f6dd5733c6cbf41c7a1614ba1e3729235169da739ae9a20492d56" + }, + "limitations": [ + "SCEPTR-default is annotation-aware and is not equivalent to sequence-only methods.", + "SCEPTR-default was not run on full REDCEA because unsupported V/J rows would require method-specific filtering.", + "REDCEA membership is sequence/TCRemP-cluster-conditioned, so retrieval is motif-conditioned.", + "Aligned one-hot is retained as an internal high-dimensional sequence control but omitted from the manuscript-facing comparison.", + "Probe mean/std reflects probe seeds, not pretrained encoder training-seed uncertainty." + ], + "outputs": { + "final_author_global_comparison.md": "b1d4019d103b5d545f3bc46f99212dadd99f73482dc9c8ec6df456d3c0382f97", + "final_author_global_comparison.tsv": "d15807f7d1401f39b10b3aa3a4364d70d9db9c87c0fe238b92c6ee2f0e9cf3b3" + }, + "protocol": { + "pgen": "native author-global vector plus identical MLP; three probe seeds", + "reconstruction": "train-only PCA64 plus identical learned decoder; three probe seeds", + "vdjdb": "native author-global vector on the fixed REDCEA gallery; macro over 87 epitopes" + }, + "status": "complete" +} diff --git a/results/author/external_pgen_results.tsv b/results/author/external_pgen_results.tsv new file mode 100644 index 0000000..482eb3c --- /dev/null +++ b/results/author/external_pgen_results.tsv @@ -0,0 +1,6 @@ +target train_subset arm seeds train_size rmse_mean rmse_std mae_mean mae_std r2_mean r2_std pearson_r_mean pearson_r_std spearman_rho_mean spearman_rho_std bias_mean bias_std training_seconds_mean inference_seq_per_second_mean peak_rss_mb_mean peak_gpu_mb_mean +log10_pgen_1mm all rtp_mlp 3 79544 0.2375036700301933 0.0007641427238683 0.1643160829299884 0.0004204611887859 0.9910726990213594 5.749766422037862e-05 0.9955328156356806 2.5301945949134647e-05 0.9958299890234856 3.869003023257598e-05 -0.0063614919328252 0.0031365612188622 74.25666666666666 828631.1210576348 1053.1158854166667 21.77001953125 +log10_pgen_1mm all tcr_bert_mlp 3 79544 0.4298724150079793 0.0022051496033906 0.3040288464942088 0.0013097794566628 0.9707542136303974 0.0003003689953682 0.9853613777329778 0.0001596107640185 0.9863067900009792 8.707651289475979e-05 0.0143588582656017 0.003591457594319 81.21 347583.1589531299 1549.37890625 28.14501953125 +log10_pgen_1mm all esm2_8m_mlp 3 79544 0.7439029042798556 0.0012426103217311 0.5208345937732529 0.0009216602240305 0.9124190107532284 0.000292707843767 0.9559005092380672 0.0001831596672659 0.9588768535120026 0.0002171379827709 0.0663262720525637 0.0016679294577322 72.43 633788.4195212495 1127.73828125 23.45751953125 +log10_pgen_1mm all tfidf_ridge 1 79544 0.785974434572495 0.5622312803788474 0.9022327566653896 0.9498971636908724 0.9653913662774836 0.0069710814573569 9.0 47475.47340859601 554.30859375 +log10_pgen_1mm all sceptr_mlp 3 79544 0.8072807829525773 0.0083542304525543 0.536926930754249 0.00316616759605 0.8968529612267799 0.0021294897691397 0.948402732471954 0.0008946298748116 0.95929616602314 0.0004665126697379 0.1042935665880658 0.0134872722784602 70.33999999999999 899745.0778283556 1022.0872395833334 21.20751953125 diff --git a/results/author/external_pgen_runs.tsv b/results/author/external_pgen_runs.tsv new file mode 100644 index 0000000..3cae4a5 --- /dev/null +++ b/results/author/external_pgen_runs.tsv @@ -0,0 +1,14 @@ +arm target train_subset train_size seed training_seconds rmse mae r2 pearson_r spearman_rho bias inference_seq_per_second inference_ms_per_sequence device peak_rss_mb peak_gpu_mb epochs_ran +esm2_8m_mlp log10_pgen_1mm all 79544 42 68.4 0.7434317223716531 0.520374913637156 0.9125300844628657 0.955902023500962 0.9589726094925388 0.066005454145396 636372.7860640743 0.0015714059775952 cuda 1131.9296875 23.45751953125 60.0 +esm2_8m_mlp log10_pgen_1mm all 79544 43 80.73 0.7429647954773283 0.5202331828575915 0.9126399243552248 0.9560829070791672 0.9586282966795376 0.0681313072794392 632408.853215861 0.0015812555357422 cuda 1126.29296875 23.45751953125 60.0 +esm2_8m_mlp log10_pgen_1mm all 79544 44 68.16 0.7453121949905853 0.521895684825011 0.9120870234415944 0.955716597134072 0.9590296543639312 0.0648420547328558 632583.6192838132 0.0015808186767974 cuda 1124.9921875 23.45751953125 60.0 +rtp_mlp log10_pgen_1mm all 79544 42 69.83 0.2370257379741502 0.1640886523530489 0.9911086533036424 0.9955494464625272 0.9958659210528849 -0.0074270037056943 905496.9714494308 0.0011043659244925 cuda 1050.56640625 21.77001953125 60.0 +rtp_mlp log10_pgen_1mm all 79544 43 66.05 0.2371002967282686 0.1640583226327462 0.991103058704482 0.9955453028703484 0.9958350139936892 -0.0028309819243721 828891.7263762074 0.0012064301864513 cuda 1054.671875 21.77001953125 60.0 +rtp_mlp log10_pgen_1mm all 79544 44 86.89 0.2383849753881611 0.1648012738041702 0.9910063850559538 0.995503697574166 0.9957890320238824 -0.0088264901684091 751504.6653472661 0.0013306637285317 cuda 1054.109375 21.77001953125 60.0 +sceptr_mlp log10_pgen_1mm all 79544 42 65.91 0.8103093724079922 0.5394118196202454 0.896084997028523 0.9479077517246606 0.9587721075749124 0.1036191435472859 1020112.022406086 0.0009802844962471 cuda 1021.7265625 21.20751953125 60.0 +sceptr_mlp log10_pgen_1mm all 79544 43 79.47 0.8136983165694129 0.5380069016025932 0.8952139752293935 0.9478649788339956 0.9594502316971228 0.1181053979058701 652900.7605952359 0.0015316263364256 cuda 1023.546875 21.20751953125 60.0 +sceptr_mlp log10_pgen_1mm all 79544 44 65.64 0.7978346598803266 0.5333620710399083 0.8992599114224236 0.949435466857206 0.9596661587973848 0.0911561583110414 1026222.4504837452 0.0009744475961606 cuda 1020.98828125 21.20751953125 60.0 +tcr_bert_mlp log10_pgen_1mm all 79544 42 86.02 0.4323397416215389 0.3047337966650835 0.970418046685067 0.985203459333992 0.9863763092964248 0.017726926052555 339208.0863098805 0.0029480429280994 cuda 1553.72265625 28.14501953125 60.0 +tcr_bert_mlp log10_pgen_1mm all 79544 43 72.09 0.4280938578492894 0.3025175762726348 0.9709962252575708 0.9855226286722562 0.986334939969123 0.0147702138797483 377791.1592998166 0.0026469650635905 cuda 1541.89453125 28.14501953125 60.0 +tcr_bert_mlp log10_pgen_1mm all 79544 44 85.52 0.4291836455531097 0.3048351665449082 0.9708483689485546 0.9853580451926848 0.98620912073739 0.0105794348645018 325750.2312496926 0.0030698366541863 cuda 1552.51953125 28.14501953125 60.0 +tfidf_ridge log10_pgen_1mm all 79544 42 9.0 0.785974434572495 0.5622312803788474 0.9022327566653896 0.9498971636908724 0.9653913662774836 0.0069710814573569 47475.47340859601 0.0210635077062536 cpu 554.30859375 diff --git a/results/author/external_reconstruction_results.tsv b/results/author/external_reconstruction_results.tsv new file mode 100644 index 0000000..b71574b --- /dev/null +++ b/results/author/external_reconstruction_results.tsv @@ -0,0 +1,7 @@ +representation seeds exact_match_mean exact_match_std token_accuracy_mean token_accuracy_std normalized_levenshtein_mean normalized_levenshtein_std within_edit_distance_1_mean within_edit_distance_1_std mean_edit_distance_mean mean_edit_distance_std training_seconds_mean epochs_mean inference_seq_per_second_mean source_dim explained_variance +rtp 3 0.8831338630192095 0.0058150137887855 0.9810685896331252 0.000560607194438 0.0130685588662131 0.0006119496602856 0.9404606255657244 0.0010878662200937 0.2455999195413859 0.0102899773206707 1254.5 59.0 13499.942816795909 128 0.968979 +onehot 3 0.8165878842736934 0.0037756299507998 0.9703579492481784 0.0004862497339854 0.0238099449743504 0.0004189465126061 0.9079084112776158 0.0018279266325006 0.4476516142009454 0.0077166637856656 998.82 47.0 13627.791460900138 1000 0.315236 +sceptr 3 0.7263401387911094 0.0125148065817577 0.9556794231100624 0.0024136647944061 0.0338323573330202 0.0020863791671621 0.8548057259713701 0.0092747603719289 0.5916725334406115 0.0353314332915674 657.6666666666666 31.0 13631.894064641703 64 1.0 +tcremp 3 0.518052901538771 0.0024158527908004 0.9371434757441994 0.0011054314818466 0.057005945958024 0.0008528920928819 0.7730061349693251 0.0042000629624502 0.934929095846324 0.0142856529454408 944.4033333333332 44.333333333333336 13506.954848081185 9000 0.959459 +tcr_bert 3 0.4777565456435013 0.0178585766284086 0.90975931989201 0.0028108844032423 0.0747954350264354 0.0028478342464577 0.6928827650943713 0.0079810659894325 1.270374467799792 0.0452585664172693 794.2933333333334 37.333333333333336 13529.272169955244 768 0.902213 +esm2_8m 3 0.2179087465218411 0.0075197155491379 0.8092609039533044 0.002076273541677 0.1568623343259775 0.001567719017009 0.3763786918770324 0.0073475867775242 2.5583827818565825 0.0221288616149074 790.4200000000001 37.333333333333336 13643.431387205686 320 0.970557 diff --git a/results/author/external_reconstruction_runs.tsv b/results/author/external_reconstruction_runs.tsv new file mode 100644 index 0000000..0e12620 --- /dev/null +++ b/results/author/external_reconstruction_runs.tsv @@ -0,0 +1,19 @@ +representation seed bottleneck_dim train_subset train_size epochs_ran best_epoch best_val_loss training_seconds test_loss exact_match token_accuracy normalized_levenshtein within_edit_distance_1 mean_edit_distance inference_seq_per_second inference_ms_per_sequence device +esm2_8m 42 64 all 79544 34 26 0.2073100912265288 715.4 0.2092864666229639 0.213617620436488 0.8070692877689258 0.1582913051676092 0.3692044654530825 2.5780951423111738 13737.439343699409 0.0727937700018776 cuda +esm2_8m 43 64 all 79544 38 30 0.206404773852764 809.74 0.2055744937597177 0.2135170471688625 0.8095149723617757 0.15711028054773 0.3760434476516142 2.562606859096852 13462.130148638444 0.0742824492824517 cuda +esm2_8m 44 64 all 79544 40 32 0.2068329342664816 846.12 0.2104361947530355 0.226591571960173 0.8111984517292117 0.1551854172625933 0.3838881625264004 2.5344463441617218 13730.72466927921 0.0728293680112438 cuda +onehot 42 64 all 79544 52 44 0.0400615889005936 1109.88 0.0400808783582387 0.8158503469777733 0.9707578308302072 0.0235220490955847 0.9084783264608268 0.4418183646786684 13437.93176766472 0.0744162135430892 cuda +onehot 43 64 all 79544 42 34 0.0394708287830536 891.93 0.0394849172100806 0.8132354420195113 0.9698166730736092 0.0242905725131555 0.9058634215025646 0.4564014884843608 13716.154190149347 0.0729067336322435 cuda +onehot 44 64 all 79544 47 39 0.0393366367102433 994.65 0.0403386892225497 0.8206778638237956 0.970499343840719 0.023617213314311 0.909383485869456 0.4447349894398069 13729.288424886348 0.0728369868162543 cuda +rtp 42 64 all 79544 60 52 0.0221906138154176 1276.43 0.0217311147791452 0.8838378758925878 0.9806996381182148 0.0133091188279378 0.9395554661570954 0.251030875993161 13431.362790330624 0.0744526088387628 cuda +rtp 43 64 all 79544 57 49 0.0216901884533655 1207.86 0.0220113017906745 0.8769988936940561 0.9807924283195696 0.0135236748927534 0.9401589057628482 0.2520366086694157 13726.01962618779 0.0728543326640817 cuda +rtp 44 64 all 79544 60 58 0.0212099805522041 1279.21 0.0209383756543199 0.8885648194709846 0.9817137024615916 0.012372882877948 0.9416675047772302 0.233732273961581 13342.446033869304 0.0749487760686112 cuda +sceptr 42 64 all 79544 36 28 0.0558294934722093 762.97 0.0567849224003461 0.7353917328774012 0.9575020877795304 0.0322961628513188 0.8625163431559891 0.5667303630694961 13706.086211692991 0.0729602881927647 cuda +sceptr 43 64 all 79544 31 23 0.0555792820568268 659.06 0.056470837826148 0.7315699487076335 0.9565940693805592 0.0329932651279869 0.8573871065070904 0.5761842502262898 13432.203122547407 0.0744479510082297 cuda +sceptr 44 64 all 79544 26 18 0.0571236062126281 550.97 0.0566988510963244 0.7120587347882933 0.9529421121700976 0.0362076440197549 0.8445137282510309 0.6321029870260485 13757.392859684716 0.0726881910111359 cuda +tcr_bert 42 64 all 79544 32 24 0.1105848010151814 681.6 0.1102362450880882 0.4596198330483757 0.9069844510134016 0.0776677400683502 0.6845016594589158 1.3154983405410845 13456.478415255033 0.0743136479798713 cuda +tcr_bert 43 64 all 79544 37 29 0.1082922487686842 785.5 0.1106430744895568 0.4783264608267122 0.9096886225957396 0.0747458457766419 0.6937544000804586 1.2706426631801266 13714.924236424891 0.0729132719044952 cuda +tcr_bert 44 64 all 79544 43 35 0.1096065732148977 915.78 0.1109284074642719 0.4953233430554158 0.9126048860668884 0.0719727192343142 0.7003922357437393 1.2249823996781657 13416.413858185811 0.0745355659545241 cuda +tcremp 42 64 all 79544 42 34 0.0778516114522249 895.52 0.0781389696475787 0.5153374233128835 0.9358753429923514 0.0579907698564299 0.7681786181233028 0.9514231117369004 13352.933211938987 0.0748899125104505 cuda +tcremp 43 64 all 79544 46 38 0.0764745114705501 975.58 0.0765142872547492 0.5199637936236549 0.9379034716791048 0.0565094918624861 0.7750176003218344 0.9268832344362868 13694.12270506786 0.0730240280109308 cuda +tcremp 44 64 all 79544 45 37 0.0775704320806723 962.11 0.0771636510124573 0.5188574876797747 0.9376516125611422 0.0565175761551559 0.7758221864628382 0.926480941365785 13473.808627236707 0.0742180646664777 cuda diff --git a/results/author/factorial_results.tsv b/results/author/factorial_results.tsv new file mode 100644 index 0000000..de1a927 --- /dev/null +++ b/results/author/factorial_results.tsv @@ -0,0 +1,8 @@ +condition reconstruction_weight tcremp_weight pgen_weight best_epoch best_validation_joint_loss test_reconstruction_loss_active test_reconstruction_token_accuracy_active test_reconstruction_exact_match_active test_tcremp_cosine_active test_tcremp_standardized_mse_active test_pgen_rmse_active test_pgen_r2_active parameters checkpoint_sha256 run_config_sha256 remote_output +R 1.0 0.0 0.0 40 0.005638612275925364 0.0062070361559643066 0.9979169387082533 0.9765664286432666 NA NA NA NA 21535913 5b3c29358a905eabc1eae262115b75db225562f072aa627488bb5764d502b23e 78002783c3a29f27c3921e31233fd2e3e4c364d8d2772cc00aea7e537dbe814c /home/evlasova/irrm-codec/experiments/trb/data-anchor-r-seed42 +T 0.0 1.0 0.0 7 0.19805858843759142 NA NA NA 0.9914940227196632 0.2756815801099142 NA NA 21535913 754277ecf372ecb412b8d588ecfd5801aa4be6e1bbd87a6d82917c58b9643ec9 f899ff4f1f4b9503d9872cfab22b97625ee3e58495a8d87d366bcb284fe493fe /home/evlasova/irrm-codec/experiments/trb/data-anchor-t-seed42 +P 0.0 0.0 1.0 38 0.005830517954523791 NA NA NA NA NA 0.2752929237653586 0.9880059307820565 21535913 6b9ea5fd0f23c21e3f7a2a4d0e983857134f11bbfe3bb7b7df7327c43bc9e5c4 936d97c4f2b5fb7324e4086c87f2a61525a7d8c54c8ae326bb0565fb924c6cf9 /home/evlasova/irrm-codec/experiments/trb/data-anchor-p-seed42 +RT 1.0 1.0 0.0 25 0.20361182044314435 0.009265304249247219 0.9968038999881856 0.9631901840490797 0.991784158396095 0.2699985514131456 NA NA 21535913 e0c6f100dce2788afd5015aff4b866af9a5fc73b77a70abc9b0d9813f5208bda ad9ad21656776121c77d969dc1432c537fde71661bf2c17985416299fdbb22d9 /home/evlasova/irrm-codec/experiments/trb/data-anchor-rt-seed42 +RP 1.0 0.0 1.0 39 0.00867614229220961 0.004723803990094098 0.99837707762046 0.9812933722216635 NA NA 0.22639804111600034 0.9918881150217478 21535913 997ce62b620ce18fbc56d88fe7414949f0a3ad108d0788aa99ba607d7df6d95b d93acfeda0bc251b80ef49bafc9b842656de2de979b1d36a7d49a0d36bdd8202 /home/evlasova/irrm-codec/experiments/trb/data-anchor-rp-seed42 +TP 0.0 1.0 1.0 12 0.20485042515300259 NA NA NA 0.9916881372136608 0.27117700439744896 0.34955449828735125 0.9806622364855879 21535913 6df6885f0652404e597e5a354c5ed44dfb63abc4a7c7e00cd6ce2550487a8e06 2e7f1edfab65c9c5882654ae0f295734d3d55858c4450a2635991680a3b27bf6 /home/evlasova/irrm-codec/experiments/trb/data-anchor-tp-seed42 +RTP 1.0 1.0 1.0 25 0.20576476722275314 0.008851642950913693 0.9967355009606954 0.9635924771195816 0.9918976390216716 0.2662354936682937 0.270233460057513 0.9884427449327019 21535913 5ecd99c754eef189a68e72be8628dd7c3858235b651fb970ad21ad5a69dbf222 a58b8a7e85a9a1aa328a5ae0ac196c6c079a55fcf1d24088f25dd2e43fc81e9f /home/evlasova/irrm-codec/experiments/trb/anchor-data-rtp-seed42 diff --git a/results/author/latent_sufficiency_summary.tsv b/results/author/latent_sufficiency_summary.tsv new file mode 100644 index 0000000..2db4f1a --- /dev/null +++ b/results/author/latent_sufficiency_summary.tsv @@ -0,0 +1,10 @@ +representation val_sequence_loss test_sequence_loss val_tcremp_loss test_tcremp_loss val_pgen_loss test_pgen_loss test_mean_normalized_regret test_worst_task_normalized_regret test_fixed_reference_hypervolume test_tasks_within_5pct_of_specialist_loss +r 0.4935558985376048 0.49224470019186 0.548148507589488 0.5506662230820216 0.0614951493528322 0.0653795911789573 0.1400491045037798 0.3722305268570544 0.5932814628050733 1 +t 0.4509414655450394 0.4490276663440188 0.2865061488114791 0.2821712378823272 0.117128964292562 0.1173834178493009 -0.0455000984472581 0.1080270920473844 0.8919729079526156 2 +p 0.6331614164344623 0.6350980117693602 0.8335210218559798 0.837555952241106 0.0115658875926671 0.0121837848696961 0.511661387724634 0.7764896312264542 0.0540858276076921 0 +rt 0.4260993086890938 0.4239572890785302 0.3990870048344427 0.3952955325072009 0.05701791602458 0.0586903250223235 -0.0570831929098857 0.1532961774080955 0.8059702254687741 1 +rp 0.4843092262983698 0.4828165204583172 0.5390500380432909 0.5401505206608808 0.0122720687155209 0.0126924586574998 0.1003535424521918 0.3574127484198617 0.6418482152942699 1 +tp 0.4384337059212025 0.4379317115096868 0.295442866793231 0.2910054249698389 0.019219655658664 0.0200339606698381 -0.0942818672224091 0.0086448937860575 0.985069940870266 2 +rtp 0.42446096833766 0.42360938070699 0.3902434068917082 0.3884632290116502 0.0208702339405904 0.0210434258818411 -0.0737242868597041 0.1436687121796011 0.8480459079597709 1 +concat_r_t_p 0.3800976034848598 0.3797286195409372 0.2779766205636249 0.2734238594102645 0.01125705180847 0.0119070518391921 -0.2091851165085149 0.0003482880518308 0.9996517119481692 3 +pca128_concat_r_t_p 0.4163787686308496 0.4150748132636582 0.2840515017505456 0.2797396175536809 0.0131192125953123 0.013556514821328 -0.1425721751878963 0.0020321932513549 0.9979678067486452 2 diff --git a/results/author/low_label_sequence_summary.tsv b/results/author/low_label_sequence_summary.tsv new file mode 100644 index 0000000..9eed89f --- /dev/null +++ b/results/author/low_label_sequence_summary.tsv @@ -0,0 +1,43 @@ +model train_fraction train_rows test_sequence_composition_rmse +r 0.01 795 0.01835094344455989 +r 0.05 3977 0.017523018379142774 +r 0.1 7954 0.017369375370154497 +r 0.25 19886 0.017267594094227467 +r 0.5 39772 0.017234372857679845 +r 1.0 79544 0.017218643463211603 +t 0.01 795 0.03147869204585527 +t 0.05 3977 0.029924893812797497 +t 0.1 7954 0.02970307989219788 +t 0.25 19886 0.02955591518184327 +t 0.5 39772 0.029504023885818596 +t 1.0 79544 0.029479354201959598 +p 0.01 795 0.04532366426571271 +p 0.05 3977 0.044574953547430206 +p 0.1 7954 0.04428606909530054 +p 0.25 19886 0.04387545458540854 +p 0.5 39772 0.04377336751769786 +p 1.0 79544 0.043726839108308116 +rt 0.01 795 0.016244031377328154 +rt 0.05 3977 0.015384379770039164 +rt 0.1 7954 0.015258002249398772 +rt 0.25 19886 0.015178035629387987 +rt 0.5 39772 0.015153765261059585 +rt 1.0 79544 0.015137956375535723 +rp 0.01 795 0.02006764040046825 +rp 0.05 3977 0.019064061738322383 +rp 0.1 7954 0.018926092173410757 +rp 0.25 19886 0.018820184904729538 +rp 0.5 39772 0.018784321535024042 +rp 1.0 79544 0.01876798572396856 +tp 0.01 795 0.03074244468361117 +tp 0.05 3977 0.02869302085614458 +tp 0.1 7954 0.028474638592191966 +tp 0.25 19886 0.028330022822164024 +tp 0.5 39772 0.028274905585994548 +tp 1.0 79544 0.02825358338746815 +rtp 0.01 795 0.016079114347764864 +rtp 0.05 3977 0.015141720406547479 +rtp 0.1 7954 0.015008292222499603 +rtp 0.25 19886 0.014917465005251243 +rtp 0.5 39772 0.014892085094678839 +rtp 1.0 79544 0.014880154198137008 diff --git a/results/author/provenance_and_hashes.tsv b/results/author/provenance_and_hashes.tsv new file mode 100644 index 0000000..dbb79c3 --- /dev/null +++ b/results/author/provenance_and_hashes.tsv @@ -0,0 +1,16 @@ +kind name path sha256 +training_source airr /projects/immunestatus/vdjrearm/airr_format/trb_background_100k.tsv 403e1db78a1a4b3006191d722ef30f533f194b27b7141e3af0e01c1e819cfaf3 +training_source tcremp_embeddings /projects/immunestatus/vdjrearm/tcremp/trb_background_100k_tcremp.parquet not recorded for large binary +training_source tcremp_representations /projects/immunestatus/vdjrearm/tcremp/trb_background_100k_tcremp_representations.tsv 52ae2d30b446b2afd5609a9da987b95facacb8bd1a2670851e98afe21fb5b2c1 +training_source pgen /projects/immunestatus/vdjrearm/pgen_1mm_background_100k/trb_background_100k_pgen.tsv 25de4450e1593c7805acaf1819439b563bf42357e24525f49d75ba93afe36caa +training_source tcremp_writer /home/evlasova/tcremp-git/tcremp/tcremp/tcremp_run.py 0052c8021fe23f542ff8d75c4e9246d78c0cd691fa93094fba176cbfec4c4252 +benchmark READY /home/evlasova/irrm-codec/data/benchmark/trb/READY.json ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167 +benchmark train-only normalizer /home/evlasova/irrm-codec/data/benchmark/trb/target_standardizer.npz ed0052ad510b7e0299628796162037cbb1a3c7e5e8d661ca4a668eb49a830b24 +tokenizer DATA-ANCHOR /home/evlasova/irrm-codec/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json 8ef9aeddf8c069d4db898369f01f97e80160ba2ceb3c2354f18547467beeed4d +downstream VDJdb 2025-07-30 vdjdb.txt pinned official snapshot 191290d17ed3f489ac32b476eda6b9e3db93fab05c0968fb5da567187a27a94a +downstream VDJdb cluster_members.txt pinned official motif membership b5d572d912c180ff0221f8966cdacedbcd978467f5367f947dbee71bdd12b1c4 +result viral multi-epitope evaluation /home/evlasova/irrm-codec/experiments/trb/vdjdb-viral-motif-top10/evaluation-1426501 712a79c9d4a2661c7da3db9d8caa0e9c04dbf59e790edfa820889bc07309ed76 +student_pr reconstruction benchmark PR #3 https://github.com/antigenomics/irrm-codec/pull/3 git-commit:603ea761f7439a2faffe314525c5ac67def28357 +student_pr pgen benchmark PR #4 https://github.com/antigenomics/irrm-codec/pull/4 git-commit:b96f06eb42d9c92e3982103bb903a1dc67d59138 +result external reconstruction locked-cohort rerun /home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/results/reconstruction/reconstruction_summary.csv 5f15ae270e153ef179cddb8651d8e7f75d5ceb3b77aa8c66c48c66fc5d0739d4 +result external pgen locked-cohort rerun /home/evlasova/irrm-codec/experiments/trb/external-model-benchmark/results/pgen/pgen_summary.csv 1be5e255e91c0b55f2c7429aeb48b75ce332af524fee17779f43070a88b8a362 diff --git a/results/author/rtp_data_anchor_error_analysis_by_length.tsv b/results/author/rtp_data_anchor_error_analysis_by_length.tsv new file mode 100644 index 0000000..f488d55 --- /dev/null +++ b/results/author/rtp_data_anchor_error_analysis_by_length.tsv @@ -0,0 +1,23 @@ +cdr3_length n_sequences exact_sequences sequence_error_rate total_target_residues edit_errors residue_error_rate mean_abs_log10_pgen_error median_abs_log10_pgen_error mean_signed_log10_pgen_error mean_true_log10_pgen +7 3 3 0.0 21 0 0.0 0.22788333892822266 0.20193147659301758 0.09326235453287761 -6.067805767059326 +8 18 17 0.05555555555555558 144 2 0.013888888888888888 0.19520963562859428 0.1939537525177002 0.10459881358676487 -6.952210797203912 +9 58 58 0.0 522 0 0.0 0.13554670070779734 0.09454631805419922 0.012654896440177128 -6.39963698387146 +10 161 161 0.0 1610 0 0.0 0.1254880768912179 0.08246088027954102 0.026373279761083376 -6.248149824438628 +11 368 368 0.0 4048 0 0.0 0.1158735207889391 0.08518195152282715 0.027172174142754597 -6.210726919381515 +12 793 790 0.003783102143757877 9516 4 0.0004203446826397646 0.13495038015695118 0.09746122360229492 0.030675953303429697 -6.365015834156532 +13 1195 1187 0.006694560669456062 15535 8 0.0005149662053427744 0.14315945134502076 0.10540390014648438 0.07770905754057433 -6.662306459179483 +14 1538 1534 0.002600780234070177 21532 5 0.00023221252089912687 0.1622169594460873 0.1293473243713379 0.08179769993448444 -7.131347616255206 +15 1632 1623 0.005514705882352922 24480 11 0.00044934640522875815 0.17407382820166795 0.1297016143798828 0.07869276112201166 -7.785865174204695 +16 1358 1343 0.011045655375552244 21728 18 0.0008284241531664212 0.19903086597684205 0.15855979919433594 0.0986646977369845 -8.657309157858892 +17 1077 1045 0.02971216341689875 18309 57 0.003113223005079469 0.22972634775060796 0.18281316757202148 0.09377350802762484 -9.486332648975935 +18 750 707 0.05733333333333335 13500 86 0.00637037037037037 0.24847226905822753 0.20470094680786133 0.0733973954518636 -10.422224502563477 +19 447 390 0.12751677852348997 8493 120 0.01412928293889085 0.3059646789926277 0.24474716186523438 0.07611795506488024 -11.592920788715883 +20 284 229 0.19366197183098588 5680 111 0.019542253521126762 0.3081234794267466 0.2438054084777832 0.08418968193967577 -12.651549712033338 +21 123 83 0.3252032520325203 2583 102 0.03948896631823461 0.3743546493654329 0.32733917236328125 0.03476118072261655 -13.97880065731886 +22 64 30 0.53125 1408 102 0.07244318181818182 0.4636581093072891 0.41320085525512695 0.09101755917072296 -15.086607545614243 +23 36 9 0.75 828 80 0.0966183574879227 0.45497918128967285 0.24609375 0.09665173954433864 -16.783052576912773 +24 18 2 0.8888888888888888 432 49 0.11342592592592593 0.4684235254923503 0.43729591369628906 0.2559358808729384 -17.646304077572292 +25 15 1 0.9333333333333333 375 54 0.144 0.5853490193684896 0.41939735412597656 0.23636004130045574 -18.517236709594727 +26 2 0 1.0 52 8 0.15384615384615385 0.9295778274536133 0.9295778274536133 0.9295778274536133 -19.613176345825195 +27 2 1 0.5 54 5 0.09259259259259259 1.296828269958496 1.296828269958496 1.296828269958496 -21.37657928466797 +28 1 0 1.0 28 8 0.2857142857142857 1.1843910217285156 1.1843910217285156 1.1843910217285156 -25.132247924804688 diff --git a/results/author/rtp_data_anchor_error_rates_by_target_length.tsv b/results/author/rtp_data_anchor_error_rates_by_target_length.tsv new file mode 100644 index 0000000..2808a96 --- /dev/null +++ b/results/author/rtp_data_anchor_error_rates_by_target_length.tsv @@ -0,0 +1,23 @@ +target_length sequences exact length_mismatch aligned_positions wrong_aligned_positions sequence_error_rate aligned_position_error_rate +7 3 3 0 21 0 0.0 0.0 +8 18 17 0 144 2 0.05555555555555558 0.013888888888888888 +9 58 58 0 522 0 0.0 0.0 +10 161 161 0 1610 0 0.0 0.0 +11 368 368 0 4048 0 0.0 0.0 +12 793 790 2 9492 2 0.003783102143757877 0.00021070375052675939 +13 1195 1187 8 15431 0 0.006694560669456062 0.0 +14 1538 1534 3 21490 2 0.002600780234070177 9.306654257794323e-05 +15 1632 1623 9 24345 0 0.005514705882352922 0.0 +16 1358 1343 12 21536 6 0.011045655375552244 0.0002786032689450223 +17 1077 1045 16 18037 38 0.02971216341689875 0.0021067805067361534 +18 750 707 21 13122 55 0.05733333333333335 0.004191434232586496 +19 447 390 21 8094 95 0.12751677852348997 0.011737089201877934 +20 284 229 25 5180 75 0.19366197183098588 0.01447876447876448 +21 123 83 12 2331 97 0.3252032520325203 0.041613041613041614 +22 64 30 11 1166 92 0.53125 0.07890222984562607 +23 36 9 14 506 43 0.75 0.08498023715415019 +24 18 2 8 240 35 0.8888888888888888 0.14583333333333334 +25 15 1 5 250 46 0.9333333333333333 0.184 +26 2 0 2 0 0 1.0 +27 2 1 1 27 0 0.5 0.0 +28 1 0 1 0 0 1.0 diff --git a/results/author/rtp_data_anchor_region_error_rates.tsv b/results/author/rtp_data_anchor_region_error_rates.tsv new file mode 100644 index 0000000..07523e5 --- /dev/null +++ b/results/author/rtp_data_anchor_region_error_rates.tsv @@ -0,0 +1,4 @@ +region eligible_positions wrong_positions error_rate +N_edge_1_3 29316 3 0.00010233319688907081 +middle 88960 584 0.006564748201438849 +C_edge_1_3 29316 1 3.411106562969027e-05 diff --git a/results/author/rtp_data_anchor_substitution_matrix.tsv b/results/author/rtp_data_anchor_substitution_matrix.tsv new file mode 100644 index 0000000..6b729e6 --- /dev/null +++ b/results/author/rtp_data_anchor_substitution_matrix.tsv @@ -0,0 +1,21 @@ + C S T A G P D E Q N H R K M I L V W Y F +C 0 1 0 0 2 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 +S 0 0 1 2 10 5 2 0 2 0 2 5 1 0 1 2 1 2 0 1 +T 0 4 0 0 5 5 0 1 2 0 0 2 2 2 1 3 0 0 1 0 +A 0 3 0 0 9 3 1 1 1 1 0 2 1 0 2 1 4 1 1 1 +G 3 8 6 6 0 7 2 2 3 2 0 15 2 2 2 7 7 0 3 1 +P 1 3 4 2 6 0 3 1 2 2 2 10 1 0 2 4 2 2 0 3 +D 0 3 0 3 1 4 0 0 0 4 1 6 1 0 0 2 3 1 0 0 +E 0 0 1 3 1 2 0 0 1 0 0 3 1 1 1 1 4 0 1 0 +Q 0 2 3 1 5 2 0 1 0 1 0 1 1 0 0 1 2 0 1 2 +N 1 0 0 1 2 3 3 0 1 0 0 5 2 0 0 2 1 1 1 1 +H 0 1 0 0 1 2 2 1 0 0 0 1 3 0 1 1 0 0 0 1 +R 1 4 2 2 11 6 6 5 2 6 2 0 3 0 2 7 6 1 0 1 +K 0 1 2 1 2 1 2 1 0 2 3 1 0 0 0 4 0 3 0 1 +M 0 0 2 0 2 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 +I 0 1 0 2 2 3 0 1 0 0 1 2 0 0 0 2 1 0 0 0 +L 1 3 4 2 5 4 4 0 0 1 1 10 1 0 0 0 3 0 5 4 +V 0 1 0 4 6 3 3 3 3 2 0 4 1 0 0 4 0 2 0 3 +W 0 2 0 1 3 1 1 1 0 1 0 1 0 0 0 0 1 0 0 0 +Y 0 0 1 1 2 0 0 0 2 0 0 0 0 0 1 5 1 0 0 1 +F 0 1 1 0 3 3 0 0 2 1 1 0 2 0 1 2 3 0 1 0 diff --git a/results/author/rtp_data_anchor_substitution_results.json b/results/author/rtp_data_anchor_substitution_results.json new file mode 100644 index 0000000..417bcc8 --- /dev/null +++ b/results/author/rtp_data_anchor_substitution_results.json @@ -0,0 +1,47 @@ +{ + "analysis": "locked_test_autoregressive_substitution_errors", + "benchmark_ready_sha256": "ce08945c0c0a975c2b05129695c26399456f185fe79b89914c0ad52e4fdcf167", + "between_group_errors": 463, + "between_group_fraction": 0.7874149659863946, + "checkpoint": "/home/evlasova/irrm-codec/experiments/trb/anchor-data-rtp-seed42/best.pt", + "checkpoint_sha256": "5ecd99c754eef189a68e72be8628dd7c3858235b651fb970ad21ad5a69dbf222", + "data_dir": "/home/evlasova/irrm-codec/data/benchmark/trb", + "exact_match": 0.9635924771195816, + "exact_sequences": 9581, + "groups": { + "C": "C", + "DEQN": "DENQ", + "HRK": "HKR", + "MILV": "ILMV", + "STAGP": "AGPST", + "WYF": "FWY" + }, + "length_matched_sequences": 9772, + "length_mismatched_sequences": 171, + "model_config": { + "d_model": 320, + "decoder_layers": 4, + "decoder_memory_tokens": 4, + "dropout": 0.1, + "encoder_layers": 4, + "ff_dim": 1280, + "input_vocab_size": 1228, + "latent_dim": 128, + "max_sequence_len": 40, + "nhead": 8, + "output_vocab_size": 25, + "pgen_head_dim": 256, + "share_input_output_embeddings": false, + "tcremp_dim": 9000, + "tcremp_head_dim": 1024 + }, + "note": "Only incorrect aligned positions from equal-length target/prediction pairs enter the matrix.", + "status": "complete", + "test_sequences": 9943, + "tokenizer": "/home/evlasova/irrm-codec/experiments/trb/tokenizers/anchored-seed42/data_anchor/anchored_tokenizer.json", + "tokenizer_sha256": "8ef9aeddf8c069d4db898369f01f97e80160ba2ceb3c2354f18547467beeed4d", + "unexpected_residue_errors": 0, + "within_group_errors": 125, + "within_group_fraction": 0.21258503401360543, + "wrong_aligned_positions": 588 +} diff --git a/results/author/tokenizer_results.tsv b/results/author/tokenizer_results.tsv new file mode 100644 index 0000000..6fd6452 --- /dev/null +++ b/results/author/tokenizer_results.tsv @@ -0,0 +1,13 @@ +tokenizer family requested_vocab actual_input_vocab best_epoch best_validation_joint_loss test_reconstruction_exact_match test_reconstruction_token_accuracy test_tcremp_cosine test_pgen_rmse parameters remote_output +Character character 25.0 25 30 0.19693734171098476 0.9815950920245399 0.9984206042743174 0.992289113360584 0.343395136972041 21142953 /home/evlasova/irrm-codec/experiments/trb/rq5-char-rtp-d128-seed42 +WordPiece-44 wordpiece 44.0 44 30 0.19666322000361444 0.9789801870662778 0.9981159176973157 0.9923110324276845 0.34131871315836837 21157033 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v44-rtp-seed42 +WordPiece-64 wordpiece 64.0 64 28 0.20685211541870166 0.9643970632605854 0.9968474266420431 0.991931193049712 0.32575211456733877 21163433 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v64-rtp-seed42 +WordPiece-128 wordpiece 128.0 128 26 0.20901615753579544 0.9598712662174395 0.996505431504592 0.9918078695230294 0.2893693995404677 21183913 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v128-rtp-seed42 +WordPiece-256 wordpiece 256.0 256 23 0.20649890744307267 0.9636930503872071 0.996660883839797 0.9919296334857589 0.2705196099398586 21224873 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v256-rtp-seed42 +WordPiece-512 wordpiece 512.0 512 25 0.2104906694103532 0.9666096751483456 0.9969966608838398 0.9918318263819961 0.31541390221471494 21306793 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v512-rtp-seed42 +WordPiece-1024 wordpiece 1024.0 1024 28 0.21072169335227994 0.972543497938248 0.9975003264499039 0.991686036310289 0.3159752198188979 21470633 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v1024-rtp-seed42 +WordPiece-2048 wordpiece 2048.0 2048 24 0.21218146349443082 0.9552448959066681 0.9959893297517115 0.9918661757301039 0.3290175757219649 21798313 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v2048-rtp-seed42 +WordPiece-4096 wordpiece 4096.0 4096 25 0.21656744164125932 0.9517248315397767 0.9954297013449735 0.9919115816768741 0.4196596483780269 22453673 /home/evlasova/irrm-codec/experiments/trb/wp-sweep-v4096-rtp-seed42 +EDGE-3 edge_anchor NA 16256 31 0.2154474285803342 0.9647993563310872 0.9967292828672872 0.9917393089431783 0.3389353724618627 26344873 /home/evlasova/irrm-codec/experiments/trb/anchor-edge3-rtp-seed42 +DATA-ANCHOR data_anchor NA 1228 25 0.20576476722275314 0.9635924771195816 0.9967355009606954 0.9918976390216716 0.270233460057513 21535913 /home/evlasova/irrm-codec/experiments/trb/anchor-data-rtp-seed42 +GERMLINE-ANCHOR germline_anchor NA 387 28 0.20924612771849702 0.9716383385296188 0.9972826931806169 0.9917630262086177 0.25866407306127065 21266793 /home/evlasova/irrm-codec/experiments/trb/anchor-germline-rtp-seed42 From f191aca53eb69d20f3ff23d31a599f4b5f2fa5ba Mon Sep 17 00:00:00 2001 From: Elizaveta Vlasova Date: Sun, 4 Oct 2026 19:42:39 +0300 Subject: [PATCH 70/70] Preserve empty result-table fields and explicit publication line endings --- .gitattributes | 4 ++++ docs/publication.md | 3 +++ 2 files changed, 7 insertions(+) diff --git a/.gitattributes b/.gitattributes index 266501f..ecdabf8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,7 @@ *.sbatch text eol=lf *.yml text eol=lf *.yaml text eol=lf +*.md text eol=lf +*.tsv text eol=lf whitespace=-blank-at-eol +*.csv text eol=lf +*.json text eol=lf diff --git a/docs/publication.md b/docs/publication.md index 62e1fe3..fc5ff6d 100644 --- a/docs/publication.md +++ b/docs/publication.md @@ -43,3 +43,6 @@ objective combinations, tokenizers, data identity/alignment, standardizers, metr external benchmark bookkeeping, and VDJdb cohort rules. Optional external encoders need requirements-benchmark.txt plus model downloads; complete GPU training and external-data experiments require separately provisioned resources. + +Tab-separated result files preserve empty terminal fields. Trailing tabs in these +files represent missing values and are retained for table-schema fidelity.