mirror of
https://github.com/Niko1221/Strata.git
synced 2026-11-07 18:35:04 -10:00
AMD: gfx1101 (RX 7800 XT, #254 by jhohertz) and gfx1200 (RX 9060 XT, #256 by Efeisot) as community-validated cards
Cut down from #254 and #256 onto 0.1.30's AMD tables: - setup.py: AMD_ARCHS / AMD_NAMES / ROCM_INDEXES / AMD_CARDS list gfx1101 (TheRock gfx110X-dgpu) and gfx1200 (gfx120X-all); amd_gpus() takes the sysfs root so the detection can be tested. - cmake/hip_backend.cmake: gfx1101 and gfx1200 build without the "not validated" warning (a status line names them community-validated); gfx1102 (#192: ctest only) keeps the warning. - docs/AMD_HIP.md (Community-validated cards: the owners' setups, ctest and numbers) and README. - tools/test_setup_amd.py: detection on a mocked KFD topology (every family, the CPU node, an iGPU and gfx1102 listed as not supported, product-name fallbacks, the ROCm index per family). Left out: the PRs' own cmake/device.cu arch checks (0.1.30's compiled_for covers them), the dp4a change (main has it), math_constants.h, the bench JSONs, the launcher, and both hipBLASLt tables (neither PR measured the prompt speed without its table). Co-Authored-By: Joseph Hohertz <[email protected]> Co-Authored-By: efeisot <[email protected]>
This commit is contained in:
1 parent
600d73070c
commit
489623c7d3
5 files changed
+145
-30
No files matched your search
@@ -84,7 +84,8 @@ one later with `SETUP.bat` (the same as `START-HERE.bat --setup`; on Linux `./se
|
||||
For **OrcaRouter's Flash-Next Uncensored IQ3_XXS**, see the [manual compatibility setup](docs/ORCA.md).
|
||||
It needs an explicit packing conversion and is not an installer menu option.
|
||||
|
||||
An **AMD Radeon RX 7900 XT / XTX, RX 9070 / 9070 XT or Radeon AI PRO R9700 on Linux** works too (experimental):
|
||||
An **AMD Radeon RX 7900 XT / XTX, RX 9070 / 9070 XT or Radeon AI PRO R9700 on Linux** works too (experimental; the
|
||||
RX 7800 XT / 7700 XT and RX 9060 XT were validated by their owners):
|
||||
`./setup.sh --backend hip`, chosen by itself on a PC with no NVIDIA card Strata can use. It installs ROCm without sudo
|
||||
and compiles the engine (one GPU, no images yet). Details: [AMD HIP](docs/AMD_HIP.md).
|
||||
|
||||
|
||||
@@ -4,20 +4,23 @@
|
||||
if(NOT DEFINED CMAKE_HIP_ARCHITECTURES OR CMAKE_HIP_ARCHITECTURES STREQUAL "")
|
||||
set(CMAKE_HIP_ARCHITECTURES gfx1100 CACHE STRING "Strata HIP target architecture(s), e.g. gfx1100 or gfx1100;gfx1201")
|
||||
endif()
|
||||
# Validated on real cards: gfx1100 (RX 7900 XT / XTX) and gfx1201 (RX 9070 / 9070 XT, Radeon AI PRO R9700).
|
||||
# The other RDNA3 / RDNA4 wave32 chips have the same LDS limit and dot4 instruction and build the same code, but
|
||||
# the maintainers have not run them (community reports: gfx1102 #192, gfx1200 #176).
|
||||
# Validated on real cards: gfx1100 (RX 7900 XT / XTX) and gfx1201 (RX 9070 / 9070 XT, Radeon AI PRO R9700) by the
|
||||
# maintainers; gfx1101 (RX 7800 XT, #254) and gfx1200 (RX 9060 XT, #256) by their owners. gfx1102 (RX 7600) has the
|
||||
# same LDS limit and dot4 instruction and passed ctest (#192), but no model run has been reported yet.
|
||||
set(_strata_hip_validated gfx1100 gfx1201)
|
||||
set(_strata_hip_unvalidated gfx1101 gfx1102 gfx1200)
|
||||
set(_strata_hip_community gfx1101 gfx1200)
|
||||
set(_strata_hip_unvalidated gfx1102)
|
||||
set(STRATA_HIP_ARCH_LIST "")
|
||||
foreach(_arch IN LISTS CMAKE_HIP_ARCHITECTURES)
|
||||
string(REGEX REPLACE ":.*$" "" _base "${_arch}") # gfx1100:xnack- -> gfx1100
|
||||
if(_base IN_LIST _strata_hip_validated)
|
||||
elseif(_base IN_LIST _strata_hip_community)
|
||||
message(STATUS "Strata HIP: ${_base} was validated by community reports (docs/AMD_HIP.md)")
|
||||
elseif(_base IN_LIST _strata_hip_unvalidated)
|
||||
message(WARNING "Strata HIP: ${_base} builds, but it is not validated on a real card yet; please report results")
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Strata HIP supports wave32 gfx1100 and gfx1201 (unvalidated: ${_strata_hip_unvalidated}); "
|
||||
"Strata HIP supports wave32 gfx1100, gfx1101, gfx1200 and gfx1201 (unvalidated: ${_strata_hip_unvalidated}); "
|
||||
"CMAKE_HIP_ARCHITECTURES is '${CMAKE_HIP_ARCHITECTURES}'")
|
||||
endif()
|
||||
list(APPEND STRATA_HIP_ARCH_LIST "${_base}")
|
||||
|
||||
+35
-12
@@ -1,8 +1,9 @@
|
||||
# Experimental AMD HIP backend (gfx1100, gfx1201)
|
||||
# Experimental AMD HIP backend (gfx1100, gfx1101, gfx1200, gfx1201)
|
||||
|
||||
This is a Linux source build for the RX 7900 XT / XTX (RDNA3, gfx1100) and the
|
||||
RX 9070 / 9070 XT / Radeon AI PRO R9700 (RDNA4, gfx1201; see [RDNA4](#rdna4-gfx1201)).
|
||||
It is opt-in; the NVIDIA installer and CUDA build remain the default. Other AMD
|
||||
RX 9070 / 9070 XT / Radeon AI PRO R9700 (RDNA4, gfx1201; see [RDNA4](#rdna4-gfx1201)). The RX 7800 XT / 7700 XT
|
||||
(gfx1101) and the RX 9060 XT (gfx1200) were validated by their owners (see [Community-validated
|
||||
cards](#community-validated-cards)). It is opt-in; the NVIDIA installer and CUDA build remain the default. Other AMD
|
||||
architectures, wave64, Windows HIP, and mixed AMD/NVIDIA execution are outside this contribution.
|
||||
|
||||
The backend maps the CUDA-shaped runtime and BLAS calls to HIP/hipBLAS, uses
|
||||
@@ -15,8 +16,8 @@ This does not claim bit-identical model answers across backends. See
|
||||
|
||||
## Install with setup (recommended)
|
||||
|
||||
On Linux with an RX 7900 XT / XTX or an RX 9070 / 9070 XT / Radeon AI PRO R9700 and the kernel's amdgpu driver
|
||||
(no ROCm install needed):
|
||||
On Linux with an RX 7900 XT / XTX, RX 7800 XT / 7700 XT, RX 9060 XT, RX 9070 / 9070 XT or Radeon AI PRO R9700 and
|
||||
the kernel's amdgpu driver (no ROCm install needed):
|
||||
|
||||
```sh
|
||||
./setup.sh --backend hip
|
||||
@@ -26,8 +27,8 @@ On Linux with an RX 7900 XT / XTX or an RX 9070 / 9070 XT / Radeon AI PRO R9700
|
||||
supported. On a PC without an NVIDIA card Strata can use, `--backend hip` is chosen automatically.
|
||||
- **ROCm:** a system ROCm 7 in `/opt/rocm` (or `$ROCM_PATH`) with hipcc and hipBLAS is used when present. Otherwise
|
||||
(or when it is older than 7.0) ROCm is installed into `.venv` from AMD's TheRock wheels (~10 GB, no sudo), pinned
|
||||
to the version this backend was tested with, from the card family's index: `gfx110X-dgpu` for gfx1100,
|
||||
`gfx120X-all` for gfx1201 (`STRATA_ROCM_VERSION` / `STRATA_ROCM_INDEX` override them).
|
||||
to the version this backend was tested with, from the card family's index: `gfx110X-dgpu` for gfx1100 / gfx1101,
|
||||
`gfx120X-all` for gfx1200 / gfx1201 (`STRATA_ROCM_VERSION` / `STRATA_ROCM_INDEX` override them).
|
||||
- **Engine:** compiled on your PC for the card's architecture (10-20 minutes, once; again after a `git pull` that
|
||||
changes it, or when you pick a card of another architecture). This needs a C++ compiler and git
|
||||
(`sudo apt install build-essential git`).
|
||||
@@ -54,9 +55,9 @@ cmake -S . -B build-hip \
|
||||
cmake --build build-hip --target strata -j2
|
||||
```
|
||||
|
||||
`CMAKE_HIP_ARCHITECTURES` is `gfx1100`, `gfx1201`, or a list such as `"gfx1100;gfx1201"` (one binary for both).
|
||||
gfx1101, gfx1102 and gfx1200 (the same wave32, 64 KiB LDS and dot4 instruction) build with a warning: they have
|
||||
not been validated on a real card here. At startup the engine and `strata-device` compare each GPU they use
|
||||
`CMAKE_HIP_ARCHITECTURES` is `gfx1100`, `gfx1101`, `gfx1200`, `gfx1201`, or a list such as `"gfx1100;gfx1201"`
|
||||
(one binary for both). gfx1102 (the same wave32, 64 KiB LDS and dot4 instruction) builds with a warning: it passed
|
||||
ctest (#192) but no model run has been reported. At startup the engine and `strata-device` compare each GPU they use
|
||||
(`gcnArchName` up to the `:` feature suffix) with the architectures the binary was compiled for, and require
|
||||
wave32. A binary carried to another card stops with the card's name, its architecture and the build's list,
|
||||
instead of failing later with "invalid device function".
|
||||
@@ -168,8 +169,30 @@ an RX 9070 XT 16 GB and a Radeon AI PRO R9700 32 GB (both gfx1201), a Ryzen 9 39
|
||||
expert arena (a Windows limit that also applies here).
|
||||
- **Known:** rarely (about 1 start in 10) a HIP run's greedy output differs from another start's at some token, on
|
||||
one card or two and on engine 0.1.29 as well; not yet explained.
|
||||
- **Not validated:** gfx1200 (RX 9060 XT; a community report is #176), images, long contexts beyond 16K,
|
||||
answer-quality benchmarks.
|
||||
- **Not validated:** images, long contexts beyond 16K, answer-quality benchmarks.
|
||||
|
||||
## Community-validated cards
|
||||
|
||||
Run by their owners, not on the maintainers' machines; setup accepts them like gfx1100 / gfx1201. No hipBLASLt table
|
||||
is shipped for them (make one with [Tuning table](#tuning-table) and compare the prompt speed with and without it).
|
||||
|
||||
- **gfx1101, RX 7800 XT 16 GB** (jhohertz, #254; engine 0.1.29, Ryzen 9 5950X, 121 GiB RAM, system ROCm with
|
||||
hipBLASLt 1.4.1): `./setup.sh --backend hip` detected the card and compiled the engine; `strata-device --selftest`
|
||||
passed; ctest 30/32 (`ple_parity` needs the Q2_0 fixture, `platform_memory_test` the memlock limit). Coder IQ1_M,
|
||||
64K context, MTP, with a table the owner calibrated: fresh prompts of 4K-9K tokens at 898-953 tok/s, decode
|
||||
38-44 tok/s (128 tokens).
|
||||
- **gfx1200, RX 9060 XT 16 GB** (Efeisot, #256 after #176; engine 0.1.29, Ryzen 9 7950X, 64 GiB RAM, ROCm 7.2 with
|
||||
hipBLASLt 1.2.2): ctest 32/32 (without `ple_parity` and `platform_memory_test`). Coder IQ1_M, greedy, MTP
|
||||
`--spec 4 --spec-min-p 0.5`, with a table the owner calibrated:
|
||||
|
||||
| prompt | prompt speed | decode |
|
||||
|---|---|---|
|
||||
| 2,374 tokens | 540 tok/s | 27.1 tok/s (0.69 draft acceptance; 31.0 at 1.00) |
|
||||
| 65K (`--kv int8 --kv-resident 65536 --prefill 16384`) | 748-753 tok/s | 26-40 tok/s by acceptance |
|
||||
| 130K (the same flags) | 725 tok/s | - |
|
||||
|
||||
Greedy output was the same across runs. For comparison, llama.cpp's HIP build measured 20 tok/s decode and
|
||||
450 tok/s prompt on that card.
|
||||
|
||||
## Tuning table
|
||||
|
||||
|
||||
@@ -710,27 +710,34 @@ def cuda_lib_dirs():
|
||||
|
||||
# ------------------------------------------------------------------------------------------------ AMD (experimental)
|
||||
# The RX 7900 XT / XTX (gfx1100) and the RX 9070 series / Radeon AI PRO R9700 (gfx1201) on Linux, through the HIP
|
||||
# backend (docs/AMD_HIP.md). There is no ready-made AMD engine: ROCm comes from AMD's TheRock Python wheels into .venv
|
||||
# (no sudo; a system ROCm 7 in /opt/rocm is used when it has hipcc and hipBLAS) and the engine is compiled here for
|
||||
# the card. One GPU, no images yet.
|
||||
# backend (docs/AMD_HIP.md); the RX 7800 XT / 7700 XT (gfx1101, #254) and the RX 9060 XT (gfx1200, #256) were run by
|
||||
# their owners. There is no ready-made AMD engine: ROCm comes from AMD's TheRock Python wheels into .venv (no sudo;
|
||||
# a system ROCm 7 in /opt/rocm is used when it has hipcc and hipBLAS) and the engine is compiled here for the cards.
|
||||
# No images yet.
|
||||
ROCM_INDEXES = {"gfx1100": "https://rocm.nightlies.amd.com/v2/gfx110X-dgpu/", # TheRock's wheels per GPU family
|
||||
"gfx1101": "https://rocm.nightlies.amd.com/v2/gfx110X-dgpu/",
|
||||
"gfx1200": "https://rocm.nightlies.amd.com/v2/gfx120X-all/",
|
||||
"gfx1201": "https://rocm.nightlies.amd.com/v2/gfx120X-all/"}
|
||||
ROCM_VERSION = os.environ.get("STRATA_ROCM_VERSION", "7.10.0a20251120") # what Strata's HIP build was tested with
|
||||
ROCM_SYSTEM_MIN = (7, 0) # an older system ROCm is passed over for the wheels (gfx1201 needs ROCm 6.4 or newer)
|
||||
AMD_ARCHS = ("gfx1100", "gfx1201")
|
||||
AMD_ARCHS = ("gfx1100", "gfx1101", "gfx1200", "gfx1201")
|
||||
AMD_NAMES = {"gfx1100": "AMD Radeon RX 7900 series (gfx1100)", # when sysfs has no product name
|
||||
"gfx1101": "AMD Radeon RX 7800 XT / 7700 XT (gfx1101)",
|
||||
"gfx1200": "AMD Radeon RX 9060 series (gfx1200)",
|
||||
"gfx1201": "AMD Radeon RX 9070 series / AI PRO R9700 (gfx1201)"}
|
||||
AMD_CARDS = "the RX 7900 XT / XTX (gfx1100) and the RX 9070 / 9070 XT / Radeon AI PRO R9700 (gfx1201)"
|
||||
AMD_CARDS = ("the RX 7900 XT / XTX (gfx1100), RX 7800 XT / 7700 XT (gfx1101), RX 9060 XT (gfx1200) and "
|
||||
"RX 9070 / 9070 XT / Radeon AI PRO R9700 (gfx1201)")
|
||||
|
||||
|
||||
def rocm_index(arch):
|
||||
return os.environ.get("STRATA_ROCM_INDEX") or ROCM_INDEXES[arch]
|
||||
|
||||
|
||||
def amd_gpus():
|
||||
def amd_gpus(sysfs="/sys"):
|
||||
"""AMD GPUs from the kernel's KFD topology (the amdgpu driver; no ROCm needed), numbered as HIP numbers them:
|
||||
the GPU nodes in order, the CPU nodes skipped. Integrated GPUs are listed too (not supported)."""
|
||||
base = Path("/sys/class/kfd/kfd/topology/nodes")
|
||||
the GPU nodes in order, the CPU nodes skipped. Integrated GPUs are listed too (not supported).
|
||||
sysfs: the tree to read (tools/test_setup_amd.py passes a mocked one)."""
|
||||
base = Path(sysfs) / "class/kfd/kfd/topology/nodes"
|
||||
found = []
|
||||
if WIN or not base.is_dir():
|
||||
return found
|
||||
@@ -746,7 +753,7 @@ def amd_gpus():
|
||||
except (OSError, ValueError):
|
||||
continue
|
||||
arch = f"gfx{ver // 10000}{(ver // 100) % 100:x}{ver % 100:x}"
|
||||
dev = Path(f"/sys/class/drm/renderD{props.get('drm_render_minor', '')}/device")
|
||||
dev = Path(sysfs) / f"class/drm/renderD{props.get('drm_render_minor', '')}/device"
|
||||
try:
|
||||
vram = int((dev / "mem_info_vram_total").read_text()) / 2 ** 30
|
||||
except (OSError, ValueError):
|
||||
@@ -1767,8 +1774,8 @@ def main() -> int:
|
||||
"this mode the experts the GPU does not hold are copied into RAM once when they fit (resident), "
|
||||
"else read through the OS file cache (mmap); resident / mmap force one of the two")
|
||||
ap.add_argument("--backend", choices=["cuda", "hip"],
|
||||
help="cuda = NVIDIA (default), hip = AMD RX 7900 XT/XTX or RX 9070 / AI PRO R9700 on Linux (experimental; chosen by itself "
|
||||
"when the PC has no NVIDIA card Strata can use)")
|
||||
help="cuda = NVIDIA (default), hip = AMD RX 7900 / 7800 / 7700 XT, RX 9060 XT / 9070 / AI PRO R9700 on "
|
||||
"Linux (experimental; chosen by itself when the PC has no NVIDIA card Strata can use)")
|
||||
ap.add_argument("--skip-build", action="store_true", help=argparse.SUPPRESS)
|
||||
a = ap.parse_args()
|
||||
if a.gpu is not None: # --gpu 0,2 means --gpus 0,2 (a user tried it: issue report)
|
||||
@@ -1882,7 +1889,7 @@ def main() -> int:
|
||||
if not found:
|
||||
fail("no NVIDIA GPU found (nvidia-smi did not answer)",
|
||||
"install the NVIDIA driver from https://www.nvidia.com/drivers and restart the PC"
|
||||
+ ("; an AMD RX 7900 XT/XTX or RX 9070 / AI PRO R9700: --backend hip" if amd else ""))
|
||||
+ (f"; AMD ({', '.join(AMD_ARCHS)}): --backend hip" if amd else ""))
|
||||
if len(found) > 1 or gpu_problem(found[0]) is not None:
|
||||
gpu_table(found)
|
||||
sel = choose_gpus(a, found) # asked when two or more cards can share the model
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
"""Tests for setup.py's AMD card detection on a mocked KFD topology (/sys/class/kfd + /sys/class/drm): the arch
|
||||
names from gfx_target_version, the CPU node skipped, HIP numbering, product names, which cards are supported and
|
||||
which TheRock index each family installs from. No GPU, no ROCm, no downloads.
|
||||
|
||||
python -m unittest tools.test_setup_amd
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
import setup # noqa: E402
|
||||
|
||||
|
||||
def fake_sysfs(root: Path, nodes: list) -> None:
|
||||
"""nodes: (gfx_target_version, simd_count, render_minor, product_name or None, vram_bytes)"""
|
||||
for i, (ver, simd, minor, name, vram) in enumerate(nodes):
|
||||
n = root / "class/kfd/kfd/topology/nodes" / str(i)
|
||||
n.mkdir(parents=True)
|
||||
(n / "properties").write_text(f"cpu_cores_count {0 if simd else 12}\nsimd_count {simd}\n"
|
||||
f"gfx_target_version {ver}\ndrm_render_minor {minor}\n")
|
||||
if simd:
|
||||
d = root / f"class/drm/renderD{minor}/device"
|
||||
d.mkdir(parents=True)
|
||||
(d / "mem_info_vram_total").write_text(str(vram))
|
||||
if name is not None:
|
||||
(d / "product_name").write_text(name + "\n")
|
||||
|
||||
|
||||
class KfdDetection(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.TemporaryDirectory()
|
||||
self.root = Path(self.tmp.name)
|
||||
self.win = setup.WIN
|
||||
setup.WIN = False
|
||||
|
||||
def tearDown(self):
|
||||
setup.WIN = self.win
|
||||
self.tmp.cleanup()
|
||||
|
||||
def test_every_family(self):
|
||||
fake_sysfs(self.root, [
|
||||
(0, 0, 0, None, 0), # the CPU node: skipped
|
||||
(110001, 120, 128, "", 16 << 30), # gfx1101 without a product name
|
||||
(120000, 64, 129, None, 16 << 30), # gfx1200, no product_name file
|
||||
(120001, 128, 130, "AMD Radeon AI PRO R9700", 32 << 30),
|
||||
(110002, 64, 131, None, 8 << 30), # gfx1102: listed, not supported
|
||||
(100306, 4, 132, None, 512 << 20), # an integrated gfx1036: listed, not supported
|
||||
(110000, 192, 133, "Radeon RX 7900 XTX", 24 << 30),
|
||||
])
|
||||
g = setup.amd_gpus(str(self.root))
|
||||
self.assertEqual([x["arch"] for x in g], ["gfx1101", "gfx1200", "gfx1201", "gfx1102", "gfx1036", "gfx1100"])
|
||||
self.assertEqual([x["index"] for x in g], [0, 1, 2, 3, 4, 5]) # HIP numbers: GPU nodes only
|
||||
self.assertEqual(g[0]["name"], setup.AMD_NAMES["gfx1101"])
|
||||
self.assertEqual(g[1]["name"], setup.AMD_NAMES["gfx1200"])
|
||||
self.assertEqual(g[2]["name"], "AMD Radeon AI PRO R9700")
|
||||
self.assertEqual(g[3]["name"], "AMD Radeon (gfx1102)")
|
||||
self.assertAlmostEqual(g[2]["vram_gb"], 32.0)
|
||||
ok = [x["arch"] for x in g if setup.amd_problem(x) is None]
|
||||
self.assertEqual(ok, ["gfx1101", "gfx1200", "gfx1201", "gfx1100"])
|
||||
self.assertIn("gfx1102", setup.amd_problem(g[3]))
|
||||
self.assertIn("gfx1036", setup.amd_problem(g[4]))
|
||||
|
||||
def test_no_kfd(self):
|
||||
self.assertEqual(setup.amd_gpus(str(self.root)), [])
|
||||
|
||||
def test_rocm_index_per_family(self):
|
||||
for arch in setup.AMD_ARCHS:
|
||||
self.assertIn(arch, setup.ROCM_INDEXES)
|
||||
self.assertTrue(setup.ROCM_INDEXES["gfx1101"].endswith("/gfx110X-dgpu/"))
|
||||
self.assertTrue(setup.ROCM_INDEXES["gfx1200"].endswith("/gfx120X-all/"))
|
||||
self.assertEqual(setup.ROCM_INDEXES["gfx1101"], setup.ROCM_INDEXES["gfx1100"])
|
||||
self.assertEqual(setup.ROCM_INDEXES["gfx1200"], setup.ROCM_INDEXES["gfx1201"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user