-
-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Add AMD ROCm/HIP support across installer and hardware detection #4720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 13 commits
7fa0192
f3cc758
062e25f
450f5de
f6c2eb8
7290199
2cb0b52
56098e5
9e33c25
4286525
7d6ac65
fd43235
10ec0cd
c22312b
726fab1
f17e007
1482326
134638d
4dc1dca
3881539
326a971
2d55e77
478bc7f
a067110
9484014
d1e3858
d1de729
f4d64ff
f9a738a
4148591
ae0f9af
ec12f9b
848c92a
86735ff
96ba872
3caaf30
263470e
1b98f6d
9d7c2e7
b37f7e6
543e721
84a9c55
c6f5b3a
810b833
8636fa6
5341e46
5305c31
7d27b2e
f98aaef
37432b6
c12e8b7
d25c570
b3627bc
5211328
1d387d6
7effb3a
bae2421
a24b27e
659c19c
83567f5
7cbc51d
cb7dbd4
e54ed86
98f0215
4a87946
1c58bb9
9e98390
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -982,7 +982,58 @@ get_torch_index_url() { | |||||||||||||
| elif [ -x "/usr/bin/nvidia-smi" ]; then | ||||||||||||||
| _smi="/usr/bin/nvidia-smi" | ||||||||||||||
| fi | ||||||||||||||
| if [ -z "$_smi" ]; then echo "$_base/cpu"; return; fi | ||||||||||||||
| if [ -z "$_smi" ]; then | ||||||||||||||
| # No NVIDIA GPU -- check for AMD ROCm GPU | ||||||||||||||
| # First confirm an actual AMD GPU is present (not just ROCm tools installed) | ||||||||||||||
| _has_rocm_gpu=false | ||||||||||||||
| if command -v rocminfo >/dev/null 2>&1 && \ | ||||||||||||||
| rocminfo 2>/dev/null | awk '/Name:[[:space:]]*gfx[0-9]/{found=1} END{exit !found}'; then | ||||||||||||||
| _has_rocm_gpu=true | ||||||||||||||
| elif command -v amd-smi >/dev/null 2>&1 && \ | ||||||||||||||
| amd-smi list 2>/dev/null | awk 'NR>1 && NF{found=1} END{exit !found}'; then | ||||||||||||||
| _has_rocm_gpu=true | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In Useful? React with 👍 / 👎. |
||||||||||||||
| fi | ||||||||||||||
| if [ "$_has_rocm_gpu" != true ]; then | ||||||||||||||
| echo "$_base/cpu"; return | ||||||||||||||
| fi | ||||||||||||||
| # AMD GPU confirmed -- detect ROCm version | ||||||||||||||
| _rocm_tag="" | ||||||||||||||
| _rocm_tag=$({ command -v amd-smi >/dev/null 2>&1 && \ | ||||||||||||||
| amd-smi version 2>/dev/null | awk -F'ROCm version: ' \ | ||||||||||||||
| 'NF>1{gsub(/[^0-9.]/, "", $2); split($2,a,"."); print "rocm"a[1]"."a[2]; ok=1; exit} END{exit !ok}'; } || \ | ||||||||||||||
|
Comment on lines
+1047
to
+1048
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The Useful? React with 👍 / 👎.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Comment on lines
+1046
to
+1048
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ROCm version parsing from
Suggested change
|
||||||||||||||
| { [ -r /opt/rocm/.info/version ] && \ | ||||||||||||||
| awk -F. '{print "rocm"$1"."$2; exit}' /opt/rocm/.info/version; } || \ | ||||||||||||||
|
Comment on lines
+1046
to
+1050
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Because Useful? React with 👍 / 👎. |
||||||||||||||
| { command -v hipconfig >/dev/null 2>&1 && \ | ||||||||||||||
| hipconfig --version 2>/dev/null | awk 'NR==1{split($1,a,"."); if(a[1]+0>0) print "rocm"a[1]"."a[2]}'; } || \ | ||||||||||||||
| { command -v dpkg-query >/dev/null 2>&1 && \ | ||||||||||||||
| ver="$(dpkg-query -W -f='${Version}\n' rocm-core 2>/dev/null)" && \ | ||||||||||||||
| [ -n "$ver" ] && \ | ||||||||||||||
| printf '%s\n' "$ver" | sed 's/^[0-9]*://' | awk -F'[.-]' '{print "rocm"$1"."$2; exit}'; } || \ | ||||||||||||||
| { 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 | ||||||||||||||
|
Comment on lines
+1046
to
+1060
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||
| # Validate _rocm_tag: must match "rocmX.Y" with major >= 1 | ||||||||||||||
| case "$_rocm_tag" in | ||||||||||||||
| rocm[1-9]*.[0-9]*) : ;; # valid (major >= 1) | ||||||||||||||
| *) _rocm_tag="" ;; # reject malformed (empty, garbled, or major=0) | ||||||||||||||
| esac | ||||||||||||||
| if [ -n "$_rocm_tag" ]; then | ||||||||||||||
| # ROCm 7.2 only has torch 2.11.0 which exceeds current bounds (<2.11.0). | ||||||||||||||
| # Fall back to rocm7.1 index which has torch 2.10.0. | ||||||||||||||
| # TODO: uncomment the next line when torch upper bound is bumped to >=2.11.0 | ||||||||||||||
| # echo "$_base/$_rocm_tag"; return | ||||||||||||||
| case "$_rocm_tag" in | ||||||||||||||
| rocm6.*|rocm7.0*|rocm7.1*) | ||||||||||||||
| echo "$_base/$_rocm_tag" ;; | ||||||||||||||
| *) | ||||||||||||||
| # ROCm 7.2+ (including future 10.x+): cap to rocm7.1 | ||||||||||||||
| echo "$_base/rocm7.1" ;; | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This remap logic treats every detected ROCm tag outside Useful? React with 👍 / 👎. |
||||||||||||||
| esac | ||||||||||||||
| return | ||||||||||||||
| fi | ||||||||||||||
| echo "$_base/cpu"; return | ||||||||||||||
| fi | ||||||||||||||
| # Parse CUDA version from nvidia-smi output (POSIX-safe, no grep -P) | ||||||||||||||
| _cuda_ver=$(LC_ALL=C $_smi 2>/dev/null \ | ||||||||||||||
| | sed -n 's/.*CUDA Version:[[:space:]]*\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p' \ | ||||||||||||||
|
|
@@ -1007,13 +1058,19 @@ case "$TORCH_INDEX_URL" in | |||||||||||||
| */cpu) | ||||||||||||||
| if [ "$SKIP_TORCH" = false ] && [ "$OS" != "macos" ]; then | ||||||||||||||
| echo "" | ||||||||||||||
| echo " NOTE: No NVIDIA GPU detected (nvidia-smi not found)." | ||||||||||||||
| echo " NOTE: No GPU detected (nvidia-smi and ROCm not found)." | ||||||||||||||
| echo " Installing CPU-only PyTorch. If you only need GGUF chat/inference," | ||||||||||||||
| echo " re-run with --no-torch for a faster, lighter install:" | ||||||||||||||
| echo " curl -fsSL https://unsloth.ai/install.sh | sh -s -- --no-torch" | ||||||||||||||
| echo " AMD ROCm users: see https://docs.unsloth.ai/get-started/install-and-update/amd" | ||||||||||||||
| echo "" | ||||||||||||||
| fi | ||||||||||||||
| ;; | ||||||||||||||
| */rocm*) | ||||||||||||||
| echo "" | ||||||||||||||
| echo " AMD ROCm detected -- installing ROCm-enabled PyTorch ($TORCH_INDEX_URL)" | ||||||||||||||
| echo "" | ||||||||||||||
| ;; | ||||||||||||||
| esac | ||||||||||||||
|
|
||||||||||||||
| # ── Install unsloth directly into the venv (no activation needed) ── | ||||||||||||||
|
|
@@ -1051,6 +1108,13 @@ elif [ -n "$TORCH_INDEX_URL" ]; then | |||||||||||||
| substep "installing PyTorch ($TORCH_INDEX_URL)..." | ||||||||||||||
| run_install_cmd "install PyTorch" uv pip install --python "$_VENV_PY" "torch>=2.4,<2.11.0" torchvision torchaudio \ | ||||||||||||||
| --index-url "$TORCH_INDEX_URL" | ||||||||||||||
| # AMD ROCm: install bitsandbytes with AMD support | ||||||||||||||
| case "$TORCH_INDEX_URL" in | ||||||||||||||
| */rocm*) | ||||||||||||||
| substep "installing bitsandbytes for AMD ROCm..." | ||||||||||||||
| run_install_cmd "install bitsandbytes (AMD)" uv pip install --python "$_VENV_PY" "bitsandbytes>=0.49.1" | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The version constraint bitsandbytes>=0.49.1 appears to be a typo. As of current releases, bitsandbytes is in the 0.45.x range. ROCm support was officially added in 0.44.0. Using a non-existent version will cause the installation to fail. Please verify the intended version (likely 0.45.1 or similar).
Suggested change
|
||||||||||||||
| ;; | ||||||||||||||
| esac | ||||||||||||||
| fi | ||||||||||||||
| # Fresh: Step 2 - install unsloth, preserving pre-installed torch | ||||||||||||||
| substep "installing unsloth (this may take a few minutes)..." | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
| DeviceType, | ||
| DEVICE, | ||
| CHAT_ONLY, | ||
| IS_ROCM, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with 👍 / 👎. |
||
| detect_hardware, | ||
| get_device, | ||
| is_apple_silicon, | ||
|
|
@@ -49,6 +50,7 @@ | |
| "DeviceType", | ||
| "DEVICE", | ||
| "CHAT_ONLY", | ||
| "IS_ROCM", | ||
| "detect_hardware", | ||
| "get_device", | ||
| "is_apple_silicon", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,6 +88,7 @@ class HostInfo: | |
| visible_cuda_devices: str | None | ||
| has_physical_nvidia: bool | ||
| has_usable_nvidia: bool | ||
| has_rocm: bool = False | ||
|
|
||
|
|
||
| @dataclass | ||
|
|
@@ -1430,6 +1431,25 @@ def detect_host() -> HostInfo: | |
| except Exception: | ||
| pass | ||
|
Comment on lines
2567
to
2568
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Broad exception handler detected. Per general rules, it is recommended to log the exception or add a descriptive comment instead of a silent pass, even for hardware probing logic. References
|
||
|
|
||
| # Detect AMD ROCm (HIP) -- require actual GPU, not just tools installed | ||
| has_rocm = False | ||
| if not is_macos: | ||
| for _cmd, _marker in ( | ||
| (["rocminfo"], "gfx"), | ||
| (["amd-smi", "list"], "gpu"), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The new ROCm detector uses Useful? React with 👍 / 👎. |
||
| ): | ||
| _exe = shutil.which(_cmd[0]) | ||
| if not _exe: | ||
| continue | ||
| try: | ||
| _result = run_capture([_exe, *_cmd[1:]], timeout = 10) | ||
| except Exception: | ||
| continue | ||
| if _result.returncode == 0 and _result.stdout.strip(): | ||
| if _marker in _result.stdout.lower(): | ||
| has_rocm = True | ||
| break | ||
|
Comment on lines
+2576
to
+2593
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ROCm detection logic in |
||
|
|
||
|
Comment on lines
+2570
to
+2613
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for detecting an AMD ROCm GPU on both Linux and Windows is duplicated in Consider creating a shared utility module with a function like |
||
| return HostInfo( | ||
| system = system, | ||
| machine = machine, | ||
|
|
@@ -1444,6 +1464,7 @@ def detect_host() -> HostInfo: | |
| visible_cuda_devices = visible_cuda_devices, | ||
| has_physical_nvidia = has_physical_nvidia, | ||
| has_usable_nvidia = has_usable_nvidia, | ||
| has_rocm = has_rocm, | ||
| ) | ||
|
|
||
|
|
||
|
|
@@ -1724,6 +1745,32 @@ def resolve_linux_cuda_choice( | |
| def resolve_upstream_asset_choice(host: HostInfo, llama_tag: str) -> AssetChoice: | ||
| upstream_assets = github_release_assets(UPSTREAM_REPO, llama_tag) | ||
| if host.is_linux and host.is_x86_64: | ||
| # AMD ROCm: try upstream ROCm prebuilt first, then fall back to source build. | ||
| # Source build (via setup.sh) compiles with -DGGML_HIP=ON and auto-detects | ||
| # the exact GPU target via rocminfo, which is more reliable for consumer | ||
| # GPUs (e.g. gfx1151) that may not be in the prebuilt. | ||
| if host.has_rocm and not host.has_usable_nvidia: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This new guard blocks the ROCm path whenever Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On Linux x86_64 AMD hosts without usable NVIDIA, this new ROCm branch is not reached in the default installer path because Useful? React with 👍 / 👎. |
||
| rocm_name = f"llama-{llama_tag}-bin-ubuntu-rocm-7.2-x64.tar.gz" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ROCm version |
||
| if rocm_name in upstream_assets: | ||
| log(f"AMD ROCm detected -- trying upstream prebuilt {rocm_name}") | ||
| log( | ||
| "Note: prebuilt is compiled for ROCm 7.2; if your ROCm version differs, " | ||
| "this may fail preflight and fall back to a source build (safe)" | ||
| ) | ||
| return AssetChoice( | ||
| repo = UPSTREAM_REPO, | ||
| tag = llama_tag, | ||
| name = rocm_name, | ||
| url = upstream_assets[rocm_name], | ||
| source_label = "upstream", | ||
| install_kind = "linux-rocm", | ||
| ) | ||
| # No ROCm prebuilt available -- fall back to source build | ||
| raise PrebuiltFallback( | ||
| "AMD ROCm detected but no upstream ROCm prebuilt found; " | ||
| "falling back to source build with HIP support" | ||
| ) | ||
|
|
||
| upstream_name = f"llama-{llama_tag}-bin-ubuntu-x64.tar.gz" | ||
| if upstream_name not in upstream_assets: | ||
| raise PrebuiltFallback("upstream Linux CPU asset was not found") | ||
|
|
@@ -1743,6 +1790,25 @@ def resolve_upstream_asset_choice(host: HostInfo, llama_tag: str) -> AssetChoice | |
| return attempts[0] | ||
| raise PrebuiltFallback("no compatible Windows CUDA asset was found") | ||
|
|
||
| # AMD ROCm on Windows: try HIP prebuilt | ||
| if host.has_rocm: | ||
| hip_name = f"llama-{llama_tag}-bin-win-hip-radeon-x64.zip" | ||
| if hip_name in upstream_assets: | ||
| log( | ||
|
Comment on lines
+3175
to
+3179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The new Useful? React with 👍 / 👎.
Comment on lines
+3176
to
+3179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This new Windows HIP branch is bypassed on the default installer path: Useful? React with 👍 / 👎. |
||
| f"AMD ROCm detected on Windows -- trying upstream HIP prebuilt {hip_name}" | ||
| ) | ||
| return AssetChoice( | ||
| repo = UPSTREAM_REPO, | ||
| tag = llama_tag, | ||
| name = hip_name, | ||
| url = upstream_assets[hip_name], | ||
| source_label = "upstream", | ||
| install_kind = "windows-hip", | ||
| ) | ||
| log( | ||
| "AMD ROCm detected on Windows but no HIP prebuilt found -- falling back to CPU" | ||
| ) | ||
|
|
||
| upstream_name = f"llama-{llama_tag}-bin-win-cpu-x64.zip" | ||
| if upstream_name not in upstream_assets: | ||
| raise PrebuiltFallback("upstream Windows CPU asset was not found") | ||
|
|
@@ -2121,7 +2187,7 @@ def overlay_directory_for_choice( | |
|
|
||
|
|
||
| def runtime_patterns_for_choice(choice: AssetChoice) -> list[str]: | ||
| if choice.install_kind in {"linux-cpu", "linux-cuda"}: | ||
| if choice.install_kind in {"linux-cpu", "linux-cuda", "linux-rocm"}: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This change introduces the Useful? React with 👍 / 👎. |
||
| return [ | ||
| "llama-server", | ||
| "llama-quantize", | ||
|
|
@@ -2131,11 +2197,12 @@ def runtime_patterns_for_choice(choice: AssetChoice) -> list[str]: | |
| "libmtmd.so*", | ||
| "libggml-cpu-*.so*", | ||
| "libggml-cuda.so*", | ||
| "libggml-hip.so*", | ||
| "libggml-rpc.so*", | ||
| ] | ||
| if choice.install_kind in {"macos-arm64", "macos-x64"}: | ||
| return ["llama-server", "llama-quantize", "lib*.dylib"] | ||
| if choice.install_kind in {"windows-cpu", "windows-cuda"}: | ||
| if choice.install_kind in {"windows-cpu", "windows-cuda", "windows-hip"}: | ||
| return ["*.exe", "*.dll"] | ||
| raise PrebuiltFallback( | ||
| f"unsupported install kind for runtime overlay: {choice.install_kind}" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This branch only checks whether
nvidia-smiexists, not whether a usable NVIDIA GPU is present. On ROCm hosts that still havenvidia-smion PATH (stale driver packages or mixed tool images), the function bypasses ROCm probing and later defaults to a CUDA wheel index when CUDA parsing fails, which breaks AMD installs instead of using the ROCm index. Gate the NVIDIA path on a successful device probe before short-circuiting the ROCm fallback.Useful? React with 👍 / 👎.