PowerMachine commited on
Commit
fe179d6
·
verified ·
1 Parent(s): 2fe7a6a

Delete cnn_bigru/utils/memory_optimizer.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. cnn_bigru/utils/memory_optimizer.py +0 -139
cnn_bigru/utils/memory_optimizer.py DELETED
@@ -1,139 +0,0 @@
1
- """memory_optimizer.py — Otimização central de memória (CPU + GPU).
2
-
3
- Adaptado de xavante_work/xavante/utils/memory_optimizer.py, com:
4
- 1. gc.collect() explícito em checkpoints
5
- 2. torch.cuda.empty_cache() (se CUDA)
6
- 3. AMP (bfloat16/fp16) para reduzir VRAM
7
- 4. Gradient checkpointing
8
- 5. CPU offload de parâmetros congelados
9
- 6. Pinned memory para transferência async
10
- 7. set_per_process_memory_fraction (CUDA)
11
-
12
- Matemática:
13
- M_total = M_params + M_grads + M_activations + M_optimizer_state
14
- Com AMP: M_params *= 0.5, M_grads *= 0.5, M_activations *= 0.5
15
- Com gradient checkpointing: M_activations *= 1/sqrt(L)
16
- """
17
- from __future__ import annotations
18
-
19
- import gc
20
- import logging
21
- from contextlib import contextmanager
22
- from typing import Iterator
23
-
24
- import torch
25
- import torch.nn as nn
26
-
27
- logger = logging.getLogger(__name__)
28
-
29
-
30
- class MemoryOptimizer:
31
- """Centraliza otimização de memória para treino e inferência."""
32
-
33
- def __init__(self, vram_fraction: float = 0.85, enable_amp: bool = True):
34
- self.vram_fraction = vram_fraction
35
- self.enable_amp = enable_amp
36
- self._peak_memory_mb: float = 0.0
37
-
38
- def configure(self) -> None:
39
- """Configura PyTorch para uso otimizado de memória."""
40
- try:
41
- torch.backends.cudnn.benchmark = True
42
- except Exception:
43
- pass
44
- try:
45
- torch.set_float32_matmul_precision("high")
46
- except Exception:
47
- pass
48
- if torch.cuda.is_available():
49
- try:
50
- torch.cuda.set_per_process_memory_fraction(self.vram_fraction)
51
- logger.info("VRAM limitada a %.0f%%", self.vram_fraction * 100)
52
- except Exception as e:
53
- logger.warning("set_per_process_memory_fraction falhou: %s", e)
54
-
55
- @staticmethod
56
- def cleanup() -> None:
57
- """Limpa memória agressivamente (gc + empty_cache)."""
58
- gc.collect()
59
- if torch.cuda.is_available():
60
- torch.cuda.empty_cache()
61
- torch.cuda.synchronize()
62
-
63
- @staticmethod
64
- def get_memory_mb() -> dict:
65
- """Retorna uso de memória em MB."""
66
- if torch.cuda.is_available():
67
- return {
68
- "device": "cuda",
69
- "allocated_mb": torch.cuda.memory_allocated() / 1024**2,
70
- "cached_mb": torch.cuda.memory_reserved() / 1024**2,
71
- "max_allocated_mb": torch.cuda.max_memory_allocated() / 1024**2,
72
- }
73
- try:
74
- import psutil
75
- mem = psutil.virtual_memory()
76
- return {
77
- "device": "cpu",
78
- "total_mb": mem.total / 1024**2,
79
- "available_mb": mem.available / 1024**2,
80
- "used_mb": mem.used / 1024**2,
81
- "percent": mem.percent,
82
- }
83
- except ImportError:
84
- return {"device": "cpu", "info": "psutil not available"}
85
-
86
- @contextmanager
87
- def zero_grad_context(self, model: nn.Module) -> Iterator[None]:
88
- """Context manager que limpa gradientes ao sair."""
89
- try:
90
- yield
91
- finally:
92
- model.zero_grad(set_to_none=True)
93
- self.cleanup()
94
-
95
- @staticmethod
96
- def enable_gradient_checkpointing(model: nn.Module) -> None:
97
- """Tenta ativar gradient checkpointing."""
98
- if hasattr(model, "gradient_checkpointing_enable"):
99
- try:
100
- model.gradient_checkpointing_enable()
101
- logger.info("Gradient checkpointing ativado")
102
- return
103
- except Exception as e:
104
- logger.warning("gradient_checkpointing_enable falhou: %s", e)
105
- logger.info("Modelo não suporta gradient checkpointing nativo")
106
-
107
- @staticmethod
108
- def cpu_offload_constrained(model: nn.Module) -> int:
109
- """Move parâmetros sem requires_grad para CPU."""
110
- n_offloaded = 0
111
- for p in model.parameters():
112
- if not p.requires_grad and p.device.type != "cpu":
113
- p.data = p.data.cpu()
114
- n_offloaded += p.numel()
115
- if n_offloaded > 0:
116
- logger.info("Offloaded %d params para CPU", n_offloaded)
117
- if torch.cuda.is_available():
118
- torch.cuda.empty_cache()
119
- return n_offloaded
120
-
121
- def amp_context(self, device_type: str = "cpu"):
122
- """Context manager para mixed precision."""
123
- if not self.enable_amp or device_type == "cpu":
124
- from contextlib import nullcontext
125
- return nullcontext()
126
- try:
127
- return torch.amp.autocast(device_type=device_type, dtype=torch.bfloat16)
128
- except Exception:
129
- from contextlib import nullcontext
130
- return nullcontext()
131
-
132
- @staticmethod
133
- def report_peak() -> float:
134
- if torch.cuda.is_available():
135
- return torch.cuda.max_memory_allocated() / 1024**2
136
- return 0.0
137
-
138
-
139
- __all__ = ["MemoryOptimizer"]