Skip to content

Studio installer (AMD, Linux): no generic ROCm torch for RDNA 1 / Polaris when the arch is readable - #13419

Open
danielhanchen wants to merge 6 commits into
mainfrom
studio-linux-uncovered-amd-cpu-torch-8529
Open

danielhanchen wants to merge 6 commits into
mainfrom
studio-linux-uncovered-amd-cpu-torch-8529

Conversation

@danielhanchen

@danielhanchen danielhanchen commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Fixes #8529 (the Linux half left open there).

The problem

On Linux, an RDNA 1 card (RX 5700 / 5600 / 5500, gfx1010 / gfx1011 / gfx1012) or a Polaris card (RX 470 to 590, gfx803) only reached the "no ROCm PyTorch wheels Unsloth installs" path when its arch could NOT be read. With ROCm installed, rocminfo reports gfx1010 and every installer treated it like a covered card:

  • install.sh (get_torch_index_url) picked the generic pytorch.org tag for the host's ROCm version (rocm6.4, rocm7.0, ...).
  • unsloth studio update (_ensure_rocm_torch) did the same over a CPU torch, and the update preflight forced that repair pass on every run.
  • setup.sh printed AMD Radeon RX 5700 XT (gfx1010) with no warning.

None of the generic wheels carry kernels for these arches (_GENERIC_ROCM_WHEEL_GFX, measured), and Linux has no per-arch index for them (_amd_arch_index_url returns None, by design since #11755). So the user downloaded a multi-GB ROCm torch that loads and then fails on its first GPU op, which is the outcome this issue reported, reached by a more expensive route.

What this PR does

When every probed AMD arch is one of gfx1010, gfx1011, gfx1012, gfx803, and no index is pinned:

  • install.sh returns the CPU index with the same wording the unreadable-arch path already prints (plus the Vulkan and TheRock hints), instead of the generic ROCm tag.
  • _ensure_rocm_torch declines to install ROCm torch onto a CPU/CUDA torch, and _amd_torch_needs_dependency_pass stops forcing a pass that would only decline again.
  • setup.sh reports AMD GPU detected (gfx1010) -- no ROCm PyTorch wheels Unsloth installs with the existing substeps. With UNSLOTH_ROCM_GFX_ARCH set, only the declared arch is checked, as the installers route on it alone.
  • install.sh's final summary says AMD GPU (gfx1010, no ROCm PyTorch wheels -- CPU fallback) instead of no usable ROCm, and its CPU note names that arch when lspci does not.

Unchanged on purpose:

  • A covered card anywhere on the host (gfx1010 + gfx1100) keeps the generic route.
  • A readable HSA_OVERRIDE_GFX_VERSION is the arch the runtime runs (amd-smi and KFD still read the physical one), so it alone is judged in all four places: 10.3.0 on an RX 5700 XT keeps the generic route, 10.1.0 on an RX 5500 still has no wheels. An unreadable value falls back to the probe. The new warning tells a user who only sets the override at runtime to export it and re-run.
  • setup.sh keeps its old report under ROCR_VISIBLE_DEVICES (its rocminfo is ROCR-filtered while the installers probe unmasked, so a hidden covered peer would be missed), unless an arch is declared.
  • UNSLOTH_TORCH_INDEX_URL / UNSLOTH_TORCH_INDEX_FAMILY pins (incl. the TheRock escape hatch) are honoured as before.
  • An existing ROCm build (e.g. a TheRock one) is not removed by studio update, and setup.sh does not call it CPU-only (it reads the venv's torch/version.py); only new installs onto CPU/CUDA torch are declined.
  • Windows is untouched (RDNA 1 routes to AMD's multi-arch index there, Unsloth Studio (AMD RDNA 1, Windows): install ROCm torch for the RX 5700 XT from AMD's multi-arch index #11755).

Tests

New tests/studio/install/test_uncovered_amd_read_arch_linux_8529.py (85 cases): the list has no wheel route and the two shell copies match the Python one; _ensure_rocm_torch over lone / mixed / spoofed / already-ROCm / pinned hosts; the update preflight; install.sh's real get_torch_index_url under sh for each arch and ROCm tag; setup.sh's report chain under bash (incl. a declared arch beside a covered card); install.sh's final GPU summary under sh.

On the merge base 45 of the 56 fail (every uncovered-arch case), the 11 controls pass. On this branch all 56 pass. Two structural tests in test_rdna1_unsupported_message_8529.py are updated for the new install.sh advisory arm (count 2 to 3, it carries the Vulkan advice) and the reshaped setup.sh report line.

Whole tests/studio/install (9.7k tests) plus the 64 other test files that read install.sh, setup.sh or install_python_stack.py, run on the merge base and on this branch: identical failure sets (4 TestProgressStepCountMatchesTotal cases and 10 others, all pre-existing). tests/sh/test_get_torch_index_url.sh (now 109: four new cases through the real _probe_amd_gfx_arch over a mock rocminfo; the three uncovered ones fail on the merge base), tests/sh/test_rocm_bad_arch_gate.sh (62) and tests/sh/test_torch_spec_extra.sh pass.

Not run on real RDNA 1 / Polaris hardware: the routing is exercised through the real shell functions and the Python installer with the probes stubbed.

@danielhanchen danielhanchen self-assigned this Oct 12, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-12T14:54:45.350498Z 8cc2021 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-12T12:43:55.498527Z 44f470b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex security review

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Oct 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44f470be73

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread studio/setup.sh Outdated
Comment on lines +4352 to +4355
_setup_unsup_gfx=$(printf '%s\n' "$_setup_gfx" "$_setup_gfx_all" | sed 's/:.*$//' \
| tr '[:upper:]' '[:lower:]' \
| awk 'NF { if ($1 !~ /^gfx(1010|1011|1012|803)$/) bad = 1; else if (!seen[$1]++) l = l (l ? ", " : "") $1 }
END { if (!bad && l != "") print l }')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor the explicit AMD arch in the setup warning

When UNSLOTH_ROCM_GFX_ARCH=gfx1010 (or another uncovered arch) is set on a mixed host that also contains a covered GPU, _setup_gfx is the authoritative override but _setup_gfx_all still contains the physical peer. Combining both lists makes this filter return empty, so setup reports an ordinary GPU such as AMD Radeon RX 7900 XTX (gfx1010) even though install.sh considers only the override and selects CPU PyTorch. Exclude the physical inventory from this test when the explicit override is set so the final report reflects the actual torch route.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in a1f8e2e: with UNSLOTH_ROCM_GFX_ARCH set, the report checks only the declared arch, matching install.sh and _runtime_gfx_target.

Comment thread install.sh
echo "[INFO] export UNSLOTH_TORCH_INDEX_URL='$THEROCK_MIRROR'" >&2
echo "[INFO] export UNSLOTH_TORCH_EXTRA=$_amd_therock_extra" >&2
fi
echo "$_base/cpu"; return

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the uncovered-arch reason in the install summary

For every readable lone gfx1010/gfx1011/gfx1012/gfx803 host, this new return resolves the index to CPU while _has_amd_rocm_gpu remains true. The later GPU summary therefore takes its generic CPU-fallback arm and prints AMD GPU (no usable ROCm -- CPU fallback), even though ROCm was successfully used to read the arch and the actual problem is the absence of compatible wheels. Carry this uncovered-arch result into the final summary so users are not told that their working ROCm installation is unusable.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in a1f8e2e: the summary now reads the probe and prints 'AMD GPU (gfx1010, no ROCm PyTorch wheels -- CPU fallback)', and the CPU note falls back to that arch when lspci names none.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: a1f8e2e42f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 08365ee426

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread install.sh Outdated
Comment on lines +5920 to +5923
_amd_unsup_all=""
[ -n "$(printf '%s' "${HSA_OVERRIDE_GFX_VERSION:-}" | tr -d '[:space:]')" ] || _amd_unsup_all=$(printf '%s\n' "$_amd_gfx_probe" | sed 's/:.*$//' | tr '[:upper:]' '[:lower:]' \
| awk 'NF { if ($1 !~ /^gfx(1010|1011|1012|803)$/) bad = 1; else if (!seen[$1]++) l = l (l ? ", " : "") $1 }
END { if (!bad && l != "") print l }')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate the HSA target before bypassing the arch gate

When an uncovered GPU has any nonblank HSA_OVERRIDE_GFX_VERSION, this condition skips the new protection even if the override still names an uncovered target. For example, HSA_OVERRIDE_GFX_VERSION=10.1.0 maps to gfx1010, so a physical gfx1010 host still runs as gfx1010 but now receives the generic ROCm wheel and reproduces the first-operation failure this change is meant to prevent; malformed or stale values have the same risk. Parse the value with the existing _hsa_override_gfx_arch helper and bypass only when the resulting runtime target has a wheel route, applying the same check to _linux_host_only_uncovered_amd and the setup report.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 704a2d6: a readable override is parsed with _hsa_override_gfx_arch and judged alone (10.3.0 keeps the generic route, 10.1.0 on a gfx1012 stays on CPU); an unreadable one falls back to the probe. Same in the Python helper, the install summary and setup.sh.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 704a2d6bfc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread install.sh
# runtime runs, whatever amd-smi reads, so it alone is judged unless an arch is declared.
_amd_unsup_src="$_amd_gfx_probe"
_amd_hsa_gfx=$(_hsa_override_gfx_arch "${HSA_OVERRIDE_GFX_VERSION:-}" 2>/dev/null) || _amd_hsa_gfx=""
[ -n "$_amd_hsa_gfx" ] && [ -z "${UNSLOTH_ROCM_GFX_ARCH:-}" ] && _amd_unsup_src="$_amd_hsa_gfx"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Let the HSA target override the installer declaration

When both overrides are set and disagree, this condition ignores the parsed HSA target even though HSA_OVERRIDE_GFX_VERSION controls the ISA that ROCr actually exposes. For example, UNSLOTH_ROCM_GFX_ARCH=gfx1030 with HSA_OVERRIDE_GFX_VERSION=10.1.0 selects the generic ROCm index here, but the runtime presents gfx1010, so the installed wheel still fails on its first GPU operation. The same exclusion is mirrored in _linux_host_only_uncovered_amd and setup.sh, so updates and the final report reinforce the unusable route; judge a valid HSA target regardless of the installer-only declaration, or explicitly resolve the conflict.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not changing this: it needs UNSLOTH_ROCM_GFX_ARCH and HSA_OVERRIDE_GFX_VERSION set to contradicting arches, a self-inflicted config. The declared arch is what every installer path already routes on (it outranks the probes by design), and base main behaves the same here.

Comment thread studio/setup.sh
Comment on lines +4380 to 4381
elif [ -n "$_setup_unsup_gfx" ] || _setup_unsup_gfx=$(_setup_unsupported_gfx_any "$_setup_mkt"); then
step "gpu" "AMD GPU detected ($_setup_unsup_gfx) -- no ROCm PyTorch wheels Unsloth installs"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid labeling retained ROCm torch as CPU-only

On a standalone unsloth studio update for a readable uncovered arch, an existing ROCm build is deliberately retained by _ensure_rocm_torch when rocm_torch_ready is true, but this newly reachable report arm does not inspect the installed torch and unconditionally says that torch stays CPU-only and training is unavailable. This is especially misleading for a user-managed or TheRock ROCm build that works on gfx1010; after the update preserves that build, the final setup report claims the opposite. Detect the installed HIP build before emitting the CPU-only substeps, or qualify the message to describe only automatic installs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 8cc2021: setup.sh reads the venv's torch/version.py and skips the CPU-only arm when torch is already a ROCm build (TheRock or hand-installed), keeping the old GPU line.

@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

1 similar comment
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 8cc2021b44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

This branch has not been deployed

No deployments
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.

[Bug] RX 5700XT doesn't recognize in Unsloth Desktop

1 participant