DIMER pipeline for ESM-2 150M (facebook/esm2_t30_150M_UR50D): protein sequence embeddings, bounded sequence-classification fine-tuning, and a digest-verified safetensors adapter
Python
0
22 commits
updated Oct 9, 2026
DIMER-oriented pipeline for ESM-2 150M (facebook/esm2_t30_150M_UR50D), pinned to an immutable Hugging Face revision. The repository exposes mean-pooled protein sequence embeddings, a labelled-dataset contract with explicit ceilings, bounded gradient fine-tuning of a sequence-classification head, held-out classification metrics with trivial baselines, and a safetensors adapter artifact that is digest-verified before it is loaded.
facebook/esm2_t30_150M_UR50Da695f6045e2e32885fa60af20c13cb35398ce30cfrom esm2_protein_pipeline import ESM2Pipeline, generate_sample_dataset, split_dataset
pipe = ESM2Pipeline.from_pretrained() # verifies the snapshot under weights/ first
emb = pipe.embed(["MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQ"])
print(emb["dimension"], len(emb["embeddings"][0])) # 640 640
splits = split_dataset(generate_sample_dataset())
pipe.adapt(splits["train"], splits["validation"]) # bounded AdamW fine-tuning
print(pipe.evaluate(splits["test"])["accuracy"])
print(pipe.classify(["MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQ"])["predictions"][0]["label"])
embed() and classify() take 1..64 sequences (MAX_SEQUENCES_PER_CALL) of at most 1,022 residues each (MAX_RESIDUES, the 1,024-token training window minus <cls>/<eos>), as uppercase one-letter strings over ACDEFGHIKLMNPQRSTVWY plus the ambiguity codes BUZOX; anything else — lowercase, gaps, whitespace — is rejected with an error naming the offending characters rather than silently mapped to <unk>. classify() requires a prior adapt() or from_artifact(). Datasets are {id, sequence, label} records: at least 12 rows and 3 per class, at most 5,000 rows and 20 classes, unique ids and unique sequences.
weights/esm2-t30-150m-ur50d/ config.json model.safetensors vocab.txt tokenizer_config.json
special_tokens_map.json README.md dimer-base-manifest.json
from_pretrained() calls stage_missing_files() then verify_snapshot() (byte size + SHA-256 of every manifest entry; staging fetches only absent entries, only at the pinned revision, and only with allow_download=True), then loads with local_files_only=True, trust_remote_code=False and use_safetensors=True. The upstream pytorch_model.bin and tf_model.h5 are deliberately absent from the manifest and are never loaded. .safetensors files are git-ignored; the Git repository does not vendor the checkpoint. See docs/WEIGHTS.md.
save_artifact(dir) writes adapter.safetensors (the trained tensors only — head, final layer norm and the unfrozen encoder layers; about 41 MB with the default two layers) plus a manifest.json recording the artifact format, the exact base model id and revision, the class order, the tensor names, the file size and SHA-256, and the full adaptation configuration. ESM2Pipeline.from_artifact(dir) re-verifies the base snapshot, then checks the artifact manifest, the base identity and every digest before deserialising, and refuses any tensor the base architecture does not have.
pip install -e . --no-deps
pytest -q -o addopts= tests
Tests are offline: injected backends and temporary manifests, never the weights.
tutorials/esm2_protein_colab.ipynb is declared E2E and is standalone (DIMER Notebook Specification 2.2 §4): it is generated by tools/build_notebook.py from tools/notebook_template.py and embeds the 3 package modules (pipeline.py, samples.py, metrics.py) verbatim in dependency order, the pinned model identity, the snapshot manifest and the exact runtime pins, so the exported .ipynb keeps working without this repository being reachable — no clone, no repository install, no repository import on its primary path. Do not edit it by hand; change the package or the template and regenerate (python tools/build_notebook.py; --check is enforced by the validator and CI). Its first cell builds an isolated Python 3.12.12 environment from the hash-locked tutorials/requirements-colab.lock.txt (manylinux wheels, so Linux x86_64 runtimes only: Colab, Kaggle or Linux Jupyter) and routes the remaining cells to it, so a one-pass Run all needs no restart. Its default path generates and validates a deterministic 96-sequence dataset whose classes are defined by a residue-order rule, splits it 56/20/20 stratified by class, stages and digest-verifies the pinned snapshot, extracts mean-pooled embeddings, measures four baselines (majority class, hydrophobic fraction, 20-residue composition nearest centroid, and the longest-hydrophobic-run rule that defines the classes), runs a 4-epoch bounded fine-tuning, evaluates accuracy/macro-F1/AUROC on the held-out test split, classifies six freshly generated sequences, exports the safetensors adapter and verifies reload parity. The fine-tuned model ties the one-line order rule on the synthetic test split, so the run shows that the adaptation contract works, not what pretraining contributes. BYOD (CSV/JSON/JSONL, by upload or BYOD_PATH) is optional and gated off by default. See tutorials/README.md.
Candidate. The notebook was revised after its Notebook Review Framework v1 review (isolated runtime, honest baselines, BYOD split contract, guided layer); no hosted run of the revised notebook is recorded yet. The previous blob's 2026-09-18 Kaggle Tesla T4 run passed only after a manual restart, which is not a one-pass Run all and not promotion evidence. The execution records and the promotion gate are in docs/release-verification.md.
facebook/esm2_t30_150M_UR50D), redistributed unmodified from the pinned revision.LICENSE).This repository’s code and accompanying documentation were developed with generative AI assistance for code development and technical writing under maintainer direction. The maintainer remains responsible for reviewing the implementation, validating results, and making release decisions. AI assistance does not constitute independent verification, provider endorsement, or release approval.
DIMER pipeline for ESM-2 150M (facebook/esm2_t30_150M_UR50D): protein sequence embeddings, bounded sequence-classification fine-tuning, and a digest-verified safetensors adapter
Python
0
22 commits
updated Oct 9, 2026
DIMER-oriented pipeline for ESM-2 150M (facebook/esm2_t30_150M_UR50D), pinned to an immutable Hugging Face revision. The repository exposes mean-pooled protein sequence embeddings, a labelled-dataset contract with explicit ceilings, bounded gradient fine-tuning of a sequence-classification head, held-out classification metrics with trivial baselines, and a safetensors adapter artifact that is digest-verified before it is loaded.
facebook/esm2_t30_150M_UR50Da695f6045e2e32885fa60af20c13cb35398ce30cfrom esm2_protein_pipeline import ESM2Pipeline, generate_sample_dataset, split_dataset
pipe = ESM2Pipeline.from_pretrained() # verifies the snapshot under weights/ first
emb = pipe.embed(["MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQ"])
print(emb["dimension"], len(emb["embeddings"][0])) # 640 640
splits = split_dataset(generate_sample_dataset())
pipe.adapt(splits["train"], splits["validation"]) # bounded AdamW fine-tuning
print(pipe.evaluate(splits["test"])["accuracy"])
print(pipe.classify(["MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQ"])["predictions"][0]["label"])
embed() and classify() take 1..64 sequences (MAX_SEQUENCES_PER_CALL) of at most 1,022 residues each (MAX_RESIDUES, the 1,024-token training window minus <cls>/<eos>), as uppercase one-letter strings over ACDEFGHIKLMNPQRSTVWY plus the ambiguity codes BUZOX; anything else — lowercase, gaps, whitespace — is rejected with an error naming the offending characters rather than silently mapped to <unk>. classify() requires a prior adapt() or from_artifact(). Datasets are {id, sequence, label} records: at least 12 rows and 3 per class, at most 5,000 rows and 20 classes, unique ids and unique sequences.
weights/esm2-t30-150m-ur50d/ config.json model.safetensors vocab.txt tokenizer_config.json
special_tokens_map.json README.md dimer-base-manifest.json
from_pretrained() calls stage_missing_files() then verify_snapshot() (byte size + SHA-256 of every manifest entry; staging fetches only absent entries, only at the pinned revision, and only with allow_download=True), then loads with local_files_only=True, trust_remote_code=False and use_safetensors=True. The upstream pytorch_model.bin and tf_model.h5 are deliberately absent from the manifest and are never loaded. .safetensors files are git-ignored; the Git repository does not vendor the checkpoint. See docs/WEIGHTS.md.
save_artifact(dir) writes adapter.safetensors (the trained tensors only — head, final layer norm and the unfrozen encoder layers; about 41 MB with the default two layers) plus a manifest.json recording the artifact format, the exact base model id and revision, the class order, the tensor names, the file size and SHA-256, and the full adaptation configuration. ESM2Pipeline.from_artifact(dir) re-verifies the base snapshot, then checks the artifact manifest, the base identity and every digest before deserialising, and refuses any tensor the base architecture does not have.
pip install -e . --no-deps
pytest -q -o addopts= tests
Tests are offline: injected backends and temporary manifests, never the weights.
tutorials/esm2_protein_colab.ipynb is declared E2E and is standalone (DIMER Notebook Specification 2.2 §4): it is generated by tools/build_notebook.py from tools/notebook_template.py and embeds the 3 package modules (pipeline.py, samples.py, metrics.py) verbatim in dependency order, the pinned model identity, the snapshot manifest and the exact runtime pins, so the exported .ipynb keeps working without this repository being reachable — no clone, no repository install, no repository import on its primary path. Do not edit it by hand; change the package or the template and regenerate (python tools/build_notebook.py; --check is enforced by the validator and CI). Its first cell builds an isolated Python 3.12.12 environment from the hash-locked tutorials/requirements-colab.lock.txt (manylinux wheels, so Linux x86_64 runtimes only: Colab, Kaggle or Linux Jupyter) and routes the remaining cells to it, so a one-pass Run all needs no restart. Its default path generates and validates a deterministic 96-sequence dataset whose classes are defined by a residue-order rule, splits it 56/20/20 stratified by class, stages and digest-verifies the pinned snapshot, extracts mean-pooled embeddings, measures four baselines (majority class, hydrophobic fraction, 20-residue composition nearest centroid, and the longest-hydrophobic-run rule that defines the classes), runs a 4-epoch bounded fine-tuning, evaluates accuracy/macro-F1/AUROC on the held-out test split, classifies six freshly generated sequences, exports the safetensors adapter and verifies reload parity. The fine-tuned model ties the one-line order rule on the synthetic test split, so the run shows that the adaptation contract works, not what pretraining contributes. BYOD (CSV/JSON/JSONL, by upload or BYOD_PATH) is optional and gated off by default. See tutorials/README.md.
Candidate. The notebook was revised after its Notebook Review Framework v1 review (isolated runtime, honest baselines, BYOD split contract, guided layer); no hosted run of the revised notebook is recorded yet. The previous blob's 2026-09-18 Kaggle Tesla T4 run passed only after a manual restart, which is not a one-pass Run all and not promotion evidence. The execution records and the promotion gate are in docs/release-verification.md.
facebook/esm2_t30_150M_UR50D), redistributed unmodified from the pinned revision.LICENSE).This repository’s code and accompanying documentation were developed with generative AI assistance for code development and technical writing under maintainer direction. The maintainer remains responsible for reviewing the implementation, validating results, and making release decisions. AI assistance does not constitute independent verification, provider endorsement, or release approval.