Instructions to use dn6/RFDiffusion-3 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use dn6/RFDiffusion-3 with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("dn6/RFDiffusion-3", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
[RFD3] Feed MPNN real backbone atoms and the schema it validates
Builds on #1. That PR made the diffusion path produce real backbones; this one makes the sequence
design path usable. It contains #1's changes, so merging this alone lands both.
MPNN never ran
MPNNModel.forward built a flat dict and handed it to foundry, which reads everything fromnetwork_input["input_features"]. Every call died with KeyError: 'input_features'. Nesting it
surfaced the rest of the contract: the network also validates decode_type, causality_pattern,mask_for_loss, bias, pair_bias, symmetry_equivalence_group, symmetry_weight andrepeat_sample_num, and it wants a per-residue temperature rather than a scalar. The scalar
settings now match MPNN_PER_INPUT_INFERENCE_DEFAULTS in foundry's mpnn/utils/inference.py;
the optional conditioning keys are present as None, which is what the network checks for.
MPNN was designing against invented geometry
Even once it ran, the caller synthesised the backbone by adding three fixed offsets to every alpha
carbon in the global frame:
n_offset = torch.tensor([-1.458, 0.0, 0.0])
c_offset = torch.tensor([0.550, 1.424, 0.0])
o_offset = torch.tensor([0.550, 2.500, 0.0])
Every nitrogen was displaced in the same global direction regardless of backbone orientation, so
the graph features MPNN depends on were meaningless. After #1 the sampler has real atom-level
coordinates, so the block now selects N, CA, C and O through the is_backbone mask the feature
pipeline already emits, and the offsets are deleted.
Also fixed
- A latent shape bug from #1: the sequence-design block read
motif_mask, which became atom-level,
where it needs residue-level. It now reads a separatemotif_token_mask. - MPNN is attached with
update_componentsand commonly left on CPU while the sampler ran on GPU.
The block follows the component's device for the call and keeps everything after it on the
sampler's device.
Verification
Run on an A10G. Bond lengths confirm the selected atoms really are N, CA, C, O in that order.
| Bond | Measured | Reference | In range |
|---|---|---|---|
| N-CA | 1.461 A | 1.458 | 100% |
| CA-C | 1.526 A | 1.525 | 100% |
| C=O | 1.236 A | 1.231 | 100% |
| C-N peptide | 1.305 A | 1.329 | 98% |
The CA slot matches the pipeline's own reported coordinates to 0.000000, which is what pins the
ordering rather than assuming it. A 100-residue design returns a full-length sequence over the
canonical alphabet. Sampling at 0.1 and 1.0 gives 5% sequence identity with composition shifting
from alanine and valine rich to diverse, confirming temperature reaches the sampler.
Known gap
Designs are not reproducible. RFDiffusionScheduler.add_noise uses torch.randn_like with no
generator, so passing generator= seeds only the initial noise and not the trajectory. Pre-existing
and untouched here.
No weight files are touched.
Verified on an A10G: N-CA 1.461 A, CA-C 1.526 A, C=O 1.236 A, and the CA slot matches the pipeline's own coordinates exactly.