Skip to content

Add nccl_version to the source-checkout torch_info fallback - #8383

Open
alanhuangyoo wants to merge 2 commits into
deepspeedai:masterfrom
alanhuangyoo:fix/torch-info-nccl-version-fallback
Open

Add nccl_version to the source-checkout torch_info fallback#8383
alanhuangyoo wants to merge 2 commits into
deepspeedai:masterfrom
alanhuangyoo:fix/torch-info-nccl-version-fallback

Conversation

@alanhuangyoo

Copy link
Copy Markdown
Contributor

Running the unit tests from a source checkout — one that was not pip installed, so
git_version_info_installed.py does not exist — fails before any test body runs:

FAILED unit/runtime/zero/test_zero_tensor_fragment.py::TestTensorFragmentSet::test_zero_fragments[none-1-local-dtype0]
    - KeyError: 'nccl_version'

setup.py:292 writes five keys:

torch_info = {
    "version": torch_version,
    "bf16_support": bf16_support,
    "cuda_version": cuda_version,
    "nccl_version": nccl_version,
    "hip_version": hip_version,
}

and the fallback in deepspeed/git_version_info.py:22 lists three:

torch_info = {'version': "0.0", "cuda_version": "0.0", "hip_version": "0.0"}

tests/unit/util.py reads nccl_version on the way into bf16_required_version_check:

if torch_info['nccl_version'] == '0.0':
    # Use runtime NCCL version if available

The "0.0" is a sentinel — the reader's own comment says so, and version, cuda_version and
hip_version all carry it for exactly that reason. nccl_version was left out, so instead of
taking the runtime-detection branch the lookup raises.

The change

Add the missing key with the same sentinel the other three use, so the reader takes the fallback
it was written to take.

Not adding bf16_support, the other key setup.py writes and this dict omits: nothing reads it
off torch_info today (get_accelerator().is_bf16_supported() is used instead), and there is no
established sentinel for a bool the way "0.0" is for a version. Happy to add it if you would
rather the two dicts match key-for-key.

Verification

Reproduced on both a CPU checkout and 2×H100:

# upstream/master, source checkout
>>> from unit.util import bf16_required_version_check; bf16_required_version_check()
KeyError: 'nccl_version'

# this branch
>>> bf16_required_version_check()
False        # no CUDA on that box, which is the correct answer

On 2 GPUs, unit/runtime/zero/test_zero_tensor_fragment.py:

master        19 failures, all  KeyError: 'nccl_version'
this branch    0 occurrences of nccl_version anywhere in the log

The failures that remain in my environment are all Unable to JIT load the {cpu_adam,fused_adam} op due to ninja not being installed — a missing build tool on that box, unrelated to this
change and present identically before and after.

yapf==0.40.0 --diff    (no diff)

setup.py writes version, bf16_support, cuda_version, nccl_version and
hip_version into git_version_info_installed. The fallback used when that
module is absent - any source checkout that was not pip-installed - listed
only three of them, so reading torch_info['nccl_version'] raised KeyError
instead of taking the '0.0' runtime-detection path the readers expect.

tests/unit/util.py:50 reads it on the way into bf16_required_version_check,
so every test that goes through there fails to even reach its body.

Signed-off-by: alanhuangyoo <alanhuangyoo@gmail.com>
@alanhuangyoo

Copy link
Copy Markdown
Contributor Author

While verifying this on 2 GPUs I hit a second symptom of the same degenerate source-checkout
version info, in case you want to handle both together. Not touching it in this PR.

unit/sequence_parallelism/test_ulysses.py::TestUlyssesCheckpointLoad::test_load_non_sequence_parallel_checkpoint:

deepspeed/runtime/zero/stage_1_and_2.py:2787, in _load_global_state
    assert required_version <= ckpt_version, f"Old version: {ckpt_version} {error_str}"
AssertionError: Old version: 0.0.0 ZeRO stage 1 changed in 0.3.17 and is not backwards
compatible with older stage 1 checkpoints.

stage_1_and_2.py:2639 stamps the checkpoint with version from git_version_info, which on a
source checkout is the "0.0.0" fallback. _load_global_state then parses it and compares
0.3.17 <= 0.0.0, so ZeRO-1 refuses to load a checkpoint the same build just wrote. It is
deterministic, not flaky.

No released DeepSpeed ever reported 0.0.0, so that value only ever means "this build does not
know its own version" rather than "very old checkpoint" — the same reading the "0.0" sentinel
gets elsewhere. Happy to send a follow-up that skips the comparison for it, if you agree that is
the right treatment.

For reference, the sweep those two came out of: unit/runtime/zero/,
unit/sequence_parallelism/, unit/sequence/, unit/v1/moe/, unit/ulysses_alst/ on 2 GPUs —
477 passed, 49 failed, and every failure except this one was CUDAMismatchException from my own
toolkit/torch mismatch.

@delock
delock self-requested a review September 1, 2026 10:46
Comment thread deepspeed/git_version_info.py Outdated
accelerator_name = ""
torch_info = {'version': "0.0", "cuda_version": "0.0", "hip_version": "0.0"}
# Keys must match what setup.py writes into git_version_info_installed, and "0.0" is the
# sentinel readers check to fall back to runtime detection. nccl_version was missing, so

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

“nccl_version was missing, so
# reading it off a source checkout raised KeyError instead of taking that fallback.”
This needs to be removed since its the reason to make the change, but not necessary after the change.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed — removed. Kept the part that describes the contract (keys have to match what setup.py writes into git_version_info_installed, and "0.0" is the sentinel readers check), since that is what someone editing this dict next needs to know. The reason for the change now lives only in the PR description and commit message.

Why the key was added belongs in the PR, not in a comment that outlives it.
The part describing the contract - keys must match what setup.py writes, and
"0.0" is the fallback sentinel - stays.

Signed-off-by: alanhuangyoo <alanhuangyoo@gmail.com>
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