install: tighten comments

This commit is contained in:
Daniel Han 2026-07-14 13:43:44 +00:00
commit 8a2389c5dc
3 changed files with 38 additions and 53 deletions

View file

@ -326,11 +326,8 @@ cu130onlytorch291 = [
"xformers @ https://download.pytorch.org/whl/cu130/xformers-0.0.33.post2-cp39-abi3-win_amd64.whl ; (sys_platform == 'win32')",
]
cu126onlytorch2100 = [
# The explicit torch pin replicates the xformers 0.0.34 wheel's transitive
# torch==2.10.0 pin on machines where the x86-64-only wheel is skipped
# (Linux aarch64 has real 2.10.0 wheels; Windows ARM64 fails loudly).
# Without it an ARM64 install of the cu126-torch2100 wrapper would proceed
# unpinned and resolve a newer torch.
# Pin torch so ARM64 installs (x86-64-only xformers wheel and its transitive
# torch pin skipped) stay on 2.10 instead of resolving newer.
"torch==2.10.0",
"xformers @ https://download.pytorch.org/whl/cu126/xformers-0.0.34-cp39-abi3-manylinux_2_28_x86_64.whl ; ('linux' in sys_platform) and (platform_machine == 'AMD64' or platform_machine == 'x86_64')",
"xformers @ https://download.pytorch.org/whl/cu126/xformers-0.0.34-cp39-abi3-win_amd64.whl ; (sys_platform == 'win32') and (platform_machine == 'AMD64' or platform_machine == 'x86_64')",
@ -348,14 +345,9 @@ cu130onlytorch2100 = [
"xformers @ https://download.pytorch.org/whl/cu130/xformers-0.0.34-cp39-abi3-win_amd64.whl ; (sys_platform == 'win32') and (platform_machine == 'AMD64' or platform_machine == 'x86_64')",
]
cu126onlytorch2110 = [
# xformers 0.0.35 does not hard-pin torch the way 0.0.34 pinned torch==2.10.0,
# so the torch 2.11 trio is pinned explicitly. Use the +cu126 LOCAL build, not
# a bare torch>=2.11: torch 2.11's default PyPI wheel is CUDA 13.0 (2.10 was
# CUDA 12.x), so a bare resolve would pair a cu130 torch with the cu126
# xformers below and fail at import. The +cu126 label only resolves from the
# matching download.pytorch.org/whl/cu126 index the installer configures, so
# torch stays on the same CUDA as xformers (or fails loudly if that index is
# absent) instead of silently mismatching.
# xformers 0.0.35 does not pin torch, so pin the trio to the +cu126 local
# build: torch 2.11 defaults to a CUDA-13 PyPI wheel, and only the +cu126 tag
# resolves from the cu126 index alongside the cu126 xformers below.
"torch==2.11.0+cu126",
"torchvision==0.26.0+cu126",
"torchaudio==2.11.0+cu126",
@ -363,9 +355,8 @@ cu126onlytorch2110 = [
"xformers @ https://download.pytorch.org/whl/cu126/xformers-0.0.35-py39-none-win_amd64.whl ; (sys_platform == 'win32') and (platform_machine == 'AMD64' or platform_machine == 'x86_64')",
]
cu128onlytorch2110 = [
# +cu128 local build for the same reason as cu126onlytorch2110 above: torch
# 2.11's default PyPI wheel is CUDA 13.0, so pin to the cu128 index to keep the
# torch trio on the same CUDA as the cu128 xformers wheel.
# Same +cuNNN pin as cu126onlytorch2110: keeps the trio on the cu128 index
# instead of torch 2.11's CUDA-13 PyPI default.
"torch==2.11.0+cu128",
"torchvision==0.26.0+cu128",
"torchaudio==2.11.0+cu128",
@ -373,13 +364,9 @@ cu128onlytorch2110 = [
"xformers @ https://download.pytorch.org/whl/cu128/xformers-0.0.35-py39-none-win_amd64.whl ; (sys_platform == 'win32') and (platform_machine == 'AMD64' or platform_machine == 'x86_64')",
]
cu130onlytorch2110 = [
# Pinned to the +cu130 local build like the cu126/cu128 extras: a bare range
# lets a configured CUDA-12 extra index win (PEP 440 ranks 2.11.0+cu126 above
# the unlabelled 2.11.0), and a ===2.11.0 pin would force-replace the trio on
# machines installed from the official cu130 index (whose wheels carry the
# +cu130 local tag). The exact +cu130 pins accept the official cu130-index
# install as-is and fail loudly anywhere the cu130 index is missing;
# _auto_install.py appends the matching index for every torch2110 CUDA extra.
# Same +cuNNN pin as the cu126/cu128 extras: a bare range lets a CUDA-12 index
# win (PEP 440 ranks +cu126 above unlabelled 2.11.0) and ===2.11.0 would
# force-replace official cu130-index installs. _auto_install.py adds the index.
"torch==2.11.0+cu130",
"torchvision==0.26.0+cu130",
"torchaudio==2.11.0+cu130",

View file

@ -1,13 +1,24 @@
# Unsloth Zoo - Utilities for Unsloth
# Copyright 2023-present Daniel Han-Chen, Michael Han-Chen & the Unsloth team. All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Regression guard for the CUDA torch2110 optional-dependency extras.
torch 2.11's DEFAULT PyPI wheel is CUDA 13.0 (torch 2.10 defaulted to CUDA 12.x).
So the CUDA-12 `cuXXXonlytorch2110` extras must pin the torch trio to the matching
`+cuXXX` local build; a bare `torch>=2.11` there would resolve a cu130 torch from
PyPI alongside the cu126/cu128 xformers wheel and fail at import. The cu130 extra is
pinned to +cu130 too: a bare or ===-pinned spec either lets a foreign CUDA index
outrank the intended wheel or force-replaces official cu130-index installs.
Hermetic: only parses pyproject.toml, no network or install.
The cuXXXonlytorch2110 extras must pin the torch trio to the matching +cuXXX local
build (torch 2.11 defaults to a CUDA-13 PyPI wheel), or resolution mismatches the
xformers wheel. Hermetic: only parses pyproject.toml, no network or install.
"""
from __future__ import annotations
@ -17,7 +28,7 @@ from pathlib import Path
import pytest
from packaging.requirements import Requirement
try: # tomllib is stdlib on Python 3.11+; older interpreters need the tomli backport.
try: # tomllib is stdlib on 3.11+; older interpreters need the tomli backport.
import tomllib
except ModuleNotFoundError: # pragma: no cover - Python 3.9 / 3.10
tomllib = pytest.importorskip("tomli")
@ -33,9 +44,7 @@ def _extra(name: str) -> list[str]:
def _reqs(specs: list[str]) -> dict[str, list[Requirement]]:
# Keyed by name -> list: each extra carries one Linux and one Windows
# xformers requirement, so a plain name -> Requirement dict would silently
# drop the Linux entry.
# name -> list: each extra has one Linux and one Windows xformers requirement.
out: dict[str, list[Requirement]] = {}
for spec in specs:
r = Requirement(spec)
@ -45,9 +54,7 @@ def _reqs(specs: list[str]) -> dict[str, list[Requirement]]:
@pytest.mark.parametrize("cuda", ["cu126", "cu128", "cu130"])
def test_cuda12_torch2110_pins_matching_local_build(cuda: str):
# Each of torch/torchvision/torchaudio must pin the exact +cuXXX local build
# so it can only resolve from the matching PyTorch CUDA index, never the
# CUDA-13 default on PyPI.
# Each trio member must pin the exact +cuXXX local build.
reqs = _reqs(_extra(f"{cuda}onlytorch2110"))
for pkg in _TORCH_TRIO:
(req,) = reqs[pkg]
@ -65,9 +72,7 @@ def test_cuda12_torch2110_pins_matching_local_build(cuda: str):
assert (
f"/whl/{cuda}/xformers-0.0.35-" in r.url
), f"xformers not on the {cuda} index: {r.url}"
# The wheels are x86-64 only, so the markers must exclude other machines
# (e.g. Linux aarch64 such as GB200/DGX Spark, Windows ARM64) where the
# torch trio resolves fine but these wheels would abort the install.
# x86-64-only wheels: markers must exclude aarch64 / ARM64.
assert r.marker is not None
assert not r.marker.evaluate({"sys_platform": "linux", "platform_machine": "aarch64"})
assert not r.marker.evaluate({"sys_platform": "win32", "platform_machine": "ARM64"})
@ -78,8 +83,7 @@ def test_cuda12_torch2110_pins_matching_local_build(cuda: str):
@pytest.mark.parametrize("cuda", ["cu126", "cu128", "cu130"])
@pytest.mark.parametrize("variant", ["", "ampere-"])
def test_torch2110_wrapper_references_matching_leaf(cuda: str, variant: str):
# The six public wrappers must pull in the usual huggingface + bitsandbytes
# pair and reference the internal leaf of the SAME CUDA version.
# Wrappers pull huggingface + bitsandbytes and the leaf of the same CUDA version.
specs = _extra(f"{cuda}-{variant}torch2110")
assert specs == [
"unsloth[huggingface]",
@ -90,11 +94,8 @@ def test_torch2110_wrapper_references_matching_leaf(cuda: str, variant: str):
@pytest.mark.parametrize("cuda", ["cu126", "cu128", "cu130"])
def test_cuda12_torch2100_keeps_torch_pinned_off_x86(cuda: str):
# The torch2100 leaves used to rely on the xformers 0.0.34 wheel's transitive
# torch==2.10.0 pin. Now that the x86-64-only wheels carry platform_machine
# markers, the leaf must pin torch explicitly so an ARM64 install stays on
# torch 2.10 (Linux aarch64 wheels exist) or fails loudly (Windows ARM64)
# instead of resolving an unpinned newer torch.
# Now the xformers wheels carry x86-64 markers, the leaf must pin torch
# explicitly so ARM64 installs stay on 2.10 instead of resolving newer.
reqs = _reqs(_extra(f"{cuda}onlytorch2100"))
(torch_req,) = reqs["torch"]
assert str(torch_req.specifier) == "==2.10.0", (

View file

@ -42,10 +42,7 @@ else: raise RuntimeError(f"Torch = {v} too new!")
if v > V('2.6.9') and cuda not in ("11.8", "12.6", "12.8", "13.0"): raise RuntimeError(f"CUDA = {cuda} not supported!")
if v >= V('2.10.0') and cuda not in ("12.6", "12.8", "13.0"): raise RuntimeError(f"Torch = {v} requires CUDA 12.6, 12.8, or 13.0! Got CUDA = {cuda}")
x = x.format(cuda.replace(".", ""), "-ampere" if False else "") # is_ampere is broken due to flash-attn
# The CUDA torch2110 extras pin the torch trio to the exact +cuNNN local build,
# which only resolves from the matching PyTorch CUDA index (a bare spec would let
# a configured foreign CUDA index outrank the intended wheel, since PEP 440 ranks
# any local build above the unlabelled release), so add that index for every
# CUDA torch 2.11 environment.
# The torch2110 extras pin the trio to +cuNNN local builds, which only resolve
# from the matching PyTorch CUDA index, so add that index for torch 2.11.
extra_index = f' --extra-index-url https://download.pytorch.org/whl/cu{cuda.replace(".", "")}' if (x.endswith('-torch2110') and cuda in ("12.6", "12.8", "13.0")) else ''
print(f'pip install --upgrade pip setuptools wheel && pip install --no-deps git+https://github.com/unslothai/unsloth-zoo.git && pip install "unsloth[{x}] @ git+https://github.com/unslothai/unsloth.git" --no-build-isolation{extra_index}')