Repository navigation
fix: let the auto XLA fraction spill into the job's host RAM - #63
Merged
Merged
Conversation
XLA_CLIENT_MEM_FRACTION is a multiple of GPU VRAM, and with unified memory XLA's limit (VRAM x max(1, fraction)) covers VRAM and host spill together. "auto" set it to host RAM / VRAM, which capped the whole job at its host RAM and left about one VRAM's worth of the requested RAM unused: with 128 GB on an 80 GB H100, XLA ran out at 127 GiB with only ~48 GiB spilled. "auto" is now 1 + (host RAM - structure_inference_ram_bytes) / VRAM, floored at 1, so the job spills into all of its host RAM except the base inference RAM kept for the process (a probe at R/V + 1 on that H100 reached 206 GiB). The README no longer claims XLA_PYTHON_CLIENT_MEM_FRACTION is exported (the shell unsets it; JAX errors if both are set). Dry-run tests run the rendered block against a fake nvidia-smi. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Snakemake runs job shells with set -euo pipefail, so when `nvidia-smi -L` did not list the slice in CUDA_VISIBLE_DEVICES (or failed), grep's exit 1 ended the whole job before inference instead of falling back to --query-gpu or the fixed 3.2. The unified-memory tests now run the rendered block in strict mode, for both backends (AF3 margin 8000 MB, AF2 16000 MB), and cover several GPUs, MIG fallbacks, [N/A] readings, host RAM at or below the margin, a pinned fraction and unified memory off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured on an H100 in both 2.9.0 images: with XLA_CLIENT_MEM_FRACTION and XLA_PYTHON_CLIENT_MEM_FRACTION both set, the CUDA plugin fails to initialise and JAX silently runs on CPU, rather than raising. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Checked against sacct for ~145k structure_inference jobs since March: the largest host RSS per 1000-token bin (MaxRSS of the srun step, which excludes unified-memory spill) stays below the default requests with at least 2x margin for both backends, so the length model still holds under the new "auto" fraction. A test now pins those anchors. The README's MIG section notes that AlphaFold 2 complexes of 1,600-2,900 residues ran out of GPU memory on 16 GB slices, where tier routing places them up to ~1,700 residues. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Snakemake prints the job's mem_mb as <TBD> or as a number depending on the version (CI renders a number), so the helper now replaces either form. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported by a user whose large predictions ran out of memory with unified memory on and RAM to spare.
With unified memory on, XLA's memory limit is
VRAM × max(1, XLA_CLIENT_MEM_FRACTION)(xla/pjrt/gpu/gpu_helpers.cc, the same in the XLA versions pinned by jax 0.5.3 and 0.9.1). That limit holds VRAM and host spill together.structure_inference_xla_mem_fraction: autoset the fraction to host RAM / VRAM, so the whole job was capped at its host RAM, and about one GPU's worth of the requested RAM could never be used. Measured on an H100 80 GB with--mem=128G:auto(1.607) ran out at 127 GiB, only about 48 GiB of it spilled. R/V + 1 (2.607) reached 206 GiB.Changes
autois now1 + (host RAM − structure_inference_ram_bytes) / VRAM, never below 1. The margin is the backend's inference base RAM (8000 MB for AF3, 16000 MB for AF2), which stays free for the process itself. It is logged in the[unified-memory]line.nvidia-smi -Ldoes not list, the job now falls back to--query-gpuinstead of failing. Snakemake runs job shells withset -euo pipefail, so the pipeline'sgrepexit 1 used to end the job before inference. That bug is already on main.XLA_PYTHON_CLIENT_MEM_FRACTIONis exported; the shell unsets it, because with both names set JAX's CUDA plugin fails and JAX runs on CPU without raising.Testing
nvidia-smi. They cover both backends, several GPUs, MIG slices listed and unlisted, failing and[N/A]readings, host RAM at or below the margin, a pinned fraction, and unified memory off. Putting back the old formula, or removing the MIG|| true, makes them fail.nvidia-smibehaviours × 3 host-RAM values: 276/276 as expected. Ade_DElocale still prints a decimal point.XLA_PYTHON_CLIENT_MEM_FRACTION=4.0on import (see notes).Notes, not changed here
--memdoes not limit spill. The margin keeps the node from being overcommitted, not the job from being killed.batch.pysetsTF_FORCE_UNIFIED_MEMORY=1andXLA_PYTHON_CLIENT_MEM_FRACTION=4.0on import if they are unset. AlphaPulldown avoids it only becauserun_structure_prediction.pystarts the GPU backend before anything imports ColabFold. With the imports reversed, unified-memory runs fell back to CPU without an error, and AF2 with unified memory off got a 4.0 fraction. The ordering has no comment or test in AlphaPulldown.TF_FORCE_UNIFIED_MEMORY=1andXLA_CLIENT_MEM_FRACTION=0.95in its own environment, sostructure_inference_unified_memory: falsestill uses managed memory there, with the limit rounded up to plain VRAM. It still fails fast instead of spilling, as before.rerun-triggers: mtime, which both bundled profiles set.Throughput review (sacct, ~145k structure_inference jobs since March 2026)
🤖 Generated with Claude Code