Skip to content

llmcompressor.transformers.compression.helpers

infer_sparse_targets_and_ignores(model, sparsity_structure, sparsity_threshold)

Infers the target and ignore layers in the given model to be used for sparsity compression

Parameters:

Name Type Description Default
model Module

model to check

required
sparsity_structure str

sparsity structure to check against

required
sparsity_threshold float

threshold for sparsity

required

Returns:

Type Description
Tuple[List[str], List[str]]

tuple of target and ignore layers

Source code in llmcompressor/transformers/compression/helpers.py
def infer_sparse_targets_and_ignores(
    model: torch.nn.Module,
    sparsity_structure: str,
    sparsity_threshold: float,
) -> Tuple[List[str], List[str]]:
    """
    Infers the target and ignore layers in the given model
    to be used for sparsity compression

    :param model: model to check
    :param sparsity_structure: sparsity structure to check against
    :param sparsity_threshold: threshold for sparsity
    :return: tuple of target and ignore layers
    """

    exhaustive_targets, exhaustive_ignore = _get_sparse_targets_ignore_dicts(
        module=model,
        sparsity_structure=sparsity_structure,
        sparsity_threshold=sparsity_threshold,
    )

    return _reduce_targets_and_ignores_into_lists(
        exhaustive_targets=exhaustive_targets,
        exhaustive_ignore=exhaustive_ignore,
    )

infer_sparsity_structure_from_model(model)

Determines the sparsity structure, if any exists, given the model

Parameters:

Name Type Description Default
model Module

model to check for sparsity structure

required

Returns:

Type Description
Optional[str]

sparsity structure as a string or None

Source code in llmcompressor/transformers/compression/helpers.py
def infer_sparsity_structure_from_model(model: torch.nn.Module) -> Optional[str]:
    """
    Determines the sparsity structure, if any exists, given the model

    :param model: model to check for sparsity structure
    :return: sparsity structure as a string or None
    """

    # check for the common sparsity structures
    structures = {"2:4"}
    for sparsity_structure in structures:
        linear_modules = get_linear_layers(model)
        offloaded_params = get_state_dict_offloaded_model(model)

        linear_modules_with_sparsity_structure = [
            tensor_follows_mask_structure(offloaded_params[f"{name}.weight"])
            for name in tqdm(
                linear_modules.keys(),
                desc="Checking whether model follows "
                f"{sparsity_structure} sparsity structure",
            )
        ]
        # if the majority of the linear modules follow the sparsity structure
        # we can assume that the model follows the sparsity structure
        # (taking into consideration the fact that some Linear layers like the
        # embedding layer might not be sparse)
        if (
            sum(linear_modules_with_sparsity_structure)
            > len(linear_modules_with_sparsity_structure) * 0.8
        ):
            return sparsity_structure

    return None

infer_sparsity_structure_from_modifiers(modifiers)

Determines the sparsity structure, if any exists, given the list of modifiers.

Parameters:

Name Type Description Default
modifiers List[Modifier]

List of modifier instances.

required

Returns:

Type Description
Optional[str]

sparsity structure as a string or None.

Source code in llmcompressor/transformers/compression/helpers.py
def infer_sparsity_structure_from_modifiers(
    modifiers: List[Modifier],  # noqa E501
) -> Optional[str]:
    """
    Determines the sparsity structure, if any exists, given the list of modifiers.

    :param modifiers: List of modifier instances.
    :return: sparsity structure as a string or None.
    """
    for modifier in modifiers:
        if hasattr(modifier, "mask_structure"):
            return modifier.mask_structure
    return None

is_sparse_compression_target(module, sparsity_threshold, sparsity_structure)

Parameters:

Name Type Description Default
module Module

module to check

required
sparsity_threshold float

threshold for sparsity

required
sparsity_structure str

sparsity structure to check against

required

Returns:

Type Description
bool

whether or not the module is a target for sparsity compression, i.e True if it is sparse and follows the sparsity structure, else False

Source code in llmcompressor/transformers/compression/helpers.py
def is_sparse_compression_target(
    module: torch.nn.Module, sparsity_threshold: float, sparsity_structure: str
) -> bool:
    """
    :param module: module to check
    :param sparsity_threshold: threshold for sparsity
    :param sparsity_structure: sparsity structure to check against
    :return: whether or not the module is a target for sparsity compression,
        i.e True if it is sparse and follows the sparsity structure, else False
    """
    with align_module_device(module):
        result = (
            hasattr(module, "weight")
            and tensor_sparsity(module.weight) >= sparsity_threshold
            and tensor_follows_mask_structure(
                tensor=module.weight, mask=sparsity_structure
            )
        )

    return result

tensor_follows_mask_structure(tensor, mask='2:4')

Parameters:

Name Type Description Default
tensor Tensor

tensor to check

required
mask str

mask structure to check for, in the format "n:m", also accepts "unstructured" as a valid mask structure

'2:4'

Returns:

Type Description
bool

True if the tensor follows the mask structure, False otherwise. Note, some weights can incidentally be zero, so we check for atleast n zeros in each chunk of size m

Source code in llmcompressor/transformers/compression/helpers.py
def tensor_follows_mask_structure(tensor: torch.Tensor, mask: str = "2:4") -> bool:
    """
    :param tensor: tensor to check
    :param mask: mask structure to check for, in the format "n:m", also accepts
        "unstructured" as a valid mask structure
    :return: True if the tensor follows the mask structure, False otherwise.
        Note, some weights can incidentally be zero, so we check for
        atleast n zeros in each chunk of size m
    """

    if mask.lower().strip() == "unstructured":
        return True

    n, m = tuple(map(int, mask.split(":")))

    # If n or m is 0, then the tensor follows the mask structure
    if n == 0 or m == 0:
        return True
    # Reshape the tensor into chunks of size m
    tensor = tensor.view(-1, m)

    # Count the number of zeros in each chunk
    zero_counts = (tensor == 0).sum(dim=1)

    # Check if the number of zeros in each chunk atleast n
    # Greater than sign is needed as some weights can incidentally
    # be zero
    return torch.all(zero_counts >= n).item()