ai-edge-quantizer-nightly 0.5.0.dev20260203__py3-none-any.whl → 0.5.0.dev20260204__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ai_edge_quantizer/utils/progress_utils.py +96 -0
- ai_edge_quantizer/utils/progress_utils_test.py +105 -0
- {ai_edge_quantizer_nightly-0.5.0.dev20260203.dist-info → ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info}/METADATA +1 -1
- {ai_edge_quantizer_nightly-0.5.0.dev20260203.dist-info → ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info}/RECORD +7 -5
- {ai_edge_quantizer_nightly-0.5.0.dev20260203.dist-info → ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info}/WHEEL +0 -0
- {ai_edge_quantizer_nightly-0.5.0.dev20260203.dist-info → ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info}/licenses/LICENSE +0 -0
- {ai_edge_quantizer_nightly-0.5.0.dev20260203.dist-info → ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright 2024 The AI Edge Quantizer Authors.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
|
|
16
|
+
"""Utility functions to display a progress bar and progress report."""
|
|
17
|
+
|
|
18
|
+
import time
|
|
19
|
+
import tracemalloc
|
|
20
|
+
import tqdm
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ProgressBar:
|
|
24
|
+
"""A Progress Bar that can be used to track the progress of a process."""
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
total_steps: int,
|
|
29
|
+
description: str = '',
|
|
30
|
+
disappear_on_finish: bool = False,
|
|
31
|
+
disable: bool = False,
|
|
32
|
+
):
|
|
33
|
+
self._progress_bar = tqdm.tqdm(
|
|
34
|
+
total=total_steps,
|
|
35
|
+
desc=description,
|
|
36
|
+
leave=not disappear_on_finish,
|
|
37
|
+
disable=disable,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def __enter__(self):
|
|
41
|
+
"""Enters the context manager."""
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
def __exit__(self, exc_type, exc_value, traceback):
|
|
45
|
+
"""Exits the context manager and closes the progress bar."""
|
|
46
|
+
self.close()
|
|
47
|
+
|
|
48
|
+
def update_single_step(self):
|
|
49
|
+
"""Updates the progress bar by a single step."""
|
|
50
|
+
self._progress_bar.update(1)
|
|
51
|
+
|
|
52
|
+
def close(self):
|
|
53
|
+
"""Closes the progress bar."""
|
|
54
|
+
self._progress_bar.close()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ProgressReport:
|
|
58
|
+
"""A class to generate a progress report for the quantization process."""
|
|
59
|
+
|
|
60
|
+
def __init__(self, description: str = ''):
|
|
61
|
+
self._description = description
|
|
62
|
+
self._start_time = None
|
|
63
|
+
|
|
64
|
+
def capture_progess_start(self):
|
|
65
|
+
self._start_time = time.time()
|
|
66
|
+
tracemalloc.start()
|
|
67
|
+
|
|
68
|
+
def render_report(
|
|
69
|
+
self,
|
|
70
|
+
original_size: int,
|
|
71
|
+
quantized_size: int,
|
|
72
|
+
quantization_ratio: float,
|
|
73
|
+
memory_peak: float,
|
|
74
|
+
total_time: float,
|
|
75
|
+
):
|
|
76
|
+
"""Prints out the progress report."""
|
|
77
|
+
print(f'Original model size: {original_size/1024:.2f} KB')
|
|
78
|
+
print(f'Quantized model size: {quantized_size/1024:.2f} KB')
|
|
79
|
+
print(f'Quantization Ratio: {quantization_ratio:.2f}')
|
|
80
|
+
print(f'Total time: {total_time:.2f} seconds')
|
|
81
|
+
print(f'Memory peak: {memory_peak:.2f} MB')
|
|
82
|
+
|
|
83
|
+
def generate_progress_report(self, original_model, quantized_model):
|
|
84
|
+
original_size = len(original_model)
|
|
85
|
+
quantized_size = len(quantized_model)
|
|
86
|
+
quantization_ratio = quantized_size / original_size
|
|
87
|
+
total_time = time.time() - self._start_time
|
|
88
|
+
_, mem_peak_bytes = tracemalloc.get_traced_memory()
|
|
89
|
+
mem_peak_mb = mem_peak_bytes / 1024 / 1024
|
|
90
|
+
self.render_report(
|
|
91
|
+
original_size,
|
|
92
|
+
quantized_size,
|
|
93
|
+
quantization_ratio,
|
|
94
|
+
mem_peak_mb,
|
|
95
|
+
total_time,
|
|
96
|
+
)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Copyright 2024 The AI Edge Quantizer Authors.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
|
|
16
|
+
import io
|
|
17
|
+
import sys
|
|
18
|
+
import time
|
|
19
|
+
import tracemalloc
|
|
20
|
+
from unittest import mock
|
|
21
|
+
|
|
22
|
+
from tensorflow.python.platform import googletest
|
|
23
|
+
from ai_edge_quantizer.utils import progress_utils
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ProgressBarTest(googletest.TestCase):
|
|
27
|
+
|
|
28
|
+
@mock.patch('tqdm.tqdm')
|
|
29
|
+
def test_progress_bar_update(self, mock_tqdm):
|
|
30
|
+
mock_progress_bar_instance = mock_tqdm.return_value
|
|
31
|
+
with progress_utils.ProgressBar(total_steps=10) as pb:
|
|
32
|
+
pb.update_single_step()
|
|
33
|
+
pb.update_single_step()
|
|
34
|
+
|
|
35
|
+
mock_tqdm.assert_called_once_with(
|
|
36
|
+
total=10, desc='', leave=True, disable=False
|
|
37
|
+
)
|
|
38
|
+
self.assertEqual(mock_progress_bar_instance.update.call_count, 2)
|
|
39
|
+
mock_progress_bar_instance.update.assert_called_with(1)
|
|
40
|
+
mock_progress_bar_instance.close.assert_called_once()
|
|
41
|
+
|
|
42
|
+
@mock.patch('tqdm.tqdm')
|
|
43
|
+
def test_progress_bar_disable(self, mock_tqdm):
|
|
44
|
+
mock_progress_bar_instance = mock_tqdm.return_value
|
|
45
|
+
with progress_utils.ProgressBar(total_steps=10, disable=True):
|
|
46
|
+
pass
|
|
47
|
+
mock_tqdm.assert_called_once_with(
|
|
48
|
+
total=10, desc='', leave=True, disable=True
|
|
49
|
+
)
|
|
50
|
+
mock_progress_bar_instance.close.assert_called_once()
|
|
51
|
+
|
|
52
|
+
@mock.patch('tqdm.tqdm')
|
|
53
|
+
def test_progress_bar_disappear_on_finish(self, mock_tqdm):
|
|
54
|
+
mock_progress_bar_instance = mock_tqdm.return_value
|
|
55
|
+
with progress_utils.ProgressBar(total_steps=10, disappear_on_finish=True):
|
|
56
|
+
pass
|
|
57
|
+
mock_tqdm.assert_called_once_with(
|
|
58
|
+
total=10, desc='', leave=False, disable=False
|
|
59
|
+
)
|
|
60
|
+
mock_progress_bar_instance.close.assert_called_once()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ProgressReportTest(googletest.TestCase):
|
|
64
|
+
|
|
65
|
+
def setUp(self):
|
|
66
|
+
super().setUp()
|
|
67
|
+
self.mock_time = self.enter_context(
|
|
68
|
+
mock.patch.object(time, 'time', autospec=True)
|
|
69
|
+
)
|
|
70
|
+
self.mock_tracemalloc_start = self.enter_context(
|
|
71
|
+
mock.patch.object(tracemalloc, 'start', autospec=True)
|
|
72
|
+
)
|
|
73
|
+
self.mock_tracemalloc_get_traced_memory = self.enter_context(
|
|
74
|
+
mock.patch.object(tracemalloc, 'get_traced_memory', autospec=True)
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def test_generate_progress_report(self):
|
|
78
|
+
self.mock_time.side_effect = [100.0, 105.5] # Start time, end time.
|
|
79
|
+
# Mock memory: current=1MB, peak=2MB.
|
|
80
|
+
self.mock_tracemalloc_get_traced_memory.return_value = (
|
|
81
|
+
1 * 1024 * 1024,
|
|
82
|
+
2 * 1024 * 1024,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
progress_report = progress_utils.ProgressReport()
|
|
86
|
+
progress_report.capture_progess_start()
|
|
87
|
+
|
|
88
|
+
original_model = b'\x01' * 2048 # 2KB.
|
|
89
|
+
quantized_model = b'\x02' * 1024 # 1KB
|
|
90
|
+
|
|
91
|
+
mock_stdout = io.StringIO()
|
|
92
|
+
with mock.patch.object(sys, 'stdout', mock_stdout):
|
|
93
|
+
progress_report.generate_progress_report(original_model, quantized_model)
|
|
94
|
+
|
|
95
|
+
self.mock_tracemalloc_start.assert_called_once()
|
|
96
|
+
output = mock_stdout.getvalue()
|
|
97
|
+
self.assertIn('Original model size: 2.00 KB', output)
|
|
98
|
+
self.assertIn('Quantized model size: 1.00 KB', output)
|
|
99
|
+
self.assertIn('Quantization Ratio: 0.50', output)
|
|
100
|
+
self.assertIn('Total time: 5.50 seconds', output)
|
|
101
|
+
self.assertIn('Memory peak: 2.00 MB', output)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == '__main__':
|
|
105
|
+
googletest.main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ai-edge-quantizer-nightly
|
|
3
|
-
Version: 0.5.0.
|
|
3
|
+
Version: 0.5.0.dev20260204
|
|
4
4
|
Summary: A quantizer for advanced developers to quantize converted AI Edge models.
|
|
5
5
|
Home-page: https://github.com/google-ai-edge/ai-edge-quantizer
|
|
6
6
|
Keywords: On-Device ML,AI,Google,TFLite,Quantization,LLMs,GenAI
|
|
@@ -67,6 +67,8 @@ ai_edge_quantizer/utils/calibration_utils.py,sha256=dFDsjc3CXaDFNbCMyoPrMVubd3ED
|
|
|
67
67
|
ai_edge_quantizer/utils/calibration_utils_test.py,sha256=jod4iokZkG00y9JrYaFzVvg4JwiA6mX8_whAMkNyoEc,9334
|
|
68
68
|
ai_edge_quantizer/utils/constrained_ops_utils.py,sha256=z0sm1R9anRRVgdgI23XQKwDRcdARdpTo_6UBDB_lHXE,4502
|
|
69
69
|
ai_edge_quantizer/utils/constrained_ops_utils_test.py,sha256=zmMIAS1WIvYK1Z9ZMMxYovIGtxfek-jvfZqrois1ahE,1756
|
|
70
|
+
ai_edge_quantizer/utils/progress_utils.py,sha256=itgRhA5Gcu0xsPjFzAsZhNfOxa2KB8Dc0a_ysQ9DCac,2940
|
|
71
|
+
ai_edge_quantizer/utils/progress_utils_test.py,sha256=t8O8kGRerq9pXGylROHI9YyAgA7KEAKwDrj8G0CBs88,3709
|
|
70
72
|
ai_edge_quantizer/utils/test_utils.py,sha256=a4Nk-wbeB09dFjTDZiA0K67d26j5DD0UDH_GIVmVG_4,8685
|
|
71
73
|
ai_edge_quantizer/utils/tfl_flatbuffer_utils.py,sha256=3mngikx_lF-qKBc5KxGX-5kELH_XGKpeGjwUyR5dfZI,12167
|
|
72
74
|
ai_edge_quantizer/utils/tfl_flatbuffer_utils_test.py,sha256=K1SbK8q92qYVtiVj0I0GtugsPTkpIpEKv9zakvFV_Sc,8555
|
|
@@ -74,8 +76,8 @@ ai_edge_quantizer/utils/tfl_interpreter_utils.py,sha256=ptdlC3WVUE9aBznT7kZQ0ZOk
|
|
|
74
76
|
ai_edge_quantizer/utils/tfl_interpreter_utils_test.py,sha256=EPOXbmXqbt3tAewo3BQQjh2mjuxrrFit5tkF0wUVYHU,12471
|
|
75
77
|
ai_edge_quantizer/utils/validation_utils.py,sha256=Mr0D6X-pTDLODFAnCX3IlqdV1OL02tlq0ZjHbqx8nzg,7439
|
|
76
78
|
ai_edge_quantizer/utils/validation_utils_test.py,sha256=T8K5mCWeMcihND2KS_dHvCJUU9lEdG2sD95EgPkaX3w,5584
|
|
77
|
-
ai_edge_quantizer_nightly-0.5.0.
|
|
78
|
-
ai_edge_quantizer_nightly-0.5.0.
|
|
79
|
-
ai_edge_quantizer_nightly-0.5.0.
|
|
80
|
-
ai_edge_quantizer_nightly-0.5.0.
|
|
81
|
-
ai_edge_quantizer_nightly-0.5.0.
|
|
79
|
+
ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
80
|
+
ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info/METADATA,sha256=zJ0WvuCMyRufJW7Z3j8zDGAhNd-y-bWvpbrjJIxw-Kg,1731
|
|
81
|
+
ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
|
82
|
+
ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info/top_level.txt,sha256=8QTfPnFXNVUhScFLaa-NWZMFWMn72M50DVPubpwWB1g,18
|
|
83
|
+
ai_edge_quantizer_nightly-0.5.0.dev20260204.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|