Example #1
0
    def testSpatialSvd(self):

        torch.manual_seed(1)

        model = mnist_torch_model.Net()

        rounding_algo = unittest.mock.MagicMock()
        rounding_algo.round.side_effect = [
            0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.1, 0.2, 0.3, 0.4,
            0.5, 0.6, 0.7, 0.8, 0.9
        ]

        mock_eval = unittest.mock.MagicMock()
        mock_eval.side_effect = [
            100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 90, 80, 70, 60, 50, 40,
            30, 20, 10, 50
        ]

        layer_db = LayerDatabase(model, input_shape=(1, 1, 28, 28))
        pruner = SpatialSvdPruner()
        comp_ratio_select_algo = GreedyCompRatioSelectAlgo(
            layer_db,
            pruner,
            SpatialSvdCostCalculator(),
            mock_eval,
            20,
            CostMetric.mac,
            Decimal(0.5),
            10,
            True,
            None,
            rounding_algo,
            True,
            bokeh_session=None)

        layer_selector = ConvNoDepthwiseLayerSelector()
        spatial_svd_algo = CompressionAlgo(
            layer_db,
            comp_ratio_select_algo,
            pruner,
            mock_eval,
            layer_selector,
            modules_to_ignore=[],
            cost_calculator=SpatialSvdCostCalculator(),
            use_cuda=next(model.parameters()).is_cuda)

        compressed_layer_db, stats = spatial_svd_algo.compress_model(
            CostMetric.mac, trainer=None)

        self.assertTrue(
            isinstance(compressed_layer_db.model.conv1, torch.nn.Sequential))
        self.assertTrue(
            isinstance(compressed_layer_db.model.conv2, torch.nn.Sequential))
        self.assertTrue(stats.per_layer_stats[0].compression_ratio <= 0.5)
        self.assertEqual(0.3, stats.per_layer_stats[1].compression_ratio)

        print("Compressed model:")
        print(compressed_layer_db.model)

        print(stats)
Example #2
0
    def create_spatial_svd_algo(cls, model: torch.nn.Module, eval_callback: EvalFunction, eval_iterations,
                                input_shape: Tuple, cost_metric: CostMetric,
                                params: SpatialSvdParameters, bokeh_session: BokehServerSession) -> CompressionAlgo:
        """
        Factory method to construct SpatialSvdCompressionAlgo

        :param model: Model to compress
        :param eval_callback: Evaluation callback for the model
        :param eval_iterations: Evaluation iterations
        :param input_shape: Shape of the input tensor for model
        :param cost_metric: Cost metric (mac or memory)
        :param params: Spatial SVD compression parameters
        :param bokeh_session: The Bokeh Session to display plots
        :return: An instance of SpatialSvdCompressionAlgo
        """

        # pylint: disable=too-many-locals
        # Rationale: Factory functions unfortunately need to deal with a lot of parameters

        # Create a layer database
        layer_db = LayerDatabase(model, input_shape)
        use_cuda = next(model.parameters()).is_cuda

        # Create a pruner
        pruner = SpatialSvdPruner()
        cost_calculator = SpatialSvdCostCalculator()
        comp_ratio_rounding_algo = RankRounder(params.multiplicity, cost_calculator)

        # Create a comp-ratio selection algorithm
        if params.mode == SpatialSvdParameters.Mode.auto:
            greedy_params = params.mode_params.greedy_params
            comp_ratio_select_algo = GreedyCompRatioSelectAlgo(layer_db, pruner, cost_calculator, eval_callback,
                                                               eval_iterations, cost_metric,
                                                               greedy_params.target_comp_ratio,
                                                               greedy_params.num_comp_ratio_candidates,
                                                               greedy_params.use_monotonic_fit,
                                                               greedy_params.saved_eval_scores_dict,
                                                               comp_ratio_rounding_algo, use_cuda,
                                                               bokeh_session=bokeh_session)
            layer_selector = ConvNoDepthwiseLayerSelector()
            modules_to_ignore = params.mode_params.modules_to_ignore
        else:
            # Convert (module,comp-ratio) pairs to (layer,comp-ratio) pairs
            layer_comp_ratio_pairs = cls._get_layer_pairs(layer_db, params.mode_params.list_of_module_comp_ratio_pairs)

            comp_ratio_select_algo = ManualCompRatioSelectAlgo(layer_db,
                                                               layer_comp_ratio_pairs,
                                                               comp_ratio_rounding_algo, cost_metric=cost_metric)

            layer_selector = ManualLayerSelector(layer_comp_ratio_pairs)
            modules_to_ignore = []

        # Create the overall Spatial SVD compression algorithm
        spatial_svd_algo = CompressionAlgo(layer_db, comp_ratio_select_algo, pruner, eval_callback,
                                           layer_selector, modules_to_ignore, cost_calculator, use_cuda)

        return spatial_svd_algo
Example #3
0
    def create_weight_svd_algo(cls, model: torch.nn.Module, eval_callback: EvalFunction, eval_iterations,
                               input_shape: Tuple, cost_metric: CostMetric,
                               params: WeightSvdParameters, bokeh_session) -> CompressionAlgo:
        """
        Factory method to construct WeightSvdCompressionAlgo

        :param model: Model to compress
        :param eval_callback: Evaluation callback for the model
        :param eval_iterations: Evaluation iterations
        :param input_shape: Shape of the input tensor for model
        :param cost_metric: Cost metric (mac or memory)
        :param rank_select_scheme: rank selection scheme. Check enum for allowed values
        :param params: Weight SVD compression parameters
        :return: An instance of WeightSvdCompressionAlgo
        """

        # pylint: disable=too-many-locals
        # Rationale: Factory functions unfortunately need to deal with a lot of parameters

        # Create a layer database
        layer_db = LayerDatabase(model, input_shape)
        use_cuda = next(model.parameters()).is_cuda

        # Create a pruner
        pruner = WeightSvdPruner()
        cost_calculator = WeightSvdCostCalculator()
        comp_ratio_rounding_algo = RankRounder(params.multiplicity, cost_calculator)

        # Create a comp-ratio selection algorithm
        if params.mode == WeightSvdParameters.Mode.auto:
            # greedy
            if params.mode_params.rank_select_scheme is RankSelectScheme.greedy:
                greedy_params = params.mode_params.select_params
                comp_ratio_select_algo = GreedyCompRatioSelectAlgo(layer_db=layer_db,
                                                                   pruner=pruner,
                                                                   cost_calculator=cost_calculator,
                                                                   eval_func=eval_callback,
                                                                   eval_iterations=eval_iterations,
                                                                   cost_metric=cost_metric,
                                                                   target_comp_ratio=greedy_params.target_comp_ratio,
                                                                   num_candidates=greedy_params.num_comp_ratio_candidates,
                                                                   use_monotonic_fit=greedy_params.use_monotonic_fit,
                                                                   saved_eval_scores_dict=greedy_params.saved_eval_scores_dict,
                                                                   comp_ratio_rounding_algo=comp_ratio_rounding_algo,
                                                                   use_cuda=use_cuda,
                                                                   bokeh_session=bokeh_session)
            # TAR method
            elif params.mode_params.rank_select_scheme is RankSelectScheme.tar:
                tar_params = params.mode_params.select_params
                comp_ratio_select_algo = TarRankSelectAlgo(layer_db=layer_db, pruner=pruner,
                                                           cost_calculator=cost_calculator,
                                                           eval_func=eval_callback,
                                                           eval_iterations=eval_iterations,
                                                           cost_metric=cost_metric,
                                                           num_rank_indices=tar_params.num_rank_indices,
                                                           use_cuda=use_cuda, pymo_utils_lib=pymo_utils)
            else:
                raise ValueError("Unknown Rank selection scheme: {}".format(params.AutoModeParams.rank_select_scheme))

            layer_selector = ConvFcLayerSelector()
            modules_to_ignore = params.mode_params.modules_to_ignore

        else:
            # Convert (module,comp-ratio) pairs to (layer,comp-ratio) pairs
            layer_comp_ratio_pairs = cls._get_layer_pairs(layer_db, params.mode_params.list_of_module_comp_ratio_pairs)

            comp_ratio_select_algo = ManualCompRatioSelectAlgo(layer_db,
                                                               layer_comp_ratio_pairs,
                                                               comp_ratio_rounding_algo, cost_metric=cost_metric)

            layer_selector = ManualLayerSelector(layer_comp_ratio_pairs)
            modules_to_ignore = []

        # Create the overall Weight SVD compression algorithm
        weight_svd_algo = CompressionAlgo(layer_db, comp_ratio_select_algo, pruner, eval_callback,
                                          layer_selector, modules_to_ignore, cost_calculator, use_cuda)

        return weight_svd_algo
Example #4
0
    def create_spatial_svd_algo(cls,
                                sess: tf.compat.v1.Session,
                                working_dir: str,
                                eval_callback: EvalFunction,
                                eval_iterations,
                                input_shape: Union[Tuple, List[Tuple]],
                                cost_metric: CostMetric,
                                params: SpatialSvdParameters,
                                bokeh_session=None) -> CompressionAlgo:
        """
        Factory method to construct SpatialSvdCompressionAlgo

        :param sess: Model, represented by a tf.compat.v1.Session, to compress
        :param working_dir: path to store temp meta and checkpoint files
        :param eval_callback: Evaluation callback for the model
        :param eval_iterations: Evaluation iterations
        :param input_shape: tuple or list of tuples of input shape to the model
        :param cost_metric: Cost metric (mac or memory)
        :param params: Spatial SVD compression parameters
        :param bokeh_session: The Bokeh Session to display plots
        :return: An instance of SpatialSvdCompressionAlgo
        """

        # pylint: disable=too-many-arguments
        # pylint: disable=too-many-locals
        # Rationale: Factory functions unfortunately need to deal with a lot of parameters

        # Create a layer database
        layer_db = LayerDatabase(sess,
                                 input_shape,
                                 working_dir,
                                 starting_ops=params.input_op_names,
                                 ending_ops=params.output_op_names)
        use_cuda = False

        # Create a pruner
        pruner = SpatialSvdPruner()
        cost_calculator = SpatialSvdCostCalculator()
        comp_ratio_rounding_algo = RankRounder(params.multiplicity,
                                               cost_calculator)

        # Create a comp-ratio selection algorithm
        if params.mode == SpatialSvdParameters.Mode.auto:
            greedy_params = params.mode_params.greedy_params
            comp_ratio_select_algo = GreedyCompRatioSelectAlgo(
                layer_db,
                pruner,
                cost_calculator,
                eval_callback,
                eval_iterations,
                cost_metric,
                greedy_params.target_comp_ratio,
                greedy_params.num_comp_ratio_candidates,
                greedy_params.use_monotonic_fit,
                greedy_params.saved_eval_scores_dict,
                comp_ratio_rounding_algo,
                use_cuda,
                bokeh_session=bokeh_session)
            layer_selector = ConvNoDepthwiseLayerSelector()
            modules_to_ignore = params.mode_params.modules_to_ignore

        else:
            # Convert (module,comp-ratio) pairs to (layer,comp-ratio) pairs
            layer_comp_ratio_pairs = cls._get_layer_pairs(
                layer_db, params.mode_params.list_of_module_comp_ratio_pairs)

            comp_ratio_select_algo = ManualCompRatioSelectAlgo(
                layer_db,
                layer_comp_ratio_pairs,
                comp_ratio_rounding_algo,
                cost_metric=cost_metric)

            layer_selector = ManualLayerSelector(layer_comp_ratio_pairs)
            modules_to_ignore = []

        # Create the overall Spatial SVD compression algorithm
        spatial_svd_algo = CompressionAlgo(layer_db, comp_ratio_select_algo,
                                           pruner, eval_callback,
                                           layer_selector, modules_to_ignore,
                                           cost_calculator, use_cuda)

        return spatial_svd_algo