Source code for torchfoo.module

__all__ = [
    "count_parameters",
    "make_ddp",
]

import warnings

import torch
from torch.nn.parallel import DistributedDataParallel


[docs] def count_parameters(m: torch.nn.Module, only: str = "all") -> int: r"""Count parameters in a module. Each unique parameter is counted once even if it appears in multiple places (e.g. weight-tied models). Args: m: the module to inspect only: which parameters to count — ``"all"`` (default), ``"trainable"``, or ``"frozen"`` Returns: The number of parameters matching *only*. """ if only not in ("all", "trainable", "frozen"): raise ValueError(f"only must be 'all', 'trainable', or 'frozen', got '{only}'") seen = set() total = 0 for p in m.parameters(): if p.data_ptr() in seen: continue seen.add(p.data_ptr()) if only == "all" or (only == "trainable") == p.requires_grad: total += p.numel() return total
[docs] def make_ddp(m: torch.nn.Module): r"""Wrap a module with DDP and convert BatchNorm to SyncBatchNorm. Returns the module unchanged if not in distributed mode. .. warning:: SyncBatchNorm only works with GPU modules. On CPU, BatchNorm layers will not be converted and a warning is emitted. Args: m: the module to wrap Returns: The DDP-wrapped module, or the original module if not distributed. """ from . import distributed as tfoodist if tfoodist.is_distributed(): use_cuda = next(m.parameters()).is_cuda if use_cuda: m = torch.nn.SyncBatchNorm.convert_sync_batchnorm(m) else: has_batchnorm = any( isinstance(mod, torch.nn.modules.batchnorm._BatchNorm) for mod in m.modules() ) if has_batchnorm: warnings.warn( "SyncBatchNorm only works with GPU modules. " "BatchNorm layers will not be converted.", stacklevel=2, ) device_ids = [tfoodist.get_rank()] if use_cuda else None return DistributedDataParallel(m, device_ids=device_ids) else: return m