[deps] 6/n towards Kimi K2.6: CUDA-13 deploy stack for Blackwell-Ultra (sm103 / B300) - #2028
[deps] 6/n towards Kimi K2.6: CUDA-13 deploy stack for Blackwell-Ultra (sm103 / B300)#2028casper-hansen wants to merge 2 commits into
Conversation
…a (sm103 / B300) The cu12x vLLM wheels ship sm_100a/sm_120a SASS only (no sm103, no PTX), so every compiled vLLM kernel fails with 'no kernel image is available' on B300. Under CUDA 13, plain sm_100 cubins are family-compatible with sm103 (verified by driver-loading the PyPI wheel's cubins on a B300), and TE's cu13 core ships explicit sm_103a kernels. uv cannot express a default-preserving CUDA-variant extra in one project (extra/group markers do not bind in sources or overrides, group-scoped sources force the variant packages into default groups, and a sub-project wrapper inherits the parent's source mappings), so the Blackwell-Ultra stack ships as deploy/cuda13/: a uv-exported pinned requirements file, the mirrored override set for the uv pip interface, and a three-phase installer that handles the sdist builds (transformer-engine-torch needs an in-tree build for its vendored build_tools helper). CUDA-12 defaults (pyproject.toml, uv.lock) are untouched. Notable pins: torch 2.11.0+cu130 (PyPI default), vllm 0.23.0 (the PyPI wheel is the CUDA-13 build and runs B300 via sm_100 family-compatible cubins), TE core cu13, flashinfer-jit-cache cu130, causal-conv1d / mamba-ssm from sdist, flash-attn removed (no torch-2.11/cu13 wheels; a CUDA-less stub crashes TE -- TE uses cuDNN fused attention and HF models fall back to SDPA). Verified on B300: a from-scratch install resolves to a package set identical to the uv.lock-managed venv that completed multi-step GRPO training, and the Kimi bridge GPU tests pass 3/3 against it. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a CUDA-13 stack deployment configuration tailored for Blackwell-Ultra GPUs (sm103), including installation scripts, dependency overrides, and pinned requirements. The review feedback focuses on improving the robustness of the deployment scripts: specifically, checking for an empty 'TE_TORCH_VERSION' and using the '-f' flag with 'curl' in 'install.sh' to handle network failures gracefully, as well as explicitly specifying 'utf-8' encoding when opening files in the Python block of 'regenerate.sh' to ensure cross-platform compatibility.
| TE_TORCH_VERSION="$(sed -n 's/^transformer-engine-torch==\([0-9.]*\).*/\1/p' "$REQ" | head -1)" | ||
| SDIST_URL="$(curl -sL "https://pypi.org/pypi/transformer-engine-torch/$TE_TORCH_VERSION/json" \ | ||
| | "$PY" -c "import json,sys; print([u['url'] for u in json.load(sys.stdin)['urls'] if u['packagetype']=='sdist'][0])")" | ||
| curl -sL "$SDIST_URL" | tar xz |
There was a problem hiding this comment.
To improve robustness and error diagnostics:
- Check if
TE_TORCH_VERSIONis empty: Iftransformer-engine-torchis missing or formatted differently inrequirements-megatron.txt,TE_TORCH_VERSIONwill be empty, leading to an invalid PyPI API request. - Use
curl -sfSLinstead ofcurl -sL: By default,curlexits with status0even on HTTP errors (like 404 or 500). Adding the-f/--failflag ensurescurlexits with a non-zero status code on failure, which triggerspipefailandset -eto halt the script immediately with a clear exit code rather than passing empty/HTML content to Python ortar.
| TE_TORCH_VERSION="$(sed -n 's/^transformer-engine-torch==\([0-9.]*\).*/\1/p' "$REQ" | head -1)" | |
| SDIST_URL="$(curl -sL "https://pypi.org/pypi/transformer-engine-torch/$TE_TORCH_VERSION/json" \ | |
| | "$PY" -c "import json,sys; print([u['url'] for u in json.load(sys.stdin)['urls'] if u['packagetype']=='sdist'][0])")" | |
| curl -sL "$SDIST_URL" | tar xz | |
| TE_TORCH_VERSION="$(sed -n 's/^transformer-engine-torch==\\([0-9.]*\\).*/\\1/p' "$REQ" | head -1)" | |
| if [ -z "$TE_TORCH_VERSION" ]; then | |
| echo "Error: Could not extract transformer-engine-torch version from $REQ" >&2 | |
| exit 1 | |
| fi | |
| SDIST_URL="$(curl -sfSL "https://pypi.org/pypi/transformer-engine-torch/$TE_TORCH_VERSION/json" \\ | |
| | "$PY" -c "import json,sys; print([u['url'] for u in json.load(sys.stdin)['urls'] if u['packagetype']=='sdist'][0])")" | |
| curl -sfSL "$SDIST_URL" | tar xz |
There was a problem hiding this comment.
Done in 60a9c6d — empty-pin check with a clear error, and curl -sfSL on both fetches so HTTP errors stop the script instead of piping error pages into python/tar.
| path = sys.argv[1] | ||
| lines = open(path).read().splitlines(True) | ||
| out, skip_via = [], False | ||
| for line in lines: | ||
| # Only the flashinfer cu130 index is used by these pins; other emitted | ||
| # extra indexes (cu128/cu129/...) would reintroduce ambiguity. | ||
| if line.startswith("--extra-index-url") and "flashinfer.ai/whl/cu130" not in line: | ||
| continue | ||
| # The editable gym path is cwd-sensitive; install.sh installs it (and | ||
| # skyrl itself) explicitly with absolute paths instead. | ||
| if line.startswith("-e ./skyrl-gym"): | ||
| skip_via = True | ||
| continue | ||
| if skip_via and line.strip().startswith("# via"): | ||
| skip_via = False | ||
| continue | ||
| skip_via = False | ||
| out.append(line) | ||
| open(path, "w").writelines(out) |
There was a problem hiding this comment.
Specify encoding="utf-8" when opening files in Python. This ensures cross-platform consistency and prevents potential UnicodeDecodeError on environments where the default system locale encoding is not UTF-8 (e.g., some minimal Docker containers or Windows environments).
| path = sys.argv[1] | |
| lines = open(path).read().splitlines(True) | |
| out, skip_via = [], False | |
| for line in lines: | |
| # Only the flashinfer cu130 index is used by these pins; other emitted | |
| # extra indexes (cu128/cu129/...) would reintroduce ambiguity. | |
| if line.startswith("--extra-index-url") and "flashinfer.ai/whl/cu130" not in line: | |
| continue | |
| # The editable gym path is cwd-sensitive; install.sh installs it (and | |
| # skyrl itself) explicitly with absolute paths instead. | |
| if line.startswith("-e ./skyrl-gym"): | |
| skip_via = True | |
| continue | |
| if skip_via and line.strip().startswith("# via"): | |
| skip_via = False | |
| continue | |
| skip_via = False | |
| out.append(line) | |
| open(path, "w").writelines(out) | |
| path = sys.argv[1] | |
| lines = open(path, encoding="utf-8").read().splitlines(True) | |
| out, skip_via = [], False | |
| for line in lines: | |
| # Only the flashinfer cu130 index is used by these pins; other emitted | |
| # extra indexes (cu128/cu129/...) would reintroduce ambiguity. | |
| if line.startswith("--extra-index-url") and "flashinfer.ai/whl/cu130" not in line: | |
| continue | |
| # The editable gym path is cwd-sensitive; install.sh installs it (and | |
| # skyrl itself) explicitly with absolute paths instead. | |
| if line.startswith("-e ./skyrl-gym"): | |
| skip_via = True | |
| continue | |
| if skip_via and line.strip().startswith("# via"): | |
| skip_via = False | |
| continue | |
| skip_via = False | |
| out.append(line) | |
| open(path, "w", encoding="utf-8").writelines(out) |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 5902652. Configure here.
…sed venvs - Remove flash-attn / transformer-engine-cu12 / nixl-cu12 from a reused venv up front: the pinned set never mentions them, so no install step would replace them, and they are exactly the packages this stack must exclude (TE-crashing stub / libtransformer_engine.so collision). - Fail fast when the transformer-engine-torch pin cannot be extracted, and make curl fail on HTTP errors (-sfSL) instead of piping error pages into python/tar. - Explicit utf-8 in regenerate.sh's rewrite helper. Co-authored-by: Cursor <cursoragent@cursor.com>

What
Ships the Blackwell-Ultra (sm103 / B300) dependency stack as
deploy/cuda13/: a uv-exported pinned requirements file, the mirrored override set for the uv pip interface, and a three-phase installer that handles the sdist builds (transformer-engine-torch needs an in-tree build for its vendored build_tools helper). CUDA-12 defaults (pyproject.toml,uv.lock) are untouched.Why
The cu12x vLLM wheels ship sm_100a/sm_120a SASS only (no sm103, no PTX), so every compiled vLLM kernel fails with "no kernel image is available" on B300. Under CUDA 13, plain sm_100 cubins are family-compatible with sm103 (verified by driver-loading the PyPI wheel's cubins on a B300), and TE's cu13 core ships explicit sm_103a kernels.
A default-preserving CUDA-variant extra cannot be expressed in one uv project (extra/group markers do not bind in sources or overrides, group-scoped sources force the variant packages into default groups, and a sub-project wrapper inherits the parent's source mappings), hence a deploy manifest.
Notable pins: torch 2.11.0+cu130 (PyPI default), vllm 0.23.0 (PyPI wheel is the CUDA-13 build), TE core cu13, flashinfer-jit-cache cu130, causal-conv1d / mamba-ssm from sdist, flash-attn removed (no torch-2.11/cu13 wheels; a CUDA-less stub crashes TE -- TE uses cuDNN fused attention and HF models fall back to SDPA).
Verified on B300: a from-scratch install resolves to a package set identical to the uv.lock-managed venv that completed multi-step GRPO training; Kimi bridge GPU tests pass 3/3 against it.
Part of the Kimi K2.x series (follow-up to #1862). Independent of the other PRs in the series.
Made with Cursor