> ## Documentation Index
> Fetch the complete documentation index at: https://proto.evodesign.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ESM3

> ESM3 is [Biohub](https://biohub.ai)'s generative protein language model, trained jointly over sequence, structure, and function. This toolkit wraps the open `esm3_sm_open_v1` checkpoint to embed, sample masked positions in, and score supplied protein sequences.

<div class="page-hero"><img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/tool/esm3/hero.png" alt="ESM3" /><div class="tool-org-badges page-hero-badges"><a href="/docs/tools/organizations/biohub" class="tool-org-badge" style={{background: "#111111"}} title="Biohub"><img src="https://mintcdn.com/bio-pro/_UGa2jUMKeVPCbLk/assets/images/cached/59f8c7606fb7.png?fit=max&auto=format&n=_UGa2jUMKeVPCbLk&q=85&s=e4891edc150dd75c0f1e262cfdb2d304" alt="" class="tool-org-badge-logo" width="192" height="192" data-path="assets/images/cached/59f8c7606fb7.png" /> Biohub</a></div></div>

<Note>
  **License:** ESM3 is open source and free for academic and commercial use under an MIT license. Please refer to [the license](https://github.com/Biohub/esm/blob/main/LICENSE.md) for full terms.
</Note>

<p class="entity-disclaimer">Proto is not affiliated with Biohub. This toolkit is open source and builds on the implementation produced by this organization. Product names, logos, and trademarks are the property of their respective owners.</p>

<hr class="entity-rule" />

<input type="radio" name="tab-esm3" id="none-esm3" class="tab-radio-input" />

<input type="radio" name="tab-esm3" id="github-esm3" class="tab-radio-input" defaultChecked />

<input type="radio" name="tab-esm3" id="hf-esm3" class="tab-radio-input" />

<input type="radio" name="tab-esm3" id="website-esm3" class="tab-radio-input" />

<input type="radio" name="tab-esm3" id="paper-esm3" class="tab-radio-input" />

<input type="radio" name="tab-esm3" id="cite-esm3" class="tab-radio-input" />

<input type="radio" name="tab-esm3" id="source-esm3" class="tab-radio-input" />

<input type="radio" name="tab-esm3" id="notebook-esm3" class="tab-radio-input" />

<input type="radio" name="tab-esm3" id="proto-esm3" class="tab-radio-input" />

<div class="tool-tab-bar">
  <span class="tool-tab-wrap"><label for="github-esm3" class="tool-tab tab-open badge-github"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> GitHub</label><label for="none-esm3" class="tool-tab tab-close badge-github"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> GitHub</label></span> <span class="tool-tab-wrap"><label for="hf-esm3" class="tool-tab tab-open badge-hf"><img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" width="16" height="16" class="hf-logo" /> HuggingFace</label><label for="none-esm3" class="tool-tab tab-close badge-hf"><img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" width="16" height="16" class="hf-logo" /> HuggingFace</label></span> <span class="tool-tab-wrap"><label for="website-esm3" class="tool-tab tab-open badge-website"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Website</label><label for="none-esm3" class="tool-tab tab-close badge-website"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Website</label></span> <span class="tool-tab-wrap"><label for="paper-esm3" class="tool-tab tab-open badge-paper"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label><label for="none-esm3" class="tool-tab tab-close badge-paper"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label></span> <span class="tool-tab-wrap"><label for="cite-esm3" class="tool-tab tab-open badge-cite"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label><label for="none-esm3" class="tool-tab tab-close badge-cite"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label></span> <span class="tool-tab-wrap"><label for="source-esm3" class="tool-tab tab-open badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Tool Source</label><label for="none-esm3" class="tool-tab tab-close badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Tool Source</label></span> <span class="tool-tab-wrap"><label for="notebook-esm3" class="tool-tab tab-open badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label><label for="none-esm3" class="tool-tab tab-close badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label></span> <span class="tool-tab-wrap"><label for="proto-esm3" class="tool-tab tab-open badge-local"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5" /><line x1="12" y1="19" x2="20" y2="19" /></svg> Run Locally</label><label for="none-esm3" class="tool-tab tab-close badge-local"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5" /><line x1="12" y1="19" x2="20" y2="19" /></svg> Run Locally</label></span>
</div>

<a href="https://github.com/Biohub/esm" target="_blank" class="tab-panel github-panel" data-tab="github-esm3">
  <div class="gh-card-wrap">
    <img src="https://opengraph.githubassets.com/1/Biohub/esm" class="gh-card-img img-fallback" alt="Biohub/esm" />

    <div class="gh-card-fallback">
      <div class="gh-fallback-org"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> Biohub/esm</div>
    </div>
  </div>

  <span class="panel-goto-btn gh-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> View repo</span></span>
</a>

<a href="https://huggingface.co/biohub/esm3-sm-open-v1" target="_blank" class="tab-panel hf-panel" data-tab="hf-esm3">
  <div class="hf-card-wrap">
    <img src="https://cdn-thumbnails.huggingface.co/social-thumbnails/models/biohub/esm3-sm-open-v1.png" class="hf-card-img img-fallback" alt="biohub/esm3-sm-open-v1" />

    <div class="hf-card-fallback">
      <div class="hf-fallback-org"><img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" width="16" height="16" class="hf-logo" /> biohub/esm3-sm-open-v1</div>
    </div>
  </div>

  <span class="panel-goto-btn hf-goto-btn"><span><img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" width="16" height="16" class="hf-logo" /> View model</span></span>
</a>

<a href="https://biohub.ai/" target="_blank" class="tab-panel website-panel" data-tab="website-esm3">
  <div class="website-info">
    <img src="https://www.google.com/s2/favicons?domain=biohub.ai&sz=32" class="website-favicon" width="24" height="24" />

    <span class="website-url">biohub.ai</span>
  </div>

  <span class="panel-goto-btn website-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Visit website</span></span>
</a>

<a href="https://doi.org/10.1126/science.ads0018" target="_blank" class="tab-panel paper-panel" data-tab="paper-esm3">
  <div class="paper-info">
    <div class="paper-title">Simulating 500 million years of evolution with a language model</div>
    <div class="paper-meta">Thomas Hayes, Roshan Rao, ... Alexander Rives</div>
    <div class="paper-meta paper-venue">Science (2025)</div>
  </div>

  <span class="panel-goto-btn pub-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Read paper</span></span>
</a>

<div class="tab-panel cite-panel" data-tab="cite-esm3">
  <div class="cite-code-wrap">
    ```bibtex theme={null}
    @article{hayes2025esm3,
      title={Simulating 500 million years of evolution with a language model},
      author={Hayes, Thomas and Rao, Roshan and Akin, Halil and Sofroniew, Nicholas J. and Oktay, Deniz and Lin, Zeming and Verkuil, Robert and Tran, Vincent Q. and Deaton, Jonathan and Wiggert, Marius and Badkundri, Rohil and Shafkat, Irhum and Gong, Jun and Derry, Alexander and Molina, Raul S. and Thomas, Neil and Khan, Yousuf A. and Mishra, Chetan and Kim, Carolyn and Bartie, Liam J. and Nemeth, Matthew and Hsu, Patrick D. and Sercu, Tom and Candido, Salvatore and Rives, Alexander},
      journal={Science},
      volume={387},
      number={6736},
      pages={850--858},
      year={2025},
      publisher={American Association for the Advancement of Science},
      doi={10.1126/science.ads0018}
    }

    @software{evolutionaryscale_2024,
      author={{EvolutionaryScale Team}},
      title={evolutionaryscale/esm},
      year={2024},
      publisher={Zenodo},
      doi={10.5281/zenodo.14219303},
      url={https://doi.org/10.5281/zenodo.14219303}
    }
    ```
  </div>

  <span class="panel-goto-btn cite-copy-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Copy citation</span></span>
</div>

<a href="https://github.com/evo-design/proto-tools/tree/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3" target="_blank" class="tab-panel source-panel" data-tab="source-esm3">
  <div class="source-info">
    <img src="https://github.com/evo-design.png?size=40" class="source-avatar" width="36" height="36" />

    <span class="source-path">evo-design/proto-tools<span class="source-subpath">/proto\_tools/tools/masked\_models/esm3</span></span>
  </div>

  <span class="panel-goto-btn source-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> View source</span></span>
</a>

<a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/examples/example.ipynb" target="_blank" class="tab-panel notebook-panel" data-tab="notebook-esm3">
  <div class="notebook-info">
    <span class="notebook-icon">
      <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
        <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />

        <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
      </svg>
    </span>

    <span class="notebook-label">Open Notebook</span>
  </div>

  <span class="panel-goto-btn notebook-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open notebook</span></span>
</a>

<div class="tab-panel proto-panel run-local-panel" data-tab="proto-esm3">
  <a href="https://github.com/evo-design/proto-tools" target="_blank" class="run-local-preview">
    <img noZoom src="https://opengraph.githubassets.com/1/evo-design/proto-tools" alt="proto-tools on GitHub" />
  </a>

  <div class="run-local-install">
    <span class="run-local-label">Run locally with proto-tools</span>

    <div class="run-local-code">
      ```bash theme={null}
      pip install git+https://github.com/evo-design/proto-tools.git
      ```
    </div>
  </div>
</div>

<div class="entity-contributors"><span class="entity-contributors-label">Toolkit contributors</span><span class="entity-contributors-people"><a class="entity-contributor" href="https://github.com/bviggiano" target="_blank" rel="noopener" title="bviggiano: 30 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/21143637?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">bviggiano</span></a><a class="entity-contributor" href="https://github.com/dguo8412" target="_blank" rel="noopener" title="dguo8412: 21 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/46211285?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">dguo8412</span></a><a class="entity-contributor" href="https://github.com/leba01" target="_blank" rel="noopener" title="leba01: 4 commits"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/124846286?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">leba01</span></a></span></div>

| Function                | Description                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ----------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `run_esm3_embeddings()` | Extract protein sequence embeddings and logits using ESM3 (GPU)              | <a href="#api-run-esm3-embeddings" class="func-table-btn func-api-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20" /></svg> Docs</a> <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_embeddings.py#L121" target="_blank" class="func-table-btn func-source-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a> |
| `run_esm3_sample()`     | Sample masked positions in protein sequences using ESM3 language model (GPU) | <a href="#api-run-esm3-sample" class="func-table-btn func-api-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20" /></svg> Docs</a> <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_sample.py#L161" target="_blank" class="func-table-btn func-source-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>         |
| `run_esm3_score()`      | Score protein sequences using ESM3 language model (GPU)                      | <a href="#api-run-esm3-score" class="func-table-btn func-api-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20" /></svg> Docs</a> <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_score.py#L88" target="_blank" class="func-table-btn func-source-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>            |

## Background

In 2025, [Hayes et al.](https://doi.org/10.1126/science.ads0018) introduced ESM3, a generative model from [EvolutionaryScale](https://www.evolutionaryscale.ai) that departs from the encoder-only design of the ESM-1/ESM-2 line. ESM3 is a masked generative transformer that represents a protein across three simultaneous tracks (amino-acid sequence, discrete structure tokens, and function annotation). Training masks spans across all three tracks, so a single model can be prompted with any combination of partial sequence, structure, and function and asked to complete the rest. The flagship 98B-parameter model (`esm3-large-2024-03`) is available through the [Biohub Platform](https://biohub.ai/) API (also offered via AWS SageMaker); the publicly released open checkpoint, `esm3_sm_open_v1`, is the small 1.4B-parameter variant.

ESM3 is the multimodal successor to ESM-2 ([Lin et al., 2023](https://doi.org/10.1126/science.ade2574)). Where ESM-2 is a sequence-only masked language model, ESM3 adds structure and function tracks and a generative objective. For pure sequence-embedding workloads ESM-2 remains lighter and faster; ESM3 is the choice when masked generative editing matters. This toolkit exposes only the sequence-track operations (embeddings, masked sampling, scoring) over supplied sequences.

## Tools

<a name="api-run-esm3-embeddings" />

<div class="tool-section-card tool-section-card--embedding">
  ### ESM3 Embeddings (`esm3-embedding`)

  Runs a single forward pass over ESM3 and mean-pools the per-residue hidden states into a fixed-length sequence descriptor. Per-position amino-acid logits are returned on request.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/shared_data_models.py#L29" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Input: MaskedModelInput">
      <ParamField path="sequences" type="List[string]" required>
        Protein sequence(s) to process. Can be provided as:
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-config-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_embeddings.py#L55" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Config: ESM3EmbeddingsConfig">
      <ParamField path="model_checkpoint" type="string" default="esm3_sm_open_v1">
        ESM3 weights variant. Currently `"esm3_sm_open_v1"` is the only public open-weights checkpoint.
      </ParamField>

      <ParamField path="return_logits" type="boolean" default="False">
        Include per-position logits in the output (large; disable to save memory).
      </ParamField>

      <ParamField path="repr_layer" type="integer" default="-1">
        Transformer layer index for embeddings. `-1` returns the post-norm last-block output (matches ESM2/ESMC `-1` semantics); other indices select pre-norm per-block hiddens. Both are captured via a forward hook on `model.transformer` since `ESM3.forward` discards them.
      </ParamField>

      <ParamField path="verbose" type="integer" default="0">
        Print status messages during model execution.
      </ParamField>

      <ParamField path="device" type="string" default="cuda">
        Device to run the model on.
      </ParamField>

      <ParamField path="timeout" type="integer" default="3600">
        Maximum execution time in seconds. `None` waits indefinitely.
      </ParamField>

      <ParamField path="seed" type="integer">
        Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
      </ParamField>

      <ParamField path="batch_size" type="integer" default="8">
        Number of sequences to process in parallel. Larger batches improve throughput but require more GPU memory.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-output-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_embeddings.py#L31" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Output: ESM3EmbeddingsOutput">
      <ResponseField name="results" type="List[SequenceEmbedding]" required>
        Per-sequence embedding results. Each `SequenceEmbedding` contains:

        <Expandable title="SequenceEmbedding">
          <ResponseField name="mean_embedding" type="List[number]" required>
            Mean-pooled embedding vector for one sequence.
          </ResponseField>

          <ResponseField name="attention_mask" type="List[integer]" required>
            Binary mask indicating valid positions (1) vs padding (0).
          </ResponseField>

          <ResponseField name="logits" type="array">
            Optional per-position amino acid logits for one sequence.
          </ResponseField>

          <ResponseField name="projection" type="Projection2D">
            Optional 2D coordinate from a UMAP projection of all embeddings in the same call. Populated when `n_sequences >= 4`; `None` otherwise (single-point or 2-3-point UMAP is meaningless).
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  The mean-pooled embedding is a learned protein representation for downstream supervised tasks such as clustering, classification, and property regression, and powers similarity search through cosine similarity on the mean vector.

  #### Usage Tips

  * **`repr_layer` selects which transformer layer is mean-pooled.** The default `-1` returns the post-norm output of the last block (matching ESM-2/ESMC `-1` semantics); other indices select pre-norm per-block hidden states, captured via a forward hook because `ESM3.forward` discards them.
  * **Per-position logits are large.** Enabling `return_logits` adds a per-position vocabulary-sized float tensor per sequence, dominating wall time and memory on long inputs. Leave it `False` unless the per-position distribution is needed.

  <a name="api-run-esm3-sample" />
</div>

<div class="tool-section-card tool-section-card--sample">
  ### ESM3 Sampling (`esm3-sample`)

  Selects positions via a configurable masking strategy, masks them, and resamples from ESM3's predicted distribution. `single_pass` fills every masked position in one forward pass; `iterative_refinement` dispatches to ESM3's native `batch_generate` for multi-round commitment. Positions can also be pre-masked directly with `_` in the input string, or a masking strategy can be used.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/shared_data_models.py#L29" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Input: MaskedModelInput">
      <ParamField path="sequences" type="List[string]" required>
        Protein sequence(s) to process. Can be provided as:
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-config-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_sample.py#L51" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Config: ESM3SampleConfig">
      <ParamField path="masking_strategy" type="MaskingStrategy">
        Positions to mask before sampling.

        <Expandable title="MaskingStrategy">
          <ParamField path="temperature" type="number" default="1.0">
            Temperature for position selection. \< 1.0 is greedy, 1.0 uses scores as-is, > 1.0 is more uniform. Only affects model-based methods.
          </ParamField>

          <ParamField path="method" type="enum" default="random">
            Scoring method for position selection. `"random"`: uniform random, `"entropy"`: highest model uncertainty, `"max-logit"`: lowest model confidence.

            Available options: `random`, `entropy`, `max-logit`
          </ParamField>

          <ParamField path="num_mutations" type="integer">
            Exact number of positions to mask per sequence.
          </ParamField>

          <ParamField path="mask_fraction" type="number">
            Fraction of designable positions to mask (e.g. 0.15 for \~15%).
          </ParamField>

          <ParamField path="fixed_positions" type="array">
            1-indexed positions that must NOT be masked. Applied uniformly to all sequences.
          </ParamField>
        </Expandable>
      </ParamField>

      <ParamField path="model_checkpoint" type="string" default="esm3_sm_open_v1">
        ESM3 weights variant.
      </ParamField>

      <ParamField path="sampling_method" type="enum" default="single_pass">
        "single\_pass" fills every mask in one forward; "iterative\_refinement" dispatches to `model.batch_generate` and uses the five GenerationConfig settings below.

        Available options: `single_pass`, `iterative_refinement`
      </ParamField>

      <ParamField path="temperature" type="number" default="1.0">
        Softmax temperature.
      </ParamField>

      <ParamField path="top_p" type="number" default="1.0">
        Nucleus threshold (iterative only).
      </ParamField>

      <ParamField path="num_steps" type="integer" default="20">
        Refinement steps (iterative only).
      </ParamField>

      <ParamField path="schedule" type="enum" default="cosine">
        Unmask schedule (iterative only).

        Available options: `cosine`, `linear`
      </ParamField>

      <ParamField path="strategy" type="enum" default="random">
        Per-round commit selection (iterative only).

        Available options: `random`, `entropy`
      </ParamField>

      <ParamField path="temperature_annealing" type="boolean" default="True">
        Anneal toward 0 across rounds (iterative only).
      </ParamField>

      <ParamField path="return_logits" type="boolean" default="False">
        Include per-position logits.
      </ParamField>

      <ParamField path="verbose" type="integer" default="0">
        Verbosity level (0=quiet, 1=info, 2=debug, 3=raw subprocess stderr). `True` is coerced to `1` and `False` to `0`.
      </ParamField>

      <ParamField path="device" type="string" default="cuda">
        Device to run on.
      </ParamField>

      <ParamField path="timeout" type="integer" default="3600">
        Maximum execution time in seconds. `None` waits indefinitely.
      </ParamField>

      <ParamField path="seed" type="integer">
        Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
      </ParamField>

      <ParamField path="batch_size" type="integer" default="8">
        Sequences per GPU forward pass.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-output-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_sample.py#L39" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Output: ESM3SampleOutput">
      <ResponseField name="results" type="List[MaskedModelSample]" required>
        One entry per input sequence, in input order, each holding the sampled sequence and its optional per-position logits.

        <Expandable title="MaskedModelSample">
          <ResponseField name="sequence" type="string" required>
            The sampled or restored protein sequence.
          </ResponseField>

          <ResponseField name="logits" type="array">
            Per-position amino acid logits for this sequence, shape `[seq_len, 20]`. Present only when the tool's config sets `return_logits=True`.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  This tool drives guided point mutation, variant generation, and infilling at designable sites. Resampling masked positions from a protein language model is the core operation behind directed-evolution proposals and antibody affinity maturation. Which positions are resampled is set by the [masking strategy](https://github.com/evo-design/proto-tools/blob/main/proto_tools/transforms/masking/README.md); see its README for the available selection methods and tuning parameters.

  #### Usage Tips

  * **`iterative_refinement` produces more coherent joint samples than `single_pass`.** It runs ESM3's `batch_generate` over `num_steps` rounds (cosine or linear unmask schedule) instead of filling every mask independently in one pass; it is roughly `num_steps×` slower. Default to it when masking more than a handful of sites.
  * **`masking_strategy` controls which positions get masked before sampling.** See the [masking strategy README](https://github.com/evo-design/proto-tools/blob/main/proto_tools/transforms/masking/README.md) for the available selection methods and tuning parameters. As an alternative to passing a strategy, pre-mask exact positions with `_` directly in the input string and the masking strategy is skipped entirely.
  * **`temperature` scales the per-position logits before sampling.** Values of 0.5 to 0.7 yield conservative mutations close to the input; values above 1.0 broaden exploration of the model's distribution.

  <a name="api-run-esm3-score" />
</div>

<div class="tool-section-card tool-section-card--score">
  ### ESM3 Scoring (`esm3-score`)

  Computes masked-language-model pseudo-perplexity for each input sequence. Each position is masked individually and the model's log-probability of the true amino acid under bidirectional context is recorded, then aggregated into per-sequence log-likelihood, average log-likelihood, and perplexity.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/shared_data_models.py#L29" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Input: MaskedModelInput">
      <ParamField path="sequences" type="List[string]" required>
        Protein sequence(s) to process. Can be provided as:
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-config-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/esm3_score.py#L35" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Config: ESM3ScoringConfig">
      <ParamField path="model_checkpoint" type="string" default="esm3_sm_open_v1">
        ESM3 weights variant.
      </ParamField>

      <ParamField path="verbose" type="integer" default="0">
        Print status messages during scoring.
      </ParamField>

      <ParamField path="device" type="string" default="cuda">
        Device to run the model on.
      </ParamField>

      <ParamField path="timeout" type="integer" default="3600">
        Maximum execution time in seconds. `None` waits indefinitely.
      </ParamField>

      <ParamField path="seed" type="integer">
        Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
      </ParamField>

      <ParamField path="batch_size" type="integer" default="8">
        Masked variants per forward pass, pooled across all input sequences. Larger batches improve throughput but use more memory.
      </ParamField>

      <ParamField path="return_logits" type="boolean" default="False">
        Include per-position logits in the output (large; disable to save memory).
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-output-section">
    <a href="https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/shared_data_models.py#L401" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Output: MaskedModelScoringOutput">
      <ResponseField name="scores" type="List[MaskedModelScoringMetrics]" required>
        List of scoring outputs, one per input sequence. Each entry is a `Metrics` subclass with scalar metrics (accessed via `score.perplexity` or `score["perplexity"]`) plus declared `logits` / `vocab` fields that carry raw model outputs when requested.

        <Expandable title="MaskedModelScoringMetrics">
          <ResponseField name="logits" type="array">
            Per-position logits array `(seq_len, vocab_size)`. `None` unless `return_logits=True`.
          </ResponseField>

          <ResponseField name="vocab" type="array">
            Token ordering for `logits`.
          </ResponseField>

          <ResponseField name="primary_metric" type="string">
            Name of the metric that best summarizes the result overall (e.g. `"avg_plddt"` for AlphaFold2). Used by downstream UI and reporting to pick a headline value.
          </ResponseField>

          <ResponseField name="metric_type" type="string">
            Concrete Metrics subclass tag; enables typed reconstruction after a serialization round-trip.
          </ResponseField>
        </Expandable>
      </ResponseField>

      **Metrics** (one set per `scores` item)

      | Metric               | Type  | Range | Availability |
      | -------------------- | ----- | ----- | ------------ |
      | `log_likelihood`     | float | ≤ 0.0 | always       |
      | `avg_log_likelihood` | float | ≤ 0.0 | always       |
      | `perplexity`         | float | ≥ 1.0 | always       |
    </Accordion>
  </div>

  #### Applications

  ESM3 pseudo-perplexity is a fitness proxy for ranking variants, filtering generated sequences for naturalness, or comparing engineered constructs against wild type. The masked log-likelihood difference between wild-type and mutant residues is a zero-shot baseline for variant-effect prediction.

  #### Usage Tips

  * **Pseudo-perplexity is a relative score, not an absolute fitness.** It is measured against the model's training distribution and is sensitive to length, so it is most useful for comparing closely related sequences of similar length.
  * **Ambiguous residues are excluded.** Perplexity is computed only over the 20 canonical amino acids; `X`, `B`, `Z`, and similar are dropped from both the log-likelihood sum and the position count.
</div>

## Toolkit Notes

These apply to every ESM3 tool in this toolkit (`esm3-embedding`, `esm3-sample`, `esm3-score`).

* **ESM3 is larger than many ESM-2 variants.** For sequence-embedding-only workloads, smaller ESM-2 variants are faster; consider reaching for ESM3 when you want masked generative editing. This toolkit takes only amino-acid sequences as input and does not expose the structure or function tracks.
* **`batch_size` controls memory usage across the toolkit.** Lower it if you OOM; raise it for short-sequence throughput. For `esm3-score`, `batch_size` counts masked variants pooled across all input sequences rather than sequences themselves (each input contributes one masked variant per position).

<Tip>
  **Example notebook:** See the [full working example](https://github.com/evo-design/proto-tools/blob/47e34afa5ea240a3b406e323dc38aa5dc85f223e/proto_tools/tools/masked_models/esm3/examples/example.ipynb) for a copy-paste-ready walkthrough.
</Tip>

## Infrastructure Guides

The following guides cover how to run tools efficiently and at scale.

<CardGroup cols={2}>
  <Card title="Tool Persistence" icon="repeat" href="/docs/tools/guides/tool-persistence">Keep a tool's model warm across calls instead of reloading it every invocation.</Card>
  <Card title="Device Management" icon="cpu" href="/docs/tools/guides/device-management">How GPUs are allocated to tools and how to target specific devices.</Card>
  <Card title="Parallel Execution" icon="layers" href="/docs/tools/guides/parallel-execution">Fan a batch of inputs out across multiple GPUs.</Card>
</CardGroup>
