rc-foundry 0.1.5__py3-none-any.whl → 0.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- foundry/inference_engines/checkpoint_registry.py +58 -11
- foundry/utils/alignment.py +10 -2
- foundry/version.py +2 -2
- foundry_cli/download_checkpoints.py +66 -66
- {rc_foundry-0.1.5.dist-info → rc_foundry-0.1.7.dist-info}/METADATA +25 -20
- rc_foundry-0.1.7.dist-info/RECORD +311 -0
- rf3/configs/callbacks/default.yaml +5 -0
- rf3/configs/callbacks/dump_validation_structures.yaml +6 -0
- rf3/configs/callbacks/metrics_logging.yaml +10 -0
- rf3/configs/callbacks/train_logging.yaml +16 -0
- rf3/configs/dataloader/default.yaml +15 -0
- rf3/configs/datasets/base.yaml +31 -0
- rf3/configs/datasets/pdb_and_distillation.yaml +58 -0
- rf3/configs/datasets/pdb_only.yaml +17 -0
- rf3/configs/datasets/train/disorder_distillation.yaml +48 -0
- rf3/configs/datasets/train/domain_distillation.yaml +50 -0
- rf3/configs/datasets/train/monomer_distillation.yaml +49 -0
- rf3/configs/datasets/train/na_complex_distillation.yaml +50 -0
- rf3/configs/datasets/train/pdb/af3_weighted_sampling.yaml +8 -0
- rf3/configs/datasets/train/pdb/base.yaml +32 -0
- rf3/configs/datasets/train/pdb/plinder.yaml +54 -0
- rf3/configs/datasets/train/pdb/train_interface.yaml +51 -0
- rf3/configs/datasets/train/pdb/train_pn_unit.yaml +46 -0
- rf3/configs/datasets/train/rna_monomer_distillation.yaml +56 -0
- rf3/configs/datasets/val/af3_ab_set.yaml +11 -0
- rf3/configs/datasets/val/af3_validation.yaml +11 -0
- rf3/configs/datasets/val/base.yaml +32 -0
- rf3/configs/datasets/val/runs_and_poses.yaml +12 -0
- rf3/configs/debug/default.yaml +66 -0
- rf3/configs/debug/train_specific_examples.yaml +21 -0
- rf3/configs/experiment/pretrained/rf3.yaml +50 -0
- rf3/configs/experiment/pretrained/rf3_with_confidence.yaml +13 -0
- rf3/configs/experiment/quick-rf3-with-confidence.yaml +15 -0
- rf3/configs/experiment/quick-rf3.yaml +61 -0
- rf3/configs/hydra/default.yaml +18 -0
- rf3/configs/hydra/no_logging.yaml +7 -0
- rf3/configs/inference.yaml +7 -0
- rf3/configs/inference_engine/base.yaml +23 -0
- rf3/configs/inference_engine/rf3.yaml +33 -0
- rf3/configs/logger/csv.yaml +6 -0
- rf3/configs/logger/default.yaml +3 -0
- rf3/configs/logger/wandb.yaml +15 -0
- rf3/configs/model/components/ema.yaml +1 -0
- rf3/configs/model/components/rf3_net.yaml +177 -0
- rf3/configs/model/components/rf3_net_with_confidence_head.yaml +45 -0
- rf3/configs/model/optimizers/adam.yaml +5 -0
- rf3/configs/model/rf3.yaml +43 -0
- rf3/configs/model/rf3_with_confidence.yaml +7 -0
- rf3/configs/model/schedulers/af3.yaml +6 -0
- rf3/configs/paths/data/default.yaml +43 -0
- rf3/configs/paths/default.yaml +21 -0
- rf3/configs/train.yaml +42 -0
- rf3/configs/trainer/cpu.yaml +6 -0
- rf3/configs/trainer/ddp.yaml +5 -0
- rf3/configs/trainer/loss/losses/confidence_loss.yaml +29 -0
- rf3/configs/trainer/loss/losses/diffusion_loss.yaml +9 -0
- rf3/configs/trainer/loss/losses/distogram_loss.yaml +2 -0
- rf3/configs/trainer/loss/structure_prediction.yaml +4 -0
- rf3/configs/trainer/loss/structure_prediction_with_confidence.yaml +2 -0
- rf3/configs/trainer/metrics/structure_prediction.yaml +14 -0
- rf3/configs/trainer/rf3.yaml +20 -0
- rf3/configs/trainer/rf3_with_confidence.yaml +13 -0
- rf3/configs/validate.yaml +45 -0
- rfd3/cli.py +10 -4
- rfd3/configs/__init__.py +0 -0
- rfd3/configs/callbacks/design_callbacks.yaml +10 -0
- rfd3/configs/callbacks/metrics_logging.yaml +20 -0
- rfd3/configs/callbacks/train_logging.yaml +24 -0
- rfd3/configs/dataloader/default.yaml +15 -0
- rfd3/configs/dataloader/fast.yaml +11 -0
- rfd3/configs/datasets/conditions/dna_condition.yaml +3 -0
- rfd3/configs/datasets/conditions/island.yaml +28 -0
- rfd3/configs/datasets/conditions/ppi.yaml +2 -0
- rfd3/configs/datasets/conditions/sequence_design.yaml +17 -0
- rfd3/configs/datasets/conditions/tipatom.yaml +28 -0
- rfd3/configs/datasets/conditions/unconditional.yaml +21 -0
- rfd3/configs/datasets/design_base.yaml +97 -0
- rfd3/configs/datasets/train/pdb/af3_train_interface.yaml +46 -0
- rfd3/configs/datasets/train/pdb/af3_train_pn_unit.yaml +42 -0
- rfd3/configs/datasets/train/pdb/base.yaml +14 -0
- rfd3/configs/datasets/train/pdb/base_no_weights.yaml +19 -0
- rfd3/configs/datasets/train/pdb/base_transform_args.yaml +59 -0
- rfd3/configs/datasets/train/pdb/na_complex_distillation.yaml +20 -0
- rfd3/configs/datasets/train/pdb/pdb_base.yaml +11 -0
- rfd3/configs/datasets/train/pdb/rfd3_train_interface.yaml +22 -0
- rfd3/configs/datasets/train/pdb/rfd3_train_pn_unit.yaml +23 -0
- rfd3/configs/datasets/train/rfd3_monomer_distillation.yaml +38 -0
- rfd3/configs/datasets/val/bcov_ppi_easy_medium.yaml +9 -0
- rfd3/configs/datasets/val/design_validation_base.yaml +40 -0
- rfd3/configs/datasets/val/dna_binder_design5.yaml +9 -0
- rfd3/configs/datasets/val/dna_binder_long.yaml +13 -0
- rfd3/configs/datasets/val/dna_binder_short.yaml +13 -0
- rfd3/configs/datasets/val/indexed.yaml +9 -0
- rfd3/configs/datasets/val/mcsa_41.yaml +9 -0
- rfd3/configs/datasets/val/mcsa_41_short_rigid.yaml +10 -0
- rfd3/configs/datasets/val/ppi_inference.yaml +7 -0
- rfd3/configs/datasets/val/sm_binder_hbonds.yaml +13 -0
- rfd3/configs/datasets/val/sm_binder_hbonds_short.yaml +15 -0
- rfd3/configs/datasets/val/unconditional.yaml +9 -0
- rfd3/configs/datasets/val/unconditional_deep.yaml +9 -0
- rfd3/configs/datasets/val/unindexed.yaml +8 -0
- rfd3/configs/datasets/val/val_examples/bcov_ppi_easy_medium_with_ori.yaml +151 -0
- rfd3/configs/datasets/val/val_examples/bcov_ppi_easy_medium_with_ori_spoof_helical_bundle.yaml +7 -0
- rfd3/configs/datasets/val/val_examples/bcov_ppi_easy_medium_with_ori_varying_lengths.yaml +28 -0
- rfd3/configs/datasets/val/val_examples/bpem_ori_hb.yaml +212 -0
- rfd3/configs/debug/default.yaml +64 -0
- rfd3/configs/debug/train_specific_examples.yaml +21 -0
- rfd3/configs/dev.yaml +9 -0
- rfd3/configs/experiment/debug.yaml +14 -0
- rfd3/configs/experiment/pretrain.yaml +31 -0
- rfd3/configs/experiment/test-uncond.yaml +10 -0
- rfd3/configs/experiment/test-unindexed.yaml +21 -0
- rfd3/configs/hydra/default.yaml +18 -0
- rfd3/configs/hydra/no_logging.yaml +7 -0
- rfd3/configs/inference.yaml +9 -0
- rfd3/configs/inference_engine/base.yaml +15 -0
- rfd3/configs/inference_engine/dev.yaml +20 -0
- rfd3/configs/inference_engine/rfdiffusion3.yaml +65 -0
- rfd3/configs/logger/csv.yaml +6 -0
- rfd3/configs/logger/default.yaml +2 -0
- rfd3/configs/logger/wandb.yaml +15 -0
- rfd3/configs/model/components/ema.yaml +1 -0
- rfd3/configs/model/components/rfd3_net.yaml +131 -0
- rfd3/configs/model/optimizers/adam.yaml +5 -0
- rfd3/configs/model/rfd3_base.yaml +8 -0
- rfd3/configs/model/samplers/edm.yaml +21 -0
- rfd3/configs/model/samplers/symmetry.yaml +10 -0
- rfd3/configs/model/schedulers/af3.yaml +6 -0
- rfd3/configs/paths/data/default.yaml +18 -0
- rfd3/configs/paths/default.yaml +22 -0
- rfd3/configs/train.yaml +28 -0
- rfd3/configs/trainer/cpu.yaml +6 -0
- rfd3/configs/trainer/ddp.yaml +5 -0
- rfd3/configs/trainer/loss/losses/diffusion_loss.yaml +12 -0
- rfd3/configs/trainer/loss/losses/sequence_loss.yaml +3 -0
- rfd3/configs/trainer/metrics/design_metrics.yaml +22 -0
- rfd3/configs/trainer/rfd3_base.yaml +35 -0
- rfd3/configs/validate.yaml +34 -0
- rfd3/engine.py +19 -11
- rfd3/inference/input_parsing.py +1 -1
- rfd3/inference/legacy_input_parsing.py +17 -1
- rfd3/inference/parsing.py +1 -0
- rfd3/inference/symmetry/atom_array.py +1 -5
- rfd3/inference/symmetry/checks.py +53 -28
- rfd3/inference/symmetry/frames.py +8 -5
- rfd3/inference/symmetry/symmetry_utils.py +38 -60
- rfd3/run_inference.py +3 -1
- rfd3/utils/inference.py +23 -0
- rc_foundry-0.1.5.dist-info/RECORD +0 -180
- {rc_foundry-0.1.5.dist-info → rc_foundry-0.1.7.dist-info}/WHEEL +0 -0
- {rc_foundry-0.1.5.dist-info → rc_foundry-0.1.7.dist-info}/entry_points.txt +0 -0
- {rc_foundry-0.1.5.dist-info → rc_foundry-0.1.7.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -3,20 +3,62 @@
|
|
|
3
3
|
import os
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from pathlib import Path
|
|
6
|
+
from typing import Iterable, List
|
|
6
7
|
|
|
8
|
+
import dotenv
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
DEFAULT_CHECKPOINT_DIR = Path.home() / ".foundry" / "checkpoints"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _normalize_paths(paths: Iterable[Path]) -> list[Path]:
|
|
14
|
+
"""Return absolute, deduplicated paths in order."""
|
|
15
|
+
seen = set()
|
|
16
|
+
normalized: List[Path] = []
|
|
17
|
+
for path in paths:
|
|
18
|
+
resolved = path.expanduser().absolute()
|
|
19
|
+
if resolved not in seen:
|
|
20
|
+
normalized.append(resolved)
|
|
21
|
+
seen.add(resolved)
|
|
22
|
+
return normalized
|
|
10
23
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
24
|
+
|
|
25
|
+
def get_default_checkpoint_dirs() -> list[Path]:
|
|
26
|
+
"""Return checkpoint search paths.
|
|
27
|
+
|
|
28
|
+
Always starts with the default ~/.foundry/checkpoints directory and then
|
|
29
|
+
appends any additional directories from the colon-separated
|
|
30
|
+
FOUNDRY_CHECKPOINT_DIRS environment variable.
|
|
14
31
|
"""
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
env_dirs = os.environ.get("FOUNDRY_CHECKPOINT_DIRS", "")
|
|
33
|
+
|
|
34
|
+
# For backward compatibility, also check FOUNDRY_CHECKPOINTS_DIR
|
|
35
|
+
if not env_dirs:
|
|
36
|
+
env_dirs = os.environ.get("FOUNDRY_CHECKPOINTS_DIR", "")
|
|
37
|
+
|
|
38
|
+
extra_dirs: list[Path] = []
|
|
39
|
+
if env_dirs:
|
|
40
|
+
extra_dirs = [Path(p.strip()) for p in env_dirs.split(":") if p.strip()]
|
|
41
|
+
return _normalize_paths([*extra_dirs, DEFAULT_CHECKPOINT_DIR])
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_default_checkpoint_dir() -> Path:
|
|
45
|
+
"""Backward-compatible helper returning the primary checkpoint directory."""
|
|
46
|
+
return get_default_checkpoint_dirs()[0]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def append_checkpoint_to_env(checkpoint_dirs: list[Path]) -> bool:
|
|
50
|
+
dotenv_path = dotenv.find_dotenv()
|
|
51
|
+
if dotenv_path:
|
|
52
|
+
checkpoint_dirs = _normalize_paths(checkpoint_dirs)
|
|
53
|
+
dotenv.set_key(
|
|
54
|
+
dotenv_path=dotenv_path,
|
|
55
|
+
key_to_set="FOUNDRY_CHECKPOINT_DIRS",
|
|
56
|
+
value_to_set=":".join(str(path) for path in checkpoint_dirs),
|
|
57
|
+
export=False,
|
|
58
|
+
)
|
|
59
|
+
return True
|
|
60
|
+
else:
|
|
61
|
+
return False
|
|
20
62
|
|
|
21
63
|
|
|
22
64
|
@dataclass
|
|
@@ -27,7 +69,12 @@ class RegisteredCheckpoint:
|
|
|
27
69
|
sha256: None = None # Optional: add checksum for verification
|
|
28
70
|
|
|
29
71
|
def get_default_path(self):
|
|
30
|
-
|
|
72
|
+
checkpoint_dirs = get_default_checkpoint_dirs()
|
|
73
|
+
for checkpoint_dir in checkpoint_dirs:
|
|
74
|
+
candidate = checkpoint_dir / self.filename
|
|
75
|
+
if candidate.exists():
|
|
76
|
+
return candidate
|
|
77
|
+
return checkpoint_dirs[0] / self.filename
|
|
31
78
|
|
|
32
79
|
|
|
33
80
|
REGISTERED_CHECKPOINTS = {
|
foundry/utils/alignment.py
CHANGED
|
@@ -18,14 +18,19 @@ def weighted_rigid_align(
|
|
|
18
18
|
Returns:
|
|
19
19
|
X_align_L: [B, L, 3]
|
|
20
20
|
"""
|
|
21
|
-
assert X_L.shape == X_gt_L.shape
|
|
22
|
-
assert X_L.shape[:-1] == w_L.shape
|
|
23
21
|
|
|
22
|
+
# Canonicalize dimensions
|
|
23
|
+
if X_L.ndim == 2:
|
|
24
|
+
X_L = X_L[None]
|
|
25
|
+
if X_gt_L.ndim == 2:
|
|
26
|
+
X_gt_L = X_gt_L[None]
|
|
24
27
|
if X_exists_L is None:
|
|
25
28
|
X_exists_L = torch.ones((X_L.shape[-2]), dtype=torch.bool)
|
|
26
29
|
if w_L is None:
|
|
27
30
|
w_L = torch.ones_like(X_L[..., 0])
|
|
28
31
|
else:
|
|
32
|
+
if w_L.ndim == 1:
|
|
33
|
+
w_L = w_L[None]
|
|
29
34
|
w_L = w_L.to(torch.float32)
|
|
30
35
|
|
|
31
36
|
# Assert `X_exists_L` is a boolean mask
|
|
@@ -33,6 +38,9 @@ def weighted_rigid_align(
|
|
|
33
38
|
X_exists_L.dtype == torch.bool
|
|
34
39
|
), "X_exists_L should be a boolean mask! Otherwise, the alignment will be incorrect (silent failure)!"
|
|
35
40
|
|
|
41
|
+
assert X_L.shape == X_gt_L.shape
|
|
42
|
+
assert X_L.shape[:-1] == w_L.shape
|
|
43
|
+
|
|
36
44
|
X_resolved = X_L[:, X_exists_L]
|
|
37
45
|
X_gt_resolved = X_gt_L[:, X_exists_L]
|
|
38
46
|
w_resolved = w_L[:, X_exists_L]
|
foundry/version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.7'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 7)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -6,7 +6,7 @@ from typing import Optional
|
|
|
6
6
|
from urllib.request import urlopen
|
|
7
7
|
|
|
8
8
|
import typer
|
|
9
|
-
from dotenv import
|
|
9
|
+
from dotenv import load_dotenv
|
|
10
10
|
from rich.console import Console
|
|
11
11
|
from rich.progress import (
|
|
12
12
|
BarColumn,
|
|
@@ -20,7 +20,8 @@ from rich.progress import (
|
|
|
20
20
|
|
|
21
21
|
from foundry.inference_engines.checkpoint_registry import (
|
|
22
22
|
REGISTERED_CHECKPOINTS,
|
|
23
|
-
|
|
23
|
+
append_checkpoint_to_env,
|
|
24
|
+
get_default_checkpoint_dirs,
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
load_dotenv(override=True)
|
|
@@ -29,6 +30,27 @@ app = typer.Typer(help="Foundry model checkpoint installation utilities")
|
|
|
29
30
|
console = Console()
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
def _resolve_checkpoint_dirs(checkpoint_dir: Optional[Path]) -> list[Path]:
|
|
34
|
+
"""Return checkpoint search path with defaults first."""
|
|
35
|
+
checkpoint_dirs = get_default_checkpoint_dirs()
|
|
36
|
+
if checkpoint_dir is not None:
|
|
37
|
+
resolved = checkpoint_dir.expanduser().absolute()
|
|
38
|
+
if resolved not in checkpoint_dirs:
|
|
39
|
+
checkpoint_dirs.insert(0, resolved)
|
|
40
|
+
else:
|
|
41
|
+
# Move to front
|
|
42
|
+
checkpoint_dirs.remove(resolved)
|
|
43
|
+
checkpoint_dirs.insert(0, resolved)
|
|
44
|
+
|
|
45
|
+
# Try to persist checkpoint dir to .env (optional, may not exist in Colab etc.)
|
|
46
|
+
if append_checkpoint_to_env(checkpoint_dirs):
|
|
47
|
+
console.print(
|
|
48
|
+
f"Tracked checkpoint directories: {':'.join(str(path) for path in checkpoint_dirs)}"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return checkpoint_dirs
|
|
52
|
+
|
|
53
|
+
|
|
32
54
|
def download_file(url: str, dest: Path, verify_hash: Optional[str] = None) -> None:
|
|
33
55
|
"""Download a file with progress bar and optional hash verification.
|
|
34
56
|
|
|
@@ -123,134 +145,112 @@ def install_model(model_name: str, checkpoint_dir: Path, force: bool = False) ->
|
|
|
123
145
|
def install(
|
|
124
146
|
models: list[str] = typer.Argument(
|
|
125
147
|
...,
|
|
126
|
-
help="Models to install: 'all', 'rfd3', 'rf3', 'mpnn', or combination",
|
|
148
|
+
help="Models to install: 'all', 'rfd3', 'rf3', 'mpnn', or a combination thereof",
|
|
127
149
|
),
|
|
128
150
|
checkpoint_dir: Optional[Path] = typer.Option(
|
|
129
151
|
None,
|
|
130
152
|
"--checkpoint-dir",
|
|
131
153
|
"-d",
|
|
132
|
-
help="Directory to save checkpoints (default
|
|
154
|
+
help="Directory to save checkpoints (default search path: ~/.foundry/checkpoints plus any $FOUNDRY_CHECKPOINT_DIRS entries)",
|
|
133
155
|
),
|
|
134
156
|
force: bool = typer.Option(
|
|
135
157
|
False, "--force", "-f", help="Overwrite existing checkpoints"
|
|
136
158
|
),
|
|
137
159
|
):
|
|
138
160
|
"""Install model checkpoints for foundry.
|
|
139
|
-
|
|
140
161
|
Examples:
|
|
141
|
-
|
|
142
162
|
foundry install all
|
|
143
|
-
|
|
144
163
|
foundry install rfd3 rf3
|
|
145
|
-
|
|
146
164
|
foundry install proteinmpnn --checkpoint-dir ./checkpoints
|
|
147
165
|
"""
|
|
148
166
|
# Determine checkpoint directory
|
|
149
|
-
|
|
150
|
-
|
|
167
|
+
checkpoint_dirs = _resolve_checkpoint_dirs(checkpoint_dir)
|
|
168
|
+
primary_checkpoint_dir = checkpoint_dirs[0]
|
|
151
169
|
|
|
152
|
-
console.print(f"[bold]
|
|
153
|
-
console.print()
|
|
170
|
+
console.print(f"[bold]Install target:[/bold] {primary_checkpoint_dir}\n")
|
|
154
171
|
|
|
155
172
|
# Expand 'all' to all available models
|
|
156
173
|
if "all" in models:
|
|
174
|
+
models_to_install = list(REGISTERED_CHECKPOINTS.keys())
|
|
175
|
+
elif "base-models" in models:
|
|
157
176
|
models_to_install = ["rfd3", "proteinmpnn", "ligandmpnn", "rf3"]
|
|
158
177
|
else:
|
|
159
178
|
models_to_install = models
|
|
160
179
|
|
|
161
180
|
# Install each model
|
|
162
181
|
for model_name in models_to_install:
|
|
163
|
-
install_model(model_name,
|
|
182
|
+
install_model(model_name, primary_checkpoint_dir, force)
|
|
164
183
|
console.print()
|
|
165
184
|
|
|
166
|
-
# Try to persist checkpoint dir to .env (optional, may not exist in Colab etc.)
|
|
167
|
-
dotenv_path = find_dotenv()
|
|
168
|
-
if dotenv_path:
|
|
169
|
-
set_key(
|
|
170
|
-
dotenv_path=dotenv_path,
|
|
171
|
-
key_to_set="FOUNDRY_CHECKPOINTS_DIR",
|
|
172
|
-
value_to_set=str(checkpoint_dir),
|
|
173
|
-
export=False,
|
|
174
|
-
)
|
|
175
|
-
console.print(f"Saved FOUNDRY_CHECKPOINTS_DIR to {dotenv_path}")
|
|
176
|
-
|
|
177
185
|
console.print("[bold green]Installation complete![/bold green]")
|
|
178
186
|
|
|
179
187
|
|
|
180
|
-
@app.command(name="list")
|
|
181
|
-
def
|
|
188
|
+
@app.command(name="list-available")
|
|
189
|
+
def list_available():
|
|
182
190
|
"""List available model checkpoints."""
|
|
183
191
|
console.print("[bold]Available models:[/bold]\n")
|
|
184
192
|
for name, info in REGISTERED_CHECKPOINTS.items():
|
|
185
193
|
console.print(f" [cyan]{name:8}[/cyan] - {info.description}")
|
|
186
194
|
|
|
187
195
|
|
|
188
|
-
@app.command()
|
|
189
|
-
def
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
"--checkpoint-dir",
|
|
193
|
-
"-d",
|
|
194
|
-
help="Checkpoint directory to show",
|
|
195
|
-
),
|
|
196
|
-
):
|
|
197
|
-
"""Show installed checkpoints."""
|
|
198
|
-
if checkpoint_dir is None:
|
|
199
|
-
checkpoint_dir = get_default_checkpoint_dir()
|
|
196
|
+
@app.command(name="list-installed")
|
|
197
|
+
def list_installed():
|
|
198
|
+
"""List installed checkpoints and their sizes."""
|
|
199
|
+
checkpoint_dirs = _resolve_checkpoint_dirs(None)
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
checkpoint_files: list[tuple[Path, float]] = []
|
|
202
|
+
for checkpoint_dir in checkpoint_dirs:
|
|
203
|
+
if not checkpoint_dir.exists():
|
|
204
|
+
continue
|
|
205
|
+
ckpts = list(checkpoint_dir.glob("*.ckpt")) + list(checkpoint_dir.glob("*.pt"))
|
|
206
|
+
for ckpt in ckpts:
|
|
207
|
+
size = ckpt.stat().st_size / (1024**3) # GB
|
|
208
|
+
checkpoint_files.append((ckpt, size))
|
|
206
209
|
|
|
207
|
-
checkpoint_files = list(checkpoint_dir.glob("*.ckpt"))
|
|
208
210
|
if not checkpoint_files:
|
|
209
|
-
console.print(
|
|
211
|
+
console.print(
|
|
212
|
+
"[yellow]No checkpoint files found in any checkpoint directory[/yellow]"
|
|
213
|
+
)
|
|
210
214
|
raise typer.Exit(0)
|
|
211
215
|
|
|
212
|
-
console.print(
|
|
216
|
+
console.print("[bold]Installed checkpoints:[/bold]\n")
|
|
213
217
|
total_size = 0
|
|
214
|
-
for ckpt in sorted(checkpoint_files):
|
|
215
|
-
size = ckpt.stat().st_size / (1024**3) # GB
|
|
218
|
+
for ckpt, size in sorted(checkpoint_files, key=lambda item: str(item[0])):
|
|
216
219
|
total_size += size
|
|
217
|
-
console.print(f" {ckpt
|
|
220
|
+
console.print(f" {ckpt} {size:8.2f} GB")
|
|
218
221
|
|
|
219
222
|
console.print(f"\n[bold]Total:[/bold] {total_size:.2f} GB")
|
|
220
223
|
|
|
221
224
|
|
|
222
|
-
@app.command()
|
|
225
|
+
@app.command(name="clean")
|
|
223
226
|
def clean(
|
|
224
|
-
checkpoint_dir: Optional[Path] = typer.Option(
|
|
225
|
-
None,
|
|
226
|
-
"--checkpoint-dir",
|
|
227
|
-
"-d",
|
|
228
|
-
help="Checkpoint directory to clean",
|
|
229
|
-
),
|
|
230
227
|
confirm: bool = typer.Option(
|
|
231
228
|
True, "--confirm/--no-confirm", help="Ask for confirmation before deleting"
|
|
232
229
|
),
|
|
233
230
|
):
|
|
234
231
|
"""Remove all downloaded checkpoints."""
|
|
235
|
-
|
|
236
|
-
checkpoint_dir = get_default_checkpoint_dir()
|
|
237
|
-
|
|
238
|
-
if not checkpoint_dir.exists():
|
|
239
|
-
console.print(f"[yellow]No checkpoints found at {checkpoint_dir}[/yellow]")
|
|
240
|
-
raise typer.Exit(0)
|
|
232
|
+
checkpoint_dirs = _resolve_checkpoint_dirs(None)
|
|
241
233
|
|
|
242
234
|
# List files to delete
|
|
243
|
-
checkpoint_files =
|
|
235
|
+
checkpoint_files: list[Path] = []
|
|
236
|
+
for checkpoint_dir in checkpoint_dirs:
|
|
237
|
+
if not checkpoint_dir.exists():
|
|
238
|
+
continue
|
|
239
|
+
checkpoint_files.extend(checkpoint_dir.glob("*.ckpt"))
|
|
240
|
+
checkpoint_files.extend(checkpoint_dir.glob("*.pt"))
|
|
241
|
+
|
|
244
242
|
if not checkpoint_files:
|
|
245
|
-
console.print(
|
|
243
|
+
console.print(
|
|
244
|
+
"[yellow]No checkpoint files found in any checkpoint directory[/yellow]"
|
|
245
|
+
)
|
|
246
246
|
raise typer.Exit(0)
|
|
247
247
|
|
|
248
248
|
console.print("[bold]Files to delete:[/bold]")
|
|
249
249
|
total_size = 0
|
|
250
|
-
for ckpt in checkpoint_files:
|
|
250
|
+
for ckpt in sorted(checkpoint_files, key=str):
|
|
251
251
|
size = ckpt.stat().st_size / (1024**3) # GB
|
|
252
252
|
total_size += size
|
|
253
|
-
console.print(f" {ckpt
|
|
253
|
+
console.print(f" {ckpt} ({size:.2f} GB)")
|
|
254
254
|
|
|
255
255
|
console.print(f"\n[bold]Total:[/bold] {total_size:.2f} GB")
|
|
256
256
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rc-foundry
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: Shared utilities and training infrastructure for biomolecular structure prediction models.
|
|
5
5
|
Author-email: Institute for Protein Design <contact@ipd.uw.edu>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -104,33 +104,34 @@ All models within Foundry rely on [AtomWorks](https://github.com/RosettaCommons/
|
|
|
104
104
|
pip install rc-foundry[all]
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
**Downloading weights**
|
|
108
|
-
|
|
107
|
+
**Downloading weights** Models can be downloaded to a target folder with:
|
|
108
|
+
```
|
|
109
|
+
foundry install base-models --checkpoint-dir <path/to/ckpt/dir>
|
|
110
|
+
```
|
|
111
|
+
where `checkpoint-dir` will be `~/.foundry/checkpoints` by default. Foundry always searches `~/.foundry/checkpoints` plus any colon-separated entries in `$FOUNDRY_CHECKPOINT_DIRS` during inference or subsequent commands to find checkpoints. `base-models` installs the latest RFD3, RF3 and MPNN variants - you can also download all of the models supported (including multiple checkpoints of RF3) with `all`, or by listing the models sequentially (e.g. `foundry install rfd3 rf3 ...`).
|
|
112
|
+
To list the registry of available checkpoints:
|
|
109
113
|
```
|
|
110
|
-
foundry
|
|
114
|
+
foundry list-available
|
|
111
115
|
```
|
|
112
|
-
|
|
116
|
+
To check what you already have downloaded (searches `~/.foundry/checkpoints` plus `$FOUNDRY_CHECKPOINT_DIRS` if set):
|
|
113
117
|
```
|
|
114
|
-
foundry
|
|
118
|
+
foundry list-installed
|
|
115
119
|
```
|
|
116
120
|
|
|
117
|
-
>*See `examples/all.ipynb` for how to run each model in a notebook.*
|
|
121
|
+
>*See `examples/all.ipynb` for how to run each model and design proteins end-to-end in a notebook.*
|
|
122
|
+
|
|
123
|
+
### Google Colab
|
|
124
|
+
For an interactive Google Colab notebook walking through a basic design pipeline with RFD3, MPNN, and RF3, please see the [IPD Design Pipeline Tutorial](https://colab.research.google.com/drive/1ZwIMV3n9h0ZOnIXX0GyKUuoiahgifBxh?usp=sharing).
|
|
118
125
|
|
|
119
126
|
### RFdiffusion3 (RFD3)
|
|
120
127
|
|
|
121
128
|
[RFdiffusion3](https://www.biorxiv.org/content/10.1101/2025.09.18.676967v2) is an all-atom generative model capable of designing protein structures under complex constraints.
|
|
122
129
|
|
|
123
|
-
> *See [models/rfd3/README.md](models/rfd3/README.md) for complete documentation.*
|
|
124
|
-
|
|
125
130
|
<div align="center">
|
|
126
|
-
<img src="
|
|
131
|
+
<img src="docs/_static/cover.png" alt="RFdiffusion3 generation trajectory." width="700">
|
|
127
132
|
</div>
|
|
128
133
|
|
|
129
|
-
|
|
130
|
-
[ProteinMPNN](https://www.science.org/doi/10.1126/science.add2187) and [LigandMPNN](https://www.nature.com/articles/s41592-025-02626-1) are lightweight inverse-folding models which can be use to design diverse sequences for backbones under constrained conditions.
|
|
131
|
-
|
|
132
|
-
> *See [models/mpnn/README.md](models/mpnn/README.md) for complete documentation.*
|
|
133
|
-
|
|
134
|
+
> *See [models/rfd3/README.md](models/rfd3/README.md) for complete documentation.*
|
|
134
135
|
|
|
135
136
|
### RosettaFold3 (RF3)
|
|
136
137
|
|
|
@@ -142,6 +143,11 @@ foundry install rfd3 ligandmpnn rf3 --checkpoint_dir <path/to/ckpt/dir>
|
|
|
142
143
|
|
|
143
144
|
> *See [models/rf3/README.md](models/rf3/README.md) for complete documentation.*
|
|
144
145
|
|
|
146
|
+
### ProteinMPNN
|
|
147
|
+
[ProteinMPNN](https://www.science.org/doi/10.1126/science.add2187) and [LigandMPNN](https://www.nature.com/articles/s41592-025-02626-1) are lightweight inverse-folding models which can be use to design diverse sequences for backbones under constrained conditions.
|
|
148
|
+
|
|
149
|
+
> *See [models/mpnn/README.md](models/mpnn/README.md) for complete documentation.*
|
|
150
|
+
|
|
145
151
|
---
|
|
146
152
|
|
|
147
153
|
## Development
|
|
@@ -159,11 +165,7 @@ foundry install rfd3 ligandmpnn rf3 --checkpoint_dir <path/to/ckpt/dir>
|
|
|
159
165
|
Install both `foundry` and models in editable mode for development:
|
|
160
166
|
|
|
161
167
|
```bash
|
|
162
|
-
|
|
163
|
-
uv pip install -e . -e ./models/rf3 -e ./models/rfd3 -e ./models/mpnn
|
|
164
|
-
|
|
165
|
-
# Or install only foundry (no models)
|
|
166
|
-
uv pip install -e .
|
|
168
|
+
uv pip install -e '.[all,dev]'
|
|
167
169
|
```
|
|
168
170
|
|
|
169
171
|
This approach allows you to:
|
|
@@ -171,6 +173,9 @@ This approach allows you to:
|
|
|
171
173
|
- Work on specific models without installing all models
|
|
172
174
|
- Add new models as independent packages in `models/`
|
|
173
175
|
|
|
176
|
+
> [!NOTE]
|
|
177
|
+
> Running tests is not currently supported, test files may be missing.
|
|
178
|
+
|
|
174
179
|
### Adding New Models
|
|
175
180
|
|
|
176
181
|
To add a new model:
|