### Community Tools # Community Tools ## JAAG: a JSON input file Assembler for AlphaFold 3 (with Glycan Integration) JAAG is a lightweight, web-based GUI tool that helps generate AlphaFold 3 input JSON files with integrated glycan support. It automates the creation of correct glycan syntax (including `bondedAtomPairs` + CCD), reducing manual errors when preparing glycoprotein or glycan–protein complexes. * Web app: https://biofgreat.org/JAAG * Source code: https://github.com/chinchc/JAAG * Paper: https://doi.org/10.1093/glycob/cwaf083 Note: JAAG is compatible with standalone AlphaFold 3, but not with the AlphaFold 3 server. ## Modeling glycans with AlphaFold 3: capabilities, caveats, and limitations Paper on modeling glycans (and other ligands) with AF3 that modeled and assessed major glycan classes and provides: * Step-by-step tutorial for building ligand inputs (applicable beyond glycans) * Ready-to-run scripts for each glycan class * Comprehensive CCD table for all SNFG monosaccharides * Discussion of caveats and limitations of AF3 * Full AF3 inputs/outputs archived on ModelArchive for reproducibility Useful resource if your AF3 ligand models appear stereochemically off. * Paper: https://doi.org/10.1093/glycob/cwaf048 * ModelArchive: https://doi.org/10.5452/ma-af3glycan --- ### Input # AlphaFold 3 Input ## Specifying Input Files You can provide inputs to `run_alphafold.py` in one of two ways: - Single input file: Use the `--json_path` flag followed by the path to a single JSON file. This path can be either a local path or a Google Cloud Storage path (starting with `gs://`), if enabled. - Multiple input files: Use the `--input_dir` flag followed by the path to a directory of JSON files. This path can be either a local directory path or a GCS path, if enabled. - Within an input file, fields with names ending in `Path` (e.g. `pairedMsaPath`) can be provided as Google Cloud Storage paths, if enabled. ### Note: Google Cloud Storage paths Google Cloud Storage (`gs://`) paths are supported for certain flags and fields if the optional `gcsfs` dependency is installed. See the [installation instructions](installation.md#optional-enable-google-cloud-storage-path-support) for details and a complete list of supported paths. ## Input Format AlphaFold 3 uses a custom JSON input format differing from the [AlphaFold Server JSON input format](https://github.com/google-deepmind/alphafold/tree/main/server). See [below](#alphafold-server-json-compatibility) for more information. The custom AlphaFold 3 format allows: * Specifying protein, RNA, and DNA chains, including modified residues. * Specifying custom multiple sequence alignment (MSA) for protein and RNA chains. * Specifying custom structural templates for protein chains. * Specifying ligands using [Chemical Component Dictionary (CCD)](https://www.wwpdb.org/data/ccd) codes. * Specifying ligands using SMILES. * Specifying ligands by defining them using the CCD mmCIF format and supplying them via the [user-provided CCD](#user-provided-ccd). * Specifying covalent bonds between entities. * Specifying multiple random seeds. Multiple examples of input JSON files are provided in https://github.com/google-deepmind/alphafold3/tree/main/examples. ## AlphaFold Server JSON Compatibility The [AlphaFold Server](https://alphafoldserver.com/) uses a separate [JSON format](https://github.com/google-deepmind/alphafold/tree/main/server) from the one used here in the AlphaFold 3 codebase. In particular, the JSON format used in the AlphaFold 3 codebase offers more flexibility and control in defining custom ligands, branched glycans, and covalent bonds between entities. We provide a converter in `run_alphafold.py` which automatically detects the input JSON format, denoted `dialect` in the converter code. The converter denotes the AlphaFoldServer JSON as `alphafoldserver`, and the JSON format defined here in the AlphaFold 3 codebase as `alphafold3`. If the detected input JSON format is `alphafoldserver`, then the converter will translate that into the JSON format `alphafold3`. ### Multiple Inputs The top-level of the `alphafoldserver` JSON format is a list, allowing specification of multiple inputs in a single JSON. In contrast, the `alphafold3` JSON format requires exactly one input per JSON file. Specifying multiple inputs in a single `alphafoldserver` JSON is fully supported. Note that the converter distinguishes between `alphafoldserver` and `alphafold3` JSON formats by checking if the top-level of the JSON is a list or not. In particular, if you pass in a `alphafoldserver`-style JSON without a top-level list, then this is considered incorrect and `run_alphafold.py` will raise an error. ### Glycans If the JSON in `alphafoldserver` format specifies glycans, the converter will raise an error. This is because translating glycans specified in the `alphafoldserver` format to the `alphafold3` format is not currently supported. ### Random Seeds The `alphafoldserver` JSON format allows users to specify `"modelSeeds": []`, in which case a seed is chosen randomly for the user. On the other hand, the `alphafold3` format requires users to specify a seed. The converter will choose a seed randomly if `"modelSeeds": []` is set when translating from `alphafoldserver` JSON format to `alphafold3` JSON format. If seeds are specified in the `alphafoldserver` JSON format, then those will be preserved in the translation to the `alphafold3` JSON format. ### Ions While AlphaFold Server treats ions and ligands as different entity types in the JSON format, AlphaFold 3 treats ions as ligands. Therefore, to specify e.g. a magnesium ion, one would specify it as an entity of type `ligand` with `ccdCodes: ["MG"]`. ### Sequence IDs The `alphafold3` JSON format requires the user to specify a unique identifier (`id`) for each entity. On the other hand, the `alphafoldserver` does not allow specification of an `id` for each entity. Thus, the converter automatically assigns one. The converter iterates through the list provided in the `sequences` field of the `alphafoldserver` JSON format, assigning an `id` to each entity using the following order ("reverse spreadsheet style"): ``` A, B, ..., Z, AA, BA, CA, ..., ZA, AB, BB, CB, ..., ZB, ... ``` For any entity with `count > 1`, an `id` is assigned arbitrarily to each "copy" of the entity. ## Top-level Structure The top-level structure of the input JSON is: ```json { "name": "Job name goes here", "modelSeeds": [1, 2], # At least one seed required. "sequences": [ {"protein": {...}}, {"rna": {...}}, {"dna": {...}}, {"ligand": {...}} ], "bondedAtomPairs": [...], # Optional. "userCCD": "...", # Optional, mutually exclusive with userCCDPath. "userCCDPath": "...", # Optional, mutually exclusive with userCCD. "dialect": "alphafold3", # Required. "version": 4 # Required. } ``` The fields specify the following: * `name: str`: The name of the job. A sanitised version of this name is used for naming the output files. * `modelSeeds: list[int]`: A list of integer random seeds. The pipeline and the model will be invoked with each of the seeds in the list. I.e. if you provide *n* random seeds, you will get *n* predicted structures, each with the respective random seed. You must provide at least one random seed. * `sequences: list[Protein | RNA | DNA | Ligand]`: A list of sequence dictionaries, each defining a molecular entity, see below. * `bondedAtomPairs: list[Bond]`: An optional list of covalently bonded atoms. These can link atoms within an entity, or across two entities. See more below. * `userCCD: str`: An optional string with user-provided chemical components dictionary. This is an expert mode for providing custom molecules when SMILES is not sufficient. This should also be used when you have a custom molecule that needs to be bonded with other entities - SMILES can't be used in such cases since it doesn't give the possibility of uniquely naming all atoms. It can also be used to provide a reference conformer for cases where RDKit fails to generate a conformer. See more below. * `userCCDPath: str`: An optional path to a file that contains the user-provided chemical components dictionary instead of providing it inline using the `userCCD` field. The path can be either absolute, or relative to the input JSON path. The file must be in the [CCD mmCIF format](https://www.wwpdb.org/data/ccd#mmcifFormat), and could be either plain text, or compressed using gzip, xz, or zstd. * `dialect: str`: The dialect of the input JSON. This must be set to `alphafold3`. See [AlphaFold Server JSON Compatibility](#alphafold-server-json-compatibility) for more information. * `version: int`: The version of the input JSON. This must be set to 1 or 2. See [AlphaFold Server JSON Compatibility](#alphafold-server-json-compatibility) and [versions](#versions) below for more information. ## Versions The top-level `version` field (for the `alphafold3` dialect) can be either `1`, `2`, or `3`. The following features have been added in respective versions: * `1`: the initial AlphaFold 3 input format. * `2`: added the option of specifying external MSA and templates using newly added fields `unpairedMsaPath`, `pairedMsaPath`, and `mmcifPath`. * `3`: added the option of specifying external user-provided CCD using newly added field `userCCDPath`. * `4`: added the option of specifying textual `description` of protein chains, RNA chains, DNA chains, or ligands. ## Sequences The `sequences` section specifies the protein chains, RNA chains, DNA chains, and ligands. Every entity in `sequences` must have a unique ID. IDs don't have to be sorted alphabetically. ### Protein Specifies a single protein chain. ```json { "protein": { "id": "A", "sequence": "PVLSCGEWQL", "modifications": [ {"ptmType": "HY3", "ptmPosition": 1}, {"ptmType": "P1L", "ptmPosition": 5} ], "description": ..., # Optional. "unpairedMsa": ..., # Mutually exclusive with unpairedMsaPath. "unpairedMsaPath": ..., # Mutually exclusive with unpairedMsa. "pairedMsa": ..., # Mutually exclusive with pairedMsaPath. "pairedMsaPath": ..., # Mutually exclusive with pairedMsa. "templates": [...] } } ``` The fields specify the following: * `id: str | list[str]`: An uppercase letter or multiple letters specifying the unique IDs for each copy of this protein chain. The IDs are then also used in the output mmCIF file. Specifying a list of IDs (e.g. `["A", "B", "C"]`) implies a homomeric chain with multiple copies. * `sequence: str`: The amino-acid sequence, specified as a string that uses the 1-letter standard amino acid codes. * `modifications: list[ProteinModification]`: An optional list of post-translational modifications. Each modification is specified using its CCD code and 1-based residue position. In the example above, we see that the first residue won't be a proline (`P`) but instead `HY3`. * `description: str`: An optional textual description of this chain. This field will is only used in the JSON format and serves as a comment describing this chain. * `unpairedMsa: str`: An optional multiple sequence alignment for this chain. This is specified using the A3M format (equivalent to the FASTA format, but also allows gaps denoted by the hyphen `-` character). See more details below. * `unpairedMsaPath: str`: An optional path to a file that contains the multiple sequence alignment for this chain instead of providing it inline using the `unpairedMsa` field. The path can be either absolute, or relative to the input JSON path. The file must be in the A3M format, and could be either plain text, or compressed using gzip, xz, or zstd. * `pairedMsa: str`: We recommend *not* using this optional field and using the `unpairedMsa` for the purposes of pairing. See more details below. * `pairedMsaPath: str`: An optional path to a file that contains the multiple sequence alignment for this chain instead of providing it inline using the `pairedMsa` field. The path can be either absolute, or relative to the input JSON path. The file must be in the A3M format, and could be either plain text, or compressed using gzip, xz, or zstd. * `templates: list[Template]`: An optional list of structural templates. See more details below. ### RNA Specifies a single RNA chain. ```json { "rna": { "id": "A", "sequence": "AGCU", "modifications": [ {"modificationType": "2MG", "basePosition": 1}, {"modificationType": "5MC", "basePosition": 4} ], "description": ..., # Optional. "unpairedMsa": ..., # Mutually exclusive with unpairedMsaPath. "unpairedMsaPath": ... # Mutually exclusive with unpairedMsa. } } ``` The fields specify the following: * `id: str | list[str]`: An uppercase letter or multiple letters specifying the unique IDs for each copy of this RNA chain. The IDs are then also used in the output mmCIF file. Specifying a list of IDs (e.g. `["A", "B", "C"]`) implies a homomeric chain with multiple copies. * `sequence: str`: The RNA sequence, specified as a string using only the letters `A`, `C`, `G`, `U`. * `modifications: list[RnaModification]`: An optional list of modifications. Each modification is specified using its CCD code and 1-based base position. * `description: str`: An optional textual description of this chain. This field will is only used in the JSON format and serves as a comment describing this chain. * `unpairedMsa: str`: An optional multiple sequence alignment for this chain. This is specified using the A3M format. See more details below. * `unpairedMsaPath: str`: An optional path to a file that contains the multiple sequence alignment for this chain instead of providing it inline using the `unpairedMsa` field. The path can be either absolute, or relative to the input JSON path. The file must be in the A3M format, and could be either plain text, or compressed using gzip, xz, or zstd. ### DNA Specifies a single DNA chain. ```json { "dna": { "id": "A", "sequence": "GACCTCT", "modifications": [ {"modificationType": "6OG", "basePosition": 1}, {"modificationType": "6MA", "basePosition": 2} ], "description": ... # Optional. } } ``` The fields specify the following: * `id: str | list[str]`: An uppercase letter or multiple letters specifying the unique IDs for each copy of this DNA chain. The IDs are then also used in the output mmCIF file. Specifying a list of IDs (e.g. `["A", "B", "C"]`) implies a homomeric chain with multiple copies. * `sequence: str`: The DNA sequence, specified as a string using only the letters `A`, `C`, `G`, `T`. * `modifications: list[DnaModification]`: An optional list of modifications. Each modification is specified using its CCD code and 1-based base position. * `description: str`: An optional textual description of this chain. This field will is only used in the JSON format and serves as a comment describing this chain. ### Ligands Specifies a single ligand. Ligands can be specified using 3 different formats: 1. [CCD code(s)](https://www.wwpdb.org/data/ccd). This is the easiest way to specify ligands. Supports specifying covalent bonds to other entities. CCD from 2022-09-28 is used. If multiple CCD codes are specified, you may want to specify a bond between these and/or a bond to some other entity. See the [bonds](#bonds) section below. 2. [SMILES string](https://en.wikipedia.org/wiki/Simplified_Molecular_Input_Line_Entry_System). This enables specifying ligands that are not in CCD. If using SMILES, you cannot specify covalent bonds to other entities as these rely on specific atom names - see the next option for what to use for this case. 3. User-provided CCD + custom ligand codes. This enables specifying ligands not in CCD, while also supporting specification of covalent bonds to other entities and backup reference coordinates for when RDKit fails to generate a conformer. This offers the most flexibility, but also requires careful attention to get all of the details right. ```json { "ligand": { "id": ["G", "H", "I"], "ccdCodes": ["ATP"], "description": ... # Optional. } }, { "ligand": { "id": "J", "ccdCodes": ["LIG-1337"], "description": ... # Optional. } }, { "ligand": { "id": "K", "smiles": "CC(=O)OC1C[NH+]2CCC1CC2", "description": ... # Optional. } } ``` The fields specify the following: * `id: str | list[str]`: An uppercase letter (or multiple letters) specifying the unique ID of this ligand. This ID is then also used in the output mmCIF file. Specifying a list of IDs (e.g. `["A", "B", "C"]`) implies a ligand that has multiple copies. * `ccdCodes: list[str]`: An optional list of CCD codes. These could be either standard CCD codes, or custom codes pointing to the [user-provided CCD](#user-provided-ccd). * `smiles: str`: An optional string defining the ligand using a SMILES string. The SMILES string must be correctly JSON-escaped. * `description: str`: An optional textual description of this chain. This field will is only used in the JSON format and serves as a comment describing this ligand. Each ligand may be specified using CCD codes or SMILES but not both, i.e. for a given ligand, the `ccdCodes` and `smiles` fields are mutually exclusive. #### SMILES string JSON escaping The SMILES string must be correctly JSON-escaped, in particular the backslash character must be escaped as two backslashes, otherwise the JSON parser will fail with a `JSONDecodeError`. For instance, the following SMILES string `CCC[C@@H](O)CC\C=C\C=C\C#CC#C\C=C\CO` has to be specified as: ```json { "ligand": { "id": "A", "smiles": "CCC[C@@H](O)CC\\C=C\\C=C\\C#CC#C\\C=C\\CO" } } ``` You can JSON-escape the SMILES string using the [`jq`](https://github.com/jqlang/jq) command-line tool which should be easily installable on most Linux systems: ```bash jq -R . <<< 'CCC[C@@H](O)CC\C=C\C=C\C#CC#C\C=C\CO' # Replace with your SMILES. ``` Alternatively, you can use this Python code: ```python import json smiles = r'CCC[C@@H](O)CC\C=C\C=C\C#CC#C\C=C\CO' # Replace with your SMILES. print(json.dumps(smiles)) ``` #### Reference structure construction with SMILES For some ligands and some random seeds, RDKit might fail to generate a conformer, indicated by the `Failed to construct RDKit reference structure` error message. In this case, you can either provide a reference structure for the ligand using the [user-provided CCD Format](#user-provided-ccd-format), or try increasing the number of RDKit conformer iterations using the `--conformer_max_iterations=...` flag. ### Ions Ions are treated as ligands, e.g. a magnesium ion would simply be a ligand with `ccdCodes: ["MG"]`. ## Multiple Sequence Alignment Protein and RNA chains allow setting a custom Multiple Sequence Alignment (MSA). If not set, the data pipeline will automatically build MSAs for protein and RNA entities using Jackhmmer/Nhmmer search over genetic databases as described in the paper. ### RNA Multiple Sequence Alignment RNA `unpairedMsa` can be either: 1. Unset (or set explicitly to `null`). AlphaFold 3 will build MSA for this RNA chain automatically. This is the recommended option. 2. Set to an empty string (`""`). AlphaFold 3 won't build the MSA for this RNA chain and the MSA input to the model will be just the RNA chain (equivalent to running MSA-free for this RNA chain). 3. Set to a non-empty A3M string. AlphaFold 3 will use the provided MSA for this RNA chain. ### Protein Multiple Sequence Alignment For protein chains, the situation is slightly more complicated due to paired and unpaired MSA (see [MSA Pairing](#msa-pairing) below for more details). The following combinations are valid for a given protein chain: 1. Both `unpairedMsa` and `pairedMsa` fields are unset (or set explicitly to `null`), AlphaFold 3 will build both MSAs automatically. This is the recommended option. 2. The `unpairedMsa` is set to to a non-empty A3M string, `pairedMsa` set to an empty string (`""`). AlphaFold 3 won't build MSA, will use the `unpairedMsa` as is and run `pairedMSA`-free. 3. The `pairedMsa` is set to to a non-empty A3M string, `unpairedMsa` set to an empty string (`""`). AlphaFold 3 won't build MSA, will use the `pairedMsa` and run `unpairedMSA`-free. **This option is not recommended**, see [MSA Pairing](#msa-pairing) below. 4. Both `unpairedMsa` and `pairedMsa` fields are set to an empty string (`""`). AlphaFold 3 will not build the MSA and the MSA input to the model will be just the query sequence (equivalent to running completely MSA-free). 5. Both `unpairedMsa` and `pairedMsa` fields are set to a custom non-empty A3M string, AlphaFold 3 will use the provided MSA instead of building one as part of the data pipeline. This is considered an expert option. Note that both `unpairedMsa` and `pairedMsa` have to either be *both* set (i.e. non-`null`), or both unset (i.e. both `null`, explicitly or implicitly). Typically, when setting `unpairedMsa`, you will set the `pairedMsa` to an empty string (`""`). For example this will run the protein chain A with the given MSA, but without any templates (template-free): ```json { "protein": { "id": "A", "sequence": ..., "unpairedMsa": "The A3M you want to run with", "pairedMsa": "", "templates": [] } } ``` When setting your own MSA, you have to make sure that: 1. The MSA is in the A3M format. This means adhering to the FASTA format while also allowing lowercase characters denoting inserted residues and hyphens (`-`) denoting gaps in sequences. 2. The first sequence is exactly equal to the query sequence. 3. If all insertions are removed from MSA hits (i.e. all lowercase letters are removed), all sequences have exactly the same length as the query (they form an exact rectangular matrix). ### MSA Pairing MSA pairing matters only when folding multiple chains (multimers), since we need to find a way to concatenate MSAs for the individual chains along the sequence dimension. If done naively, by simply concatenating the individual MSA matrices along the sequence dimension and padding so that all MSAs have the same depth, one can end up with rows in the concatenated MSA that are formed by sequences from different organisms. It may be desirable to ensure that across multiple chains, sequences in the MSA that are from the same organism end up in the same MSA row. AlphaFold 3 internally achieves this by looking for the UniProt organism ID in the `pairedMsa` and pairing sequences based on this information. We recommend users do the pairing manually or use the output of an appropriate software and then provide the MSA using only the `unpairedMsa` field. This method gives exact control over the placement of each sequence in the MSA, as opposed to relying on name-matching post-processing heuristics used for `pairedMsa`. When setting `unpairedMsa` manually, the `pairedMsa` must be explicitly set to an empty string (`""`). Make sure to run with `--resolve_msa_overlaps=false`. This prevents deduplication of the unpaired MSA within each chain against the paired MSA sequences. Even if you set `pairedMsa` to an empty string, the query sequence(s) will still be added in there and the deduplication procedure could destroy the carefully crafted sequence positioning in the unpaired MSA. For instance, if there are two chains `DEEP` and `MIND` which we want to be paired on organism A and C, we can achieve it as follows: ```txt > query DEEP > match 1 (organism A) D--P > match 2 (organism B) DD-P > match 3 (organism C) DD-P ``` ```txt > query MIND > match 1 (organism A) M--D > Empty hit to make sure pairing is achieved ---- > match 2 (organism C) MIN- ``` The resulting MSA when chains are concatenated will then be: ```txt > query DEEPMIND > match 1 + match 1 D--PM--D > match 2 + padding DD-P---- > match 3 + match 2 DD-PMIN- ``` ## Structural Templates Structural templates can be specified only for protein chains: ```json "templates": [ { "mmcif": ..., # Mutually exclusive with mmcifPath. "mmcifPath": ..., # Mutually exclusive with mmcif. "queryIndices": [0, 1, 2, 4, 5, 6], "templateIndices": [0, 1, 2, 3, 4, 8] } ] ``` The fields specify the following: * `mmcif: str`: A string containing the single chain protein structural template in the mmCIF format. * `mmcifPath: str`: An optional path to a file that contains the mmCIF with the structural template instead of providing it inline using the `mmcifPath` field. The path can be either absolute, or relative to the input JSON path. The file must be in the mmCIF format, and could be either plain text, or compressed using gzip, xz, or zstd. * `queryIndices: list[int]`: O-based indices in the query sequence, defining the mapping from query residues to template residues. * `templateIndices: list[int]`: O-based indices in the template sequence, specifying the mapping from query residues to template residues defined in the mmCIF file. Note that unresolved mmCIF residues must be taken into account when specifying template indices. A template is specified as an mmCIF string containing a single chain with the structural template together with a 0-based mapping that maps query residue indices to the template residue indices. The mapping is specified using two lists of the same length. E.g. to express a mapping `{0: 0, 1: 2, 2: 5, 3: 6}`, you would specify the two indices lists as: ```json "queryIndices": [0, 1, 2, 3], "templateIndices": [0, 2, 5, 6] ``` Note that mmCIFs can have residues with missing atom coordinates (present in residue tables but missing in the `_atom_site` table) – these must be taken into account when specifying template indices. E.g. to align residues 4–7 in a template with unresolved residues 1, 2, 3 and resolved residues 4, 5, 6, 7, you need to set the template indices to 3, 4, 5, 6 (since 0-based indexing is used). An example of a protein with unresolved residues 1–20 can be found here: https://www.rcsb.org/structure/8UXY. You can provide multiple structural templates. Note that if an mmCIF containing more than one chain is provided, you will get an error since it is not possible to determine which of the chains should be used as the template. You can run template-free (but still run genetic search and build MSA) by setting templates to `[]` and either explicitly setting both `unpairedMsa` and `pairedMsa` to `null`: ```json "protein": { "id": "A", "sequence": ..., "pairedMsa": null, "unpairedMsa": null, "templates": [] } ``` Or you can simply fully omit them: ```json "protein": { "id": "A", "sequence": ..., "templates": [] } ``` You can also run with pre-computed MSA, but let AlphaFold 3 search for templates. This can be achieved by setting `unpairedMsa` and `pairedMsa`, but keeping templates unset (or set to `null`). The profile given as an input to Hmmsearch when searching for templates will be built from the provided `unpairedMsa`: ```json "protein": { "id": "A", "sequence": ..., "unpairedMsa": ..., "pairedMsa": ..., "templates": null } ``` Or you can simply fully omit the `templates` field thus setting it implicitly to `null`: ```json "protein": { "id": "A", "sequence": ..., "unpairedMsa": ..., "pairedMsa": ..., } ``` ## Bonds To manually specify covalent bonds, use the `bondedAtomPairs` field. This is intended for modelling covalent ligands, and for defining multi-CCD ligands (e.g. glycans). Defining covalent bonds between or within polymer entities is not currently supported. Bonds are specified as pairs of (source atom, destination atom), with each atom being uniquely addressed using 3 fields: * **Entity ID** (`str`): this corresponds to the `id` field for that entity. * **Residue ID** (`int`): this is 1-based residue index *within* the chain. For single-residue ligands, this is simply set to 1. * **Atom name** (`str`): this is the unique atom name *within* the given residue. The atom name for protein/RNA/DNA residues or CCD ligands can be looked up in the CCD for the given chemical component. This also explains why SMILES ligands don't support bonds: there is no atom name that could be used to define the bond. This shortcoming can be addressed by using the user-provided CCD format (see below). The example below shows two bonds: ```json "bondedAtomPairs": [ [["A", 145, "SG"], ["L", 1, "C04"]], [["J", 1, "O6"], ["J", 2, "C1"]] ] ``` The first bond is between chain A, residue 145, atom SG and chain L, residue 1, atom C04. This is a typical example for a covalent ligand. The second bond is between chain J, residue 1, atom O6 and chain J, residue 2, atom C1. This bond is within the same entity and is a typical example when defining a glycan. All bonds are implicitly assumed to be covalent bonds. Other bond types are not supported. ### Defining Glycans Glycans are bound to a protein residue, and they are typically formed of multiple chemical components. To define a glycan, define a new ligand with all of the chemical components of the glycan. Then define a bond that links the glycan to the protein residue, and all bonds that are within the glycan between its individual chemical components. For example, to define the following glycan composed of 4 components (CMP1, CMP2, CMP3, CMP4) bound to an asparagine in a protein chain A: ``` ⋮ ALA CMP4 | | ASN ―― CMP1 ―― CMP2 | | ALA CMP3 ⋮ ``` You will need to specify: 1. Protein chain A. 2. Ligand chain B with the 4 components. 3. Bonds ASN-CMP1, CMP1-CMP2, CMP2-CMP3, CMP2-CMP4. ## User-provided CCD There are two approaches to model a custom ligand not defined in the CCD: 1. If the ligand is not bonded to other entities, it can be defined using a [SMILES string](https://en.wikipedia.org/wiki/Simplified_Molecular_Input_Line_Entry_System). 2. If it is bonded to other entities, or to be able to customise relevant features (such as bond orders, atom names and ideal coordinates used when conformer generation fails), it is necessary to define that particular ligand using the [CCD mmCIF format](https://www.wwpdb.org/data/ccd#mmcifFormat). Note that if a full CCD mmCIF is provided, any SMILES string input as part of that mmCIF is ignored. Once defined, this ligand needs to be assigned a name that doesn't clash with existing CCD ligand names (e.g. `LIG-1`). Avoid underscores (`_`) in the name, as it could cause issues in the mmCIF format. The newly defined ligand can then be used as a standard CCD ligand using its custom name, and bonds can be linked to it using its named atom scheme. ### Using user-provided CCD for polymer modifications The user-provided CCD can also be used for specifying non-canonical amino acids or nucleotides in the protein/RNA/DNA chains, not only custom ligands. In this case, the custom component is referenced from the polymer `modifications` field using its CCD component ID: ```json { "protein": { "id": "A", "sequence": "MDQHQAFKEATELLEKMKTSSDEERVEYLRKAVRLFNLTSEGQQGELVGKFKEAGVLIRAVDLS", "modifications": [{"ptmType": "MYMOD", "ptmPosition": 30}] } } ``` In the example above, residue 30 is replaced by the custom component `MYMOD`. * `ptmType` must match the component ID defined in the user-provided CCD. * The user-provided CCD should describe an appropriate peptide-linking polymer component rather than a free non-polymer ligand. * The user-provided CCD entry should include the expected backbone atoms and bond graph for the residue, adjusted for the residue position in the polymer chain. E.g. atoms and bond graphs for the mid-chain residue and terminal residue may differ. The same principle applies to RNA and DNA chains. This workflow is useful for modeling non-canonical amino acids or nucleotides in the context of polymer chains. By contrast, external covalent ligands should generally be modeled as ligand entities plus `bondedAtomPairs`. ### Conformer Generation The data pipeline attempts to generate a conformer for ligands using RDKit. The `Mol` used to generate the conformer is constructed either from the information provided in the CCD mmCIF, or from the SMILES string if that is the only information provided. If conformer generation fails, the model will fall back to using the ideal coordinates in the CCD mmCIF if these are provided. If they are not provided, the model will use the reference coordinates if the last modification date given in the CCD mmCIF is prior to the training cutoff date. If no coordinates can be found in this way, all conformer coordinates are set to zero and the model will output `NaN` (`null` in the output JSON) confidences for the ligand. Note that sometimes conformer generation failures can be resolved by increasinging the number of RDKit conformer iterations using the `--conformer_max_iterations=...` flag. ### User-provided CCD Format The user-provided CCD must be passed either: * In the `userCCD` field (in the root of the input JSON) as a string. Note that JSON doesn't allow newlines within strings, so newline characters (`\n`) must be used to delimit lines. Single rather than double quotes should also be used around strings like the chemical formula. * In the `userCCDPath` field, as a path to a file that contains the user-provided chemical components dictionary. The path can be either absolute, or relative to the input JSON path. The file must be in the [CCD mmCIF format](https://www.wwpdb.org/data/ccd#mmcifFormat), and could be either plain text, or compressed using gzip, xz, or zstd. The main pieces of information used are the atom names and elements, bonds, and also the ideal coordinates (`pdbx_model_Cartn_{x,y,z}_ideal`) which essentially serve as a structural template for the ligand if RDKit fails to generate conformers for that ligand. The user-provided CCD can also be used to redefine standard chemical components in the CCD. This can be useful if you need to redefine the ideal coordinates. Below is an example user-provided CCD redefining component X7F, which serves to illustrate the required sections. For readability purposes, newlines have not been replaced by `\n`. ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### Mandatory fields Parsing the user-provided CCD needs only a subset of the fields that CCD uses. The mandatory fields are described below. Refer to [CCD documentation](https://www.wwpdb.org/data/ccd#mmcifFormat) for more detailed explanation of each field. Note that not all of these fields are input to the model, but they are necessary for the data pipeline to run – see the [Model input fields](#model-input-fields) section below. **Singular fields (containing just a single value)** * `_chem_comp.id`: The ID of the component. Must match the `_data` record and must not contain special CIF characters (like `_` or `#`). * `_chem_comp.name`: Optional full name of the component. If unknown, set to `?`. * `_chem_comp.type`: Type of the component, typically `non-polymer`. * `_chem_comp.formula`: Optional component formula. If unknown, set to `?`. * `_chem_comp.mon_nstd_parent_comp_id`: Optional parent component ID. If unknown, set to `?`. * `_chem_comp.pdbx_synonyms`: Optional synonym IDs. If unknown, set to `?`. * `_chem_comp.formula_weight`: Optional weight of the component. If unknown, set to `?`. **Per-atom fields (containing one record per atom)** * `_chem_comp_atom.comp_id`: Component ID. * `_chem_comp_atom.atom_id`: Atom ID. * `_chem_comp_atom.type_symbol`: Atom element type. * `_chem_comp_atom.charge`: Atom charge. * `_chem_comp_atom.pdbx_leaving_atom_flag`: Optional flag determining whether this is a leaving atom. If unset, assumed to be no (`N`) for all atoms. * `_chem_comp_atom.pdbx_model_Cartn_x_ideal`: Ideal x coordinate. * `_chem_comp_atom.pdbx_model_Cartn_y_ideal`: Ideal y coordinate. * `_chem_comp_atom.pdbx_model_Cartn_z_ideal`: Ideal z coordinate. **Per-bond fields (containing one record per bond)** * `_chem_comp_bond.atom_id_1`: The ID of the first of the two atoms that define the bond. * `_chem_comp_bond.atom_id_2`: The ID of the second of the two atoms that define the bond. * `_chem_comp_bond.value_order`: The bond order of the chemical bond associated with the specified atoms. * `_chem_comp_bond.pdbx_aromatic_flag`: Whether the bond is aromatic. ### Model input fields The following fields are used to generate input for the model: * `_chem_comp_atom.atom_id`: Atom ID. * `_chem_comp_atom.type_symbol`: Atom element type. * `_chem_comp_atom.charge`: Atom charge. * `_chem_comp_atom.pdbx_model_Cartn_x_ideal`: Ideal x coordinate. Only used if conformer generation fails. * `_chem_comp_atom.pdbx_model_Cartn_y_ideal`: Ideal y coordinate. Only used if conformer generation fails. * `_chem_comp_atom.pdbx_model_Cartn_z_ideal`: Ideal z coordinate. Only used if conformer generation fails. * `_chem_comp_bond.atom_id_1`: The ID of the first of the two atoms that define the bond. * `_chem_comp_bond.atom_id_2`: The ID of the second of the two atoms that define the bond. ## Full Example An example illustrating all the aspects of the input format is provided below. Note that AlphaFold 3 won't run this input out of the box as it abbreviates certain fields and the sequences are not biologically meaningful. ``` /* Detailed source-code truncated for AI context efficiency. */ ``` --- ### Installation # Installation and Running Your First Prediction You will need a machine running Linux; AlphaFold 3 does not support other operating systems. Full installation requires up to 1 TB of disk space to keep genetic databases (SSD storage is recommended) and an NVIDIA GPU with Compute Capability 8.0 or greater (GPUs with more memory can predict larger protein structures). We have verified that inputs with up to 5,120 tokens can fit on a single NVIDIA A100 80 GB, or a single NVIDIA H100 80 GB. We have verified numerical accuracy on both NVIDIA A100 and H100 GPUs. Especially for long targets, the genetic search stage can consume a lot of RAM – we recommend running with at least 64 GB of RAM. We provide installation instructions for a machine with an NVIDIA A100 80 GB GPU and a clean Ubuntu 22.04 LTS installation, and expect that these instructions should aid others with different setups. If you are installing locally outside of a Docker container, please ensure CUDA, cuDNN, and JAX are correctly installed; the [JAX installation documentation](https://jax.readthedocs.io/en/latest/installation.html#nvidia-gpu) is a useful reference for this case. Note that the Docker container requires that the host machine has CUDA 12.6 installed. The instructions provided below describe how to: 1. Provision a machine on GCP. 1. Install Docker. 1. Install NVIDIA drivers for an A100. 1. Obtain genetic databases. 1. Obtain model parameters. 1. Build the AlphaFold 3 Docker container or Singularity image. ## Provisioning a Machine Clean Ubuntu images are available on Google Cloud, AWS, Azure, and other major platforms. Using an existing Google Cloud project, we provisioned a new machine: * We recommend using `--machine-type a2-ultragpu-1g` but feel free to use `--machine-type a2-highgpu-1g` for smaller predictions. * If desired, replace `--zone us-central1-a` with a zone that has quota for the machine you have selected. See [gpu-regions-zones](https://cloud.google.com/compute/docs/gpus/gpu-regions-zones). ```sh gcloud compute instances create alphafold3 \ --machine-type a2-ultragpu-1g \ --zone us-central1-a \ --image-family ubuntu-2204-lts \ --image-project ubuntu-os-cloud \ --maintenance-policy TERMINATE \ --boot-disk-size 1000 \ --boot-disk-type pd-balanced ``` This provisions a bare Ubuntu 22.04 LTS image on an [A2 Ultra](https://cloud.google.com/compute/docs/accelerator-optimized-machines#a2-vms) machine with 12 CPUs, 170 GB RAM, 1 TB disk and NVIDIA A100 80 GB GPU attached. We verified the following installation steps from this point. ## Installing Docker These instructions are for rootless Docker. ### Installing Docker on Host Note these instructions only apply to Ubuntu 22.04 LTS images, see above. Add Docker's official GPG key. Official Docker instructions are [here](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository). The commands we ran are: ```sh sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc ``` Add the repository to apt sources: ```sh echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo docker run hello-world ``` ### Enabling Rootless Docker Official Docker instructions are [here](https://docs.docker.com/engine/security/rootless/#distribution-specific-hint). The commands we ran are: ```sh sudo apt-get install -y uidmap systemd-container sudo machinectl shell $(whoami)@ /bin/bash -c 'dockerd-rootless-setuptool.sh install && sudo loginctl enable-linger $(whoami) && DOCKER_HOST=unix:///run/user/1001/docker.sock docker context use rootless' ``` ## Installing GPU Support ### Installing NVIDIA Drivers Official Ubuntu instructions are [here](https://documentation.ubuntu.com/server/how-to/graphics/install-nvidia-drivers/). The commands we ran are: ```sh sudo apt-get -y install alsa-utils ubuntu-drivers-common sudo ubuntu-drivers install sudo nvidia-smi --gpu-reset nvidia-smi # Check that the drivers are installed. ``` Accept the "Pending kernel upgrade" dialog if it appears. You will need to reboot the instance with `sudo reboot now` to reset the GPU if you see the following warning: ```text NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running. ``` Proceed only if `nvidia-smi` has a sensible output. ### Installing NVIDIA Support for Docker Official NVIDIA instructions are [here](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html). The commands we ran are: ```sh curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get update sudo apt-get install -y nvidia-container-toolkit nvidia-ctk runtime configure --runtime=docker --config=$HOME/.config/docker/daemon.json systemctl --user restart docker sudo nvidia-ctk config --set nvidia-container-cli.no-cgroups --in-place ``` Check that your container can see the GPU: ```sh docker run --rm --gpus all nvidia/cuda:12.6.0-base-ubuntu22.04 nvidia-smi ``` Example output: ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ## Obtaining AlphaFold 3 Source Code Install `git` and download the AlphaFold 3 repository: ```sh git clone https://github.com/google-deepmind/alphafold3.git ``` ## Obtaining Genetic Databases This step requires `wget` and `zstd` to be installed on your machine. On Debian-based systems install them by running `sudo apt install wget zstd`. AlphaFold 3 needs multiple genetic (sequence) protein and RNA databases to run: * [BFD small](https://bfd.mmseqs.com/) * [MGnify](https://www.ebi.ac.uk/metagenomics/) * [PDB](https://www.rcsb.org/) (structures in the mmCIF format) * [PDB seqres](https://www.rcsb.org/) * [UniProt](https://www.uniprot.org/uniprot/) * [UniRef90](https://www.uniprot.org/help/uniref) * [NT](https://www.ncbi.nlm.nih.gov/nucleotide/) * [RFam](https://rfam.org/) * [RNACentral](https://rnacentral.org/) We provide a bash script `fetch_databases.sh` that can be used to download and set up all of these databases. This process takes around 45 minutes when not installing on local SSD. We recommend running the following in a `screen` or `tmux` session as downloading and decompressing the databases takes some time. ```sh cd alphafold3 # Navigate to the directory with cloned AlphaFold 3 repository. ./fetch_databases.sh [] ``` This script downloads the databases from a mirror hosted on GCS, with all versions being the same as used in the AlphaFold 3 paper, to the directory ``. If not specified, the default `` is `$HOME/public_databases`. :ledger: **Note: The download directory `` should *not* be a subdirectory in the AlphaFold 3 repository directory.** If it is, the Docker build will be slow as the large databases will be copied during the image creation. :ledger: **Note: The total download size for the full databases is around 252 GB and the total size when unzipped is 630 GB. Please make sure you have sufficient hard drive space, bandwidth, and time to download. We recommend using an SSD for better genetic search performance.** :ledger: **Note: If the download directory and datasets don't have full read and write permissions, it can cause errors with the MSA tools, with opaque (external) error messages. Please ensure the required permissions are applied, e.g. with the `sudo chmod 755 --recursive ` command.** Once the script has finished, you should have the following directory structure: ```sh mmcif_files/ # Directory containing ~200k PDB mmCIF files. bfd-first_non_consensus_sequences.fasta mgy_clusters_2022_05.fa nt_rna_2023_02_23_clust_seq_id_90_cov_80_rep_seq.fasta pdb_seqres_2022_09_28.fasta rfam_14_9_clust_seq_id_90_cov_80_rep_seq.fasta rnacentral_active_seq_id_90_cov_80_linclust.fasta uniprot_all_2021_04.fa uniref90_2022_05.fa ``` Optionally, after the script finishes, you may want copy databases to an SSD. You can use theses two scripts: * `src/scripts/gcp_mount_ssd.sh []` Mounts and formats an unmounted GCP SSD drive to the specified path. It will skip the either step if the disk is either already formatted or already mounted. The default `` is `/mnt/disks/ssd`. * `src/scripts/copy_to_ssd.sh [] []` this will copy as many files that it can fit on to the SSD. The default `` is `$HOME/public_databases`, and must match the path used in the `fetch_databases.sh` command above, and the default `` is `/mnt/disks/ssd/public_databases`. ## Obtaining Model Parameters You can download the AlphaFold 3 model parameters from https://storage.googleapis.com/alphafold3/af3.bin.zst. Use is subject to these [terms of use](https://github.com/google-deepmind/alphafold3/blob/main/WEIGHTS_TERMS_OF_USE.md). Download the model parameters to a directory of your choosing, referred to as `` in the following instructions. As with the databases, this should *not* be a subdirectory in the AlphaFold 3 repository directory. ## Building the Docker Container That Will Run AlphaFold 3 Then, build the Docker container. This builds a container with all the right python dependencies: ```sh docker build -t alphafold3 -f docker/Dockerfile . ``` If you hit `No file descriptors available (os error 24)` on systems like AlmaLinux/Rocky/RHEL, you need to manually expand the file descriptor limits during the build by appending `--ulimit nofile=65535:65535`: ```sh docker build --ulimit nofile=65535:65535 -t alphafold3 -f docker/Dockerfile . ``` Create an input JSON file, using either the example in the [README](https://github.com/google-deepmind/alphafold3?tab=readme-ov-file#installation-and-running-your-first-prediction) or a [custom input](https://github.com/google-deepmind/alphafold3/blob/main/docs/input.md), and place it in a directory, e.g. `$HOME/af_input`. You can now run AlphaFold 3! ```sh docker run -it \ --volume $HOME/af_input:/root/af_input \ --volume $HOME/af_output:/root/af_output \ --volume :/root/models \ --volume :/root/public_databases \ --gpus all \ alphafold3 \ python run_alphafold.py \ --json_path=/root/af_input/fold_input.json \ --model_dir=/root/models \ --output_dir=/root/af_output ``` where `$HOME/af_input` is the directory containing the input JSON file; `$HOME/af_output` is the directory where the output will be written to; and `` and `` are the directories containing the databases and model parameters. The values of these directories must match the directories used in previous steps for downloading databases and model weights, and for the input file. :ledger: Note: You may also need to create the output directory, `$HOME/af_output` directory before running the `docker` command and make it and the input directory writable from the docker container, e.g. by running `chmod 755 $HOME/af_input $HOME/af_output`. In most cases `docker` and `run_alphafold.py` will create the output directory if it does not exist. :ledger: **Note: In the example above the databases have been placed on the persistent disk, which is slow.** If you want better genetic and template search performance, make sure all databases are placed on a local SSD. If you have some databases on an SSD in the `` directory and some databases on a slower disk in the `` directory, you can mount both directories and specify `db_dir` multiple times. This will enable the fast access to databases with a fallback to the larger, slower disk: ```sh docker run -it \ --volume $HOME/af_input:/root/af_input \ --volume $HOME/af_output:/root/af_output \ --volume :/root/models \ --volume :/root/public_databases \ --volume :/root/public_databases_fallback \ --gpus all \ alphafold3 \ python run_alphafold.py \ --json_path=/root/af_input/fold_input.json \ --model_dir=/root/models \ --db_dir=/root/public_databases \ --db_dir=/root/public_databases_fallback \ --output_dir=/root/af_output ``` If you get an error like the following, make sure the models and data are in the paths (flags named `--volume` above) in the correct locations. ``` docker: Error response from daemon: error while creating mount source path '/srv/alphafold3_data/models': mkdir /srv/alphafold3_data/models: permission denied. ``` `run_alphafold.py` supports many flags for controlling performance, running on multiple input files, specifying external binary paths, and more. See ```sh docker run alphafold3 python run_alphafold.py --help ``` for more information. :ledger: **Optional: Enable Google cloud storage path support** AlphaFold 3 supports reading and writing specific files directly from Google Cloud Storage (`gs://` paths). Since GCS is an optional feature, the required `gcsfs` dependency is not installed by default. To enable GCS support when building the Docker container, pass the `UV_EXTRAS` build argument when running `docker build`: ```sh docker build --build-arg UV_EXTRAS="--extra gcsfs" -t alphafold3 -f docker/Dockerfile . ``` The following command-line flags support `gs://` paths: - `--input_dir` - `--json_path` - `--output_dir` - `--model_dir` - `--pdb_database_path` - In the JSON input file, fields with names ending in `Path` (e.g. `pairedMsaPath`) can be provided as Google Cloud Storage paths, if enabled. :warning: All other database paths (e.g., `--db_dir`, `--small_bfd_database_path`, etc.) and binary paths (e.g., `--jackhmmer_binary_path`) do **not** support `gs://` paths and must be local file paths. ## Running Using Singularity Instead of Docker You may prefer to run AlphaFold 3 within Singularity. You'll still need to *build* the Singularity image from the Docker container. Afterwards, you will not have to depend on Docker (at structure prediction time). ### Install Singularity Official Singularity instructions are [here](https://docs.sylabs.io/guides/3.3/user-guide/installation.html). The commands we ran are: ```sh wget https://github.com/sylabs/singularity/releases/download/v4.2.1/singularity-ce_4.2.1-jammy_amd64.deb sudo dpkg --install singularity-ce_4.2.1-jammy_amd64.deb sudo apt-get install -f ``` ### Build the Singularity Container From the Docker Image After building the *Docker* container above with `docker build -t`, start a local Docker registry and upload your image `alphafold3` to it. Singularity's instructions are [here](https://github.com/apptainer/singularity/issues/1537). The commands we ran are: ```sh docker run -d -p 5000:5000 --restart=always --name registry registry:2 docker tag alphafold3 localhost:5000/alphafold3 docker push localhost:5000/alphafold3 ``` Then build the Singularity container: ```sh SINGULARITY_NOHTTPS=1 singularity build alphafold3.sif docker://localhost:5000/alphafold3:latest ``` You can confirm your build by starting a shell and inspecting the environment. For example, you may want to ensure the Singularity image can access your GPU. You may want to restart your computer if you have issues with this. ```sh singularity exec --nv alphafold3.sif sh -c 'nvidia-smi' ``` You can now run AlphaFold 3! ```sh singularity exec --nv alphafold3.sif <> ``` For example: ```sh singularity exec \ --nv \ --bind $HOME/af_input:/root/af_input \ --bind $HOME/af_output:/root/af_output \ --bind :/root/models \ --bind :/root/public_databases \ alphafold3.sif \ python run_alphafold.py \ --json_path=/root/af_input/fold_input.json \ --model_dir=/root/models \ --db_dir=/root/public_databases \ --output_dir=/root/af_output ``` Or with some databases on SSD in location ``: ```sh singularity exec \ --nv \ --bind $HOME/af_input:/root/af_input \ --bind $HOME/af_output:/root/af_output \ --bind :/root/models \ --bind :/root/public_databases \ --bind :/root/public_databases_fallback \ alphafold3.sif \ python run_alphafold.py \ --json_path=/root/af_input/fold_input.json \ --model_dir=/root/models \ --db_dir=/root/public_databases \ --db_dir=/root/public_databases_fallback \ --output_dir=/root/af_output ``` ## Running AlphaFold 3 without a GPU (CPU-only) It is possible to run AlphaFold 3 on a computer without a GPU. Note though that this is not an officially supported mode (we don't perform rigorous numerical accuracy testing for this mode). This mode can be useful for utilizing machines without a GPU if you don't mind the longer folding times (roughly 100x slower than on a GPU). ### Direct installation without Docker on Linux or Mac OS Since JAX doesn't support running natively on Mac GPU as of 2026, you have to resort to running AlphaFold 3 in the slow CPU-only mode even though it has a GPU (`jax-metal` is unfinished as of July 2026). 1. Download all required databases and AlphaFold 3 weights (see above). 2. Install the [HMMER Suite](http://hmmer.org/). See http://hmmer.org/documentation.html for installation instructions. 3. Install [uv](https://docs.astral.sh/uv/). See https://docs.astral.sh/uv/getting-started/installation/ for installation instructions. 4. Clone the AlphaFold 3 GitHub repository ```sh git clone https://github.com/google-deepmind/alphafold3.git ``` 5. Navigate in the `alphafold3` directory and run the following commands to install AlphaFold 3: ```sh cd alphafold3 uv venv --python 3.12 source .venv/bin/activate uv sync uv run build_data ``` 6. Check the installation by running the AlphaFold 3 data test: ```sh uv run python run_alphafold_data_test.py ``` 7. You can now run AlphaFold 3. If you are running on a Linux CPU-only machine, make sure to set flags `--jax_backend="cpu"` and `--flash_attention_implementation="xla"`. If you are running on Mac OS with Apple Silicon, you can set `--jax_backend="mps"` instead and get roughly 3x better inference performance by using the built-in GPU: ```sh uv run run_alphafold.py \ --json_path="..." \ --output_dir="..." \ --model_dir="..." \ --jax_backend="cpu" \ --flash_attention_implementation="xla" ``` #### Running on Mac OS using the Apple Silicon GPU As an alternative to CPU-only mode, AlphaFold 3 inference can run on the Apple Silicon GPU with `--jax_backend="mps"` via the community supported `jax-mps` Metal plugin. This is an unofficial and experimental path, but it is roughly 3× faster than CPU (possibly more on newer M chips). --- ### Known Issues # Known Issues ## Numerical performance for CUDA Capability 7.x GPUs All CUDA Capability 7.x GPUs (e.g. V100) produce obviously bad output, with lots of clashing residues (the clashes cause a ranking score of -99 or lower), unless the environment variable `XLA_FLAGS` is set to include `--xla_disable_hlo_passes=custom-kernel-fusion-rewriter`. ## Incorrect handling of two-letter atoms in SMILES ligands Between commits https://github.com/google-deepmind/alphafold3/commit/f8df1c7 and https://github.com/google-deepmind/alphafold3/commit/4e4023c, AlphaFold 3 handled incorrectly any two-letter atoms (e.g. Cl, Br) in ligands defined using SMILES strings. ## MSA discrepancy between AlphaFold 3 and AlphaFold Server ### The root cause of the problem The released AlphaFold 3 and AlphaFold Server use the same model weights and equivalent featurisation and model code. However, the way they run genetic search is slightly different. The released AlphaFold 3 searches each database in one go, while AlphaFold Server has a sharded version of each database (split into multiple smaller FASTA files) and searches all of the shards in parallel. The results of these parallel searches are then merged together at the end. The discrepancy is caused by a different (deeper) MSA on AlphaFold Server in some cases. We discovered that the issue is caused by running sharded Jackhmmer in AlphaFold Server without the `--domZ` flag (has to be set together with the `--Z` flag and set to the same value) which means that effectively the AlphaFold Server is running with roughly 100× more permissive `--domE` filter. This means more sequences are sometimes included in the MSA. We are keeping behaviour unchanged in both the released AlphaFold 3 and in the AlphaFold Server, however, we are giving users with local installs an option to replicate AlphaFold Server behaviour locally. In our large scale tests the difference did not matter, it is only very specific inputs that get better accuracy with the deeper MSA. See https://github.com/google-deepmind/alphafold3/issues/492 for an example input where a protein-DNA complex gets significantly higher ipTM and pTM with AlphaFold Server compared to a local run. ### Replicating AlphaFold Server behaviour locally If you want to replicate AlphaFold Server behaviour (i.e. better folding accuracy in some cases), you can increase the value of the Jackhmmer/Nhmmer `--domE` flag by 100× compared to its default value. Alternatively, you can run the sharded MSA search while not setting the `--domZ` value – you would have to modify the code to do it. We added support for searching against sharded databases in AlphaFold 3 in https://github.com/google-deepmind/alphafold3/commit/805adc3863841d83d631ccd18136ad58ce3ecb34 and the way to run AlphaFold 3 with sharded databases is documented in https://github.com/google-deepmind/alphafold3/blob/main/docs/performance.md#sharded-genetic-databases. It can provide 10–30× speedup (potentially even more, depending on hardware) of the genetic search. In general, we recommend experimenting with MSA if you are seeing a prediction with low predicted confidence. Typically adding more *relevant* sequences in the MSA will increase AlphaFold prediction accuracy and model confidence scores. ### Gated Linear Unit Tokamax `NotImplementedError` When running AlphaFold 3 in certain configurations (e.g. on Mac OS with the MPS backend), you might see errors like this: ``` NotImplementedError: Not supported on gpu. Failed to run implementation Traceback (most recent call last): File "tokamax/_src/ops/gated_linear_unit/api.py", line 114, in gated_linear_unit return fn(x, weights, activation=activation, precision=precision) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "tokamax/_src/ops/op.py", line 197, in __call__ raise NotImplementedError(f"Not supported on {device.device_kind}.") NotImplementedError: Not supported on gpu. ``` Tokamax will the chose another implementation and run the prediction successfully, so these are safe to ignore. --- ### Metadata Antibody Antigen # Metadata for Antibody-Antigen pairs used to create figure 5a Figure 5a in the AlphaFold 3 paper was created using 71 antibody–antigen complexes, containing 166 antibody–antigen interfaces spanning 65 interface clusters. Scores were averaged within each interface cluster then across clusters. Note that the first bioassembly is used in all cases. We provide metadata for these complexes and the associated clusters in this CSV file: https://github.com/google-deepmind/alphafold3/blob/main/docs/metadata_antibody_antigen.csv --- ### Model Parameters # Model Parameters AlphaFold 3 layer names, shapes, and dtypes are documented in the table below. This can be used for example to generate random parameters for AlphaFold 3 performance optimisation on new accelerators without having to obtain the official parameters. It is important to not generate zero-only parameters for performance optimisations as accelerators often have shortcuts for zero-only arguments (e.g. `0 * tensor` can be optimised to a no-op). Producing random parameters could be done similarly to the following snippet: ```py from alphafold3.model import params import numpy as np import zstandard parameters = ... # Data from the parameters schema. with zstandard.open('random_weights.bin.zst', 'wb') as compressed: for scope_name, shape, dtype in parameters: if scope_name == '__meta__:__identifier__': # The identifier can be all zeros. arr = np.zeros(shape=shape, dtype=dtype) else: # Do not use all-zero params, instead sample uniformly between -1 and 1. arr = np.random.uniform(low=-1, high=1, size=shape).astype(dtype) scope_name = scope_name.split(':') compressed.write(params.encode_record(*scope_name, arr)) ``` ## Parameters Schema ``` /* Detailed source-code truncated for AI context efficiency. */ ``` --- ### Output # AlphaFold 3 Output ## Output Directory Structure For every input job, AlphaFold 3 writes all its outputs in a directory called by the sanitized version of the job name. E.g. for job name "My first fold (TEST)", AlphaFold 3 will write its outputs in a directory called `My_first_fold_TEST` (the case is respected). If such directory already exists, AlphaFold 3 will append a timestamp to the directory name to avoid overwriting existing data unless `--force_output_dir` is passed. The output directory can also be a Google Cloud Storage path (`gs://`) if the `gcsfs` dependency is installed (see the [installation instructions](installation.md#optional-enable-google-cloud-storage-path-support)). The following structure is used within the output directory: * Sub-directories with results for each sample and seed. There will be *num\_seeds* \* *num\_samples* such sub-directories. The naming pattern is `seed-_sample-`. Each of these directories contains a confidence JSON, summary confidence JSON, and the mmCIF with the predicted structure. * Distogram for each seed: `seed-_distogram/distogram.npz`. The Numpy zip file contains a single key: `distogram`. The distogram can be large, its shape is `(num_tokens, num_tokens, 64)` and dtype `np.float16` (almost 3 GiB for a 5,000-token input). Only saved if AlphaFold 3 is run with `--save_distogram=true`. * Embeddings for each seed: `seed-_embeddings/embeddings.npz`. The Numpy zip file contains 2 keys: `single_embeddings` and `pair_embeddings`. The embeddings can be large, their shapes are `(num_tokens, 384)` for `single_embeddings`, and `(num_tokens, num_tokens, 128)` for `pair_embeddings`. Their dtype is `np.float16` (almost 6 GiB for a 5,000-token input). Only saved if AlphaFold 3 is run with `--save_embeddings=true`. * Top-ranking prediction mmCIF: `_model.cif`. This file contains the predicted coordinates and should be compatible with most structural biology tools. We do not provide the output in the PDB format, the CIF file can be easily converted into one if needed. * Top-ranking prediction confidence JSON: `_confidences.json`. * Top-ranking prediction summary confidence JSON: `_summary_confidences.json`. * Job input JSON file with the MSA and template data added by the data pipeline: `_data.json`. * Ranking scores for all predictions: `ranking_scores.csv`. The prediction with highest ranking is the one included in the root directory. * Output terms of use: `TERMS_OF_USE.md`. Below is an example AlphaFold 3 output directory listing for a job called "Hello Fold", that has been ran with 1 seed and 5 samples: ```txt hello_fold/ ├── seed-1234_distogram # Only if --save_distogram=true. │ └── hello_fold_seed-1234_distogram.npz # Only if --save_distogram=true. ├── seed-1234_embeddings # Only if --save_embeddings=true. │ └── hello_fold_seed-1234_embeddings.npz # Only if --save_embeddings=true. ├── seed-1234_sample-0/ │ ├── hello_fold_seed-1234_sample-0_confidences.json │ ├── hello_fold_seed-1234_sample-0_model.cif │ └── hello_fold_seed-1234_sample-0_summary_confidences.json ├── seed-1234_sample-1/ │ ├── hello_fold_seed-1234_sample-1_confidences.json │ ├── hello_fold_seed-1234_sample-1_model.cif │ └── hello_fold_seed-1234_sample-1_summary_confidences.json ├── seed-1234_sample-2/ │ ├── hello_fold_seed-1234_sample-2_confidences.json │ ├── hello_fold_seed-1234_sample-2_model.cif │ └── hello_fold_seed-1234_sample-2_summary_confidences.json ├── seed-1234_sample-3/ │ ├── hello_fold_seed-1234_sample-3_confidences.json │ ├── hello_fold_seed-1234_sample-3_model.cif │ └── hello_fold_seed-1234_sample-3_summary_confidences.json ├── seed-1234_sample-4/ │ ├── hello_fold_seed-1234_sample-4_confidences.json │ ├── hello_fold_seed-1234_sample-4_model.cif │ └── hello_fold_seed-1234_sample-4_summary_confidences.json ├── TERMS_OF_USE.md ├── hello_fold_confidences.json ├── hello_fold_data.json ├── hello_fold_model.cif ├── hello_fold_ranking_scores.csv └── hello_fold_summary_confidences.json ``` ## Confidence Metrics Similar to AlphaFold 2 and AlphaFold-Multimer, AlphaFold 3 outputs include confidence metrics. The main metrics are: * **pLDDT:** a per-atom confidence estimate on a 0-100 scale where a higher value indicates higher confidence. pLDDT aims to predict a modified LDDT score that only considers distances to polymers. For proteins this is similar to the [lDDT-Cα metric](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3799472/) but with more granularity as it can vary per atom not just per residue. For ligand atoms, the modified LDDT considers the errors only between the ligand atom and polymers, not other ligand atoms. For DNA/RNA a wider radius of 30 Å is used for the modified LDDT instead of 15 Å. * **PAE (predicted aligned error)**: an estimate of the error in the relative position and orientation between two tokens in the predicted structure. Higher values indicate higher predicted error and therefore lower confidence. For proteins and nucleic acids, PAE score is essentially the same as AlphaFold 2, where the error is measured relative to frames constructed from the protein backbone. For small molecules and post-translational modifications, a frame is constructed for each atom from its closest neighbors from a reference conformer. * **pTM and ipTM scores**: the predicted template modeling (pTM) score and the interface predicted template modeling (ipTM) score are both derived from a measure called the template modeling (TM) score. This measures the accuracy of the entire structure ([Zhang and Skolnick, 2004](https://doi.org/10.1002/prot.20264); [Xu and Zhang, 2010](https://doi.org/10.1093/bioinformatics/btq066)). A pTM score above 0.5 means the overall predicted fold for the complex might be similar to the true structure. ipTM measures the accuracy of the predicted relative positions of the subunits within the complex. Values higher than 0.8 represent confident high-quality predictions, while values below 0.6 suggest a failed prediction. ipTM values between 0.6 and 0.8 are a gray zone where predictions could be correct or incorrect. The TM score is very strict for small structures or short chains, so pTM assigns values less than 0.05 when fewer than 20 tokens are involved; for these cases PAE or pLDDT may be more indicative of prediction quality. For detailed description of these confidence metrics see the [AlphaFold 3 paper](https://www.nature.com/articles/s41586-024-07487-w). For protein components, the [AlphaFold: A Practical guide](https://www.ebi.ac.uk/training/online/courses/alphafold/inputs-and-outputs/evaluating-alphafolds-predicted-structures-using-confidence-scores/) course for structures provides additional tutorials on the confidence metrics. If you are interested in a specific entity or interaction, then there are confidences available in the outputs which are specific to each chain or chain-pair, as opposed to the full complex. See below for more details on all the confidence metrics that are returned. ## Multi-Seed and Multi-Sample Results By default, the model samples five predictions per seed. The top-ranked prediction across all samples and seeds is available at the top-level of the output directory. All samples along with their associated confidences are available in subdirectories of the output directory. For ranking of the full complex use the `ranking_score` (higher is better). This score uses overall structure confidences (pTM and ipTM), but also includes terms that penalize clashes and encourage disordered regions not to have spurious helices – these extra terms mean the score should only be used to rank structures. If you are interested in a specific entity or interaction, you may want to rank by a metric specific to that chain or chain-pair, as opposed to the full complex. In that case, use the per chain or per chain-pair confidence metrics described below for ranking. ## Metrics in Confidences JSON For each predicted sample we provide two JSON files. One contains summary metrics – summaries for either the whole structure, per chain or per chain-pair – and the other contains full 1D or 2D arrays. Summary outputs: * `ptm`: A scalar in the range 0-1 indicating the predicted TM-score for the full structure. * `iptm`: A scalar in the range 0-1 indicating predicted interface TM-score (confidence in the predicted interfaces) for all interfaces in the structure. * `fraction_disordered`: A scalar in the range 0-1 that indicates what fraction of the prediction structure is disordered, as measured by accessible surface area, see our [paper](https://www.nature.com/articles/s41586-024-07487-w) for details. * `has_clash`: A boolean indicating if the structure has a significant number of clashing atoms (more than 50% of a chain, or a chain with more than 100 clashing atoms). * `ranking_score`: A scalar in the range \[-100, 1.5\] that can be used for ranking predictions, it incorporates `ptm`, `iptm`, `fraction_disordered` and `has_clash` into a single number with the following equation: 0.8 × ipTM \+ 0.2 × pTM \+ 0.5 × disorder − 100 × has_clash. * `chain_pair_pae_min`: A \[num_chains, num_chains\] array. Element (i, j) of the array contains the lowest PAE value across rows restricted to chain i and columns restricted to chain j. This has been found to correlate with whether two chains interact or not, and in some cases can be used to distinguish binders from non-binders. * `chain_pair_iptm`: A \[num_chains, num_chains\] array. Off-diagonal element (i, j) of the array contains the ipTM restricted to tokens from chains i and j. Diagonal element (i, i) contains the pTM restricted to chain i. Can be used for ranking a specific interface between two chains, when you know that they interact, e.g. for antibody-antigen interactions * `chain_ptm`: A \[num_chains\] array. Element i contains the pTM restricted to chain i. Can be used for ranking individual chains when the structure of that chain is most of interest, rather than the cross-chain interactions it is involved with. * `chain_iptm:` A \[num_chains\] array that gives the average confidence (interface pTM) in the interface between each chain and all other chains. Can be used for ranking a specific chain, when you care about where the chain binds to the rest of the complex and you do not know which other chains you expect it to interact with. This is often the case with ligands. * `chain_ids:` A \[num_chains\] array with chain IDs in the same order as all of the other chain-level arrays to make the JSON more self-contained. Full array outputs: * `pae`: A \[num\_tokens, num\_tokens\] array. Element (i, j) indicates the predicted error in the position of token j, when the prediction is aligned to the ground truth using the frame of token i. * `atom_plddts`: A \[num_atoms\] array, element i indicates the predicted local distance difference test (pLDDT) for atom i in the prediction. * `contact_probs`: A \[num_tokens, num_tokens\] array. Element (i, j) indicates the predicted probability that token i and token j are in contact (8 Å between the representative atom for each token), see [paper](https://www.nature.com/articles/s41586-024-07487-w) for details. * `token_chain_ids`: A \[num_tokens\] array indicating the chain ids corresponding to each token in the prediction. * `atom_chain_ids`: A \[num_atoms\] array indicating the chain ids corresponding to each atom in the prediction. ## Embeddings AlphaFold 3 can be run with `--save_embeddings=true` to save the embeddings for each seed. The file is in the [compressed Numpy `.npz` format](https://numpy.org/doc/stable/reference/generated/numpy.savez_compressed.html) and can be loaded using `numpy.load` as a dictionary-like object with two arrays: * `single_embeddings`: A \`[num\_tokens, 384\] array containing the embeddings for each token. * `pair_embeddings`: A \[num\_tokens, num\_tokens, 128\] array containing the pairwise embeddings between all tokens. You can use for instance the following Python code to load the embeddings: ```py import numpy as np with open('embeddings.npz', 'rb') as f: embeddings = np.load(f) single_embeddings = embeddings['single_embeddings'] pair_embeddings = embeddings['pair_embeddings'] ``` ## Chirality checks In the AlphaFold 3 paper Posebusters results, a penalty was applied to the ranking score if the ligand of interest contained chiral errors. By running multiple seeds and using this chiral aware ranking, chiral error rates were greatly reduced. We provide the method `compare_chirality` in [`model/scoring/chirality.py`](https://github.com/google-deepmind/alphafold3/blob/main/src/alphafold3/model/scoring/chirality.py) to replicate these chiral checks. Chirality is checked against CCD structures if available, otherwise users can supply custom RDKit Mol objects for comparison. --- ### Performance # Performance ## Running the Pipeline in Stages The `run_alphafold.py` script can be executed in stages to optimise resource utilisation. This can be useful for: 1. Splitting the CPU-only data pipeline from model inference (which requires a GPU), to optimise cost and resource usage. 1. Generating the JSON output file from the data pipeline only run and then using it for multiple different inference only runs across seeds or across variations of other features (e.g. a ligand or a partner chain). 1. Generating the JSON output for multiple individual monomer chains (e.g. for chains A, B, C, D), then running the inference on all possible chain pairs (AB, AC, AD, BC, BD, CD) by creating dimer JSONs by merging the monomer JSONs. By doing this, the MSA and template search need to be run just 4 times (once for each chain), instead of 12 times. ### Data Pipeline Only Launch `run_alphafold.py` with `--run_inference=false` to generate Multiple Sequence Alignments (MSAs) and templates, without running featurisation and model inference. This stage can be quite costly in terms of runtime, CPU, and RAM use. The output will be JSON files augmented with MSAs and templates that can then be directly used as input for running inference. ### Pre-computing and reusing MSA and templates When folding multiple candidate chains with a set of fixed chains (i.e. chains that are the same for all the runs), you can optimize the process by computing the MSA and templates for the fixed chains only once. The computations for the changing candidate chains will still be performed for each run: 1. Run the AlphaFold 3 data pipeline for the fixed chains using the `--run_inference=false` flag. This step generates a JSON file containing the MSA and template data for these chains. 2. When constructing your multimer input JSONs, populate the entries for the fixed chains using the data generated in the previous step. * For the fixed chains: Specifically, copy the `unpairedMsa`, `pairedMsa`, and `templates` fields from the pre-computed JSON into the multimer input JSON. This prevents these fields from being recomputed. * For the candidate chains: Leave these fields unset (or `null`) in the multimer input JSON. This will signal the pipeline to compute them dynamically for each run. This technique can also be extended to efficiently process all combinations of *n* first chains and *m* second chains. Instead of performing *n* × *m* full computations, you can reduce this to *n* + *m* data pipeline runs. In this scenario: 1. Run the data pipeline (step 1 above, with `--run_inference=false`) for all *n* individual first chains and all *m* individual second chains. 2. Assemble the dimer input JSONs for each desired pair by combining their respective pre-computed monomer JSONs. 3. Run only the inference step on these assembled JSONs using the `--run_data_pipeline=false` flag. This approach has been discussed in multiple GitHub issues, such as: https://github.com/google-deepmind/alphafold3/issues/171 (which links to other similar issues). ### Featurisation and Model Inference Only Launch `run_alphafold.py` with `--run_data_pipeline=false` to skip the data pipeline and run only featurisation and model inference. This stage requires the input JSON file to contain pre-computed MSAs and templates (or they must be explicitly set to empty if you want to run MSA and template free). ## Data Pipeline The runtime of the data pipeline (i.e. genetic sequence search and template search) can vary significantly depending on the size of the input and the number of homologous sequences found, as well as the available hardware – the disk speed can influence genetic search speed in particular. If you would like to improve performance, it's recommended to increase the disk speed (e.g. by leveraging a RAM-backed filesystem), or increase the available CPU cores and add more parallelisation. This can help because AlphaFold 3 runs genetic search against 4 databases in parallel, so the optimal number of cores is the number of cores used for each Jackhmmer process times 4. Also note that for sequences with deep MSAs, Jackhmmer or Nhmmer may need a substantial amount of RAM beyond the recommended 64 GB of RAM. ### Sharded genetic databases The run time of the genetic database search can be *significantly* sped up by splitting the genetic databases if a machine with many CPU cores is used and the databases are on very fast SSD or in a RAM-backed filesystem. With this technique you can make Jackhmmer/Nhmmer genetic search fully utilize your hardware and take advantage of multi-core systems. Each genetic database with *n* sequences is split into *s* shards, each containing roughly *n* / *s* sequences. We recommend splitting the sequences between shards randomly to make sure each shard has similar sequence length distribution. This could be achieved using standard tools: 1. Shuffle the sequences in the fasta. This can be done for example by running: `seqkit shuffle --two-pass ` 2. Split the shuffled fasta in *s* shards. This can be done for example by running: `seqkit split2 --by-part ` Make sure the shards names follow this pattern: `prefix--of-`, both `shard_index` and `total_shards` having always 5 digits, with leading zeros as needed. The `shard_index` goes from 0 to `total_shards - 1`. A file "path" (spec) for a sharded file is `prefix@`. E.g. for a file named `uniprot.fasta` split into 3 shards, the names of the shards should be: * `uniprot.fasta-00000-of-00003` * `uniprot.fasta-00001-of-00003` * `uniprot.fasta-00002-of-00003` The file spec for these files is `uniprot.fasta@3`. Save the total number of sequences in the protein databases, and the total number of nucleic bases in the RNA databases – these will be needed later as a flag to Jackhmmer/Nhmmer to correctly scale e-values across all shards. Save the sharded databases on a fast SSD or in a RAM-backed filesystem, then launch AlphaFold with the sharded paths instead of normal paths and set the Z-values. For instance with each database sharded into 16 shards: ```bash python run_alphafold.py \ --small_bfd_database_path="bfd-first_non_consensus_sequences.fasta@64" \ --small_bfd_z_value=65984053 \ --mgnify_database_path="mgy_clusters_2022_05.fa@512" \ --mgnify_z_value=623796864 \ --uniprot_cluster_annot_database_path="uniprot_cluster_annot_2021_04.fasta@256" \ --uniprot_cluster_annot_z_value=225619586 \ --uniref90_database_path="uniref90_2022_05.fasta@128" \ --uniref90_z_value=153742194 \ --ntrna_database_path="nt_rna_2023_02_23_clust_seq_id_90_cov_80_rep_seq.fasta@256" \ --ntrna_z_value=76752.808514 \ --rfam_database_path="rfam_14_9_clust_seq_id_90_cov_80_rep_seq.fasta@16" \ --rfam_z_value=138.115553 \ --rna_central_database_path="rnacentral_active_seq_id_90_cov_80_linclust.fasta@64" \ --rna_central_z_value=13271.415730 --jackhmmer_n_cpu=2 \ --jackhmmer_max_parallel_shards=16 \ --nhmmer_n_cpu=2 \ --nhmmer_max_parallel_shards=16 ``` This run will utilize (2 CPUs) × (16 max parallel shards) × (4 protein dbs searched in parallel) = 128 cores for each protein chain, and (2 CPUs) × (16 max parallel shards) × (3 RNA dbs searched in parallel) = 96 cores for each RNA chain. Make sure to tune: * the Jackhmmer/Nhmmer number of CPUs, * the maximum number of shards searched in parallel, * and the number of shards for each database so that the memory bandwidth and CPUs on your machine are optimally utilized. You should aim for consistent shard sizes across all databases (so e.g. if database A is split into 16 shards and is 3× smaller than database B, database B should be split into 3 × 16 = 48 shards). ## Model Inference Table 8 in the Supplementary Information of the [AlphaFold 3 paper](https://nature.com/articles/s41586-024-07487-w) provides compile-free inference timings for AlphaFold 3 when configured to run on 16 NVIDIA A100s, with 40 GB of memory per device. In contrast, this repository supports running AlphaFold 3 on a single NVIDIA A100 with 80 GB of memory in a configuration optimised to maximise throughput. We compare compile-free inference timings of these two setups in the table below using GPU seconds (i.e. multiplying by 16 when using 16 A100s). The setup in this repository is more efficient (by at least 2×) across all token sizes, indicating its suitability for high-throughput applications. Num Tokens | 1 A100 80 GB (GPU secs) | 16 A100 40 GB (GPU secs) | Improvement :--------- | ----------------------: | -----------------------: | ----------: 1024 | 62 | 352 | 5.7× 2048 | 275 | 1136 | 4.1× 3072 | 703 | 2016 | 2.9× 4096 | 1434 | 3648 | 2.5× 5120 | 2547 | 5552 | 2.2× ## Accelerator Hardware Requirements We officially support the following configurations, and have extensively tested them for numerical accuracy and throughput efficiency: - 1 NVIDIA A100 (80 GB) - 1 NVIDIA H100 (80 GB) We compare compile-free inference timings of both configurations in the following table: Num Tokens | 1 A100 80 GB (seconds) | 1 H100 80 GB (seconds) :--------- | ---------------------: | ---------------------: 1024 | 62 | 34 2048 | 275 | 144 3072 | 703 | 367 4096 | 1434 | 774 5120 | 2547 | 1416 ### Other Hardware Configurations #### NVIDIA A100 (40 GB) AlphaFold 3 can run on inputs of size up to 4,352 tokens on a single NVIDIA A100 (40 GB) with the following configuration changes: 1. Enabling [unified memory](#unified-memory). 1. Adjusting `pair_transition_shard_spec` in `model_config.py`: ```py pair_transition_shard_spec: Sequence[_Shape2DType] = ( (2048, None), (3072, 1024), (None, 512), ) ``` The format of entries in `pair_transition_shard_spec` is `(num_tokens_upper_bound, shard_size)`. Setting `shard_size=None` means there is no upper bound. For the example above: * `(2048, None)`: for sequences up to 2,048 tokens, do not shard * `(3072, 1024)`: for sequences up to 3,072 tokens, shard in chunks of 1,024 * `(None, 512)`: for all other sequences, shard in chunks of 512 While numerically accurate, this configuration will have lower throughput compared to the set up on the NVIDIA A100 (80 GB), due to less available memory. #### NVIDIA V100 There are known numerical issues with CUDA Capability 7.x devices. To work around the issue, set the ENV XLA_FLAGS to include `--xla_disable_hlo_passes=custom-kernel-fusion-rewriter`. With the above flag set, AlphaFold 3 can run on inputs of size up to 1,280 tokens on a single NVIDIA V100 using [unified memory](#unified-memory). #### NVIDIA P100 AlphaFold 3 can run on inputs of size up to 1,024 tokens on a single NVIDIA P100 with no configuration changes needed. #### Other devices Large-scale numerical tests have not been performed on any other devices but they are believed to be numerically accurate. There are known numerical issues with CUDA Capability 7.x devices. To work around the issue, set the environment variable `XLA_FLAGS` to include `--xla_disable_hlo_passes=custom-kernel-fusion-rewriter`. ## Compilation Buckets To avoid excessive re-compilation of the model, AlphaFold 3 implements compilation buckets: ranges of input sizes using a single compilation of the model. When featurising an input, AlphaFold 3 determines the smallest bucket the input fits into, then adds any necessary padding. This may avoid re-compiling the model when running inference on the input if it belongs to the same bucket as a previously processed input. The configuration of bucket sizes involves a trade-off: more buckets leads to more re-compilations of the model, but less padding. By default, the largest bucket size is 5,120 tokens. Processing inputs larger than this maximum bucket size triggers the creation of a new bucket for exactly that input size, and a re-compilation of the model. In this case, you may wish to redefine the compilation bucket sizes via the `--buckets` flag in `run_alphafold.py` to add additional larger bucket sizes. For example, suppose you are running inference on inputs with token sizes: `5132, 5280, 5342`. Using the default bucket sizes configured in `run_alphafold.py` will trigger three separate model compilations, one for each unique token size. If instead you pass in the following flag to `run_alphafold.py` ``` --buckets 256,512,768,1024,1280,1536,2048,2560,3072,3584,4096,4608,5120,5376 ``` when running inference on the above three input sizes, the model will be compiled only once for the bucket size `5376`. **Note:** for this specific example with input sizes `5132, 5280, 5342`, passing in `--buckets 5376` is sufficient to achieve the desired compilation behaviour. The provided example with multiple buckets illustrates a more general solution suitable for diverse input sizes. ## Additional Flags ### Compilation Time Workaround with XLA Flags To work around a known XLA issue causing the compilation time to greatly increase, the following environment variable must be set (it is set by default in the provided `Dockerfile`). ```sh ENV XLA_FLAGS="--xla_gpu_enable_triton_gemm=false" ``` ### CUDA Capability 7.x GPUs For all CUDA Capability 7.x GPUs (e.g. V100) the environment variable `XLA_FLAGS` must be changed to include `--xla_disable_hlo_passes=custom-kernel-fusion-rewriter`. Disabling the Tritron GEMM kernels is not necessary as they are not supported for such GPUs. ```sh ENV XLA_FLAGS="--xla_disable_hlo_passes=custom-kernel-fusion-rewriter" ``` ### GPU Memory The following environment variables (set by default in the `Dockerfile`) enable folding a single input of size up to 5,120 tokens on a single A100 (80 GB) or a single H100 (80 GB): ```sh ENV XLA_PYTHON_CLIENT_PREALLOCATE=true ENV XLA_CLIENT_MEM_FRACTION=0.95 ``` #### Unified Memory If you would like to run AlphaFold 3 on inputs larger than 5,120 tokens, or on a GPU with less memory (an A100 with 40 GB of memory, for instance), we recommend enabling unified memory. Enabling unified memory allows the program to spill GPU memory to host memory if there isn't enough space. This prevents an OOM, at the cost of making the program slower by accessing host memory instead of device memory. To learn more, check out the [NVIDIA blog post](https://developer.nvidia.com/blog/unified-memory-cuda-beginners/). You can enable unified memory by setting the following environment variables in your `Dockerfile`: ```sh ENV XLA_PYTHON_CLIENT_PREALLOCATE=false ENV TF_FORCE_UNIFIED_MEMORY=true ENV XLA_CLIENT_MEM_FRACTION=3.2 ``` ### JAX Persistent Compilation Cache You may also want to make use of the JAX persistent compilation cache, to avoid unnecessary recompilation of the model between runs. You can enable the compilation cache with the `--jax_compilation_cache_dir ` flag in `run_alphafold.py`. More detailed instructions are available in the [JAX documentation](https://jax.readthedocs.io/en/latest/persistent_compilation_cache.html#persistent-compilation-cache), and more specifically the instructions for use on [Google Cloud](https://jax.readthedocs.io/en/latest/persistent_compilation_cache.html#persistent-compilation-cache). In particular, note that if you would like to make use of a non-local filesystem, such as Google Cloud Storage, you will need to install [`etils`](https://github.com/google/etils) (this is not included by default in the AlphaFold 3 Docker container). ---