diff --git a/install.ps1 b/install.ps1 index 5d70be4b4d..bb52ba58ab 100644 --- a/install.ps1 +++ b/install.ps1 @@ -255,30 +255,53 @@ function Install-UnslothStudio { return $null } - # Map a detected HIP SDK version to Radeon's Windows torch wheels. - # Returns @{ Torch = ...; Torchvision = ...; Torchaudio = ... } or $null - # when the version is unsupported. Wheels are cp312 only. + # Map a ROCm release version to the full Radeon Windows wheel set. + # Returns @{ SdkCore, SdkDevel, SdkLibraries, SdkTarball, Torch, + # Torchvision, Torchaudio } or $null when unsupported. AMD's docs at + # rocm.docs.amd.com/projects/radeon-ryzen/.../install-pytorch.html + # require a two-step install: first the rocm_sdk_* wheels (~1.4 GB; + # ship the runtime that torch links against), then torch itself. Both + # are mandatory -- torch import fails with missing DLLs otherwise. + # Wheels are cp312 only. function Get-RocmWheelUrls { param([Parameter(Mandatory = $true)]$Version) $base721 = 'https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/' $base711 = 'https://repo.radeon.com/rocm/windows/rocm-rel-7.1.1/' if ($Version.Major -eq 7 -and $Version.Minor -eq 2) { return @{ - Torch = $base721 + 'torch-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' - Torchvision = $base721 + 'torchvision-0.24.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' - Torchaudio = $base721 + 'torchaudio-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' + SdkCore = $base721 + 'rocm_sdk_core-7.2.1-py3-none-win_amd64.whl' + SdkDevel = $base721 + 'rocm_sdk_devel-7.2.1-py3-none-win_amd64.whl' + SdkLibraries = $base721 + 'rocm_sdk_libraries_custom-7.2.1-py3-none-win_amd64.whl' + SdkTarball = $base721 + 'rocm-7.2.1.tar.gz' + Torch = $base721 + 'torch-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' + Torchvision = $base721 + 'torchvision-0.24.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' + Torchaudio = $base721 + 'torchaudio-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' } } if ($Version.Major -eq 7 -and $Version.Minor -eq 1) { + # 7.1.1 stamps SDK wheels with `0.1.dev0`; torch gets rocmsdk date tag. return @{ - Torch = $base711 + 'torch-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' - Torchvision = $base711 + 'torchvision-0.24.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' - Torchaudio = $base711 + 'torchaudio-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' + SdkCore = $base711 + 'rocm_sdk_core-0.1.dev0-py3-none-win_amd64.whl' + SdkDevel = $base711 + 'rocm_sdk_devel-0.1.dev0-py3-none-win_amd64.whl' + SdkLibraries = $base711 + 'rocm_sdk_libraries_custom-0.1.dev0-py3-none-win_amd64.whl' + SdkTarball = $base711 + 'rocm-0.1.dev0.tar.gz' + Torch = $base711 + 'torch-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' + Torchvision = $base711 + 'torchvision-0.24.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' + Torchaudio = $base711 + 'torchaudio-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' } } return $null } + # Default Windows ROCm release when HIP_PATH is absent. HIP_PATH is an + # optional hint, NOT a prerequisite -- regular torch users only need + # an AMD graphics driver (26.2.2+ for 7.2.1) and Python 3.12. PyTorch + # does not publish Windows ROCm wheels on download.pytorch.org (see + # the "ROCm is not available on Windows" note on pytorch.org), so + # repo.radeon.com is the only source until pytorch/pytorch#159520 + # lands upstream Windows ROCm hosting in a future release. + $DefaultWindowsRocmVersion = @{ Major = 7; Minor = 2 } + function New-StudioShortcuts { param( [Parameter(Mandatory = $true)][string]$UnslothExePath @@ -646,9 +669,12 @@ shell.Run cmd, 0, False # users with both cards get the NVIDIA torch path they expect. if ($HasNvidiaSmi) { $HasAmdGpu = $false } - # Resolve HIP SDK when we are taking the AMD path. We still probe here - # even when $HasAmdGpu is $false so the status line is informative on - # mixed NVIDIA+AMD hosts. + # Probe HIP SDK as an OPTIONAL version hint. The HIP SDK developer + # toolkit is NOT a prerequisite for running torch on Windows -- AMD's + # install docs only require the graphics driver (26.2.2+ for 7.2.1) + # and Python 3.12. We use $HipSdkVersion when present to select a + # matching ROCm wheel release; otherwise we fall back to the newest + # stable release ($DefaultWindowsRocmVersion). $HipSdkVersion = $null if ($HasAmdGpu) { $HipSdkVersion = Get-HipSdkVersion @@ -658,11 +684,11 @@ shell.Run cmd, 0, False step "gpu" "NVIDIA GPU detected" } elseif ($HasAmdGpu) { if ($HipSdkVersion) { - step "gpu" ("AMD GPU detected (HIP SDK {0}.{1})" -f $HipSdkVersion.Major, $HipSdkVersion.Minor) + step "gpu" ("AMD GPU detected (HIP SDK {0}.{1} hint)" -f $HipSdkVersion.Major, $HipSdkVersion.Minor) } else { - step "gpu" "AMD GPU detected (HIP SDK missing)" "Yellow" - substep "Install HIP SDK from https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html" "Yellow" - substep "and re-run this installer." "Yellow" + step "gpu" ("AMD GPU detected (will use rocm-rel-{0}.{1}.x)" -f $DefaultWindowsRocmVersion.Major, $DefaultWindowsRocmVersion.Minor) + substep "HIP SDK not found (optional). Ensure AMD graphics driver is up to date:" "DarkGray" + substep "https://www.amd.com/en/support/download/drivers.html" "DarkGray" } } else { step "gpu" "none (chat-only / GGUF)" "Yellow" @@ -925,12 +951,26 @@ shell.Run cmd, 0, False # The AMD/ROCm path does not use a --index-url; instead it installs # explicit wheel URLs from repo.radeon.com. $TorchIndexUrl stays $null - # on that branch so the NVIDIA/CPU path is visibly bypassed. + # on that branch so the NVIDIA/CPU path is visibly bypassed. HIP_PATH + # is a hint only -- we fall back to $DefaultWindowsRocmVersion when + # it is absent or points at an unsupported version, because the HIP + # SDK is NOT a runtime prerequisite for torch on Windows. $TorchIndexUrl = $null $RocmWheelUrls = $null + $RocmReleaseVersion = $null if ($HasAmdGpu) { if ($HipSdkVersion) { $RocmWheelUrls = Get-RocmWheelUrls -Version $HipSdkVersion + if ($RocmWheelUrls) { + $RocmReleaseVersion = $HipSdkVersion + } + } + if (-not $RocmWheelUrls) { + if ($HipSdkVersion) { + substep ("HIP SDK {0}.{1} is too old; falling back to rocm-rel-{2}.{3}.x" -f $HipSdkVersion.Major, $HipSdkVersion.Minor, $DefaultWindowsRocmVersion.Major, $DefaultWindowsRocmVersion.Minor) "Yellow" + } + $RocmWheelUrls = Get-RocmWheelUrls -Version $DefaultWindowsRocmVersion + $RocmReleaseVersion = $DefaultWindowsRocmVersion } } else { $TorchIndexUrl = Get-TorchIndexUrl @@ -1008,26 +1048,57 @@ shell.Run cmd, 0, False if ($SkipTorch) { substep "skipping PyTorch (--no-torch flag set)." "Yellow" } elseif (-not $RocmWheelUrls) { - if (-not $HipSdkVersion) { - Write-Host "[ERROR] AMD GPU detected but HIP SDK is not installed." -ForegroundColor Red - Write-Host " Download it from https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html" -ForegroundColor Yellow - Write-Host " and re-run this installer." -ForegroundColor Yellow - } else { - Write-Host "[ERROR] AMD HIP SDK $($HipSdkVersion.Major).$($HipSdkVersion.Minor) detected." -ForegroundColor Red - Write-Host " Unsloth requires HIP SDK 7.1 or later on Windows. Please update from" -ForegroundColor Yellow - Write-Host " https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html" -ForegroundColor Yellow - } + # Should be unreachable because the detection block above + # always falls back to $DefaultWindowsRocmVersion, but guard + # anyway so a future refactor that drops the fallback does + # not install CPU torch on an AMD host. + Write-Host "[ERROR] Could not resolve Windows ROCm wheel URLs." -ForegroundColor Red + Write-Host " This is a bug; please file it at github.com/unslothai/unsloth/issues" -ForegroundColor Yellow return } else { - substep "installing PyTorch ROCm wheels from repo.radeon.com..." - substep "(first wheel is ~780 MB; download may take a few minutes)" + # Verify the venv's Python is 3.12 -- Radeon's wheels are cp312 + # only and pip would fail with a confusing error otherwise. + $venvPyVer = '' + try { + $venvPyVer = (& $VenvPython -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" 2>$null | Out-String).Trim() + } catch {} + if ($venvPyVer -and $venvPyVer -ne "3.12") { + Write-Host "[ERROR] Radeon Windows ROCm wheels require Python 3.12 (venv has $venvPyVer)." -ForegroundColor Red + Write-Host " Install Python 3.12 from https://www.python.org/downloads/ and re-run." -ForegroundColor Yellow + return + } + + substep ("installing Radeon ROCm wheels for rocm-rel-{0}.{1}.x ..." -f $RocmReleaseVersion.Major, $RocmReleaseVersion.Minor) + substep "Step 1/2: ROCm SDK runtime (~1.4 GB -- this will take a while)" + # Use python -m pip (NOT uv) because (a) AMD's documented + # procedure uses pip, (b) uv has known wheel-corruption issues + # on these big ROCm/bnb wheels (unslothai/unsloth#4966), and + # (c) pip's dep resolver is the combination AMD validates. We + # install all four SDK artefacts in one command so pip does + # not reset torch between them. + $sdkInstallExit = Invoke-InstallCommand { + & $VenvPython -m pip install --no-cache-dir --force-reinstall ` + $RocmWheelUrls.SdkCore ` + $RocmWheelUrls.SdkDevel ` + $RocmWheelUrls.SdkLibraries ` + $RocmWheelUrls.SdkTarball + } + if ($sdkInstallExit -ne 0) { + Write-Host "[ERROR] Failed to install ROCm SDK wheels (exit code $sdkInstallExit)" -ForegroundColor Red + Write-Host " Verify your AMD graphics driver is recent and repo.radeon.com is reachable." -ForegroundColor Yellow + return + } + + substep "Step 2/2: PyTorch + torchvision + torchaudio (~820 MB)" $torchInstallExit = Invoke-InstallCommand { - uv pip install --python $VenvPython ` - $RocmWheelUrls.Torch $RocmWheelUrls.Torchvision $RocmWheelUrls.Torchaudio + & $VenvPython -m pip install --no-cache-dir --force-reinstall ` + $RocmWheelUrls.Torch ` + $RocmWheelUrls.Torchvision ` + $RocmWheelUrls.Torchaudio } if ($torchInstallExit -ne 0) { Write-Host "[ERROR] Failed to install ROCm PyTorch (exit code $torchInstallExit)" -ForegroundColor Red - Write-Host " Verify HIP SDK $($HipSdkVersion.Major).$($HipSdkVersion.Minor) is installed and wheels are reachable." -ForegroundColor Yellow + Write-Host " Update your AMD graphics driver: https://www.amd.com/en/support/download/drivers.html" -ForegroundColor Yellow return } } diff --git a/studio/install_python_stack.py b/studio/install_python_stack.py index 8aa050ad53..d087a4a098 100644 --- a/studio/install_python_stack.py +++ b/studio/install_python_stack.py @@ -43,9 +43,23 @@ _ROCM_TORCH_INDEX: dict[tuple[int, int], str] = { } _PYTORCH_WHL_BASE = "https://download.pytorch.org/whl" -# Windows AMD ROCm torch wheels live at repo.radeon.com, not download.pytorch.org. -# Keyed by HIP SDK (major, minor). Wheels are cp312 only and require the HIP SDK -# to be pre-installed. +# Windows AMD ROCm torch wheels live at repo.radeon.com because PyTorch +# does NOT publish Windows ROCm wheels on download.pytorch.org (and says so +# on pytorch.org/get-started/locally: "ROCm is not available on Windows"). +# Every wheel under download.pytorch.org/whl/rocm{6.4,7.1,7.2}/ is +# manylinux_2_28_x86_64 only. Upstream work to ship Windows ROCm wheels is +# tracked at pytorch/pytorch#159520, targeted for torch 2.10/2.11 but not +# yet delivered. Until then repo.radeon.com is the only source. +# +# AMD's official install procedure +# (rocm.docs.amd.com/projects/radeon-ryzen/.../install-pytorch.html) is a +# TWO-STEP pip install: +# Step 1: rocm_sdk_core + rocm_sdk_devel + rocm_sdk_libraries_custom + +# rocm-.tar.gz. These wheels ship the ROCm runtime libraries +# that torch links against at import time. They total about 1.4 +# GB. The HIP SDK developer toolkit (HIP_PATH) is NOT a substitute +# -- torch imports the Python-packaged runtime from rocm_sdk_*. +# Step 2: torch + torchvision + torchaudio. About 820 MB. # # As of 2026-04, repo.radeon.com/rocm/windows/ contains four release dirs: # rocm-rel-6.4.4/ -- PEP 503 simple index (torch/, torchvision/, torchaudio/ @@ -55,18 +69,38 @@ _PYTORCH_WHL_BASE = "https://download.pytorch.org/whl" # so the filename changes whenever AMD rebuilds and we # cannot hardcode a URL for it. Supporting 6.4.4 would # require parsing the PEP 503 index at install time -- -# out of scope here; users on that SDK get a "please -# upgrade to 7.1+" error. -# rocm-rel-7.1.1/ -- flat layout, stable `+rocmsdk20251116` date tag. -# rocm-rel-7.2/ -- flat layout, stable `+rocmsdk20260116` date tag. -# rocm-rel-7.2.1/ -- flat layout, stable `+rocm7.2.1` version tag. Newest -# 7.2.x release as of writing; superset of rocm-rel-7.2. +# out of scope here. +# rocm-rel-7.1.1/ -- flat layout, torch stable `+rocmsdk20251116` tag, +# SDK wheels stamped `0.1.dev0` (pre-release marker). +# rocm-rel-7.2/ -- flat layout, torch stable `+rocmsdk20260116` tag. +# rocm-rel-7.2.1/ -- flat layout, torch stable `+rocm7.2.1` tag, SDK +# wheels stamped `7.2.1`. Newest 7.2.x release as of +# writing; superset of rocm-rel-7.2. # -# The map below routes HIP SDK 7.2.x -> rocm-rel-7.2.1 wheels (newer, bug -# fixes) rather than rocm-rel-7.2; torch bundles its own ROCm runtime so the -# host SDK point version does not need to match the wheel tag exactly. +# HIP SDK detection via HIP_PATH is an OPTIONAL version hint, not a +# prerequisite. Users only need an AMD graphics driver (26.2.2+ for 7.2.1) +# and Python 3.12. When HIP_PATH is absent or points at an unsupported +# version, we default to the newest stable release (7.2.1). _ROCM_WINDOWS_TORCH_WHEELS: dict[tuple[int, int], dict[str, str]] = { (7, 2): { + # Step 1: ROCm SDK wheels (ship the runtime torch imports) + "sdk_core": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/" + "rocm_sdk_core-7.2.1-py3-none-win_amd64.whl" + ), + "sdk_devel": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/" + "rocm_sdk_devel-7.2.1-py3-none-win_amd64.whl" + ), + "sdk_libraries": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/" + "rocm_sdk_libraries_custom-7.2.1-py3-none-win_amd64.whl" + ), + "sdk_tarball": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/" + "rocm-7.2.1.tar.gz" + ), + # Step 2: torch wheels "torch": ( "https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/" "torch-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl" @@ -81,6 +115,25 @@ _ROCM_WINDOWS_TORCH_WHEELS: dict[tuple[int, int], dict[str, str]] = { ), }, (7, 1): { + # Step 1: ROCm SDK wheels -- note 7.1.1 stamps the SDK wheels with + # `0.1.dev0` while keeping the torch wheels at 2.9.0. + "sdk_core": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.1.1/" + "rocm_sdk_core-0.1.dev0-py3-none-win_amd64.whl" + ), + "sdk_devel": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.1.1/" + "rocm_sdk_devel-0.1.dev0-py3-none-win_amd64.whl" + ), + "sdk_libraries": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.1.1/" + "rocm_sdk_libraries_custom-0.1.dev0-py3-none-win_amd64.whl" + ), + "sdk_tarball": ( + "https://repo.radeon.com/rocm/windows/rocm-rel-7.1.1/" + "rocm-0.1.dev0.tar.gz" + ), + # Step 2: torch wheels "torch": ( "https://repo.radeon.com/rocm/windows/rocm-rel-7.1.1/" "torch-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl" @@ -95,6 +148,13 @@ _ROCM_WINDOWS_TORCH_WHEELS: dict[tuple[int, int], dict[str, str]] = { ), }, } +# Default Windows ROCm release when HIP_PATH is absent or unreadable. Users +# only need a recent AMD graphics driver and Python 3.12 -- the HIP SDK +# developer toolkit is NOT required for running torch. +_DEFAULT_WINDOWS_ROCM_VERSION: tuple[int, int] = (7, 2) +_AMD_RADEON_DRIVER_URL = ( + "https://www.amd.com/en/support/download/drivers.html" +) _HIP_SDK_DOWNLOAD_URL = ( "https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html" ) @@ -373,16 +433,31 @@ def _has_usable_nvidia_gpu() -> bool: def _ensure_rocm_torch_windows() -> None: - """Install Radeon's Windows ROCm torch wheels when an AMD GPU + HIP SDK - are both present. Called from _ensure_rocm_torch(). + """Install Radeon's Windows ROCm SDK + torch wheels when an AMD GPU is + present. Called from _ensure_rocm_torch(). - Silently returns when no AMD GPU is visible, so NVIDIA and CPU-only - Windows hosts are never touched. When an AMD GPU is present but the - HIP SDK is missing or too old, prints a pointer to the HIP SDK - download page and returns without raising -- the Linux helper has the - same shape. NVIDIA takes precedence on mixed AMD+NVIDIA hosts so - install.ps1 and setup.ps1 (which install CUDA torch in that case) - are not clobbered. + AMD's documented install procedure + (rocm.docs.amd.com/projects/radeon-ryzen/.../install-pytorch.html) is + a TWO-STEP sequence: first the rocm_sdk_* wheels (which ship the ROCm + runtime libraries torch links against at import time), then the torch + wheels themselves. Both steps are mandatory -- torch import fails + with missing-DLL errors without the SDK wheels, even on a host that + has the HIP SDK developer toolkit installed, because torch imports + the Python-packaged runtime. + + HIP_PATH is treated as an OPTIONAL version hint, not a prerequisite. + Regular users only need the AMD graphics driver (26.2.2+ for 7.2.1) + and Python 3.12, as documented by AMD. When HIP_PATH is missing or + points at an unsupported version, we default to the newest stable + release (_DEFAULT_WINDOWS_ROCM_VERSION) rather than erroring out. + + NVIDIA takes precedence on mixed AMD+NVIDIA hosts. Silently returns + when no AMD GPU is visible so NVIDIA and CPU-only Windows hosts are + never touched. Both pip installs pass force_pip=True because uv's + installer has known problems with these wheels -- matches the fix in + unslothai/unsloth#4966 for bitsandbytes on Linux ROCm, and AMD's own + troubleshooting notes flag pip dep-resolver overwrite scenarios on + this procedure. """ # NVIDIA wins on mixed hosts -- matches the Linux branch and avoids # overwriting a freshly installed CUDA torch with ROCm wheels. @@ -391,27 +466,6 @@ def _ensure_rocm_torch_windows() -> None: if not _has_rocm_gpu_windows(): return - ver = _detect_rocm_version_windows() - if ver is None: - _safe_print( - _red( - " AMD GPU detected but HIP SDK was not found. Install it " - f"from {_HIP_SDK_DOWNLOAD_URL} and re-run setup." - ) - ) - return - - wheels = _ROCM_WINDOWS_TORCH_WHEELS.get(ver) - if wheels is None: - _safe_print( - _red( - f" HIP SDK {ver[0]}.{ver[1]} detected. Unsloth on Windows " - f"requires HIP SDK 7.1 or 7.2. Please update from " - f"{_HIP_SDK_DOWNLOAD_URL}" - ) - ) - return - # Radeon wheels are cp312 only. Warn (do not crash) when the venv's # Python is not 3.12 -- pip will fail anyway with a clearer message. if (sys.version_info.major, sys.version_info.minor) != (3, 12): @@ -424,20 +478,79 @@ def _ensure_rocm_torch_windows() -> None: ) return + # Prefer HIP_PATH as a version hint when available, but fall back to + # the newest stable release so users without the developer SDK still + # get a working install. + detected = _detect_rocm_version_windows() + ver: tuple[int, int] + using_default = False + if detected is not None and detected in _ROCM_WINDOWS_TORCH_WHEELS: + ver = detected + elif detected is not None: + # Detected but unsupported (e.g. 6.4): fall back to newest with a + # visible notice so the user knows what happened. + _safe_print( + _dim( + f" HIP SDK {detected[0]}.{detected[1]} is too old; " + f"falling back to newest stable wheels " + f"({_DEFAULT_WINDOWS_ROCM_VERSION[0]}.{_DEFAULT_WINDOWS_ROCM_VERSION[1]})" + ) + ) + ver = _DEFAULT_WINDOWS_ROCM_VERSION + using_default = True + else: + ver = _DEFAULT_WINDOWS_ROCM_VERSION + using_default = True + + wheels = _ROCM_WINDOWS_TORCH_WHEELS.get(ver) + if wheels is None: + _safe_print( + _red( + f" No Windows ROCm wheel map for version {ver[0]}.{ver[1]}. " + f"Please file an issue at github.com/unslothai/unsloth/issues." + ) + ) + return + + source = "default" if using_default else "HIP_PATH" _safe_print( _dim( - f" HIP SDK {ver[0]}.{ver[1]} -- installing torch from " - f"repo.radeon.com/rocm/windows/" + f" Installing Radeon ROCm wheels for Windows " + f"(rocm-rel-{ver[0]}.{ver[1]}.x, {source}) from repo.radeon.com" ) ) + if using_default: + _safe_print( + _dim( + f" Ensure your AMD graphics driver is recent; get the " + f"latest from {_AMD_RADEON_DRIVER_URL}" + ) + ) + + # Step 1: ROCm SDK wheels (runtime libraries torch imports). ~1.4 GB + # download on a clean venv. pip_install( - f"ROCm torch (Windows, HIP SDK {ver[0]}.{ver[1]})", + f"ROCm SDK (Windows, {ver[0]}.{ver[1]})", + "--force-reinstall", + "--no-cache-dir", + wheels["sdk_core"], + wheels["sdk_devel"], + wheels["sdk_libraries"], + wheels["sdk_tarball"], + constrain = False, + force_pip = True, + ) + + # Step 2: torch wheels. ~820 MB download. + pip_install( + f"ROCm torch (Windows, {ver[0]}.{ver[1]})", "--force-reinstall", "--no-cache-dir", wheels["torch"], wheels["torchvision"], wheels["torchaudio"], constrain = False, + force_pip = True, ) diff --git a/studio/setup.ps1 b/studio/setup.ps1 index a74b116ff5..f9b9eae11a 100644 --- a/studio/setup.ps1 +++ b/studio/setup.ps1 @@ -320,29 +320,45 @@ function Get-HipSdkVersion { return $null } -# Map a detected HIP SDK version to Radeon's Windows torch wheels. -# Returns @{ Torch = ...; Torchvision = ...; Torchaudio = ... } or $null. +# Map a ROCm release version to Radeon's full Windows wheel set. +# Returns @{ SdkCore, SdkDevel, SdkLibraries, SdkTarball, Torch, +# Torchvision, Torchaudio } or $null when unsupported. AMD's install docs +# require a two-step install: first the rocm_sdk_* wheels (~1.4 GB; +# runtime torch links against), then torch itself. Wheels are cp312 only. function Get-RocmWheelUrls { param([Parameter(Mandatory = $true)]$Version) $base721 = 'https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/' $base711 = 'https://repo.radeon.com/rocm/windows/rocm-rel-7.1.1/' if ($Version.Major -eq 7 -and $Version.Minor -eq 2) { return @{ - Torch = $base721 + 'torch-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' - Torchvision = $base721 + 'torchvision-0.24.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' - Torchaudio = $base721 + 'torchaudio-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' + SdkCore = $base721 + 'rocm_sdk_core-7.2.1-py3-none-win_amd64.whl' + SdkDevel = $base721 + 'rocm_sdk_devel-7.2.1-py3-none-win_amd64.whl' + SdkLibraries = $base721 + 'rocm_sdk_libraries_custom-7.2.1-py3-none-win_amd64.whl' + SdkTarball = $base721 + 'rocm-7.2.1.tar.gz' + Torch = $base721 + 'torch-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' + Torchvision = $base721 + 'torchvision-0.24.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' + Torchaudio = $base721 + 'torchaudio-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl' } } if ($Version.Major -eq 7 -and $Version.Minor -eq 1) { return @{ - Torch = $base711 + 'torch-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' - Torchvision = $base711 + 'torchvision-0.24.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' - Torchaudio = $base711 + 'torchaudio-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' + SdkCore = $base711 + 'rocm_sdk_core-0.1.dev0-py3-none-win_amd64.whl' + SdkDevel = $base711 + 'rocm_sdk_devel-0.1.dev0-py3-none-win_amd64.whl' + SdkLibraries = $base711 + 'rocm_sdk_libraries_custom-0.1.dev0-py3-none-win_amd64.whl' + SdkTarball = $base711 + 'rocm-0.1.dev0.tar.gz' + Torch = $base711 + 'torch-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' + Torchvision = $base711 + 'torchvision-0.24.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' + Torchaudio = $base711 + 'torchaudio-2.9.0%2Brocmsdk20251116-cp312-cp312-win_amd64.whl' } } return $null } +# Default Windows ROCm release when HIP_PATH is absent. HIP_PATH is an +# optional hint, not a prerequisite -- torch runtime comes from the +# rocm_sdk wheels, so users only need a graphics driver and Python 3.12. +$DefaultWindowsRocmVersion = @{ Major = 7; Minor = 2 } + # Find Visual Studio Build Tools for cmake -G flag. # Strategy: (1) vswhere, (2) scan filesystem (handles broken vswhere registration). # Returns @{ Generator = "Visual Studio 17 2022"; InstallPath = "C:\..."; Source = "..." } or $null. @@ -624,7 +640,9 @@ try { } catch {} if ($HasNvidiaSmi) { $HasAmdGpu = $false } -# Resolve HIP SDK when taking the AMD path. +# Probe HIP SDK as an optional version hint. Not a prerequisite -- torch +# links against the Python-packaged rocm_sdk wheels, so regular users +# only need the AMD graphics driver (26.2.2+ for 7.2.1) and Python 3.12. $HipSdkVersion = $null if ($HasAmdGpu) { $HipSdkVersion = Get-HipSdkVersion @@ -634,13 +652,11 @@ if ($HasNvidiaSmi) { step "gpu" "NVIDIA GPU detected" } elseif ($HasAmdGpu) { if ($HipSdkVersion) { - step "gpu" ("AMD GPU detected (HIP SDK {0}.{1})" -f $HipSdkVersion.Major, $HipSdkVersion.Minor) + step "gpu" ("AMD GPU detected (HIP SDK {0}.{1} hint)" -f $HipSdkVersion.Major, $HipSdkVersion.Minor) } else { - Write-Host "" - step "gpu" "AMD GPU detected (HIP SDK missing)" "Yellow" - substep "Install HIP SDK from https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html" "Yellow" - substep "and re-run this installer." "Yellow" - Write-Host "" + step "gpu" ("AMD GPU detected (will use rocm-rel-{0}.{1}.x)" -f $DefaultWindowsRocmVersion.Major, $DefaultWindowsRocmVersion.Minor) + substep "HIP SDK not found (optional). Ensure AMD graphics driver is up to date:" "DarkGray" + substep "https://www.amd.com/en/support/download/drivers.html" "DarkGray" } } else { Write-Host "" @@ -1638,19 +1654,30 @@ if ($HasNvidiaSmi) { } if ($CuTag -eq "rocm") { - if (-not $HipSdkVersion) { - Write-Host "[FAILED] AMD GPU detected but HIP SDK is not installed." -ForegroundColor Red - Write-Host " Download it from https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html" -ForegroundColor Yellow - Write-Host " and re-run this setup." -ForegroundColor Yellow - exit 1 + # HIP_PATH is an optional hint -- fall back to newest stable when + # absent or unsupported, because the HIP developer SDK is NOT a + # runtime prerequisite for torch on Windows (AMD's docs only list + # the graphics driver + Python 3.12). Users without HIP_PATH still + # get a working install. + $RocmWheelUrls = $null + $RocmReleaseVersion = $null + if ($HipSdkVersion) { + $RocmWheelUrls = Get-RocmWheelUrls -Version $HipSdkVersion + if ($RocmWheelUrls) { $RocmReleaseVersion = $HipSdkVersion } } - $RocmWheelUrls = Get-RocmWheelUrls -Version $HipSdkVersion if (-not $RocmWheelUrls) { - Write-Host "[FAILED] AMD HIP SDK $($HipSdkVersion.Major).$($HipSdkVersion.Minor) is not supported." -ForegroundColor Red - Write-Host " Unsloth on Windows requires HIP SDK 7.1 or later. Please update from" -ForegroundColor Yellow - Write-Host " https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html" -ForegroundColor Yellow + if ($HipSdkVersion) { + substep ("HIP SDK {0}.{1} is too old; falling back to rocm-rel-{2}.{3}.x" -f $HipSdkVersion.Major, $HipSdkVersion.Minor, $DefaultWindowsRocmVersion.Major, $DefaultWindowsRocmVersion.Minor) "Yellow" + } + $RocmWheelUrls = Get-RocmWheelUrls -Version $DefaultWindowsRocmVersion + $RocmReleaseVersion = $DefaultWindowsRocmVersion + } + if (-not $RocmWheelUrls) { + Write-Host "[FAILED] Could not resolve Windows ROCm wheel URLs (bug)." -ForegroundColor Red + Write-Host " Please file an issue at github.com/unslothai/unsloth/issues" -ForegroundColor Yellow exit 1 } + # Radeon wheels are cp312 only. Warn loudly when the venv's Python is # a different minor version so the pip error makes sense. We do not # exit here because setup.ps1 is also invoked as "unsloth studio update" @@ -1662,14 +1689,49 @@ if ($CuTag -eq "rocm") { substep "Warning: Radeon Windows ROCm wheels require Python 3.12, venv has $venvPyVer." "Yellow" substep "Re-create the venv with Python 3.12 from https://python.org if pip fails below." "Yellow" } - substep "installing PyTorch ROCm wheels from repo.radeon.com..." - substep "(first wheel is ~780 MB; download may take a few minutes)" + + substep ("installing Radeon ROCm wheels for rocm-rel-{0}.{1}.x from repo.radeon.com..." -f $RocmReleaseVersion.Major, $RocmReleaseVersion.Minor) + substep "Step 1/2: ROCm SDK runtime (~1.4 GB, may take several minutes)" + # Use `python -m pip install` NOT uv for the Radeon wheels. AMD's + # docs specify pip; uv has known issues on similar large ROCm wheels + # (matches the bitsandbytes situation in unslothai/unsloth#4966); and + # using pip directly is the combination AMD validates. if ($script:UnslothVerbose) { - Fast-Install $RocmWheelUrls.Torch $RocmWheelUrls.Torchvision $RocmWheelUrls.Torchaudio + & python -m pip install --no-cache-dir --force-reinstall ` + $RocmWheelUrls.SdkCore ` + $RocmWheelUrls.SdkDevel ` + $RocmWheelUrls.SdkLibraries ` + $RocmWheelUrls.SdkTarball + $sdkInstallExit = $LASTEXITCODE + $output = "" + } else { + $output = & python -m pip install --no-cache-dir --force-reinstall ` + $RocmWheelUrls.SdkCore ` + $RocmWheelUrls.SdkDevel ` + $RocmWheelUrls.SdkLibraries ` + $RocmWheelUrls.SdkTarball | Out-String + $sdkInstallExit = $LASTEXITCODE + } + if ($sdkInstallExit -ne 0) { + Write-Host "[FAILED] ROCm SDK install failed (exit code $sdkInstallExit)" -ForegroundColor Red + Write-Host $output -ForegroundColor Red + Write-Host " Verify your AMD graphics driver is recent: https://www.amd.com/en/support/download/drivers.html" -ForegroundColor Yellow + exit 1 + } + + substep "Step 2/2: PyTorch + torchvision + torchaudio (~820 MB)" + if ($script:UnslothVerbose) { + & python -m pip install --no-cache-dir --force-reinstall ` + $RocmWheelUrls.Torch ` + $RocmWheelUrls.Torchvision ` + $RocmWheelUrls.Torchaudio $torchInstallExit = $LASTEXITCODE $output = "" } else { - $output = Fast-Install $RocmWheelUrls.Torch $RocmWheelUrls.Torchvision $RocmWheelUrls.Torchaudio | Out-String + $output = & python -m pip install --no-cache-dir --force-reinstall ` + $RocmWheelUrls.Torch ` + $RocmWheelUrls.Torchvision ` + $RocmWheelUrls.Torchaudio | Out-String $torchInstallExit = $LASTEXITCODE } if ($torchInstallExit -ne 0) {