Skip to content

llmcompressor.pytorch.utils.helpers

Utility / helper functions

Functions:

get_linear_layers

get_linear_layers(module: Module) -> Dict[str, Module]

Parameters:

  • module

    (Module) –

    the module to grab all linear layers for

Returns:

  • Dict[str, Module]

    a list of all linear layers in the module

Source code in llmcompressor/pytorch/utils/helpers.py
def get_linear_layers(module: Module) -> Dict[str, Module]:
    """
    :param module: the module to grab all linear layers for
    :return: a list of all linear layers in the module
    """
    return {
        name: mod for name, mod in module.named_modules() if isinstance(mod, Linear)
    }

get_quantized_layers

get_quantized_layers(
    module: Module,
) -> List[Tuple[str, Module]]

Parameters:

  • module

    (Module) –

    the module to get the quantized layers from

Returns:

  • List[Tuple[str, Module]]

    a list containing the names and modules of the quantized layers (Embedding, Linear, Conv2d, Conv3d)

Source code in llmcompressor/pytorch/utils/helpers.py
def get_quantized_layers(module: Module) -> List[Tuple[str, Module]]:
    """
    :param module: the module to get the quantized layers from
    :return: a list containing the names and modules of the quantized layers
        (Embedding, Linear, Conv2d, Conv3d)
    """

    quantized_layers = []
    for name, mod in module.named_modules():
        if hasattr(mod, "quantization_scheme"):
            weight_scheme = getattr(mod.quantization_scheme, "weights", None)
            if weight_scheme is not None and hasattr(mod, "weight"):
                quantized_layers.append((name, mod))

    return quantized_layers

set_deterministic_seeds

set_deterministic_seeds(seed: int = 0)

Manually seeds the numpy, random, and torch packages. Also sets torch.backends.cudnn.deterministic to True

Parameters:

  • seed

    (int, default: 0 ) –

    the manual seed to use. Default is 0

Source code in llmcompressor/pytorch/utils/helpers.py
def set_deterministic_seeds(seed: int = 0):
    """
    Manually seeds the numpy, random, and torch packages.
    Also sets torch.backends.cudnn.deterministic to True
    :param seed: the manual seed to use. Default is 0
    """
    numpy.random.seed(seed)
    random.seed(seed)
    torch.manual_seed(seed)
    torch.backends.cudnn.deterministic = True

tensor_sparsity

tensor_sparsity(
    tens: Tensor,
    dim: Union[
        None, int, List[int], Tuple[int, ...]
    ] = None,
) -> Tensor

Parameters:

  • tens

    (Tensor) –

    the tensor to calculate the sparsity for

  • dim

    (Union[None, int, List[int], Tuple[int, ...]], default: None ) –

    the dimension(s) to split the calculations over; ex, can split over batch, channels, or combos

Returns:

  • Tensor

    the sparsity of the input tens, ie the fraction of numbers that are zero

Source code in llmcompressor/pytorch/utils/helpers.py
def tensor_sparsity(
    tens: Tensor, dim: Union[None, int, List[int], Tuple[int, ...]] = None
) -> Tensor:
    """
    :param tens: the tensor to calculate the sparsity for
    :param dim: the dimension(s) to split the calculations over;
        ex, can split over batch, channels, or combos
    :return: the sparsity of the input tens, ie the fraction of numbers that are zero
    """
    if dim is None:
        zeros = (tens.cpu() == 0).sum()
        total = tens.numel()

        return zeros.float() / float(total)

    if isinstance(dim, int):
        dim = [dim]

    if max(dim) >= len(tens.shape):
        raise ValueError(
            "Unsupported dim given of {} in {} for tensor shape {}".format(
                max(dim), dim, tens.shape
            )
        )

    sum_dims = [ind for ind in range(len(tens.shape)) if ind not in dim]
    zeros = (tens == 0).sum(dim=sum_dims) if sum_dims else tens == 0
    total = numpy.prod(
        [tens.shape[ind] for ind in range(len(tens.shape)) if ind not in dim]
    )

    permute_order = sorted(
        ((d, len(dim) - i - 1) for i, d in enumerate(dim)), reverse=True
    )
    permute = [d[1] for d in permute_order]

    if permute != [i for i in range(len(permute))]:
        # need to permute to get desired dimensions at the front
        zeros = zeros.permute(*permute).contiguous()

    return zeros.float() / float(total)

tensors_module_forward

tensors_module_forward(
    tensors: Union[
        Tensor, Iterable[Tensor], Mapping[Any, Tensor]
    ],
    module: Module,
    check_feat_lab_inp: bool = True,
) -> Any

Default function for calling into a model with data for a forward execution. Returns the model result. Note, if an iterable the features to be passed into the model are considered to be at index 0 and other indices are for labels.

Supported use cases: single tensor, iterable with first tensor taken as the features to pass into the model

Parameters:

  • tensors

    (Union[Tensor, Iterable[Tensor], Mapping[Any, Tensor]]) –

    the data to be passed into the model, if an iterable the features to be passed into the model are considered to be at index 0 and other indices are for labels

  • module

    (Module) –

    the module to pass the data into

  • check_feat_lab_inp

    (bool, default: True ) –

    True to check if the incoming tensors looks like it's made up of features and labels ie a tuple or list with 2 items (typical output from a data loader) and will call into the model with just the first element assuming it's the features False to not check

Returns:

  • Any

    the result of calling into the model for a forward pass

Source code in llmcompressor/pytorch/utils/helpers.py
def tensors_module_forward(
    tensors: Union[Tensor, Iterable[Tensor], Mapping[Any, Tensor]],
    module: Module,
    check_feat_lab_inp: bool = True,
) -> Any:
    """
    Default function for calling into a model with data for a forward execution.
    Returns the model result.
    Note, if an iterable the features to be passed into the model are considered
    to be at index 0 and other indices are for labels.

    Supported use cases: single tensor,
    iterable with first tensor taken as the features to pass into the model

    :param tensors: the data to be passed into the model, if an iterable the features
        to be passed into the model are considered to be at index 0 and other indices
        are for labels
    :param module: the module to pass the data into
    :param check_feat_lab_inp: True to check if the incoming tensors looks like
        it's made up of features and labels ie a tuple or list with 2 items
        (typical output from a data loader) and will call into the model with just
        the first element assuming it's the features False to not check
    :return: the result of calling into the model for a forward pass
    """
    if (
        (isinstance(tensors, tuple) or isinstance(tensors, List))
        and len(tensors) == 2
        and check_feat_lab_inp
    ):
        # assume if this is a list or tuple of 2 items that it is made up of
        # (features, labels) pass the features into a recursive call for the model
        return tensors_module_forward(tensors[0], module, check_feat_lab_inp=False)

    if isinstance(tensors, Tensor):
        return module(tensors)

    if isinstance(tensors, Mapping):
        return module(**tensors)

    if isinstance(tensors, Iterable):
        return module(*tensors)

    raise ValueError(
        "unrecognized type for data given of {}".format(tensors.__class__.__name__)
    )

tensors_to_device

tensors_to_device(
    tensors: Union[
        Tensor, Iterable[Tensor], Dict[Any, Tensor]
    ],
    device: str,
) -> Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]

Default function for putting a tensor or collection of tensors to the proper device. Returns the tensor references after being placed on the proper device.

Supported use cases: - single tensor - Dictionary of single tensors - Dictionary of iterable of tensors - Dictionary of dictionary of tensors - Iterable of single tensors - Iterable of iterable of tensors - Iterable of dictionary of tensors

Parameters:

  • tensors

    (Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]) –

    the tensors or collection of tensors to put onto a device

  • device

    (str) –

    the string representing the device to put the tensors on, ex: 'cpu', 'cuda', 'cuda:1'

Returns:

  • Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]

    the tensors or collection of tensors after being placed on the device

Source code in llmcompressor/pytorch/utils/helpers.py
def tensors_to_device(
    tensors: Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]], device: str
) -> Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]:
    """
    Default function for putting a tensor or collection of tensors to the proper device.
    Returns the tensor references after being placed on the proper device.

    Supported use cases:
        - single tensor
        - Dictionary of single tensors
        - Dictionary of iterable of tensors
        - Dictionary of dictionary of tensors
        - Iterable of single tensors
        - Iterable of iterable of tensors
        - Iterable of dictionary of tensors

    :param tensors: the tensors or collection of tensors to put onto a device
    :param device: the string representing the device to put the tensors on,
        ex: 'cpu', 'cuda', 'cuda:1'
    :return: the tensors or collection of tensors after being placed on the device
    """
    if isinstance(tensors, Tensor):
        return tensors.to(device)

    if isinstance(tensors, OrderedDict):
        return OrderedDict(
            [(key, tensors_to_device(tens, device)) for key, tens in tensors.items()]
        )

    if isinstance(tensors, Mapping):
        return {key: tensors_to_device(tens, device) for key, tens in tensors.items()}

    if isinstance(tensors, tuple):
        return tuple(tensors_to_device(tens, device) for tens in tensors)

    if isinstance(tensors, Iterable):
        return [tensors_to_device(tens, device) for tens in tensors]

    raise ValueError(
        "unrecognized type for tensors given of {}".format(tensors.__class__.__name__)
    )

tensors_to_precision

tensors_to_precision(
    tensors: Union[
        Tensor, Iterable[Tensor], Dict[Any, Tensor]
    ],
    full_precision: bool,
) -> Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]

Parameters:

  • tensors

    (Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]) –

    the tensors to change the precision of

  • full_precision

    (bool) –

    True for full precision (float 32) and False for half (float 16)

Returns:

  • Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]

    the tensors converted to the desired precision

Source code in llmcompressor/pytorch/utils/helpers.py
def tensors_to_precision(
    tensors: Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]], full_precision: bool
) -> Union[Tensor, Iterable[Tensor], Dict[Any, Tensor]]:
    """
    :param tensors: the tensors to change the precision of
    :param full_precision: True for full precision (float 32) and
        False for half (float 16)
    :return: the tensors converted to the desired precision
    """
    if isinstance(tensors, Tensor):
        return tensors.float() if full_precision else tensors.half()

    if isinstance(tensors, Mapping):
        return {
            key: tensors_to_precision(tens, full_precision)
            for key, tens in tensors.items()
        }

    if isinstance(tensors, tuple):
        return tuple(tensors_to_precision(tens, full_precision) for tens in tensors)

    if isinstance(tensors, Iterable):
        return [tensors_to_precision(tens, full_precision) for tens in tensors]

    raise ValueError(
        "unrecognized type for tensors given of {}".format(tensors.__class__.__name__)
    )