Studio: fix ROCm visibility precedence + narrow ROCm child env
Two reviewer-flagged correctness bugs in the AMD GPU probe path. 1) ROCm visibility precedence was reversed. torch.cuda enumerates GPUs relative to HIP_VISIBLE_DEVICES / ROCR_VISIBLE_DEVICES on ROCm builds, but the probe's env-var lookup checked CUDA_VISIBLE_DEVICES first. With CUDA_VISIBLE_DEVICES=0,1 and HIP_VISIBLE_DEVICES=6,7 the probe returned [(0, ...), (1, ...)] when torch's view was actually [(6, ...), (7, ...)]. The wrong physical IDs flowed downstream into CUDA_VISIBLE_DEVICES for the llama-server subprocess, pinning it to GPUs 0,1 instead of 6,7. Fix: branch on torch.version.hip. On ROCm, prefer HIP > ROCR > CUDA (matches torch's own ordering). On NVIDIA, use CUDA only -- ignoring any HIP/ROCR vars the parent happens to have set. 2) Child env narrowing only set CUDA_VISIBLE_DEVICES. On ROCm, llama-server honors HIP/ROCR; if the parent shell exported HIP_VISIBLE_DEVICES=4,5 and the selector picked just GPU 4, the child still saw both because we never narrowed HIP/ROCR. Now we set all three on ROCm so the AMD subprocess actually sees the planned subset. Both branches verified via temp/pr_simulation/sim_5172_rocm_precedence.py (7/7 cases pass), including the reviewer's verbatim R5 case (CVD=0,1 + HIP/ROCR=6,7).
This commit is contained in:
parent
6e94603754
commit
eff55fb8db
1 changed files with 28 additions and 13 deletions
|
|
@ -609,19 +609,23 @@ class LlamaCppBackend:
|
||||||
return []
|
return []
|
||||||
if not hasattr(torch.cuda, "mem_get_info"):
|
if not hasattr(torch.cuda, "mem_get_info"):
|
||||||
return []
|
return []
|
||||||
# torch.cuda enumerates GPUs RELATIVE to CUDA_VISIBLE_DEVICES
|
# torch.cuda enumerates GPUs RELATIVE to the visibility mask.
|
||||||
# (or HIP_VISIBLE_DEVICES on ROCm). Downstream we feed these
|
# On NVIDIA builds the mask is CUDA_VISIBLE_DEVICES; on AMD
|
||||||
# IDs back into CUDA_VISIBLE_DEVICES for the llama-server
|
# ROCm builds it is HIP_VISIBLE_DEVICES (or ROCR_VISIBLE_DEVICES
|
||||||
# subprocess, so we must translate visible ordinals back to
|
# if HIP is unset). Downstream we feed these IDs back into the
|
||||||
# physical indices first; otherwise launching with
|
# llama-server subprocess as CVD, so we must translate visible
|
||||||
# ``CUDA_VISIBLE_DEVICES=2,3`` would get rewritten to
|
# ordinals back to physical indices first; otherwise launching
|
||||||
|
# with ``CUDA_VISIBLE_DEVICES=2,3`` would get rewritten to
|
||||||
# ``CUDA_VISIBLE_DEVICES=0,1`` and target the wrong GPUs.
|
# ``CUDA_VISIBLE_DEVICES=0,1`` and target the wrong GPUs.
|
||||||
physical_ids: Optional[list[int]] = None
|
physical_ids: Optional[list[int]] = None
|
||||||
cvd = (
|
if getattr(torch.version, "hip", None) is not None:
|
||||||
os.environ.get("CUDA_VISIBLE_DEVICES")
|
cvd = (
|
||||||
or os.environ.get("HIP_VISIBLE_DEVICES")
|
os.environ.get("HIP_VISIBLE_DEVICES")
|
||||||
or os.environ.get("ROCR_VISIBLE_DEVICES")
|
or os.environ.get("ROCR_VISIBLE_DEVICES")
|
||||||
)
|
or os.environ.get("CUDA_VISIBLE_DEVICES")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cvd = os.environ.get("CUDA_VISIBLE_DEVICES")
|
||||||
if cvd and cvd.strip():
|
if cvd and cvd.strip():
|
||||||
try:
|
try:
|
||||||
physical_ids = [int(x.strip()) for x in cvd.split(",") if x.strip()]
|
physical_ids = [int(x.strip()) for x in cvd.split(",") if x.strip()]
|
||||||
|
|
@ -1792,9 +1796,20 @@ class LlamaCppBackend:
|
||||||
f"{new_ld}:{existing_ld}" if existing_ld else new_ld
|
f"{new_ld}:{existing_ld}" if existing_ld else new_ld
|
||||||
)
|
)
|
||||||
|
|
||||||
# Pin to selected GPU(s) via CUDA_VISIBLE_DEVICES
|
# Pin to selected GPU(s). On ROCm, llama-server (and any torch
|
||||||
|
# in the subprocess) honors HIP_VISIBLE_DEVICES / ROCR_VISIBLE_DEVICES;
|
||||||
|
# narrowing only CUDA_VISIBLE_DEVICES leaves an AMD child seeing
|
||||||
|
# the full HIP/ROCR set the parent inherited.
|
||||||
if gpu_indices is not None:
|
if gpu_indices is not None:
|
||||||
env["CUDA_VISIBLE_DEVICES"] = ",".join(str(i) for i in gpu_indices)
|
pinned = ",".join(str(i) for i in gpu_indices)
|
||||||
|
env["CUDA_VISIBLE_DEVICES"] = pinned
|
||||||
|
try:
|
||||||
|
import torch as _torch
|
||||||
|
if getattr(_torch.version, "hip", None) is not None:
|
||||||
|
env["HIP_VISIBLE_DEVICES"] = pinned
|
||||||
|
env["ROCR_VISIBLE_DEVICES"] = pinned
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
self._stdout_lines = []
|
self._stdout_lines = []
|
||||||
self._process = subprocess.Popen(
|
self._process = subprocess.Popen(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue