From d25c570a06caaeb679bb34e97270e681565a0100 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Wed, 8 Apr 2026 12:07:39 +0000 Subject: [PATCH] Fix gemini round 4: remove risky bytes-vs-MB heuristic in _parse_memory_mb The previous heuristic divided any bare number above 10_000_000 by 1024*1024 on the assumption that large unit-less values were bytes. This misclassified small VRAM allocations: 5 MB of used VRAM reported as 5_242_880 bytes without a unit would be taken at face value and render as 5_242_880 MB (~5 TB) in the monitoring UI. Modern amd-smi always provides explicit units (MiB/GiB dict form), and legacy amd-smi returns bare numbers in MB -- the heuristic never had a real workload to handle. Drop it and default to MB for bare numeric input, keeping the existing unit-aware branches for dict / string inputs unchanged. The unrelated gemini suggestion to "default minor to 0" in the amd-smi version awk parser was intentionally NOT applied: rocm7.0 and rocm7.1 ship different wheel sets, so silently substituting 0 for a missing minor could install the wrong wheels. The existing reject-and-fall-through behaviour is safer. --- studio/backend/utils/hardware/amd.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/studio/backend/utils/hardware/amd.py b/studio/backend/utils/hardware/amd.py index 0cf51b4cb6..93daae4605 100644 --- a/studio/backend/utils/hardware/amd.py +++ b/studio/backend/utils/hardware/amd.py @@ -67,8 +67,10 @@ def _parse_numeric(value: Any) -> Optional[float]: def _parse_memory_mb(value: Any) -> Optional[float]: """Parse a memory value from amd-smi output and return MB. - Handles bare numbers (assumed MB), dict-shaped values with units - ({"value": 192, "unit": "GiB"}), and byte-scale heuristic fallback. + Handles bare numbers (assumed MB -- the amd-smi convention on every + version we have seen), dict-shaped values with explicit units + (``{"value": 192, "unit": "GiB"}`` on newer releases), and plain + strings like ``"8192 MiB"``. """ unit = "" raw_value = value @@ -98,10 +100,13 @@ def _parse_memory_mb(value: Any) -> Optional[float]: # Plain bytes return num / (1024 * 1024) - # No explicit unit -- heuristic: values > 10M are likely bytes - if num > 10_000_000: - return num / (1024 * 1024) - return num # Assume MB + # No explicit unit -- default to MB, which is the amd-smi convention + # for bare numeric values. A previous heuristic assumed values above + # ~10M were bytes, but that misclassifies small VRAM allocations + # (e.g. 5 MB = 5,242,880 reported without a unit) as ~5 TB. Modern + # amd-smi always ships explicit units, so the heuristic branch only + # fired for legacy output where MB was already the convention. + return num def _extract_gpu_metrics(gpu_data: dict) -> dict[str, Any]: