fix(p1g): garde-fou VRAM adapté à la mémoire unifiée (DGX GB10)
resolve_device('auto') renvoyait 'cpu' sur le GB10 : le plafond max_total_gb=6
(pensé pour la RTX 12 Go dédiés) voyait used≈99 Go car la mémoire UNIFIÉE compte
la RAM système. Au-dessus de DEFAULT_LARGE_VRAM_GB=24 (grosse carte / mémoire
unifiée), le plafond n'est plus appliqué ; seul free >= min_free_gb décide.
RTX (<=24 Go) inchangée.
Détecté au bench GB10 2026-06-08 (auto->cpu, OCR 10x plus lent). +2 tests (17/17).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,12 @@ _VALID = {"cpu", "cuda", "auto"}
|
||||
# Garde-fous par défaut (Go).
|
||||
DEFAULT_MIN_FREE_GB = 2.0 # VRAM libre minimale pour autoriser cuda
|
||||
DEFAULT_MAX_TOTAL_GB = 6.0 # plafond d'usage VRAM total après bascule
|
||||
# Au-delà de ce total VRAM, on considère une grosse carte (data-center) ou une
|
||||
# mémoire UNIFIÉE (DGX GB10 : ~121 Go partagés CPU+GPU). Dans ce cas `used`
|
||||
# (= total - free) inclut la RAM système → le plafond fixe `max_total_gb` (pensé
|
||||
# pour la RTX 12 Go dédiés) devient un faux positif qui force CPU à tort. On ne
|
||||
# l'applique donc QUE sous ce seuil ; au-dessus, seul `free ≥ min_free_gb` décide.
|
||||
DEFAULT_LARGE_VRAM_GB = 24.0
|
||||
|
||||
|
||||
def _env_override() -> Optional[str]:
|
||||
@@ -135,13 +141,22 @@ def resolve_device(
|
||||
)
|
||||
return "cpu"
|
||||
|
||||
if used_gb > max_total_gb:
|
||||
# Plafond d'usage : seulement sur carte dédiée "petite" (type RTX). Sur grosse
|
||||
# mémoire / mémoire unifiée (GB10), `used` inclut la RAM système → non pertinent.
|
||||
if total_gb <= DEFAULT_LARGE_VRAM_GB and used_gb > max_total_gb:
|
||||
logger.info(
|
||||
"auto: usage VRAM %.1f Go > plafond %.1f Go — CPU",
|
||||
used_gb, max_total_gb,
|
||||
"auto: usage VRAM %.1f Go > plafond %.1f Go (carte %.1f Go) — CPU",
|
||||
used_gb, max_total_gb, total_gb,
|
||||
)
|
||||
return "cpu"
|
||||
|
||||
if total_gb > DEFAULT_LARGE_VRAM_GB:
|
||||
logger.info(
|
||||
"auto: grosse mémoire/unifiée %.1f Go, libre %.1f Go — CUDA (plafond ignoré)",
|
||||
total_gb, free_gb,
|
||||
)
|
||||
return "cuda"
|
||||
|
||||
logger.info(
|
||||
"auto: VRAM libre %.1f Go (usage %.1f/%.1f Go) — CUDA",
|
||||
free_gb, used_gb, total_gb,
|
||||
|
||||
@@ -105,6 +105,26 @@ def test_resolve_auto_cuda_when_under_total_cap(monkeypatch):
|
||||
max_total_gb=6.0) == "cuda"
|
||||
|
||||
|
||||
# ── mémoire unifiée / grosse carte (DGX GB10) : plafond inapplicable ─────────
|
||||
|
||||
def test_resolve_auto_cuda_on_unified_memory_ignores_total_cap(monkeypatch):
|
||||
"""Mémoire unifiée GB10 : total=121, free=22 → used=99 > cap 6, MAIS total
|
||||
> seuil grosse mémoire (24) → plafond ignoré, free 22 ≥ min 2 → CUDA.
|
||||
Sans ce comportement, le DGX tomberait à tort sur CPU (régression observée
|
||||
au bench GB10 2026-06-08)."""
|
||||
monkeypatch.delenv("RPA_VISION_DEVICE", raising=False)
|
||||
with _mock_cuda(available=True, free_gb=22.0, total_gb=121.0):
|
||||
assert device_policy.resolve_device("auto", min_free_gb=2.0,
|
||||
max_total_gb=6.0) == "cuda"
|
||||
|
||||
|
||||
def test_resolve_auto_cpu_on_large_memory_when_free_too_low(monkeypatch):
|
||||
"""Grosse mémoire mais free < min → CPU (free reste le garde-fou réel)."""
|
||||
monkeypatch.delenv("RPA_VISION_DEVICE", raising=False)
|
||||
with _mock_cuda(available=True, free_gb=1.0, total_gb=121.0):
|
||||
assert device_policy.resolve_device("auto", min_free_gb=2.0) == "cpu"
|
||||
|
||||
|
||||
# ── override env RPA_VISION_DEVICE ──────────────────────────────────────────
|
||||
|
||||
def test_env_override_cpu_forces_cpu_even_in_auto(monkeypatch):
|
||||
|
||||
Reference in New Issue
Block a user