Spaces:
Runtime error
Runtime error
| # copyright (c) 2021 PaddlePaddle Authors. All Rights Reserve. | |
| # | |
| # 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 sys | |
| import paddle.profiler as profiler | |
| # A global variable to record the number of calling times for profiler | |
| # functions. It is used to specify the tracing range of training steps. | |
| _profiler_step_id = 0 | |
| # A global variable to avoid parsing from string every time. | |
| _profiler_options = None | |
| _prof = None | |
| class ProfilerOptions(object): | |
| ''' | |
| Use a string to initialize a ProfilerOptions. | |
| The string should be in the format: "key1=value1;key2=value;key3=value3". | |
| For example: | |
| "profile_path=model.profile" | |
| "batch_range=[50, 60]; profile_path=model.profile" | |
| "batch_range=[50, 60]; tracer_option=OpDetail; profile_path=model.profile" | |
| ProfilerOptions supports following key-value pair: | |
| batch_range - a integer list, e.g. [100, 110]. | |
| state - a string, the optional values are 'CPU', 'GPU' or 'All'. | |
| sorted_key - a string, the optional values are 'calls', 'total', | |
| 'max', 'min' or 'ave. | |
| tracer_option - a string, the optional values are 'Default', 'OpDetail', | |
| 'AllOpDetail'. | |
| profile_path - a string, the path to save the serialized profile data, | |
| which can be used to generate a timeline. | |
| exit_on_finished - a boolean. | |
| ''' | |
| def __init__(self, options_str): | |
| assert isinstance(options_str, str) | |
| self._options = { | |
| 'batch_range': [10, 20], | |
| 'state': 'All', | |
| 'sorted_key': 'total', | |
| 'tracer_option': 'Default', | |
| 'profile_path': '/tmp/profile', | |
| 'exit_on_finished': True, | |
| 'timer_only': True | |
| } | |
| self._parse_from_string(options_str) | |
| def _parse_from_string(self, options_str): | |
| for kv in options_str.replace(' ', '').split(';'): | |
| key, value = kv.split('=') | |
| if key == 'batch_range': | |
| value_list = value.replace('[', '').replace(']', '').split(',') | |
| value_list = list(map(int, value_list)) | |
| if len(value_list) >= 2 and value_list[0] >= 0 and value_list[ | |
| 1] > value_list[0]: | |
| self._options[key] = value_list | |
| elif key == 'exit_on_finished': | |
| self._options[key] = value.lower() in ("yes", "true", "t", "1") | |
| elif key in [ | |
| 'state', 'sorted_key', 'tracer_option', 'profile_path' | |
| ]: | |
| self._options[key] = value | |
| elif key == 'timer_only': | |
| self._options[key] = value | |
| def __getitem__(self, name): | |
| if self._options.get(name, None) is None: | |
| raise ValueError( | |
| "ProfilerOptions does not have an option named %s." % name) | |
| return self._options[name] | |
| def add_profiler_step(options_str=None): | |
| ''' | |
| Enable the operator-level timing using PaddlePaddle's profiler. | |
| The profiler uses a independent variable to count the profiler steps. | |
| One call of this function is treated as a profiler step. | |
| Args: | |
| profiler_options - a string to initialize the ProfilerOptions. | |
| Default is None, and the profiler is disabled. | |
| ''' | |
| if options_str is None: | |
| return | |
| global _prof | |
| global _profiler_step_id | |
| global _profiler_options | |
| if _profiler_options is None: | |
| _profiler_options = ProfilerOptions(options_str) | |
| # profile : https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/performance_improving/profiling_model.html#chakanxingnengshujudetongjibiaodan | |
| # timer_only = True only the model's throughput and time overhead are displayed | |
| # timer_only = False calling summary can print a statistical form that presents performance data from different perspectives. | |
| # timer_only = False the output Timeline information can be found in the profiler_log directory | |
| if _prof is None: | |
| _timer_only = str(_profiler_options['timer_only']) == str(True) | |
| _prof = profiler.Profiler( | |
| scheduler = (_profiler_options['batch_range'][0], _profiler_options['batch_range'][1]), | |
| on_trace_ready = profiler.export_chrome_tracing('./profiler_log'), | |
| timer_only = _timer_only) | |
| _prof.start() | |
| else: | |
| _prof.step() | |
| if _profiler_step_id == _profiler_options['batch_range'][1]: | |
| _prof.stop() | |
| _prof.summary( | |
| op_detail=True, | |
| thread_sep=False, | |
| time_unit='ms') | |
| _prof = None | |
| if _profiler_options['exit_on_finished']: | |
| sys.exit(0) | |
| _profiler_step_id += 1 | |