2022-05-31 04:00:12 +00:00
|
|
|
from contextlib import contextmanager
|
2022-11-17 06:43:49 +00:00
|
|
|
from enum import Enum
|
2022-05-31 04:00:12 +00:00
|
|
|
from functools import partial
|
2022-11-17 06:43:49 +00:00
|
|
|
from typing import List
|
|
|
|
|
|
|
|
import torch
|
|
|
|
|
|
|
|
from colossalai.gemini import TensorState
|
2022-06-10 06:48:28 +00:00
|
|
|
from colossalai.gemini.gemini_mgr import GeminiManager
|
2022-12-05 09:11:06 +00:00
|
|
|
from colossalai.tensor.param_op_hook import ColoParamOpHook
|
2022-05-31 04:00:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TrainingPhase(Enum):
|
|
|
|
FORWARD = 0
|
|
|
|
BACKWARD = 1
|
|
|
|
|
|
|
|
|
2022-12-05 09:11:06 +00:00
|
|
|
class GeminiZeROHook(ColoParamOpHook):
|
2022-05-31 04:00:12 +00:00
|
|
|
|
2022-06-10 06:48:28 +00:00
|
|
|
def __init__(self, gemini_manager: GeminiManager) -> None:
|
2022-05-31 04:00:12 +00:00
|
|
|
super().__init__()
|
2022-06-10 06:48:28 +00:00
|
|
|
self._gemini_manager = gemini_manager
|
|
|
|
self._chunk_manager = gemini_manager.chunk_manager
|
2022-05-31 04:00:12 +00:00
|
|
|
self._training_phase = TrainingPhase.FORWARD
|
|
|
|
|
|
|
|
def pre_op(self, params):
|
2022-06-16 04:54:46 +00:00
|
|
|
params = [p for p in params if not getattr(p, '_ddp_to_ignore', False)]
|
2022-06-09 12:56:34 +00:00
|
|
|
chunks = self._chunk_manager.get_chunks(params)
|
2022-05-31 04:00:12 +00:00
|
|
|
for p in params:
|
|
|
|
self._chunk_manager.trans_tensor_state(p, TensorState.COMPUTE)
|
2022-06-10 06:48:28 +00:00
|
|
|
self._gemini_manager.sample_overall_data()
|
2022-10-14 09:53:16 +00:00
|
|
|
self._gemini_manager.adjust_layout(chunks)
|
2022-06-09 12:56:34 +00:00
|
|
|
for chunk in chunks:
|
|
|
|
self._chunk_manager.access_chunk(chunk)
|
2022-12-13 16:47:06 +00:00
|
|
|
|
|
|
|
# record cuda model data of the current OP
|
2022-12-13 09:11:31 +00:00
|
|
|
self._gemini_manager.record_model_data_volume()
|
2022-05-31 04:00:12 +00:00
|
|
|
|
|
|
|
def post_op(self, params):
|
2022-06-16 04:54:46 +00:00
|
|
|
params = [p for p in params if not getattr(p, '_ddp_to_ignore', False)]
|
2022-05-31 04:00:12 +00:00
|
|
|
for p in params:
|
|
|
|
tensor_state = TensorState.HOLD if self._training_phase == TrainingPhase.FORWARD or not p.requires_grad else TensorState.HOLD_AFTER_BWD
|
|
|
|
self._chunk_manager.trans_tensor_state(p, tensor_state)
|
|
|
|
|
|
|
|
def pre_forward(self, params: List[torch.Tensor]) -> None:
|
|
|
|
self.pre_op(params)
|
|
|
|
|
|
|
|
def post_forward(self, params: List[torch.Tensor]) -> None:
|
|
|
|
self.post_op(params)
|
|
|
|
|
|
|
|
def pre_backward(self, params: List[torch.Tensor]) -> None:
|
|
|
|
self.pre_op(params)
|
|
|
|
|
|
|
|
def post_backward(self, params: List[torch.Tensor]) -> None:
|
|
|
|
self.post_op(params)
|
|
|
|
|
|
|
|
@contextmanager
|
|
|
|
def switch_training_phase(self, training_phase: TrainingPhase = TrainingPhase.BACKWARD):
|
2022-10-09 01:18:51 +00:00
|
|
|
old_training_phase = self._training_phase
|
2022-05-31 04:00:12 +00:00
|
|
|
try:
|
|
|
|
self._training_phase = training_phase
|
|
|
|
yield
|
|
|
|
finally:
|
|
|
|
self._training_phase = old_training_phase
|
|
|
|
|
|
|
|
switch_to_backward = switch_training_phase
|
|
|
|
switch_to_forward = partial(switch_to_backward, training_phase=TrainingPhase.FORWARD)
|