Module neuralops.compression_engine.liftr
LIFTR – Linearized Function Trick Compressor. Registered as 'liftr', 'liftr_compressor', 'liftr_class'.
Mathematical Formulation: Activation: ReLU(x) → Identity(x), GELU(x) / SiLU(x) ≈ α·x Attention: Softmax(QK^T/√d)V → (1/N) Σ V_i
Functions
def liftr_compressor_entry(model: nn.Module, comp_config: Any = None, **kwargs: Any) ‑> Any-
Expand source code
@COMPRESSOR_REGISTRY.register("liftr") @COMPRESSOR_REGISTRY.register("liftr_compressor") @COMPRESSOR_REGISTRY.register("liftr_factory") def liftr_compressor_entry( model: nn.Module, comp_config: Any = None, **kwargs: Any, ) -> Any: """Factory function for LIFTR compressor.""" replace_attention = _cfg_get( comp_config, "liftr_replace_attention", _cfg_get(comp_config, "replace_attention", kwargs.pop("replace_attention", False)), ) gelu_coefficient = _cfg_get( comp_config, "liftr_gelu_coefficient", _cfg_get(comp_config, "gelu_coefficient", kwargs.pop("gelu_coefficient", 0.8)), ) target_attention_only = _cfg_get( comp_config, "liftr_target_attention_only", _cfg_get( comp_config, "target_attention_only", kwargs.pop("target_attention_only", False), ), ) skip_filter = _cfg_get( comp_config, "skip_should_compress_filter", kwargs.pop("skip_should_compress_filter", False), ) return_stats = kwargs.pop("return_stats", kwargs.pop("return_tuple", False)) compressor = LIFTRCompressor( model, replace_attention=replace_attention, gelu_coefficient=gelu_coefficient, target_attention_only=target_attention_only, skip_should_compress_filter=skip_filter, comp_config=comp_config, **kwargs, ) compressed_model, stats = compressor.compress() if return_stats: return compressed_model, stats return compressed_modelFactory function for LIFTR compressor.
Classes
class LIFTRCompressor (model: nn.Module,
replace_attention: bool = False,
gelu_coefficient: float = 0.8,
validation_calibration: bool = False,
calibration_threshold: float = 0.2,
target_attention_only: bool = False,
skip_should_compress_filter: bool = False,
**kwargs: Any)-
Expand source code
@COMPRESSOR_REGISTRY.register("liftr_class") @COMPRESSOR_REGISTRY.register("liftr_compressor_class") class LIFTRCompressor(BaseCompressor): # LIFTR-FIX-01: this is a compressor, not an attention. is_custom_attention: bool = False CRITICAL_MODULE_KEYWORDS = [ "classifier", "score", "lm_head", "pooler", "embed", "wte", "wpe", "shared", "head", "logits", ] def __init__( self, model: nn.Module, replace_attention: bool = False, gelu_coefficient: float = 0.8, validation_calibration: bool = False, calibration_threshold: float = 0.20, target_attention_only: bool = False, skip_should_compress_filter: bool = False, **kwargs: Any, ) -> None: super().__init__(model, name="liftr", **kwargs) cfg = kwargs.get("comp_config", kwargs.get("cfg")) self.cfg = cfg self.replace_attention = bool( _cfg_get( cfg, "liftr_replace_attention", _cfg_get(cfg, "replace_attention", replace_attention), ) ) self.gelu_coefficient = float( _cfg_get( cfg, "liftr_gelu_coefficient", _cfg_get(cfg, "gelu_coefficient", gelu_coefficient), ) ) self.validation_calibration = bool( _cfg_get( cfg, "validation_calibration", validation_calibration, ) ) self.calibration_threshold = float( _cfg_get( cfg, "calibration_threshold", calibration_threshold, ) ) self.target_attention_only = bool( _cfg_get( cfg, "liftr_target_attention_only", _cfg_get(cfg, "target_attention_only", target_attention_only), ) ) self.skip_should_compress_filter = bool( _cfg_get( cfg, "skip_should_compress_filter", skip_should_compress_filter, ) ) self.linearized_activations_count = 0 self.linearized_attentions_count = 0 self.replaced_modules: list[str] = [] self.skipped_layers: list[str] = [] self.stats: dict[str, Any] = {} self._compressed_params: int = 0 def _is_critical(self, name: str) -> bool: low = name.lower() if any(part in name.split(".") for part in ("lora_A", "lora_B")): return True return any(kw in low for kw in self.CRITICAL_MODULE_KEYWORDS) def _is_already_compressed(self, module: nn.Module) -> bool: """LIFTR-FIX-06: skip already-compressed module types.""" cls_name = module.__class__.__name__ return cls_name in ( "LSCPrunedLoRALinear", "DynamicSVDLinear", "SVDLinear", "FactorisedLinear", "FactorizedLinear", "LowRankPlusSparseLinear", "_LinearizedAttentionWrapper", ) def _linearize_module( self, module: nn.Module, prefix: str = "", _depth: int = 0, ) -> None: """Recursively replaces activation functions and (optionally) attention blocks.""" if _depth > 16: return for name, child in list(module.named_children()): full_name = f"{prefix}.{name}" if prefix else name if self._is_critical(full_name): continue if self._is_already_compressed(child): if hasattr(child, "lora_A") or child.__class__.__name__.lower() == "loralinear": continue if isinstance(child, _LinearizedAttentionWrapper): continue # Skip LoRA-wrapped modules. if hasattr(child, "lora_A") or child.__class__.__name__.lower() == "loralinear": continue is_attn_layer = any(k in full_name.lower() for k in _ATTN_NAMES) # --- Activation linearization --- if isinstance(child, nn.ReLU): if self.target_attention_only and not is_attn_layer: self.skipped_layers.append(full_name) continue setattr(module, name, nn.Identity()) self.linearized_activations_count += 1 self.replaced_modules.append(full_name) continue if isinstance(child, _SILU_CLASSES): if self.target_attention_only and not is_attn_layer: self.skipped_layers.append(full_name) continue setattr(module, name, _LinearizedGELU(alpha=self.gelu_coefficient)) self.linearized_activations_count += 1 self.replaced_modules.append(full_name) continue # --- Attention linearization --- if self.replace_attention and is_attn_layer: if "norm" in name.lower(): self._linearize_module(child, prefix=full_name, _depth=_depth + 1) continue if isinstance(child, (nn.Linear, nn.LayerNorm, nn.RMSNorm, nn.Embedding)): self._linearize_module(child, prefix=full_name, _depth=_depth + 1) continue # BERT / RoBERTa nested structure: linearize inner self-attention. if hasattr(child, "self") and hasattr(child, "output"): self._linearize_module(child, prefix=full_name, _depth=_depth + 1) continue if isinstance(child, _LinearizedAttentionWrapper): continue if not hasattr(child, "_liftr_skip") and not isinstance( child, _LinearizedAttentionWrapper ): try: wrapped = _LinearizedAttentionWrapper(child, layer_name=full_name) setattr(module, name, wrapped) self.linearized_attentions_count += 1 self.replaced_modules.append(full_name) except Exception as e: logger.warning("LIFTR: failed to wrap %s: %s", full_name, e) continue # --- Recurse --- self._linearize_module(child, prefix=full_name, _depth=_depth + 1) # ------------------------------------------------------------------ def compress(self, **kwargs: Any) -> tuple[nn.Module, dict[str, Any]]: # LIFTR-FIX-15: idempotence if getattr(self.model, "_liftr_compressed", False): logger.warning("LIFTR: model already compressed; skipping.") try: stats = self.get_compression_stats() except Exception: stats = {} return self.model, stats # LIFTR-FIX-11: safe device resolution. first_param = next(iter(self.model.parameters()), None) device = first_param.device if first_param is not None else torch.device("cpu") # LIFTR-FIX-03: dummy_in defined at function scope. dummy_in: torch.Tensor | None = None orig_out: torch.Tensor | None = None if self.validation_calibration: try: self.model.eval() dummy_in = torch.randint(0, 100, (1, 8), device=device, dtype=torch.long) with torch.no_grad(): res = self.model(dummy_in) if hasattr(res, "logits"): orig_out = res.logits.detach() elif isinstance(res, (tuple, list)): orig_out = res[0].detach() else: orig_out = res.detach() except Exception as e: logger.debug("LIFTR baseline calibration failed: %s", e) dummy_in = None orig_out = None # Apply linearization. self._linearize_module(self.model) # Freeze parameters in skipped modules. if self.skipped_layers: skipped_set = set(self.skipped_layers) for name, module in self.model.named_modules(): if name in skipped_set: for p in module.parameters(recurse=False): p.requires_grad = False # Post-linearization validation. validation_passed = True rel_diff = 0.0 if self.validation_calibration and orig_out is not None and dummy_in is not None: try: with torch.no_grad(): res_new = self.model(dummy_in) if hasattr(res_new, "logits"): new_out = res_new.logits elif isinstance(res_new, (tuple, list)): new_out = res_new[0] else: new_out = res_new rel_diff = ( torch.norm(orig_out.float() - new_out.float()) / (torch.norm(orig_out.float()) + 1e-8) ).item() if rel_diff > self.calibration_threshold: logger.warning( "LIFTR: validation diff %.4f > threshold %.4f.", rel_diff, self.calibration_threshold, ) validation_passed = False except Exception as e: logger.warning("LIFTR: post-linearization validation failed: %s", e) validation_passed = False try: self._compressed_params = self._count_params(self.model) except Exception: self._compressed_params = sum(p.numel() for p in self.model.parameters()) try: stats = self.get_compression_stats() except Exception: stats = {} stats.update( { "linearized_activations": self.linearized_activations_count, "linearized_attentions": self.linearized_attentions_count, "replace_attention": self.replace_attention, "replaced_modules": self.replaced_modules, "gelu_coefficient": self.gelu_coefficient, "target_attention_only": self.target_attention_only, "validation_calibration": self.validation_calibration, "validation_passed": validation_passed, "calibration_rel_diff": rel_diff, # LIFTR-FIX-08: explicit note. "effective_parameter_ratio": 1.0, "flops_reduction_pct": 0.0, "method": "liftr_linearization", "note": ( "LIFTR performs functional linearization (activation & attention). " "It does NOT reduce parameters; original attention submodules are " "retained as `self.original_attn` for safe delegation." ), } ) self.stats = stats self.model._liftr_compressed = True logger.info( "LIFTR: %d activations linearized, %d attentions wrapped.", self.linearized_activations_count, self.linearized_attentions_count, ) return self.model, statsBase class for all compressors. Not a nn.Module to avoid parameter storage.
Ancestors
Class variables
var CRITICAL_MODULE_KEYWORDS-
The type of the None singleton.
var is_custom_attention : bool-
The type of the None singleton.
Inherited members