def forward(self, input_tensor: torch.Tensor) -> torch.Tensor | InferenceBatch:
        """Forward pass through the model.

        Args:
            input_tensor (torch.Tensor): Input image tensor.

        Raises:
            ValueError: When the memory bank is not initialized.

        Returns:
            torch.Tensor | InferenceBatch: During training, returns distance
                tensor. During inference, returns anomaly predictions.

        Example:
            >>> model = CfaModel(...)
            >>> x = torch.randn(32, 3, 256, 256)
            >>> predictions = model(x)
        """
        if self.memory_bank.ndim == 0:
            msg = "Memory bank is not initialized. Run `initialize_centroid` method first."
            raise ValueError(msg)

        self.feature_extractor.eval()
        with torch.no_grad():
            features = self.feature_extractor(input_tensor)
            features = list(features.values())

        target_features = self.descriptor(features)
        distance = self.compute_distance(target_features)

        if self.training:
            return distance

        anomaly_map = self.anomaly_map_generator(
            distance=distance,
            scale=target_features.shape[-2:],
            image_size=input_tensor.shape[-2:],
        ).squeeze()
        pred_score = torch.amax(anomaly_map, dim=(-2, -1))
        return InferenceBatch(pred_score=pred_score, anomaly_map=anomaly_map)
Forward pass through the model.

        Args:
            input_tensor (torch.Tensor): Input image tensor.

        Raises:
            ValueError: When the memory bank is not initialized.

        Returns:
            torch.Tensor | InferenceBatch: During training, returns distance
                tensor. During inference, returns anomaly predictions.

        Example:
            >>> model = CfaModel(...)
            >>> x = torch.randn(32, 3, 256, 256)
            >>> predictions = model(x)
        
src/anomalib/models/image/cfa/torch_model.py