Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NNCF]: Optimized memory footprint by removing redundant collected statistics #2563

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b84acfd
feat: Added a method for removing stat_point
AdiKsOnDev Mar 8, 2024
3a85e8f
feat: Integrated remove_statistic_point() to the pipelines
AdiKsOnDev Mar 8, 2024
42260a4
refactor: Rename the parameter name
AdiKsOnDev Mar 8, 2024
e4c6755
fix: Removed unnecessary list conversion
AdiKsOnDev Mar 8, 2024
c83ce10
fix: Wrong parameter usage
AdiKsOnDev Mar 9, 2024
5c7bdaa
refactor: Refactored the code to match PEP rules
AdiKsOnDev Mar 9, 2024
4368f49
CI/CD: Tests for the new feature
AdiKsOnDev Mar 9, 2024
856ce28
fix: Made a copy of the self.data dictionary
AdiKsOnDev Mar 9, 2024
ef4bb4a
refactor: Pre-Commit reformatting
AdiKsOnDev Mar 9, 2024
13356ca
fix: Returned the deleted line
AdiKsOnDev Mar 11, 2024
3131d48
fix: Typo in the method's name
AdiKsOnDev Mar 11, 2024
182728d
refactor: algorithm name
AdiKsOnDev Mar 11, 2024
13587a4
fix: Fixed the references to renamed algorithm
AdiKsOnDev Mar 11, 2024
6314994
fix: Used _algorithm_key attribute, instead of the algorithm Object i…
AdiKsOnDev Mar 11, 2024
73a7de9
fix: Added a loop for removing all algorithms
AdiKsOnDev Mar 12, 2024
b4eed33
fix: Correctly removed the statistical points
AdiKsOnDev Mar 12, 2024
dc846fa
fix: statistical points get remove only after being used
AdiKsOnDev Mar 13, 2024
884a489
CI/CD: Modified Tests for new functionality
AdiKsOnDev Mar 15, 2024
cf3abe8
fix: Method removes only the algorithm's tensor
AdiKsOnDev Mar 15, 2024
7b2b3da
fix: Returned the correct usage of new method
AdiKsOnDev Mar 15, 2024
6e4f5c8
fix: Forgot to append to list
AdiKsOnDev Mar 15, 2024
0625e85
feat: Added _algorithm_key property to base class
AdiKsOnDev Mar 15, 2024
3bcad1e
fix: Update nncf/quantization/algorithms/algorithm.py
AdiKsOnDev Mar 19, 2024
2ede9ca
fix: Utilised the encapsulation
AdiKsOnDev Mar 19, 2024
7b2c92b
refactor: Pre-Commit changes
AdiKsOnDev Mar 19, 2024
1238dbe
fix: Correct usage of algorithm_key()
AdiKsOnDev Mar 20, 2024
5f32d93
fix: Compare alg name instead of Object itself
AdiKsOnDev Mar 31, 2024
3bf0fef
fix: Iterating through items of collectors
AdiKsOnDev Mar 31, 2024
56fa9e6
fix: Should work now
AdiKsOnDev Mar 31, 2024
427f680
fix: Type 'str' not callable
AdiKsOnDev Mar 31, 2024
80b6afc
fix: @property deleted
AdiKsOnDev Apr 2, 2024
7fa02d4
Merge branch 'openvinotoolkit:develop' into develop
AdiKsOnDev Apr 3, 2024
495bd4f
git: Sync fork
AdiKsOnDev Apr 3, 2024
a0a0c5f
fix: Returned property decorator
AdiKsOnDev Apr 3, 2024
aefd170
refactor: Formatted & Cleaned the code
AdiKsOnDev Apr 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions nncf/common/tensor_statistics/statistic_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,32 @@ def add_statistic_point(self, statistic_point: StatisticPoint) -> None:

self.data[target_node_name].append(statistic_point)

def remove_statistic_points(self, algorithm_key: str) -> None:
"""
Method to remove statistic point associated with a given algorithm
from statistic point container.

:param algorithm_key: Algorithm key.
"""
reduced_data = {}
for target_node_name, statistic_points in self.data.items():
# Reassign every target node name IF it doesn't contain the given algorithm
reduced_statistics = []
for statistic_point in statistic_points:
statistic_point.algorithm_to_tensor_collectors = {
algorithm: value
for algorithm, value in statistic_point.algorithm_to_tensor_collectors.items()
if algorithm != algorithm_key
}

if statistic_point.algorithm_to_tensor_collectors:
reduced_statistics.append(statistic_point)

if reduced_statistics:
reduced_data[target_node_name] = reduced_statistics
AdiKsOnDev marked this conversation as resolved.
Show resolved Hide resolved

self.data = reduced_data

def iter_through_statistic_points_in_target_node(
self, target_node_name: str, filter_fn: Callable[[StatisticPoint], bool]
) -> StatisticPoint:
Expand Down
11 changes: 11 additions & 0 deletions nncf/quantization/algorithms/algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ class Algorithm(ABC):
Base class for all Post-Training algorithms.
"""

def __init__(self):
self._algorithm_key = ""

def algorithm_key(self) -> str:
AdiKsOnDev marked this conversation as resolved.
Show resolved Hide resolved
"""
Returns algorithm key.

:return: Algorithm key as string.
"""
return self._algorithm_key

@property
@abstractmethod
def available_backends(self) -> List[BackendType]:
Expand Down
5 changes: 4 additions & 1 deletion nncf/quantization/algorithms/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,14 @@ def run_step(

pipeline_steps = self._remove_unsupported_algorithms(get_backend(model))
pipeline_step = pipeline_steps[step_index]

for algorithm in pipeline_step[:-1]:
current_model = algorithm.apply(current_model, current_graph, step_statistics)
current_graph = NNCFGraphFactory.create(current_model)
step_statistics.remove_statistic_points(algorithm.algorithm_key())

nikita-malininn marked this conversation as resolved.
Show resolved Hide resolved
current_model = pipeline_step[-1].apply(current_model, current_graph, step_statistics)
step_statistics.remove_statistic_points(pipeline_step[-1].algorithm_key())

return current_model

Expand Down Expand Up @@ -162,7 +166,6 @@ def run_from_step(

# Run current pipeline step
step_model = self.run_step(step_index, step_statistics, step_model, step_graph)

step_graph = None # We should rebuild the graph for the next pipeline step

return step_model
Expand Down
49 changes: 49 additions & 0 deletions tests/common/test_statistic_points.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright (c) 2024 Intel Corporation
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pytest

from nncf.common.graph.transformations.commands import TargetPoint
from nncf.common.graph.transformations.commands import TargetType
from nncf.common.tensor_statistics.collectors import TensorStatisticCollectorBase
from nncf.common.tensor_statistics.statistic_point import StatisticPoint
from nncf.common.tensor_statistics.statistic_point import StatisticPointsContainer


class TestStatisticPointsContainer:
@pytest.fixture
def container_with_statistics(self):
container = StatisticPointsContainer()
target_type = TargetType.LAYER
target_point = TargetPoint(target_type)
target_point.target_node_name = "Node"
# tensor_collector = TensorStatisticCollectorBase()
AdiKsOnDev marked this conversation as resolved.
Show resolved Hide resolved
statistic_point = StatisticPoint(target_point, TensorStatisticCollectorBase, "minmax")
statistic_point = StatisticPoint(target_point, TensorStatisticCollectorBase, "post_training")
container.add_statistic_point(statistic_point)
return container

def test_remove_statistic_points(self, container_with_statistics):
container_with_statistics.remove_statistic_points("minmax")

# Verify that the statistics for the specified algorithm are removed
for target_node_name, statistic_points in container_with_statistics.data.items():
for statistic_point in statistic_points:
assert (
"minmax" not in statistic_point.algorithm_to_tensor_collectors
and "post_training" in statistic_point.algorithm_to_tensor_collectors
)

def test_remove_statistic_points_empty_container(self):
empty_container = StatisticPointsContainer()
empty_container.remove_statistic_points("algorithm")

# Verify that removing statistics from an empty container has no effect
assert not empty_container.data
Loading