Protein design is a search problem. Choose amino acids for an eight-residue protein sequence and more than 25 billion combinations are possible. Choose amino acids for a 100-residue protein sequence and the number of possibilities exceeds the number of atoms in the observable universe. Somewhere in that space is a protein that opens a path to a new therapy. There are too many combinations to search exhaustively, so finding it depends on knowing where to look.
RFD4-Proteina, an NVIDIA BioNeMo open model co-developed with the Institute for Protein Design at the University of Washington’s School of Medicine, navigates that space using patterns learned from nature. It co-designs protein sequences and all-atom structures, and uses reward-guided inference-time search to focus compute on the most promising candidates.
This tutorial shows computational biologists, ML engineers and drug discovery researchers how to design protein binder candidates against PD-L1, an oncology target, using reward-guided inference-time search and introduces experimental validation results across design tasks.
You can access RFD4-Proteina in two ways:
- Choose the open model for training, inference, method development, and direct control over sampling code or
- Choose the NIM microservice for rapid inference deployment with an HTTP interface
Building on Proteina-Complexa’s partially latent approach, RFD4-Proteina combines explicit backbone coordinates with latent representation, learned sequence and atomistic variables. Its autoencoder decoder produces the sequence and all-atom structure together, removing the separate inverse-folding handoff to a model such as ProteinMPNN.
Prerequisites
- Open model - Supported Linux GPU host and Python 3.12; follow the repository setup guide and use a supported NVIDIA GPU.
- Model cache: Setup downloads the Hugging Face bundle automatically; set HF_HOME only if you want a different cache directory.
- Supported Linux GPU host and Python 3.12; follow
- NIM - Self-host: x86_64 or arm64 Linux meeting theNIM prerequisites , Docker, NVIDIA Driver, NVIDIA Container Toolkit, and anNGC API key .
- NIM API endpoint (not recommended for production runs): HTTP access through NVIDIAbuild.nvidia.com via Shell and Python scripts, no local GPU or model installation required.
About RFD4-Proteina #
The search loop shown in Figure 1, above, is where RFD4-Proteina focuses its compute.
During inference-time reasoning search, the model denoises generation trajectories to obtain structures, scores these designs, retains and branches promising partial states, and continues until the generation criteria are reached.
Rewards can measure geometry, interactions, or independent prediction confidence. This kind of extra search optimizes designs against a specified objective to yield higher-scoring designs. Later in this tutorial, you will see how a user can enable this functionality through the open model and the NIM.
RFD4-Proteina is faster and uses less memory than RFD3 for several reasons:
- It works on a residue-level latent representation instead of atom-level, which avoids memory blow-up.
- Engineering of the diffusion process cuts sampling from about 400 steps in Proteina-Complexa to 60, and computation is concentrated on the parts of the process that matter most thanks to reasoning capabilities in the model.
- Inference-time search is also faster, since the oracles (OF3 and physics methods like tmol ) are CUDA-accelerated.
- The model and kernels were co-designed with the cuEquivariance and BioNeMo Inference Runtime (BIR) teams for speed and scalability.
From a molecular design idea to candidate designs #
The workflow in Figure 3, above, demonstrates how to use RFD4-Proteina to go from a scientific objective to candidates for experimental testing. An agent can coordinate these tools and track results, while scientists define the objectives and use experimental evidence to guide the next round.
Preparing the molecular inputs and environment #
Begin by defining the criteria and requirements for generation. For example, RFD4-Proteina expects users to define what may change, what must remain fixed, and computational and experimental success criteria.
Use AtomWorks to generate /manipulate the input data. AtomWorks is the molecular data layer used to prepare structures and design annotations for RFD4-Proteina. Its Python and PyMOL workflows prepare fixed atoms, designable residues, hotspots, and molecular context. Preserve the supplied ligand or motif chemistry when designing surrounding protein.
Both the open model and NIM accept annotated CIFs or a condition specification plus its source structure. The specification below fixes the target and defines the new binder.
The repository’s cropped PD-L1 structure from PDB 5O45 serves as the target. Fix the target’s sequence and backbone coordinates, allow its side chains to repack, and direct binder generation toward hotspot atoms on Tyr56, Met115, and Tyr123. The new binder has 100–150 residues, with free sequence and coordinates.
Clone the repository, then run the examples from its root. This writes pdl1.json; both paths use the same target CIF and conditions.
git clone https://github.com/RosettaCommons/RFD4-Proteina.git
cd RFD4-Proteina
cat > pdl1.json <<'JSON'
{
"pdl1_binder": {
"input": "docs/examples/inputs/5o45_cropped.cif",
"contig": "100-150, /0, A17-131",
"conditions": {
"C_CRD": {"true": [{"select": "sel('A') and is_protein_backbone"}]},
"C_SEQ": {"true": [{"select": "sel('A')"}]},
"C_HOT": {"true": [
{"select": "sel('A/*/56/[CG,OH]')"},
{"select": "sel('A/*/115/[CG,SD]')"},
{"select": "sel('A/*/123/[CD2,OH]')"}
]}
}
}
}
JSON
Open model setup
On a supported Linux/CUDA system, install the repository environment with a current uv release (validated with 0.12.24). If uv is already installed, update it first so it recognizes CUDA 13.2. Setup caches the Hugging Face model bundle, including the paired autoencoder. While the model repository is private, authenticate with hf auth login using an account with access.
bash setup.sh --native
source .venv/bin/activate
NIM environment setup
To host the NIM, run this block in Bash on a supported GPU host with Docker and NVIDIA Container Toolkit installed.
read -rsp 'NGC API key: ' NGC_API_KEY; echo
export NGC_API_KEY
printf '%s' "$NGC_API_KEY" | docker login nvcr.io \
-u '$oauthtoken' --password-stdin
image=nvcr.io/nim/ipd/rfd4-proteina:latest
docker pull "$image"
export RFD4_NIM_IMAGE="$(docker image inspect \
--format '{{index .RepoDigests 0}}' "$image")"
printf '%s\n' "$RFD4_NIM_IMAGE" > nim-image.txt
export LOCAL_NIM_CACHE="$HOME/.cache/nim"
mkdir -p "$LOCAL_NIM_CACHE"
docker run -d --rm --name rfd4-proteina \
--runtime=nvidia --gpus 'device=0' -p 8000:8000 \
-e NGC_API_KEY -v "$LOCAL_NIM_CACHE":/opt/nim/.cache \
--shm-size=16g "$RFD4_NIM_IMAGE"
Generate sequences and structures #
Open-model generation
Save the following as design.py in the repository root. The same script supports generation and search. Proteina.from_pretrained("nvidia/RFD4-Proteina") loads the current Hugging Face model and paired autoencoder checkpoints.
import hydra
from rfd4_proteina import Proteina
from rfproteina.generate import run_generation
@hydra.main(config_path="configs", config_name="inference", version_base="1.3")
def main(cfg):
model = Proteina.from_pretrained("nvidia/RFD4-Proteina")
run_generation(cfg, model=model)
if __name__ == "__main__":
main()
Generate one candidate from the repository root:
python design.py inputs=pdl1.json out_dir=runs/pdl1-open seed=42 compile_lengths=null
Outputs are saved under runs/pdl1-open/inference_samples/. Add num_replicates=10 for ten candidates and choose a new out_dir for each run. Hugging Face caches downloads; add revision=”<commit>” to from_pretrained to reproduce a particular model version.
NIM generation
Save this as nim_client.py. It sends the PD-L1 condition spec and target CIF to the NIM, then saves generated structures and response metrics.
import json
from pathlib import Path
import requests
spec = json.loads(Path("pdl1.json").read_text())["pdl1_binder"]
target = Path(spec["input"])
spec["input"] = target.name
payload = {
"task": "motif_scaffolding",
"input": {"format": "condition_spec", "example_id": "pdl1_binder",
"spec": spec, "files": [{"filename": target.name, "content": target.read_text()}]},
"sampling": {"num_replicates": 1, "seed": 42},
"metrics": {"tags": ["design", "hotspot_conditioning"]},
}
def submit(payload, out):
out.mkdir(parents=True, exist_ok=True)
response = requests.post("http://localhost:8000/biology/ipd/rfd4-proteina/generative",
json=payload, timeout=1800)
response.raise_for_status()
result = response.json()
(out / "response.json").write_text(json.dumps(result, indent=2))
for i, design in enumerate(result["designs"]):
dest = out / f"design-{i}.cif"
dest.write_text(design["structure"]["content"])
print(design["design_id"], dest)
if __name__ == "__main__":
submit(payload, Path("runs/pdl1-nim"))
Install requests and run the client from the repository root. Keep pdl1.json beside the target CIF.
python -m pip install requests
python nim_client.py
Performance optimizations across open model and NIM
For faster design iteration, the BioIR backend accelerates RFD4-Proteina by 1.37–1.73× over the default compiled backend across six tested Hopper GPU configurations (see Figure 4, below). On H100 PCIe, total suite time drops from 161 to 111 seconds, about 31% less runtime. The benchmark uses batch size 1 and sums warm end-to-end timings across 15 sequence lengths (128–1,024 tokens).
Inference-time search with external oracles #
Open-model search with OpenFold3
Install the optional OpenFold3 runtime and weights with ./scripts/download_example_data.sh ./data_path. Set OF3_IMAGE, OF3_MODEL_DIR, and OF3_JAX_CACHE_DIR to the paths it prints, then run mkdir -p "$OF3_JAX_CACHE_DIR". Apptainer must be available on the GPU host.
This example uses the AlphaFold3 codebase, which is released under the open-source Apache 2.0 license, and the OpenFold3 model weights, which are also released under the Apache 2.0 license.
Reuse design.py with the search preset:
python design.py inference_experiment=inference_beam_example \
metrics/refolding_oracles=of3 inputs=pdl1.json subset_to_examples=null \
num_replicates=1 out_dir=runs/pdl1-open-search seed=42 compile_lengths=null
The preset uses two branches, a beam width of three, and scoring at steps 20, 40, 50 and 60. It rewards the designed chain’s OpenFold3 pLDDT (oracle.plddt_coi), with a floor of 50, and saves qualifying rollouts at reward 80. This measures confidence in the binder, not evidence of binding; inspect interface and refolding metrics separately. Outputs are under runs/pdl1-open-search/.
NIM search with OpenFold3
Save this as nim_search_request.py. It reuses the PD-L1 input and submits a reward-guided OpenFold3 search.
from pathlib import Path
from nim_client import payload, submit
key = "oracle_of3_nvcf.overall_plddt"
payload["sampling"]["num_steps"] = 60
payload["search"] = {
"step_checkpoints": [0, 20, 40, 50, 60],
"n_branch": 2, "beam_width": 3,
"reward_metrics_tags": ["unconditional_refolding"],
"weights": {key: 1.0}, "clip_values": {key: {"min": 50.0}},
"intermediate_save_min_reward": 80.0,
}
payload["metrics"] = {"tags": ["design", "unconditional_refolding"]}
submit(payload, Path("runs/pdl1-nim-search"))
Enable the NIM oracle
Mount the OpenFold3 reward.py callback as described in the oracle guide. It reports oracle_of3_nvcf.overall_plddt for the whole complex; evaluate the binder interface separately.
Save the OpenFold3 NVCF callback from the oracle guide as reward.py and export OF3_NIM_API_KEY with an NVCF invoke credential. Relaunch the service with this callback:
docker stop rfd4-proteina
docker run -d --rm --name rfd4-proteina \
--gpus 'device=0' -p 8000:8000 --shm-size=16g \
-e NGC_API_KEY -v "$LOCAL_NIM_CACHE:/opt/nim/.cache" \
-v "$PWD/reward.py:/opt/nim/reward.py:ro" \
-e NIM_ALLOW_ORACLE_PLUGIN=true -e OF3_NIM_API_KEY \
"$RFD4_NIM_IMAGE"
Run the search script. It saves designs and response metrics under runs/pdl1-nim-search/.
python nim_search_request.py
This request uses two branches, checkpoints [0, 20, 40, 50, 60], and a beam width of three. It sets a reward floor of 50 and saves intermediate designs with scores of at least 80. These are example thresholds for OpenFold3 overall pLDDT, a prediction-confidence metric for the whole complex. Search-time reward tags and final reporting tags are separate.
Search output counts vary. Inspect the generated CIFs and retained metrics before selecting candidates. Include refolding and scoring in compute comparisons.
Filter and rank candidates
Check constraints, motif preservation, clashes, interfaces, refolding consistency, and structural diversity metrics. OpenFold3, and RoseTTAFold3 provide prediction options; TMol provides Rosetta-inspired all-atom scoring and optimization.
Common metrics include ipTM (interface Predicted Template Modeling), ipSAE (interaction prediction Score from Aligned Errors), and RMSD (Root Mean Square Deviation) scores from protein structure prediction models like OpenFold 3, along with interaction energies from physics-based models like TMol.
Test experimentally and refine #
Table 1, above, highlights RFD4-Proteina’s broad range of capabilities across molecular tasks. It not only supports this variety of tasks, in the accompanying manuscript it is demonstrated that the model is also the state-of-the-art model across this breadth of molecular tasks, both in terms of output quality and throughput.
Turn that throughput into scientific progress by selecting diverse candidates for synthesis, expression, and task-specific assays. Feed experimental outcomes back into the objective, constraints, and ranking criteria for the next round.
Run a campaign with an AI agent #
Use the rfd4-proteina-campaign skill to coordinate generation, search and evaluation with a record of inputs, model versions and compute use. The rfd4-proteina-package skill produces a results archive with structures, metrics and a filtering report.
Use rfd4-proteina-campaign to design 100–150-residue PD-L1 binders from pdl1.json, preserving its target and hotspot constraints. Use the Hugging Face model via from_pretrained and OpenFold3. Agree on criteria and a compute budget, then compare generation with reward-guided search and run a campaign via rfd4-proteina-campaign. Return up to ten diverse candidates with scores and compute usage; package the results with rfd4-proteina-package.
Apply the workflow to your design problem #
RFD4-Proteina combines fast generation, smart search, and agent programmability in one workflow. Joint sequence and all-atom structure generation streamlines candidate creation, while reward-guided search focuses compute on task-specific objectives. Shared condition specifications connect both form factors to common evaluation tools, and NIM’s HTTP API lets agents submit requests and inspect results.
Use the open model for method development and NIM for application integration with optional BioIR acceleration, bringing computational exploration and experimental feedback into an iterative design campaign.
Get started with the RFD4-Proteina NIM microservice, explore the open model on GitHub, or point your agent at BioNeMo Agent Toolkit skills.