Skip to content

Cache the Modal sandbox install chain in image layers - #8536

Merged
delock merged 1 commit into
deepspeedai:masterfrom
delock:bake-modal-install-layers
Sep 16, 2026
Merged

delock merged 1 commit into
deepspeedai:masterfrom
delock:bake-modal-install-layers

Conversation

@delock

@delock delock commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Why

The modal-torch-latest sandbox installs its whole dependency chain at runtime, after the sandbox clock starts: requirements (~3.6 min) plus the forced Torch reinstall (~3 min) — roughly 8 of the fixed sandbox lifetime, every run. The v1 GPU suite now runs close to that lifetime (#8519's merge-queue run was SIGKILLed at the sandbox deadline with the suite at 90%), so the fixed install overhead is directly eating test budget.

What

  • Bake the static chain into content-addressed Modal image layers:
    • a requirements layer keyed by the merge-group base SHA (bases move slowly, so the layer cache stays hot; the raw-file URLs embed the SHA, so a requirements change rebuilds the layer),
    • a Torch layer keyed by the preset, applied after the requirements layer.
  • Layer order preserves the previous guarantee: the Torch pin lands last, so a transitive dependency cannot displace the intended CUDA build variant.
  • The runtime pip install -r commands are kept unchanged as correctness guards: they are a near no-op when the baked layers are current, and install the difference when a candidate branch changed a requirements file — caching only speeds things up, it never changes the final environment.
  • The runtime reinstall Torch packages command is removed (now the image layer).
  • DS_CI_BASE_SHA is wired from the workflow (pull_request.base.sha || merge_group.base_sha), falling back to the candidate SHA on events without a base — that only lowers the cache hit rate, never correctness.

Net effect: warm runs hand ~6.5 min back to pytest; cold runs (new preset / new base SHA) pay a one-time layer build that is shared across subsequent runs.

Verification

  • python3 ci/test_tests_fetcher.py: 16/16 passed.
  • pre-commit run --files ci/torch_latest.py .github/workflows/modal-torch-latest.yml: all hooks passed.
  • Exercised _build_sandbox_image and build_remote_commands against a stub Modal module: layer order is requirements → Torch pin; the runtime chain keeps the guard commands and no longer reinstalls Torch; base_sha falls back to the candidate SHA on push events.
  • Sandbox-equivalent execution still needs a real Modal run (first merge-queue entry after merge will build the layers).

The dependency installs (requirements + the Torch pin) ran inside every
sandbox and consumed roughly eight minutes of the fixed sandbox lifetime,
which the v1 GPU suite now runs against. Bake them into content-addressed
image layers instead: the requirements layer is keyed by the merge-group
base SHA and the Torch layer by the preset, so warm runs skip both. The
runtime pip install -r commands stay as no-op correctness guards for a
candidate branch that changed a requirements file. Layer order keeps the
Torch pin last, preserving the previous guarantee that a transitive
dependency cannot displace the intended CUDA build.

Signed-off-by: Ma, Guokai <guokai.ma@intel.com>
@delock
delock requested a review from loadams as a code owner September 16, 2026 08:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25fb5b7fe3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread ci/torch_latest.py
Comment on lines +487 to +488
# Torch itself is pinned in the image (see _build_sandbox_image), after the requirements
# layers, so a transitive dependency cannot displace the intended CUDA build.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Re-pin Torch after installing candidate requirements

When a merge-group candidate changes any of the three requirements files to require a Torch or Torchvision version incompatible with the selected preset, the runtime pip install -r guards run after the baked Torch layer and can replace that preset. Because the former runtime reinstall is gone, pytest may then run against a different Torch/CUDA stack while still receiving the preset's --torch_ver and --cuda_ver; reapply or validate the pin after the candidate requirements are installed.

Useful? React with 👍 / 👎.

Comment thread ci/torch_latest.py
Comment on lines +412 to +416
image = modal_module.Image.from_registry(preset["image"], add_python="3.10")
image = image.run_commands(
f"python -m pip install -r {requirements_url}/requirements.txt "
f"-r {requirements_url}/requirements-dev.txt -r {requirements_url}/requirements-deepcompile.txt")
return image.pip_install(preset["torch_package"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the controller tests for the image-layer API

Running python3 ci/test_torch_latest.py on this tree regresses from 22/23 in the parent to 18/23: three controller tests now abort here because the fake Image.from_registry result does not implement the newly used run_commands/pip_install chaining contract, and the structural-plan test still requires the removed reinstall Torch packages command. Update the consolidated Modal fake and expectations so these controller paths remain exercised.

AGENTS.md reference: AGENTS.md:L34-L34

Useful? React with 👍 / 👎.

env:
DS_CI_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
DS_CI_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
DS_CI_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || '' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required Signed-off-by trailer

Commit 871569c57da8129205c742de1c13371d8677ee11 is a non-merge commit, but its commit message has no Signed-off-by trailer. This violates the repository's DCO requirement and can cause the commit to be rejected by the DCO gate; recreate it with git commit --signoff.

AGENTS.md reference: AGENTS.md:L8-L8

Useful? React with 👍 / 👎.

@delock
delock added this pull request to the merge queue Sep 16, 2026
Merged via the queue into deepspeedai:master with commit 83dd543 Sep 16, 2026
13 checks passed
@delock
delock deleted the bake-modal-install-layers branch September 16, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants