lhallee commited on
Commit
6fbf698
·
verified ·
1 Parent(s): a298547

Update FastPLMs files

Browse files
README.md CHANGED
@@ -10,7 +10,7 @@ tags:
10
 
11
  # Synthyra/ESM3_small
12
 
13
- This checkpoint packages the FastPLMs `ESM3` implementation.
14
 
15
  Accepted inputs are sequence, structure, and function tracks prepared through
16
  the multimodal helpers.
@@ -28,9 +28,7 @@ Supported Transformers entry points are `AutoConfig`, `AutoModel`.
28
  | Attention variants | Supported: `eager`, `sdpa`, `flex_attention` |
29
  | Compliance | Declared: exact release evidence is required |
30
 
31
- A supported interface is not a pretrained downstream predictor. Classification
32
- heads start untrained, and declared compliance metadata is not a claim that an
33
- arbitrary local build passed its release gate.
34
 
35
  ## Install and platform requirements
36
 
@@ -41,12 +39,12 @@ python -m pip install -r \
41
  "https://huggingface.co/Synthyra/ESM3_small/resolve/main/requirements.txt"
42
  ```
43
 
44
- The FastPLMs implementation itself is embedded in the model repository and loaded
45
- by Transformers through `trust_remote_code=True`.
46
 
47
- Python 3.11-3.14, PyTorch 2.13, and Transformers 5.13 are required. The declared CPU gate covers tiny offline contracts; published checkpoint throughput and parity require the documented device tier. The Hub quick start below requires network
48
- access on first download. For an air-gapped run, first build the manifest-pinned
49
- local artifact and use the offline form shown in the example.
50
 
51
  ## Quick start
52
 
@@ -62,22 +60,22 @@ model = AutoModel.from_pretrained(
62
  ```
63
 
64
  For offline validation, replace `model_id` with the manifest-built
65
- `dist/hub/ESM3_small` path and pass `local_files_only=True`.
66
 
67
  ## Attention and compliance
68
 
69
  The quick start selects `sdpa` explicitly. Declared variants are `eager`, `sdpa`, `flex_attention`. An unavailable
70
- requested backend raises instead of silently switching implementations.
71
- `output_attentions=True` may use the documented, one-call eager fallback solely
72
- to materialize attention tensors; the configured backend remains unchanged.
73
 
74
- This family declares the `compliance` tier. Release evidence binds the exact
75
  checkpoint, backend, dtype, hardware, inputs, and reference revision.
76
 
77
  ## Dataset embeddings
78
 
79
- The shared embedding mixin preserves input order and biological-position
80
- masking. It accepts sequences, identified records, mappings, or a FASTA path:
81
 
82
  ```python
83
  pooled = model.embed_dataset(
@@ -94,12 +92,12 @@ print(residues[0].tensor.shape) # (l, d)
94
  ```
95
 
96
  Set `output` and `format="safetensors"` or `"sqlite"` for transactional,
97
- bounded-memory persistence. Resume verifies input order, model state, tokenizer
98
- policy, backend, dtype, and pooling configuration before appending.
99
 
100
  ## PEFT fine-tuning
101
 
102
- Install the direct training dependencies, then attach LoRA to the loaded checkpoint:
103
 
104
  ```bash
105
  python -m pip install "datasets>=4.8,<5" "peft>=0.19,<0.20"
@@ -118,17 +116,17 @@ peft_model = get_peft_model(
118
  )
119
  ```
120
 
121
- This checkpoint has no advertised classifier. Supply the task-specific
122
- objective and preserve any new head through `modules_to_save`.
123
  All FastPLMs checkpoints follow the Transformers `PreTrainedModel` contract and
124
- can be adapted with PEFT. The ESM2-specific shipped CLI is an example, not a
125
  support boundary. Record the target modules, base revision, data identity, and
126
  trainable parameter scope.
127
 
128
  ## Test-time training
129
 
130
  TTT samples masked views of one protein and updates only injected low-rank
131
- adapters. Base checkpoint weights remain frozen:
132
 
133
  ```python
134
  from transformers import AutoModel
@@ -146,14 +144,14 @@ ttt_model.ttt_reset()
146
  print(metrics)
147
  ```
148
 
149
- Persisted adapters retain their deterministic reset state. TTT adds latency
150
- and memory, can worsen an output, and does not establish biological function.
151
 
152
  ## Sequence inference and masked-sequence generation
153
 
154
- ESM3 owns its sequence preparation. This example exercises the sequence track;
155
- the public input contract also supports structure and function tracks through
156
- the multimodal helpers:
157
 
158
  ```python
159
  import torch
@@ -171,10 +169,9 @@ print(output.structure_logits.shape)
171
  print(output.function_logits.shape)
172
  ```
173
 
174
- When `return_dict=False`, ESM3 follows the standard base-model tuple prefix:
175
  `last_hidden_state`, then requested `hidden_states` and `attentions`. Multimodal
176
- logits and extensions follow that prefix. Prefer named fields for individual
177
- tracks.
178
 
179
  Generate masked sequence positions with an explicit seed:
180
 
@@ -190,8 +187,8 @@ generated = model.generate("MK____A", config)
190
  print(generated)
191
  ```
192
 
193
- Underscores mark positions to generate. Model outputs are predictions over
194
- tracks, not experimental measurements of structure or function.
195
 
196
  ## Runtime contract
197
 
@@ -211,8 +208,8 @@ tracks, not experimental measurements of structure or function.
211
  ## Release record
212
 
213
  - FastPLMs weights: `Synthyra/ESM3_small`
214
- - Runtime revision: recorded separately in the built artifact and published commit
215
- - Source-tree and runtime-bundle SHA-256: recorded in `provenance.json`
216
  - Official checkpoint: `biohub/esm3-sm-open-v1`
217
  - Artifact source: `fast`
218
  - State transform: `esm3_to_fastplms_v1`
@@ -220,19 +217,17 @@ tracks, not experimental measurements of structure or function.
220
  - Release tiers: `check`, `compliance`, `feature`, `artifact`, `benchmark`
221
  - Unresolved required file identities: `0`
222
 
223
- `provenance.json` records exact file identities, conversion, source revisions,
224
- legal texts, schema, and attestations. A nonzero unresolved count blocks release.
225
 
226
  ## Validation boundary
227
 
228
- Declared tiers compare applicable configuration, tokenizer behavior, state,
229
- and representative inference with the pinned reference. Metadata alone does
230
- not claim a build passed, a backend is faster, or an output is biologically
231
- valid.
232
 
233
  ## License
234
 
235
  Checkpoint terms: MIT. The Hub model-card identifier is
236
- `mit`. Applicable source licenses, notices, attribution,
237
- and conversion records are distributed with the local artifact. Review them
238
- before use.
 
10
 
11
  # Synthyra/ESM3_small
12
 
13
+ This checkpoint contains the FastPLMs `ESM3` implementation.
14
 
15
  Accepted inputs are sequence, structure, and function tracks prepared through
16
  the multimodal helpers.
 
28
  | Attention variants | Supported: `eager`, `sdpa`, `flex_attention` |
29
  | Compliance | Declared: exact release evidence is required |
30
 
31
+ A supported interface is not a pretrained downstream predictor. Classification heads start untrained. Compliance metadata does not show that a local build passed its release gate.
 
 
32
 
33
  ## Install and platform requirements
34
 
 
39
  "https://huggingface.co/Synthyra/ESM3_small/resolve/main/requirements.txt"
40
  ```
41
 
42
+ The FastPLMs implementation itself is embedded in the model repository.
43
+ Transformers loads it through `trust_remote_code=True`.
44
 
45
+ This model requires Python 3.11-3.14, PyTorch 2.13, and Transformers 5.13. The CPU gate covers small offline tests. Published checkpoint throughput and parity require the documented device tier. The Hub quick start needs network access for
46
+ the first download. For an air-gapped run, build the manifest-pinned local
47
+ artifact first and use the offline example.
48
 
49
  ## Quick start
50
 
 
60
  ```
61
 
62
  For offline validation, replace `model_id` with the manifest-built
63
+ `dist/hub/ESM3_small` path. Pass `local_files_only=True`.
64
 
65
  ## Attention and compliance
66
 
67
  The quick start selects `sdpa` explicitly. Declared variants are `eager`, `sdpa`, `flex_attention`. An unavailable
68
+ requested backend raises. It does not silently change implementation.
69
+ `output_attentions=True` can use the documented one-call eager fallback to
70
+ materialize attention tensors. The configured backend does not change.
71
 
72
+ This family declares the `compliance` tier. Release evidence identifies the
73
  checkpoint, backend, dtype, hardware, inputs, and reference revision.
74
 
75
  ## Dataset embeddings
76
 
77
+ The shared embedding mixin keeps input order and biological-position masking.
78
+ It accepts sequences, identified records, mappings, or a FASTA path:
79
 
80
  ```python
81
  pooled = model.embed_dataset(
 
92
  ```
93
 
94
  Set `output` and `format="safetensors"` or `"sqlite"` for transactional,
95
+ bounded-memory storage. Resume checks input order, model state, tokenizer
96
+ policy, backend, dtype, and pooling configuration before it appends data.
97
 
98
  ## PEFT fine-tuning
99
 
100
+ Install the training dependencies. Then attach LoRA to the loaded checkpoint:
101
 
102
  ```bash
103
  python -m pip install "datasets>=4.8,<5" "peft>=0.19,<0.20"
 
116
  )
117
  ```
118
 
119
+ This checkpoint has no advertised classifier. Supply the task objective and
120
+ preserve any new head through `modules_to_save`.
121
  All FastPLMs checkpoints follow the Transformers `PreTrainedModel` contract and
122
+ can use PEFT. The ESM2-specific shipped CLI is an example, not a
123
  support boundary. Record the target modules, base revision, data identity, and
124
  trainable parameter scope.
125
 
126
  ## Test-time training
127
 
128
  TTT samples masked views of one protein and updates only injected low-rank
129
+ adapters. Base checkpoint weights stay frozen:
130
 
131
  ```python
132
  from transformers import AutoModel
 
144
  print(metrics)
145
  ```
146
 
147
+ Saved adapters retain their deterministic reset state. TTT adds latency and
148
+ memory, can worsen an output, and does not show biological function.
149
 
150
  ## Sequence inference and masked-sequence generation
151
 
152
+ ESM3 prepares its sequence input. This example uses the sequence track. The
153
+ public input contract also supports structure and function tracks through the
154
+ multimodal helpers:
155
 
156
  ```python
157
  import torch
 
169
  print(output.function_logits.shape)
170
  ```
171
 
172
+ When `return_dict=False`, ESM3 uses the standard base-model tuple prefix:
173
  `last_hidden_state`, then requested `hidden_states` and `attentions`. Multimodal
174
+ logits and extensions follow this prefix. Use named fields for individual tracks.
 
175
 
176
  Generate masked sequence positions with an explicit seed:
177
 
 
187
  print(generated)
188
  ```
189
 
190
+ Underscores mark positions to generate. Model outputs are track predictions,
191
+ not experimental measurements of structure or function.
192
 
193
  ## Runtime contract
194
 
 
208
  ## Release record
209
 
210
  - FastPLMs weights: `Synthyra/ESM3_small`
211
+ - Runtime revision: recorded in the built artifact and published commit
212
+ - Source-tree and runtime-bundle SHA-256: recorded in the source record
213
  - Official checkpoint: `biohub/esm3-sm-open-v1`
214
  - Artifact source: `fast`
215
  - State transform: `esm3_to_fastplms_v1`
 
217
  - Release tiers: `check`, `compliance`, `feature`, `artifact`, `benchmark`
218
  - Unresolved required file identities: `0`
219
 
220
+ The source record records exact file identities, conversion, source revisions,
221
+ legal texts, schema, and attestations. A nonzero unresolved count blocks a release.
222
 
223
  ## Validation boundary
224
 
225
+ Declared tiers compare configuration, tokenizer behavior, state, and
226
+ representative inference with the pinned reference. Metadata does not show that
227
+ a build passed, that a backend is faster, or that an output is biologically valid.
 
228
 
229
  ## License
230
 
231
  Checkpoint terms: MIT. The Hub model-card identifier is
232
+ `mit`. The local artifact contains applicable source
233
+ licenses, notices, attribution, and conversion records. Review them before use.
 
THIRD_PARTY_NOTICES.md CHANGED
@@ -46,7 +46,7 @@ explicitly defines the repository release as including pretrained DPLM1 and
46
  DPLM2 weights, and the same revision carries the complete
47
  [Apache-2.0 license](https://github.com/bytedance/dplm/blob/8a2e15e53416b4536f03f79ad1f6f6a9cbd5e19d/LICENSE).
48
  FastPLMs records both checkpoint families as Apache-2.0 and distributes the
49
- verbatim license plus `LICENSES/dplm/PROVENANCE.md`. Converted weights retain
50
  those terms and remain subject to the ordinary artifact and publication gates.
51
 
52
  ## Biohub
@@ -80,7 +80,7 @@ TorchMetrics, Lightning Utilities, and NVIDIA DLLogger. Their exact versions or
80
  revision are pinned in `docker/constraints/esmfold.txt`; OpenFold imports them
81
  eagerly, and FastPLMs production code does not depend on them. DLLogger's exact
82
  source identity and installed-license handling are recorded in
83
- `LICENSES/dllogger/PROVENANCE.md`.
84
 
85
  ## ProteinTTT
86
 
@@ -93,7 +93,7 @@ revision-specific provenance are under `LICENSES/protein-ttt/`.
93
  For every supported family, `src/fastplms/models.toml` records an immutable
94
  official checkpoint revision, an immutable FastPLMs checkpoint revision, file
95
  digests, a named state transformation, and a mechanism-level conversion record.
96
- Generated artifacts reproduce that record in `provenance.json`. A release or
97
  artifact build must fail when a required file identity, legal text, attribution
98
  notice, modified-file notice, upstream revision, or conversion record is absent
99
  or differs from its manifest digest.
 
46
  DPLM2 weights, and the same revision carries the complete
47
  [Apache-2.0 license](https://github.com/bytedance/dplm/blob/8a2e15e53416b4536f03f79ad1f6f6a9cbd5e19d/LICENSE).
48
  FastPLMs records both checkpoint families as Apache-2.0 and distributes the
49
+ verbatim license plus `LICENSES/dplm/SOURCE_RECORD.md`. Converted weights retain
50
  those terms and remain subject to the ordinary artifact and publication gates.
51
 
52
  ## Biohub
 
80
  revision are pinned in `docker/constraints/esmfold.txt`; OpenFold imports them
81
  eagerly, and FastPLMs production code does not depend on them. DLLogger's exact
82
  source identity and installed-license handling are recorded in
83
+ `LICENSES/dllogger/SOURCE_RECORD.md`.
84
 
85
  ## ProteinTTT
86
 
 
93
  For every supported family, `src/fastplms/models.toml` records an immutable
94
  official checkpoint revision, an immutable FastPLMs checkpoint revision, file
95
  digests, a named state transformation, and a mechanism-level conversion record.
96
+ Generated artifacts reproduce that record in `source-record.json`. A release or
97
  artifact build must fail when a required file identity, legal text, attribution
98
  notice, modified-file notice, upstream revision, or conversion record is absent
99
  or differs from its manifest digest.
fastplms/models.toml CHANGED
@@ -88,7 +88,7 @@ license_files = ["LICENSE"]
88
  license_digests = ["LICENSE=sha256:cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30"]
89
  distribution_files = [
90
  "LICENSE=sha256:cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30",
91
- "PROVENANCE.md=sha256:a659f74be9073cf1ad2d2f7071531ca56959b421f111152cf4c41184ace5970e",
92
  ]
93
 
94
  [[upstreams]]
@@ -122,7 +122,7 @@ license_files = ["LICENSE"]
122
  license_digests = ["LICENSE=sha256:da6d3703ed11cbe42bd212c725957c98da23cbff1998c05fa4b3d976d1a58e93"]
123
  distribution_files = [
124
  "LICENSE=sha256:da6d3703ed11cbe42bd212c725957c98da23cbff1998c05fa4b3d976d1a58e93",
125
- "PROVENANCE.md=sha256:950adb94daf15e646ddf226dacfe2a8e77801aa0793e439a9a3490a48eb666e7",
126
  ]
127
 
128
  [[upstreams]]
@@ -136,7 +136,7 @@ license_digests = ["LICENSE=sha256:cfc7749b96f63bd31c3c42b5c471bf756814053e847c1
136
  distribution_files = [
137
  "LICENSE=sha256:cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30",
138
  "MODIFICATIONS.md=sha256:fd6f0aa1086a0c996cf967b326d18e965660cda0ad5c7f36a3474a8490720da3",
139
- "PROVENANCE.md=sha256:48c903db43a217a3126afaefbac60b7ddac7efda2dfcc0cbff0bffc7d6c30081",
140
  ]
141
 
142
  [[upstreams]]
@@ -149,7 +149,7 @@ license_files = ["LICENSE"]
149
  license_digests = ["LICENSE=sha256:bb01e7d5554f9e2e117172e56551452f68a7818df7bc8e71cd7a776a1d4ba3df"]
150
  distribution_files = [
151
  "LICENSE=sha256:bb01e7d5554f9e2e117172e56551452f68a7818df7bc8e71cd7a776a1d4ba3df",
152
- "PROVENANCE.md=sha256:dc641c37353c2efd50ccbdb316ca4aae495ec02c1563e0e15bac92f75fc482e5",
153
  ]
154
 
155
  [families.esm2]
@@ -187,7 +187,8 @@ reference_adapter = "tests.parity.support.reference_adapters.esm_plusplus"
187
  attention = ["eager", "sdpa", "flex_attention", "flash_attention_2", "flash_attention_3"]
188
  dtypes = ["float32", "bfloat16"]
189
  bf16_execution = "static_parameters"
190
- precisions = ["default"]
 
191
  vram_tier = "sequence"
192
  checkpoint_license = "MIT"
193
  hub_license = "mit"
@@ -267,7 +268,7 @@ checkpoint_license = "Apache-2.0"
267
  hub_license = "apache-2.0"
268
  weights_publication_allowed = true
269
  state_transform = "dplm_to_fastplms_v1"
270
- conversion_provenance = "Input: the pinned official DPLM1 checkpoint. Transformation: apply dplm_to_fastplms_v1, omitting the unused absolute-position table for rotary checkpoints and materializing the tied input/output embedding values as independent tensors. Output: the pinned Synthyra DPLM checkpoint. Validation: release parity compares exact state identity after the declared transform, tokenizer behavior, generation, and inference. License basis: the pinned ByteDance DPLM Apache-2.0 LICENSE and README explicitly scope the repository release to the pretrained DPLM1 and DPLM2 weights; immutable evidence is recorded in LICENSES/dplm/PROVENANCE.md. Limitation: redistribution remains subject to Apache-2.0 and the pinned source record; no broader rights are inferred."
271
  representative = "dplm_150m"
272
  documentation = "docs/models.md#dplm"
273
  test_tiers = ["check", "compliance", "feature", "artifact", "benchmark"]
@@ -291,7 +292,7 @@ checkpoint_license = "Apache-2.0"
291
  hub_license = "apache-2.0"
292
  weights_publication_allowed = true
293
  state_transform = "dplm2_to_fastplms_v1"
294
- conversion_provenance = "Input: the pinned official DPLM2 checkpoint. Transformation: apply dplm2_to_fastplms_v1, retaining the independent language-model head and trained encoder contact head while omitting the unused absolute-position table for rotary checkpoints. Output: the pinned Synthyra DPLM2 checkpoint. Validation: release parity compares exact keys and values after the declared omission, non-aliasing, tokenizer behavior, generation, and inference. License basis: the pinned ByteDance DPLM Apache-2.0 LICENSE and README explicitly scope the repository release to the pretrained DPLM1 and DPLM2 weights; immutable evidence is recorded in LICENSES/dplm/PROVENANCE.md. Limitation: no head exception is permitted by this source record, and redistribution remains subject to Apache-2.0."
295
  representative = "dplm2_150m"
296
  documentation = "docs/models.md#dplm2"
297
  test_tiers = ["check", "compliance", "feature", "artifact", "benchmark"]
 
88
  license_digests = ["LICENSE=sha256:cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30"]
89
  distribution_files = [
90
  "LICENSE=sha256:cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30",
91
+ "SOURCE_RECORD.md=sha256:a659f74be9073cf1ad2d2f7071531ca56959b421f111152cf4c41184ace5970e",
92
  ]
93
 
94
  [[upstreams]]
 
122
  license_digests = ["LICENSE=sha256:da6d3703ed11cbe42bd212c725957c98da23cbff1998c05fa4b3d976d1a58e93"]
123
  distribution_files = [
124
  "LICENSE=sha256:da6d3703ed11cbe42bd212c725957c98da23cbff1998c05fa4b3d976d1a58e93",
125
+ "SOURCE_RECORD.md=sha256:950adb94daf15e646ddf226dacfe2a8e77801aa0793e439a9a3490a48eb666e7",
126
  ]
127
 
128
  [[upstreams]]
 
136
  distribution_files = [
137
  "LICENSE=sha256:cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30",
138
  "MODIFICATIONS.md=sha256:fd6f0aa1086a0c996cf967b326d18e965660cda0ad5c7f36a3474a8490720da3",
139
+ "SOURCE_RECORD.md=sha256:48c903db43a217a3126afaefbac60b7ddac7efda2dfcc0cbff0bffc7d6c30081",
140
  ]
141
 
142
  [[upstreams]]
 
149
  license_digests = ["LICENSE=sha256:bb01e7d5554f9e2e117172e56551452f68a7818df7bc8e71cd7a776a1d4ba3df"]
150
  distribution_files = [
151
  "LICENSE=sha256:bb01e7d5554f9e2e117172e56551452f68a7818df7bc8e71cd7a776a1d4ba3df",
152
+ "SOURCE_RECORD.md=sha256:dc641c37353c2efd50ccbdb316ca4aae495ec02c1563e0e15bac92f75fc482e5",
153
  ]
154
 
155
  [families.esm2]
 
187
  attention = ["eager", "sdpa", "flex_attention", "flash_attention_2", "flash_attention_3"]
188
  dtypes = ["float32", "bfloat16"]
189
  bf16_execution = "static_parameters"
190
+ precisions = ["default", "fp8"]
191
+ experimental_precisions = ["fp8"]
192
  vram_tier = "sequence"
193
  checkpoint_license = "MIT"
194
  hub_license = "mit"
 
268
  hub_license = "apache-2.0"
269
  weights_publication_allowed = true
270
  state_transform = "dplm_to_fastplms_v1"
271
+ conversion_provenance = "Input: the pinned official DPLM1 checkpoint. Transformation: apply dplm_to_fastplms_v1, omitting the unused absolute-position table for rotary checkpoints and materializing the tied input/output embedding values as independent tensors. Output: the pinned Synthyra DPLM checkpoint. Validation: release parity compares exact state identity after the declared transform, tokenizer behavior, generation, and inference. License basis: the pinned ByteDance DPLM Apache-2.0 LICENSE and README explicitly scope the repository release to the pretrained DPLM1 and DPLM2 weights; immutable evidence is recorded in LICENSES/dplm/SOURCE_RECORD.md. Limitation: redistribution remains subject to Apache-2.0 and the pinned source record; no broader rights are inferred."
272
  representative = "dplm_150m"
273
  documentation = "docs/models.md#dplm"
274
  test_tiers = ["check", "compliance", "feature", "artifact", "benchmark"]
 
292
  hub_license = "apache-2.0"
293
  weights_publication_allowed = true
294
  state_transform = "dplm2_to_fastplms_v1"
295
+ conversion_provenance = "Input: the pinned official DPLM2 checkpoint. Transformation: apply dplm2_to_fastplms_v1, retaining the independent language-model head and trained encoder contact head while omitting the unused absolute-position table for rotary checkpoints. Output: the pinned Synthyra DPLM2 checkpoint. Validation: release parity compares exact keys and values after the declared omission, non-aliasing, tokenizer behavior, generation, and inference. License basis: the pinned ByteDance DPLM Apache-2.0 LICENSE and README explicitly scope the repository release to the pretrained DPLM1 and DPLM2 weights; immutable evidence is recorded in LICENSES/dplm/SOURCE_RECORD.md. Limitation: no head exception is permitted by this source record, and redistribution remains subject to Apache-2.0."
296
  representative = "dplm2_150m"
297
  documentation = "docs/models.md#dplm2"
298
  test_tiers = ["check", "compliance", "feature", "artifact", "benchmark"]
fastplms/models/esm3/modeling_esm3.py CHANGED
@@ -1350,12 +1350,13 @@ class MultiHeadAttention(nn.Module):
1350
  def forward(
1351
  self,
1352
  x: torch.Tensor,
1353
- seq_id: torch.Tensor | None,
1354
  attention_mask: torch.Tensor | None = None,
 
 
1355
  output_attentions: bool = False,
1356
  effective_backend: AttentionBackend | None = None,
1357
  ) -> tuple[torch.Tensor, torch.Tensor | None]:
1358
- # x: (b, l, d); seq_id, attention_mask: (b, l)
1359
  qkv = self.layernorm_qkv(x) # (b, l, 3 * d)
1360
  query, key, value = torch.chunk(qkv, 3, dim=-1)
1361
  query = self.q_ln(query).to(query.dtype)
@@ -1368,13 +1369,7 @@ class MultiHeadAttention(nn.Module):
1368
  h=self.n_heads,
1369
  )
1370
  query, key, value = map(reshaper, (query, key, value)) # each (b, h, l, d_h)
1371
-
1372
- mask = None
1373
- if seq_id is not None:
1374
- mask = (seq_id.unsqueeze(-1) == seq_id.unsqueeze(-2)).unsqueeze(1)
1375
- if attention_mask is not None:
1376
- key_padding_mask = attention_mask[:, None, None, :]
1377
- mask = key_padding_mask if mask is None else mask & key_padding_mask
1378
 
1379
  if effective_backend is None:
1380
  effective_backend = resolve_attention_backend_for_call(
@@ -1401,15 +1396,6 @@ class MultiHeadAttention(nn.Module):
1401
  else:
1402
  attn_weights = None
1403
  if effective_backend == AttentionBackend.FLEX:
1404
- block_mask = self._create_flex_block_mask(seq_id, attention_mask, query)
1405
- if seq_id is not None and attention_mask is not None:
1406
- mask_semantics = "sequence_id_and_padding"
1407
- elif seq_id is not None:
1408
- mask_semantics = "sequence_id_equality"
1409
- elif attention_mask is not None:
1410
- mask_semantics = "padding"
1411
- else:
1412
- mask_semantics = "dense"
1413
  fn = _get_flex_attention_fn(
1414
  device=query.device,
1415
  dtype=query.dtype,
@@ -1423,7 +1409,7 @@ class MultiHeadAttention(nn.Module):
1423
  query,
1424
  key,
1425
  value,
1426
- block_mask=block_mask,
1427
  scale=self.scale,
1428
  )
1429
  elif effective_backend == AttentionBackend.SDPA:
@@ -1442,37 +1428,6 @@ class MultiHeadAttention(nn.Module):
1442
  context = einops.rearrange(context, "b h s d -> b s (h d)") # (b, l, d)
1443
  return self.out_proj(context), attn_weights
1444
 
1445
- @staticmethod
1446
- def _create_flex_block_mask(
1447
- seq_id: torch.Tensor | None,
1448
- attention_mask: torch.Tensor | None,
1449
- query: torch.Tensor,
1450
- ) -> BlockMask | None:
1451
- if seq_id is None and attention_mask is None:
1452
- return None
1453
- if create_block_mask is None:
1454
- raise RuntimeError(
1455
- "Flex Attention requested but torch.create_block_mask is unavailable."
1456
- )
1457
- batch_size, _, seq_len, _ = query.shape
1458
-
1459
- def mask_mod(batch_idx, _head_idx, q_idx, kv_idx):
1460
- if seq_id is None:
1461
- return attention_mask[batch_idx, kv_idx]
1462
- allowed = seq_id[batch_idx, q_idx] == seq_id[batch_idx, kv_idx]
1463
- if attention_mask is not None:
1464
- allowed = allowed & attention_mask[batch_idx, kv_idx]
1465
- return allowed
1466
-
1467
- return create_block_mask(
1468
- mask_mod,
1469
- batch_size,
1470
- 1,
1471
- seq_len,
1472
- seq_len,
1473
- device=query.device,
1474
- )
1475
-
1476
 
1477
  class GeometricReasoningOriginalImpl(nn.Module):
1478
  def __init__(
@@ -1683,6 +1638,8 @@ class UnifiedTransformerBlock(nn.Module):
1683
  x: torch.Tensor,
1684
  sequence_id: torch.Tensor | None,
1685
  attention_mask: torch.Tensor | None,
 
 
1686
  frames: Affine3D,
1687
  frames_mask: torch.Tensor,
1688
  chain_id: torch.Tensor,
@@ -1693,8 +1650,9 @@ class UnifiedTransformerBlock(nn.Module):
1693
  if self.use_plain_attn:
1694
  plain_residual, attn_weights = self.attn(
1695
  x,
1696
- sequence_id,
1697
  attention_mask,
 
 
1698
  output_attentions=output_attentions,
1699
  effective_backend=effective_backend,
1700
  )
@@ -1772,9 +1730,17 @@ class TransformerStack(nn.Module):
1772
  chain_id = torch.ones(size=batch_dims, dtype=torch.int64, device=x.device)
1773
  if affine is None or affine_mask is None:
1774
  raise ValueError("affine and affine_mask are required for ESM3 transformer calls.")
1775
- effective_backend = resolve_attention_backend_for_call(
1776
- self.attention_backend,
1777
- output_attentions=output_attentions,
 
 
 
 
 
 
 
 
1778
  )
1779
  all_hidden_states = [] if output_hidden_states else None
1780
  all_attentions = []
@@ -1783,6 +1749,8 @@ class TransformerStack(nn.Module):
1783
  x,
1784
  sequence_id,
1785
  attention_mask,
 
 
1786
  affine,
1787
  affine_mask,
1788
  chain_id,
@@ -1797,6 +1765,110 @@ class TransformerStack(nn.Module):
1797
  attentions = tuple(all_attentions) if output_attentions else None
1798
  return self.norm(x), x, hidden_states, attentions
1799
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1800
 
1801
  class EncodeInputs(nn.Module):
1802
  def __init__(self, d_model: int, sequence_vocab_size: int = 64) -> None:
@@ -2049,26 +2121,6 @@ class ESM3Core(nn.Module):
2049
  function_tokens,
2050
  residue_annotation_tokens,
2051
  )
2052
- expected_mask_shape = tuple(x.shape[:2])
2053
- if sequence_id is not None and tuple(sequence_id.shape) != expected_mask_shape:
2054
- raise ValueError(
2055
- "sequence_id must have shape (batch, sequence); "
2056
- f"expected {expected_mask_shape}, received {tuple(sequence_id.shape)}."
2057
- )
2058
- if attention_mask is not None:
2059
- if tuple(attention_mask.shape) != expected_mask_shape:
2060
- raise ValueError(
2061
- "attention_mask must have shape (batch, sequence); "
2062
- f"expected {expected_mask_shape}, received {tuple(attention_mask.shape)}."
2063
- )
2064
- if attention_mask.dtype != torch.bool and not bool(
2065
- torch.logical_or(attention_mask == 0, attention_mask == 1).all()
2066
- ):
2067
- raise ValueError("attention_mask must contain only boolean or 0/1 values.")
2068
- attention_mask = attention_mask.to(device=x.device, dtype=torch.bool)
2069
- if not bool(attention_mask.any(dim=-1).all()):
2070
- raise ValueError("attention_mask must keep at least one valid key per batch row.")
2071
- affine_mask = affine_mask & attention_mask
2072
  x, embedding, hidden_states, attentions = self.transformer(
2073
  x,
2074
  sequence_id,
 
1350
  def forward(
1351
  self,
1352
  x: torch.Tensor,
 
1353
  attention_mask: torch.Tensor | None = None,
1354
+ flex_block_mask: BlockMask | None = None,
1355
+ mask_semantics: str = "dense",
1356
  output_attentions: bool = False,
1357
  effective_backend: AttentionBackend | None = None,
1358
  ) -> tuple[torch.Tensor, torch.Tensor | None]:
1359
+ # x: (b, l, d); attention_mask: (b, 1, l, l) or (b, 1, 1, l)
1360
  qkv = self.layernorm_qkv(x) # (b, l, 3 * d)
1361
  query, key, value = torch.chunk(qkv, 3, dim=-1)
1362
  query = self.q_ln(query).to(query.dtype)
 
1369
  h=self.n_heads,
1370
  )
1371
  query, key, value = map(reshaper, (query, key, value)) # each (b, h, l, d_h)
1372
+ mask = attention_mask
 
 
 
 
 
 
1373
 
1374
  if effective_backend is None:
1375
  effective_backend = resolve_attention_backend_for_call(
 
1396
  else:
1397
  attn_weights = None
1398
  if effective_backend == AttentionBackend.FLEX:
 
 
 
 
 
 
 
 
 
1399
  fn = _get_flex_attention_fn(
1400
  device=query.device,
1401
  dtype=query.dtype,
 
1409
  query,
1410
  key,
1411
  value,
1412
+ block_mask=flex_block_mask,
1413
  scale=self.scale,
1414
  )
1415
  elif effective_backend == AttentionBackend.SDPA:
 
1428
  context = einops.rearrange(context, "b h s d -> b s (h d)") # (b, l, d)
1429
  return self.out_proj(context), attn_weights
1430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1431
 
1432
  class GeometricReasoningOriginalImpl(nn.Module):
1433
  def __init__(
 
1638
  x: torch.Tensor,
1639
  sequence_id: torch.Tensor | None,
1640
  attention_mask: torch.Tensor | None,
1641
+ flex_block_mask: BlockMask | None,
1642
+ mask_semantics: str,
1643
  frames: Affine3D,
1644
  frames_mask: torch.Tensor,
1645
  chain_id: torch.Tensor,
 
1650
  if self.use_plain_attn:
1651
  plain_residual, attn_weights = self.attn(
1652
  x,
 
1653
  attention_mask,
1654
+ flex_block_mask,
1655
+ mask_semantics,
1656
  output_attentions=output_attentions,
1657
  effective_backend=effective_backend,
1658
  )
 
1730
  chain_id = torch.ones(size=batch_dims, dtype=torch.int64, device=x.device)
1731
  if affine is None or affine_mask is None:
1732
  raise ValueError("affine and affine_mask are required for ESM3 transformer calls.")
1733
+ attention_mask, flex_block_mask, affine_mask, mask_semantics, effective_backend = (
1734
+ self._prepare_attention_masks(
1735
+ sequence_id=sequence_id,
1736
+ attention_mask=attention_mask,
1737
+ affine_mask=affine_mask,
1738
+ batch_size=x.shape[0],
1739
+ seq_len=x.shape[1],
1740
+ device=x.device,
1741
+ attention_backend=self.attention_backend,
1742
+ output_attentions=output_attentions,
1743
+ )
1744
  )
1745
  all_hidden_states = [] if output_hidden_states else None
1746
  all_attentions = []
 
1749
  x,
1750
  sequence_id,
1751
  attention_mask,
1752
+ flex_block_mask,
1753
+ mask_semantics,
1754
  affine,
1755
  affine_mask,
1756
  chain_id,
 
1765
  attentions = tuple(all_attentions) if output_attentions else None
1766
  return self.norm(x), x, hidden_states, attentions
1767
 
1768
+ @staticmethod
1769
+ @torch.compiler.disable
1770
+ def _prepare_attention_masks(
1771
+ sequence_id: torch.Tensor | None,
1772
+ attention_mask: torch.Tensor | None,
1773
+ affine_mask: torch.Tensor,
1774
+ batch_size: int,
1775
+ seq_len: int,
1776
+ device: torch.device,
1777
+ attention_backend: AttentionBackend,
1778
+ output_attentions: bool,
1779
+ ) -> tuple[
1780
+ torch.Tensor | None,
1781
+ BlockMask | None,
1782
+ torch.Tensor,
1783
+ str,
1784
+ AttentionBackend,
1785
+ ]:
1786
+ expected_mask_shape = (batch_size, seq_len)
1787
+ if sequence_id is not None and tuple(sequence_id.shape) != expected_mask_shape:
1788
+ raise ValueError(
1789
+ "sequence_id must have shape (batch, sequence); "
1790
+ f"expected {expected_mask_shape}, received {tuple(sequence_id.shape)}."
1791
+ )
1792
+ if attention_mask is not None:
1793
+ if tuple(attention_mask.shape) != expected_mask_shape:
1794
+ raise ValueError(
1795
+ "attention_mask must have shape (batch, sequence); "
1796
+ f"expected {expected_mask_shape}, received {tuple(attention_mask.shape)}."
1797
+ )
1798
+ if attention_mask.dtype != torch.bool and not bool(
1799
+ torch.logical_or(attention_mask == 0, attention_mask == 1).all()
1800
+ ):
1801
+ raise ValueError("attention_mask must contain only boolean or 0/1 values.")
1802
+ attention_mask = attention_mask.to(device=device, dtype=torch.bool)
1803
+ if not bool(attention_mask.any(dim=-1).all()):
1804
+ raise ValueError("attention_mask must keep at least one valid key per batch row.")
1805
+ affine_mask = affine_mask & attention_mask
1806
+
1807
+ effective_backend = resolve_attention_backend_for_call(
1808
+ attention_backend,
1809
+ output_attentions=output_attentions,
1810
+ )
1811
+
1812
+ if sequence_id is not None and attention_mask is not None:
1813
+ mask_semantics = "sequence_id_and_padding"
1814
+ elif sequence_id is not None:
1815
+ mask_semantics = "sequence_id_equality"
1816
+ elif attention_mask is not None:
1817
+ mask_semantics = "padding"
1818
+ else:
1819
+ mask_semantics = "dense"
1820
+
1821
+ dense_mask = None
1822
+ flex_block_mask = None
1823
+ has_attention_mask = sequence_id is not None or attention_mask is not None
1824
+ if effective_backend == AttentionBackend.FLEX and has_attention_mask:
1825
+ flex_block_mask = TransformerStack._create_flex_block_mask(
1826
+ sequence_id,
1827
+ attention_mask,
1828
+ batch_size,
1829
+ seq_len,
1830
+ device,
1831
+ )
1832
+ else:
1833
+ if sequence_id is not None:
1834
+ dense_mask = (sequence_id.unsqueeze(-1) == sequence_id.unsqueeze(-2)).unsqueeze(1)
1835
+ if attention_mask is not None:
1836
+ key_padding_mask = attention_mask[:, None, None, :]
1837
+ dense_mask = (
1838
+ key_padding_mask if dense_mask is None else dense_mask & key_padding_mask
1839
+ )
1840
+ return dense_mask, flex_block_mask, affine_mask, mask_semantics, effective_backend
1841
+
1842
+ @staticmethod
1843
+ def _create_flex_block_mask(
1844
+ sequence_id: torch.Tensor | None,
1845
+ attention_mask: torch.Tensor | None,
1846
+ batch_size: int,
1847
+ seq_len: int,
1848
+ device: torch.device,
1849
+ ) -> BlockMask:
1850
+ if create_block_mask is None:
1851
+ raise RuntimeError(
1852
+ "Flex Attention requested but torch.create_block_mask is unavailable."
1853
+ )
1854
+
1855
+ def mask_mod(batch_idx, _head_idx, q_idx, kv_idx):
1856
+ if sequence_id is None:
1857
+ return attention_mask[batch_idx, kv_idx]
1858
+ allowed = sequence_id[batch_idx, q_idx] == sequence_id[batch_idx, kv_idx]
1859
+ if attention_mask is not None:
1860
+ allowed = allowed & attention_mask[batch_idx, kv_idx]
1861
+ return allowed
1862
+
1863
+ return create_block_mask(
1864
+ mask_mod,
1865
+ batch_size,
1866
+ 1,
1867
+ seq_len,
1868
+ seq_len,
1869
+ device=device,
1870
+ )
1871
+
1872
 
1873
  class EncodeInputs(nn.Module):
1874
  def __init__(self, d_model: int, sequence_vocab_size: int = 64) -> None:
 
2121
  function_tokens,
2122
  residue_annotation_tokens,
2123
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2124
  x, embedding, hidden_states, attentions = self.transformer(
2125
  x,
2126
  sequence_id,
fastplms_bundle.py CHANGED
The diff for this file is too large to render. See raw diff
 
modeling_fastplms.py CHANGED
@@ -12,7 +12,7 @@ from zipfile import ZIP_DEFLATED, ZipFile
12
 
13
  from .fastplms_bundle import RUNTIME_DATA, RUNTIME_HASH
14
 
15
- if RUNTIME_HASH != "b02f11de9f863ef10745381a7dc9ba25a161eed3e41ab4d1712ce772d265ae1a":
16
  raise RuntimeError("FastPLMs runtime identity differs from the bridge.")
17
 
18
  _RUNTIME_TEMPORARIES = []
 
12
 
13
  from .fastplms_bundle import RUNTIME_DATA, RUNTIME_HASH
14
 
15
+ if RUNTIME_HASH != "6fc80802a28c93c5200cbe876afa1e1f7984cba094062417774f0cfaa00eb89e":
16
  raise RuntimeError("FastPLMs runtime identity differs from the bridge.")
17
 
18
  _RUNTIME_TEMPORARIES = []