multimodalart's picture
multimodalart HF Staff
Initial Lip Forcing 14B streaming demo
9368ee7 verified
Raw
History Blame Contribute Delete
6.25 kB
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
from typing import Callable, Any, TYPE_CHECKING
import torch
from torch.utils.data import DataLoader
from lipforcing.utils import instantiate
import lipforcing.utils.logging_utils as logger
if TYPE_CHECKING:
from lipforcing.configs.config import BaseConfig
from lipforcing.trainer import Trainer
from lipforcing.methods import FastGenModel
class CallbackDict:
def __init__(self, config: BaseConfig, trainer: Trainer):
self._callbacks = {}
callback_configs = config.trainer.callbacks
if callback_configs:
if isinstance(callback_configs, list):
logger.warning(msg="The 'config.trainer.callbacks' parameter should be a dict instead of a list. ")
callback_configs = {f"callback_{k}": v for k, v in enumerate(callback_configs)}
for callback_name, current_callback_cfg in callback_configs.items():
if "_target_" not in current_callback_cfg:
logger.critical(
f"Callback {callback_name} is missing the '_target_' field. \n Skip {current_callback_cfg}"
)
continue
logger.critical(f"Instantiating callback {callback_name}: {current_callback_cfg}")
_callback = instantiate(current_callback_cfg)
assert isinstance(_callback, Callback), f"{current_callback_cfg} is not a valid callback."
_callback.config = config
_callback.trainer = trainer
_callback.on_app_begin()
self._callbacks[callback_name] = _callback
def __getattr__(self, method_name: str) -> Callable:
def load_state_dict(state_dict: dict[str, Any]) -> None:
for name, callback in self._callbacks.items():
if name in state_dict:
callback.load_state_dict(state_dict[name])
else:
logger.warning(f"Callback {name} not found in checkpoint.")
def state_dict() -> dict[str, Any]:
return {name: self._callbacks[name].state_dict() for name in self._callbacks}
def callbacks_wrapper(*args, **kwargs):
for callback in self._callbacks.values():
assert hasattr(callback, method_name)
method = getattr(callback, method_name)
assert callable(method), f"{method_name} is not callable."
method(*args, **kwargs)
if method_name == "state_dict":
return state_dict
if method_name == "load_state_dict":
return load_state_dict
return callbacks_wrapper
class Callback:
config: "BaseConfig"
trainer: "Trainer"
def on_app_begin(self) -> None:
pass
def on_model_init_start(self, model: FastGenModel) -> None:
pass
def on_model_init_end(self, model: FastGenModel | torch.nn.parallel.DistributedDataParallel) -> None:
pass
def on_optimizer_init_start(self, model: FastGenModel) -> None:
pass
def on_optimizer_init_end(self, model: FastGenModel) -> None:
pass
def on_load_checkpoint_start(self, model: FastGenModel) -> None:
pass
def on_load_checkpoint_end(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def on_dataloader_init_start(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def on_dataloader_init_end(
self, model: FastGenModel, dataloader_train: DataLoader, dataloader_val: DataLoader, iteration: int = 0
) -> None:
pass
def on_train_begin(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def on_training_step_begin(
self,
model: FastGenModel,
iteration: int = 0,
) -> None:
pass
def on_training_accum_step_begin(
self,
model: FastGenModel,
data_batch: dict[str, torch.Tensor],
iteration: int = 0,
accum_iter: int = 0,
) -> None:
pass
def on_backward_begin(
self,
model: FastGenModel,
data_batch: dict[str, torch.Tensor],
output_batch: dict[str, torch.Tensor | Callable],
loss_dict: dict[str, torch.Tensor],
iteration: int = 0,
accum_iter: int = 0,
) -> None:
pass
def on_training_step_end(
self,
model: FastGenModel,
data_batch: dict[str, torch.Tensor],
output_batch: dict[str, torch.Tensor | Callable],
loss_dict: dict[str, torch.Tensor],
iteration: int = 0,
) -> None:
pass
def on_optimizer_step_begin(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def on_train_end(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def on_validation_begin(self, model: FastGenModel, iteration: int = 0, idx: int = 0) -> None:
pass
def on_validation_step_begin(
self, model: FastGenModel, data_batch: dict[str, torch.Tensor], step: int = 0, iteration: int = 0, idx: int = 0
) -> None:
pass
def on_validation_step_end(
self,
model: FastGenModel,
data_batch: dict[str, torch.Tensor],
output_batch: dict[str, torch.Tensor | Callable],
loss_dict: dict[str, torch.Tensor],
step: int = 0,
iteration: int = 0,
idx: int = 0,
) -> None:
pass
def on_validation_end(self, model: FastGenModel, iteration: int = 0, idx: int = 0) -> None:
pass
def on_save_checkpoint_start(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def on_save_checkpoint_success(self, model: FastGenModel, iteration: int = 0, path: str = None) -> None:
pass
def on_save_checkpoint_end(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def on_app_end(self, model: FastGenModel, iteration: int = 0) -> None:
pass
def state_dict(self) -> dict[str, Any]:
return {}
def load_state_dict(self, state_dict: dict[str, Any]) -> None:
pass