More aggressive GPU memory cleanup function, tries to release PyTorch reserved but unallocated memory. Args: force_sync: Whether to force device synchronization max_retries: Maximum number of retries
(force_sync: bool = True, max_retries: int = 3)
| 29 | |
| 30 | |
| 31 | def aggressive_empty_cache(force_sync: bool = True, max_retries: int = 3) -> None: |
| 32 | """ |
| 33 | More aggressive GPU memory cleanup function, tries to release PyTorch reserved |
| 34 | but unallocated memory. |
| 35 | |
| 36 | Args: |
| 37 | force_sync: Whether to force device synchronization |
| 38 | max_retries: Maximum number of retries |
| 39 | """ |
| 40 | device = get_torch_device() |
| 41 | if not device.is_available(): |
| 42 | return |
| 43 | |
| 44 | for attempt in range(max_retries): |
| 45 | # Record memory status before cleanup |
| 46 | before_reserved = device.memory_reserved() |
| 47 | before_allocated = device.memory_allocated() |
| 48 | |
| 49 | # Run garbage collection |
| 50 | gc.collect() |
| 51 | |
| 52 | # Clear PyTorch cache |
| 53 | device.empty_cache() |
| 54 | |
| 55 | # Force synchronization (optional) |
| 56 | if force_sync: |
| 57 | device.synchronize() |
| 58 | |
| 59 | # Record memory status after cleanup |
| 60 | after_reserved = device.memory_reserved() |
| 61 | after_allocated = device.memory_allocated() |
| 62 | |
| 63 | # Calculate freed memory |
| 64 | reserved_freed = before_reserved - after_reserved |
| 65 | allocated_freed = before_allocated - after_allocated |
| 66 | |
| 67 | logger.info( |
| 68 | f"Memory cleanup attempt {attempt + 1}: Freed {reserved_freed / 1024**3:.2f} GB reserved, " |
| 69 | f"{allocated_freed / 1024**3:.2f} GB allocated" |
| 70 | ) |
| 71 | |
| 72 | # Stop retrying if little memory was freed |
| 73 | if reserved_freed < 1024**3: # less than 1GB |
| 74 | break |
| 75 | |
| 76 | |
| 77 | def reset_memory_stats() -> None: |
no test coverage detected