[Model] Cap derived cache budget and account for stager detach
Address review on #6629: - Cap the derived retention budget at a quarter of device capacity so a large staged total cannot monopolize a small device; the multiplier itself stays pending an instrumented target run. - Log every release decision (reason, cached bytes, effective budget and cap, staged total, free/total memory) and every staging OOM retry with its staged byte total, so a single target run validates the headroom multiplier directly. - Make stager detach symmetric: set_cache_retention now shrinks the previous cache's budget before growing the new one, so cache -> None -> same cache counts the staged bytes exactly once (regression test added). Signed-off-by: hsliuustc0106 <liuhongsheng4@huawei.com>
This commit is contained in:
1 parent
ba5943dddb
commit
c5295f3ffe
3 files changed
+97
-9
No files matched your search
@@ -237,12 +237,53 @@ def test_allocator_cache_budget_is_derived_from_attached_stager_bytes(patched_ru
|
||||
stager.set_cache_retention(retention)
|
||||
assert retention.budget_bytes == 2 * expected_bytes
|
||||
|
||||
# Detaching and re-attaching the same cache also counts the bytes once.
|
||||
stager.set_cache_retention(None)
|
||||
assert retention.budget_bytes == 0
|
||||
stager.set_cache_retention(retention)
|
||||
assert retention.budget_bytes == 2 * expected_bytes
|
||||
|
||||
# A second stager grows the budget by its own staged bytes.
|
||||
extra = PinnedModuleStager(torch.nn.Linear(2, 2), torch.device("cpu"), pin_memory=False)
|
||||
extra.set_cache_retention(retention)
|
||||
assert retention.budget_bytes == 2 * (expected_bytes + extra.staged_bytes)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("reserved", "allocated", "free", "expected_release"),
|
||||
[
|
||||
# Derived budget 2 * 1000 = 2000 uncapped, but capacity cap = 25 and
|
||||
# cached = 30 exceeds it, so the cap must trigger the release.
|
||||
(40, 10, 80, True),
|
||||
# Within the cap (cached = 20 <= 25) and the free floor holds.
|
||||
(30, 10, 80, False),
|
||||
],
|
||||
)
|
||||
def test_allocator_cache_budget_is_capped_by_device_capacity(
|
||||
monkeypatch,
|
||||
patched_runtime,
|
||||
reserved,
|
||||
allocated,
|
||||
free,
|
||||
expected_release,
|
||||
):
|
||||
empty_cache, _ = patched_runtime
|
||||
monkeypatch.setattr(torch.accelerator, "memory_reserved", lambda _device: reserved)
|
||||
monkeypatch.setattr(torch.accelerator, "memory_allocated", lambda _device: allocated)
|
||||
monkeypatch.setattr(
|
||||
residency_module.current_omni_platform,
|
||||
"get_device_memory",
|
||||
lambda _device: (free, 100),
|
||||
)
|
||||
retention = BoundedAllocatorCache(torch.device("cpu"))
|
||||
retention.grow_retention_budget(1000)
|
||||
|
||||
released = retention.release_if_needed()
|
||||
|
||||
assert released is expected_release
|
||||
assert empty_cache.call_count == int(expected_release)
|
||||
|
||||
|
||||
def test_allocator_cache_releases_when_telemetry_is_unavailable(monkeypatch, patched_runtime):
|
||||
empty_cache, _ = patched_runtime
|
||||
|
||||
|
||||
Reference in new issue
Block a user