Serialize hash-pinned dynamo install per node (fix concurrent pip race) - #245
Open
Ankur-singh wants to merge 2 commits into
Open
Serialize hash-pinned dynamo install per node (fix concurrent pip race)#245Ankur-singh wants to merge 2 commits into
Ankur-singh wants to merge 2 commits into
Conversation
_hash_cached_source_install flock-serializes the build but then runs the post-build pip installs on every task/rank. All tasks on a node share the container site-packages, so N concurrent 'pip install --force-reinstall' race on shared dependency files. On containers that pre-ship ai-dynamo's Python deps at conflicting versions (e.g. nvcr.io/nvidia/tensorrt-llm/release), the concurrent uninstall/reinstall fails with 'OSError: [Errno 2] No such file' (e.g. uninstalling typing_extensions) and the job is cancelled. Serialize the post-build pip installs per node with a node-local flock + sentinel in /tmp (site-packages is per node): only the first local task installs, the rest block then skip. Build cache logic unchanged.
Ankur-singh
requested review from
alec-flowers,
csahithi,
ishandhanani and
nlevin-ui
as code owners
July 6, 2026 00:58
_live_source_install_for_top_of_tree has no cache/flock at all: every task clones+builds+pip-installs into shared paths (/sgl-workspace or /tmp, and the container site-packages), so N tasks on a node race on both the build dir and the install. Wrap the whole install in the same node-local flock + sentinel as the hash path (fixed sentinel key since HEAD has no hash) so only the first local task installs and the rest skip.
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.
Problem
srtctl's
dynamo.install: trueruns itspip installs (and, for top-of-tree, the whole clone+build) on every task/rank. With pyxis/enroot, all tasks on a node that share a--container-imageshare one container instance — one rootfs, onesite-packages, one/tmp. So N concurrent installs race on those shared paths.On containers that pre-ship ai-dynamo's Python deps at conflicting versions (e.g.
nvcr.io/nvidia/tensorrt-llm/release, which carries pydantic / pydantic-core / typing-extensions / uvloop for TRT-LLM),--force-reinstalltears those down concurrently and dies:Repro: a Qwen3.5 dynamo-trt disagg sweep on the TRT-LLM rc20 release container (TP2 prefill / TP4 decode → multiple tasks per node) — every worker log shows the doubled
Processing …/ai_dynamo_runtime.whland theOSErrorabove (NVIDIA/InferenceMAX#133).SGLang
dynamo.hashconfigs run the same code path but don't fail: their container doesn't pre-ship those conflicting deps, so--force-reinstallisn't removing shared files out from under a racing sibling.Fix
Serialize the install per node with a node-local
flock+ sentinel in/tmp(site-packages is per node / per container instance): the first local task installs, the rest block on the lock then skip. This is the desired end state anyway — one shared install per node that all ranks import — just without concurrent writers.Both install paths are guarded:
_hash_cached_source_install(dynamo.hash) — the shared/configsbuild-flock is unchanged; the new node-local guard wraps only the post-buildpip installs. Sentinel keyed by hash._live_source_install_for_top_of_tree(dynamo.top_of_tree) — had no flock at all, and both the SGLang and portable branches clone/build/install into shared paths (/sgl-workspaceor/tmp, plus site-packages). The whole install is now wrapped in the same node-local guard. Fixed sentinel key (HEAD has no hash; a container instance only ever installs one top-of-tree build).Successful run: https://github.com/NVIDIA/InferenceMAX/actions/runs/28761452215/job/85277686958?pr=133
Test
Extended
test_hash_install_commandandtest_top_of_tree_install_commandto assert the node-local guard (flock -x 201, the sentinel check/touch, the201>lock file); existing substring assertions still hold.tests/test_configs.pyis fully green (112 passed). Full suite passes except two pre-existing, unrelated console-rendering assertions (test_apply_json::test_apply_without_json_emits_prose_only,test_dry_run::…test_srun_options_shown) that also fail on cleanmainin a narrow terminal.