installer: fix false "no GPU detected" on AMD hosts (dead KFD check) + clearer ROCm-less warning (#7314)
* installer: fix Linux AMD GPU detection + actionable ROCm-less warning The rocminfo/amd-smi-less fallback in _has_amd_rocm_gpu keyed on a /gpu_id/ line inside each KFD node's properties file, but gpu_id is a separate sibling sysfs file and never appears in properties. The guard never matched, so the fallback missed every AMD host without ROCm tooling (e.g. a fresh CachyOS/Arch box) and reported 'no GPU detected' despite vendor_id 4098 being present in the KFD topology. Detect via vendor_id == 4098 directly: the KFD CPU node reports vendor_id 0, so any 4098 node is an AMD GPU, while NVIDIA's KFD nodes report 4318 and stay excluded. Also rework the 'ROCm version could not be determined' warning into an actionable message (install the ROCm/HIP SDK; Arch/CachyOS: rocm-hip-sdk) so ROCm-less users know the concrete next step instead of silently landing on CPU-only PyTorch. * tests: replace the FNR==1 KFD invariant with the per-line vendor_id check The FNR==1 reset guarded the old paired gpu_id+vendor_id awk against cross-node state leakage. The new detection is a single atomic vendor_id==4098 line condition, so there is no per-node state to reset; assert the new invariant instead (single-line vendor match, and no /gpu_id/ pattern, which never matched inside properties). tests/studio/install/test_rocm_support.py: 344 passed, 2 skipped. * installer: mirror the KFD vendor_id fix in setup.sh + honest CPU-fallback summary Codex P2 follow-ups: - studio/setup.sh carried the same dead gpu_id-inside-properties awk, so a host install.sh now routes to ROCm still failed setup's independent AMD re-probe and got a CPU llama.cpp. Use the same per-line vendor_id 4098 check. - When the AMD GPU is detected but the torch index stays CPU, the summary printed the old false diagnosis (gpu none / "No GPU detected"). Gate both on _has_amd_rocm_gpu and say what actually happened: AMD GPU present, no usable ROCm, CPU fallback. - Structure test asserting setup.sh's KFD awk stays in sync with install.sh. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Keep KFD-only AMD hosts on the CPU fallback (Codex P2s) The KFD-topology fix makes _has_amd_rocm_gpu / _setup_amd_detected true on hosts that expose an AMD GPU to the kernel but ship no rocminfo/amd-smi. Detection alone does not mean ROCm is usable or that the gfx arch is known, and two downstream paths wrongly assumed it did: - studio/setup.sh forwarded --has-rocm with no gfx, so install_llama_prebuilt found no per-gfx bundle and dropped to a HIP source build (slow, or a hard failure without build deps) instead of the CPU prebuilt these hosts used to get. Now --has-rocm is forwarded for a gfx-unknown host only when hipcc is present; otherwise it keeps the CPU prebuilt. - install.sh get_torch_index_url selected a generic rocmX.Y index whenever the ROCm version was readable, but the Strix reroute only learns gfx from rocminfo/amd-smi, so a Strix KFD-only host landed on the broken _grouped_mm wheels. Now, when neither rocminfo nor amd-smi is present (gfx unknowable), it stays on CPU with a hint to install them. Detection and the improved diagnostics are unchanged; only the routing for gfx-unknown KFD-only hosts is made safe. Adds tests for both gates. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Harden KFD-only fallback: probe gfx, accept versioned hipcc (Codex P2s) Follow-up to the previous commit's two guards: - install.sh: the KFD-only torch guard tested only 'command -v rocminfo/amd-smi', so a host where those binaries exist but do not enumerate the GPU (gfx unreadable) slipped through and, with hipconfig/rocm-core present, still got a generic rocm index -- breaking Strix. Now it actually reads the gfx (rocminfo, then amd-smi list / static --asic, the same probe the reroute uses) and falls back to CPU whenever the arch is unreadable, not just when the binaries are absent. - studio/setup.sh: the hipcc gate missed a HIP toolchain installed only under a versioned prefix (/opt/rocm-*/bin/hipcc), which the source build at setup.sh:1663 does support, so such hosts were dropped to the CPU prebuilt unnecessarily. The gate now also accepts /opt/rocm-*/bin/hipcc. Tests updated to assert the gfx-read (not binary-presence) gate and the versioned hipcc path; full test_rocm_support.py green (347 passed). Verified the gfx probe by execution: rocminfo-with-no-gfx now routes to CPU, amd-smi fallback still resolves gfx. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Honor UNSLOTH_ROCM_GFX_ARCH before the CPU fallback for PR #7314 Seed both the gfx-unknown guard in get_torch_index_url and the Strix reroute from UNSLOTH_ROCM_GFX_ARCH before probing rocminfo/amd-smi, so a host that names its arch reaches the correct rocm index instead of being forced to CPU (or to the generic wheels) when the runtime probes can't enumerate the GPU. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Probe gfx with visibility masks cleared for PR #7314 (Codex P2) rocminfo/amd-smi honor ROCR/HIP_VISIBLE_DEVICES, so a container that masks the GPU (e.g. ROCR_VISIBLE_DEVICES=-1) would make the gfx probe read nothing and force CPU torch, even though the KFD-based AMD detection is env-independent and hipconfig can still supply the ROCm version. Clear the visibility masks for the rocminfo/amd-smi arch probe only (the Strix reroute keeps them for per-GPU index selection), so a masked/container host keeps its ROCm route. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Re-probe gfx unmasked in the Strix reroute when a mask hides all agents for PR #7314 (Codex P2) * Remove leftover conflict marker from the test merge * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Report an explicit CPU pin instead of a ROCm misdiagnosis for PR #7314 (Codex P3) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Trigger the reroute re-probe on a set-but-empty visibility mask for PR #7314 (subagent review) * Guard the ROCm version chain against set -e when no source exists for PR #7314 (simulation find) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Preserve the inferred-gfx reroute for KFD-only hosts (Codex P2) The gfx-unknown CPU guard in get_torch_index_url fired before the runtime-less reroute could run: with the KFD topology fix, _has_amd_rocm_gpu is true on KFD-only hosts, so the reroute's '! _has_amd_rocm_gpu' gate never let _infer_linux_amd_gfx_arch route them to AMD per-arch wheels, regressing inferable boxes (PCI/cpuinfo/ lspci) from arch-specific PyTorch to CPU-only. - Factor the override->rocminfo->amd-smi gfx probe (masks cleared) into _probe_amd_gfx_arch, shared by the guard and the reroute gate so the two can't disagree on what 'readable' means. - Reroute gate now also fires when the GPU is detected but the probe is empty (KFD-only). Deliberate CPU fallbacks (old/unreadable ROCm version) all had a readable gfx and stay excluded. - The guard defers to the reroute (no false 'installing CPU-only PyTorch' promise) only when inference yields a supported family; otherwise the actionable CPU warning is unchanged. Executed tests: KFD-only host reroutes to repo.amd.com per-arch wheels and exports UNSLOTH_ROCM_GFX_ARCH for setup.sh; readable-gfx CPU fallback stays un-rerouted; undetected-GPU reroute unchanged; the guard's three inference outcomes covered. Suite: 375 passed, bash -n clean on both scripts. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix two false diagnostics on the KFD-only paths (Codex P3s) 1. get_torch_index_url: with UNSLOTH_ROCM_GFX_ARCH set on a KFD-only host that has no ROCm version sources, the no-version endpoint printed 'falling back to CPU-only PyTorch' even though the reroute (gated on the override) then installs the per-arch wheels. When the override maps to a wheel family, defer with an accurate message; an unmappable override keeps the CPU warning since the reroute can't route it either. 2. Runtime-less reroute: the KFD-only branch reached the warning 'ROCm runtime not visible (/dev/kfd, rocminfo, amd-smi)' although /dev/kfd is exactly what detected the GPU. The diagnostic now distinguishes KFD-visible/tooling-blind hosts from truly runtime-invisible ones. Executed tests: supported override defers without the false CPU warning, unsupported override and readable-gfx no-version hosts keep it; KFD-only reroute emits the KFD wording, undetected-GPU reroute keeps the original. Version sources are shimmed so the tests hold on dev boxes with a real hipconfig. Suite: 376 passed, bash -n clean. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Daniel Han <danielhanchen@gmail.com>
This commit is contained in:
parent
bfb6b9600c
commit
430ada617a
3 changed files with 704 additions and 35 deletions
168
install.sh
168
install.sh
|
|
@ -2115,13 +2115,16 @@ _has_amd_rocm_gpu() {
|
|||
amd-smi list 2>/dev/null | awk '/^GPU[[:space:]]*[:\[][[:space:]]*[0-9]/{ found=1 } END{ exit !found }'; then
|
||||
return 0
|
||||
elif [ -e /dev/kfd ] && \
|
||||
awk 'FNR==1{ gpu=0; amd=0 } /gpu_id/{ gpu=($2+0>0) } /vendor_id/{ amd=($2==4098) } \
|
||||
gpu && amd { found=1 } END{ exit !found }' \
|
||||
awk '/vendor_id/ && $2 == 4098 { found = 1 } END { exit !found }' \
|
||||
/sys/class/kfd/kfd/topology/nodes/*/properties 2>/dev/null; then
|
||||
# vendor_id 4098 = 0x1002 (AMD). NVIDIA open kernel module (driver
|
||||
# 560+) can register KFD topology nodes with non-zero gpu_id but
|
||||
# vendor_id 4318 (0x10DE). Require AMD vendor to avoid misrouting
|
||||
# NVIDIA-only hosts to the ROCm install path.
|
||||
# vendor_id 4098 = 0x1002 (AMD) marks a GPU node: the KFD CPU node
|
||||
# reports vendor_id 0, so any 4098 node is an AMD GPU. NVIDIA's open
|
||||
# kernel module (driver 560+) registers KFD nodes as vendor_id 4318
|
||||
# (0x10DE), so this never false-positives on NVIDIA-only hosts.
|
||||
# The prior check also required a gpu_id line, but gpu_id is a SIBLING
|
||||
# sysfs file, not a line in properties -- it never matched, so the
|
||||
# fallback silently missed every ROCm-less AMD host (issue: fresh
|
||||
# Arch/CachyOS boxes reporting "no GPU detected").
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
|
|
@ -2230,6 +2233,30 @@ EOF
|
|||
return 1
|
||||
}
|
||||
|
||||
# Reads the AMD gfx arch for wheel-index decisions: a user-set
|
||||
# UNSLOTH_ROCM_GFX_ARCH is authoritative (lowercased), else rocminfo, then
|
||||
# amd-smi. rocminfo/amd-smi honor ROCR/HIP_VISIBLE_DEVICES, so a container mask
|
||||
# (e.g. ROCR_VISIBLE_DEVICES=-1) would hide a GPU that the env-independent KFD
|
||||
# detection still sees -- the tool probes run with the masks cleared. Prints the
|
||||
# gfx token(s) or nothing when unreadable, and always returns 0 (a failing probe
|
||||
# as the last command would trip set -e in callers' assignments). Shared by
|
||||
# get_torch_index_url's gfx gate and the runtime-less reroute gate so the two
|
||||
# can never disagree on what "readable" means.
|
||||
_probe_amd_gfx_arch() {
|
||||
_ensure_rocm_probe_env
|
||||
_pg=$(printf '%s' "${UNSLOTH_ROCM_GFX_ARCH:-}" | tr '[:upper:]' '[:lower:]')
|
||||
if [ -z "$_pg" ] && command -v rocminfo >/dev/null 2>&1; then
|
||||
_pg=$( (unset ROCR_VISIBLE_DEVICES HIP_VISIBLE_DEVICES; rocminfo 2>/dev/null) | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
fi
|
||||
if [ -z "$_pg" ] && command -v amd-smi >/dev/null 2>&1; then
|
||||
_pg=$( (unset ROCR_VISIBLE_DEVICES HIP_VISIBLE_DEVICES; amd-smi list 2>/dev/null) | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
if [ -z "$_pg" ]; then
|
||||
_pg=$( (unset ROCR_VISIBLE_DEVICES HIP_VISIBLE_DEVICES; amd-smi static --asic 2>/dev/null) | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
fi
|
||||
fi
|
||||
printf '%s\n' "$_pg"
|
||||
}
|
||||
|
||||
# ── Detect GPU and choose PyTorch index URL ──
|
||||
# Mirrors Get-TorchIndexUrl in install.ps1.
|
||||
# On CPU-only machines this returns the cpu index, avoiding the solver
|
||||
|
|
@ -2283,6 +2310,29 @@ get_torch_index_url() {
|
|||
if ! _has_amd_rocm_gpu; then
|
||||
echo "$_base/cpu"; return
|
||||
fi
|
||||
# A generic rocm index is only safe when the gfx arch is readable: the
|
||||
# Strix reroute (gfx1150/1151 -> arch-specific index) learns gfx from
|
||||
# rocminfo/amd-smi, so if those are missing OR do not enumerate the GPU, an
|
||||
# unknown-arch box might be Strix and would get the broken _grouped_mm
|
||||
# wheels. Probe via the shared helper (override first, then rocminfo/amd-smi
|
||||
# with visibility masks cleared); if the arch is unreadable, never guess a
|
||||
# rocm index. A KFD-only host whose arch is still inferable from hardware
|
||||
# IDs (PCI/cpuinfo/lspci) returns the cpu index and lets the runtime-less
|
||||
# reroute below upgrade it to AMD per-arch wheels -- the reroute gate uses
|
||||
# this same probe, so the handoff can't misfire. Only when inference fails
|
||||
# too is CPU final, with the actionable warning.
|
||||
_amd_gfx_probe=$(_probe_amd_gfx_arch)
|
||||
if [ -z "$_amd_gfx_probe" ]; then
|
||||
if _amd_inferred_gfx=$(_infer_linux_amd_gfx_arch 2>/dev/null) && \
|
||||
[ -n "$_amd_inferred_gfx" ] && \
|
||||
_amd_arch_index_family_for_gfx "$_amd_inferred_gfx" >/dev/null 2>&1; then
|
||||
echo "[WARN] AMD GPU detected but rocminfo/amd-smi can't read its gfx arch -- inferring $_amd_inferred_gfx from hardware IDs." >&2
|
||||
echo "$_base/cpu"; return
|
||||
fi
|
||||
echo "[WARN] AMD GPU detected but its gfx arch can't be read (rocminfo/amd-smi missing or not enumerating the GPU) -- installing CPU-only PyTorch." >&2
|
||||
echo "[WARN] For GPU PyTorch, install or repair rocminfo/amd-smi (e.g. sudo pacman -S rocm-hip-sdk) and re-run this installer." >&2
|
||||
echo "$_base/cpu"; return
|
||||
fi
|
||||
# AMD GPU confirmed -- detect ROCm version
|
||||
_rocm_tag=""
|
||||
_rocm_tag=$({ command -v amd-smi >/dev/null 2>&1 && \
|
||||
|
|
@ -2299,7 +2349,11 @@ get_torch_index_url() {
|
|||
{ command -v rpm >/dev/null 2>&1 && \
|
||||
ver="$(rpm -q --qf '%{VERSION}\n' rocm-core 2>/dev/null)" && \
|
||||
[ -n "$ver" ] && \
|
||||
printf '%s\n' "$ver" | awk -F'[.-]' '{print "rocm"$1"."$2; exit}'; }) 2>/dev/null
|
||||
printf '%s\n' "$ver" | awk -F'[.-]' '{print "rocm"$1"."$2; exit}'; }) 2>/dev/null || _rocm_tag=""
|
||||
# ^ || guard: when EVERY version source is missing (e.g. rocminfo present
|
||||
# but rocm-core not installed, so dpkg-query/rpm exit 1), the whole ||
|
||||
# chain fails and set -e would kill the installer BEFORE the actionable
|
||||
# no-version WARN below -- exactly the fresh-install case it exists for.
|
||||
# Validate _rocm_tag: must match "rocmX.Y" with major >= 1
|
||||
case "$_rocm_tag" in
|
||||
rocm[1-9]*.[0-9]*) : ;; # valid (major >= 1)
|
||||
|
|
@ -2335,12 +2389,27 @@ get_torch_index_url() {
|
|||
esac
|
||||
return
|
||||
fi
|
||||
# AMD GPU confirmed by rocminfo/amd-smi but ROCm version could not be
|
||||
# read from any source (amd-smi, /opt/rocm/.info/version, hipconfig,
|
||||
# dpkg, rpm). Warn explicitly rather than silently installing CPU PyTorch.
|
||||
echo "[WARN] AMD GPU detected but ROCm version could not be determined -- falling back to CPU-only PyTorch" >&2
|
||||
echo "[WARN] Ensure one of the following is accessible: amd-smi, hipconfig, /opt/rocm/.info/version, rocm-core package" >&2
|
||||
echo "[WARN] To install ROCm: https://rocm.docs.amd.com/en/latest/deploy/linux/index.html" >&2
|
||||
# AMD GPU confirmed (rocminfo/amd-smi or the KFD topology fallback) but
|
||||
# no ROCm/HIP install was found to read the version from (amd-smi,
|
||||
# /opt/rocm/.info/version, hipconfig, dpkg, rpm). This is the common
|
||||
# fresh-install case: the GPU is real, but with no ROCm userspace the
|
||||
# correct PyTorch build can't be selected. Warn with an actionable fix
|
||||
# rather than silently installing CPU PyTorch.
|
||||
# A user-set UNSLOTH_ROCM_GFX_ARCH seeded the probe above, so rocminfo/
|
||||
# amd-smi may still be unable to see the GPU; when the named arch maps to
|
||||
# a wheel family, the runtime-less reroute (gated on the override) will
|
||||
# install the AMD per-arch wheels -- a CPU-only warning here would be
|
||||
# false for that path. Defer like the inferable-arch branch does.
|
||||
if [ -n "${UNSLOTH_ROCM_GFX_ARCH:-}" ] && \
|
||||
_amd_arch_index_family_for_gfx "$_amd_gfx_probe" >/dev/null 2>&1; then
|
||||
echo "[WARN] AMD GPU detected with no readable ROCm version, but UNSLOTH_ROCM_GFX_ARCH=$_amd_gfx_probe is set -- routing to AMD per-arch wheels." >&2
|
||||
echo "$_base/cpu"; return
|
||||
fi
|
||||
echo "[WARN] AMD GPU detected, but no ROCm/HIP install was found to select the matching GPU PyTorch build -- falling back to CPU-only PyTorch." >&2
|
||||
echo "[WARN] Install the ROCm/HIP SDK, then re-run this installer:" >&2
|
||||
echo "[WARN] Arch / CachyOS : sudo pacman -S rocm-hip-sdk" >&2
|
||||
echo "[WARN] other distros : https://rocm.docs.amd.com/en/latest/deploy/linux/index.html" >&2
|
||||
echo "[WARN] Minimum required for version detection: amd-smi, hipconfig, /opt/rocm/.info/version, or the rocm-core package." >&2
|
||||
echo "$_base/cpu"; return
|
||||
fi
|
||||
# Parse CUDA version from nvidia-smi output (POSIX-safe, no grep -P).
|
||||
|
|
@ -2841,14 +2910,20 @@ TORCH_INDEX_URL=$(get_torch_index_url)
|
|||
# Linux: ROCm runtime missing but a supported AMD gfx arch is inferable (Strix Halo
|
||||
# in /proc/cpuinfo, lspci marketing name, UNSLOTH_ROCM_GFX_ARCH). Route to AMD's
|
||||
# per-arch wheels like install.ps1 does on Windows (unslothai#7301).
|
||||
# Gated on _has_amd_rocm_gpu being FALSE: a */cpu index on a host whose GPU IS
|
||||
# visible to the ROCm probes is a deliberate fallback (unsupported/unreadable
|
||||
# ROCm version, after its own warning), not a missing runtime -- rerouting it
|
||||
# would contradict that decision. An explicit UNSLOTH_ROCM_GFX_ARCH override
|
||||
# stays authoritative either way.
|
||||
# Gated on the runtime probes NOT naming a gfx: either no AMD GPU is detected at
|
||||
# all (_has_amd_rocm_gpu false), or the GPU is visible only through the
|
||||
# env-independent KFD topology while rocminfo/amd-smi can't read its arch
|
||||
# (KFD-only host, unslothai#7314 -- before the KFD detection fix these hosts
|
||||
# reached this reroute via the false branch, so the empty-probe condition
|
||||
# preserves that routing). A */cpu index chosen WITH a readable gfx
|
||||
# (unsupported/unreadable ROCm version, after its own warning) is a deliberate
|
||||
# fallback -- rerouting it would contradict that decision, and stays excluded
|
||||
# because the shared probe returns its gfx. An explicit UNSLOTH_ROCM_GFX_ARCH
|
||||
# override stays authoritative either way.
|
||||
if [ "$_torch_index_pinned" = false ] && [ "$SKIP_TORCH" = false ] && \
|
||||
! _has_usable_nvidia_gpu && \
|
||||
{ [ -n "${UNSLOTH_ROCM_GFX_ARCH:-}" ] || ! _has_amd_rocm_gpu; } && \
|
||||
{ [ -n "${UNSLOTH_ROCM_GFX_ARCH:-}" ] || ! _has_amd_rocm_gpu || \
|
||||
[ -z "$(_probe_amd_gfx_arch)" ]; } && \
|
||||
case "$(uname -s)" in Linux) true ;; *) false ;; esac && \
|
||||
case "$_ARCH" in x86_64|amd64) true ;; *) false ;; esac; then
|
||||
# ROCm torch wheels are x86_64-only; get_torch_index_url returns CPU on other
|
||||
|
|
@ -2880,7 +2955,13 @@ if [ "$_torch_index_pinned" = false ] && [ "$SKIP_TORCH" = false ] && \
|
|||
;;
|
||||
esac
|
||||
echo "" >&2
|
||||
echo " [WARN] ROCm runtime not visible (/dev/kfd, rocminfo, amd-smi) but $_linux_inferred_gfx inferred." >&2
|
||||
# KFD-only hosts reach this reroute with /dev/kfd present
|
||||
# (that's what detected them), so don't claim it's missing.
|
||||
if _has_amd_rocm_gpu; then
|
||||
echo " [WARN] AMD GPU visible via the kernel driver (KFD) but rocminfo/amd-smi can't read its gfx arch; using $_linux_inferred_gfx." >&2
|
||||
else
|
||||
echo " [WARN] ROCm runtime not visible (/dev/kfd, rocminfo, amd-smi) but $_linux_inferred_gfx inferred." >&2
|
||||
fi
|
||||
echo " [WARN] Routing to AMD arch-specific wheels ($(_strip_index_url_credentials "$TORCH_INDEX_URL"))." >&2
|
||||
echo " [WARN] These wheels bundle their own ROCm runtime; install the kernel stack for native compute:" >&2
|
||||
echo " [WARN] https://docs.unsloth.ai/get-started/install-and-update/amd" >&2
|
||||
|
|
@ -3004,8 +3085,10 @@ case "$_torch_index_leaf" in
|
|||
# || true on each probe: no gfx match makes grep exit 1, which under
|
||||
# set -euo pipefail would abort the installer before the next fallback
|
||||
# runs (now that the case matches every rocm* index, not just rocm7.1).
|
||||
_gfx_all=""
|
||||
if command -v rocminfo >/dev/null 2>&1; then
|
||||
# A user-supplied UNSLOTH_ROCM_GFX_ARCH overrides probing (mirrors setup.sh
|
||||
# and the display block), so a Strix override still reaches the arch index.
|
||||
_gfx_all=$(printf '%s' "${UNSLOTH_ROCM_GFX_ARCH:-}" | tr '[:upper:]' '[:lower:]')
|
||||
if [ -z "$_gfx_all" ] && command -v rocminfo >/dev/null 2>&1; then
|
||||
_gfx_all=$(rocminfo 2>/dev/null | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
fi
|
||||
if [ -z "$_gfx_all" ] && command -v amd-smi >/dev/null 2>&1; then
|
||||
|
|
@ -3016,6 +3099,23 @@ case "$_torch_index_leaf" in
|
|||
_gfx_all=$(amd-smi static --asic 2>/dev/null | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
fi
|
||||
fi
|
||||
# get_torch_index_url reads the arch with ROCR/HIP masks cleared, so a
|
||||
# mask hiding every agent (e.g. ROCR_VISIBLE_DEVICES=-1) still lands
|
||||
# here on a generic rocm index; re-probe unmasked or a masked-out Strix
|
||||
# box keeps the broken generic wheels. Partial masks never get here
|
||||
# (they enumerate at least one agent above) and keep their selection.
|
||||
# ${VAR+x} (not :-): a SET-but-empty mask also hides every agent and
|
||||
# must trigger the re-probe too.
|
||||
if [ -z "$_gfx_all" ] && [ -n "${ROCR_VISIBLE_DEVICES+x}${HIP_VISIBLE_DEVICES+x}" ]; then
|
||||
if command -v rocminfo >/dev/null 2>&1; then
|
||||
_gfx_all=$( (unset ROCR_VISIBLE_DEVICES HIP_VISIBLE_DEVICES; rocminfo 2>/dev/null) | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
fi
|
||||
if [ -z "$_gfx_all" ] && command -v amd-smi >/dev/null 2>&1; then
|
||||
_gfx_all=$( (unset ROCR_VISIBLE_DEVICES HIP_VISIBLE_DEVICES; amd-smi list 2>/dev/null) | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
[ -z "$_gfx_all" ] && \
|
||||
_gfx_all=$( (unset ROCR_VISIBLE_DEVICES HIP_VISIBLE_DEVICES; amd-smi static --asic 2>/dev/null) | grep -oE 'gfx[1-9][0-9a-z]{2,3}' || true)
|
||||
fi
|
||||
fi
|
||||
_runtime_gfx=""
|
||||
if [ -n "$_gfx_all" ]; then
|
||||
_vis="${HIP_VISIBLE_DEVICES:-${ROCR_VISIBLE_DEVICES:-}}"
|
||||
|
|
@ -3169,6 +3269,17 @@ elif case "$TORCH_INDEX_URL" in */rocm*|*/gfx*) true ;; *) false ;; esac; then
|
|||
elif [ "$OS" = "macos" ] && [ "$_ARCH" = "arm64" ]; then
|
||||
# Apple Silicon: PyTorch gets Metal (MPS) acceleration over unified memory, so not CPU-only.
|
||||
step "gpu" "Apple Silicon (Metal, unified memory)"
|
||||
elif _has_amd_rocm_gpu; then
|
||||
if [ "$_torch_index_pinned" = true ]; then
|
||||
# An explicit UNSLOTH_TORCH_INDEX_URL/_FAMILY pin skipped all probing;
|
||||
# do not claim ROCm is unusable when a CPU/other index was requested.
|
||||
step "gpu" "AMD GPU (torch index pinned: $_torch_index_leaf)" "$C_WARN"
|
||||
else
|
||||
# AMD GPU visible to the kernel but the torch index stayed CPU: no usable
|
||||
# ROCm userspace to pick a wheel. "none" would repeat the false diagnosis
|
||||
# this installer used to give.
|
||||
step "gpu" "AMD GPU (no usable ROCm -- CPU fallback)" "$C_WARN"
|
||||
fi
|
||||
else
|
||||
step "gpu" "none (CPU-only)" "$C_WARN"
|
||||
fi
|
||||
|
|
@ -3177,8 +3288,17 @@ fi
|
|||
case "$TORCH_INDEX_URL" in
|
||||
*/cpu)
|
||||
if [ "$SKIP_TORCH" = false ] && [ "$OS" != "macos" ]; then
|
||||
substep "No GPU detected -- installing CPU-only PyTorch." "$C_WARN"
|
||||
if [ "$OS" = "wsl" ]; then
|
||||
if [ "$_torch_index_pinned" = true ]; then
|
||||
# An explicit CPU pin is a request, not a detection failure:
|
||||
# skip the SDK guidance (ROCm may be perfectly healthy here).
|
||||
substep "CPU-only PyTorch (index pinned via UNSLOTH_TORCH_INDEX_URL / _FAMILY)."
|
||||
elif _has_amd_rocm_gpu; then
|
||||
substep "AMD GPU detected, but no usable ROCm/HIP install -- installing CPU-only PyTorch." "$C_WARN"
|
||||
substep "Install the ROCm/HIP SDK and re-run this installer for GPU PyTorch." "$C_WARN"
|
||||
else
|
||||
substep "No GPU detected -- installing CPU-only PyTorch." "$C_WARN"
|
||||
fi
|
||||
if [ "$OS" = "wsl" ] && [ "$_torch_index_pinned" = false ]; then
|
||||
# WSL + no GPU detected (detection above found nothing). Common
|
||||
# cause: an AMD GPU whose ROCm-on-WSL runtime isn't exposed yet --
|
||||
# /dev/dxg present (graphics) but no ROCm runtime.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue