[Feature] Refactor Estimator for computing FLOPs/Params/Latency.#230
[Feature] Refactor Estimator for computing FLOPs/Params/Latency.#230sunnyxiaohu merged 22 commits intoopen-mmlab:dev-1.xfrom
Conversation
1. add EvaluatorLoop in engine.runners; 2. add estimator for structures (both subnet & supernet); 3. add layer_counter for each op.
Codecov Report
@@ Coverage Diff @@
## dev-1.x #230 +/- ##
==========================================
- Coverage 0.48% 0.44% -0.04%
==========================================
Files 144 159 +15
Lines 5943 6454 +511
Branches 959 1059 +100
==========================================
Hits 29 29
- Misses 5909 6420 +511
Partials 5 5
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
mmrazor/registry/registry.py
Outdated
| # manage visualizer backend | ||
| VISBACKENDS = Registry('vis_backend', parent=MMENGINE_VISBACKENDS) | ||
|
|
||
| ESTIMATOR = Registry('estimator') |
There was a problem hiding this comment.
ESTIMATOR -> ESTIMATORS
| if (i + 1) == max_iter: | ||
| fps = (i + 1 - num_warmup) / pure_inf_time | ||
| if PRINT: | ||
| print( |
There was a problem hiding this comment.
use logger to print, with debug logger level.
| mean_times_pre_image_ = sum(times_pre_image_list_) / len( | ||
| times_pre_image_list_) | ||
| if PRINT: | ||
| print( |
There was a problem hiding this comment.
use logger to print, with debug logger level.
|
|
||
| @ESTIMATOR.register_module() | ||
| class BaseEstimator(metaclass=ABCMeta): | ||
| """Evaluator for calculating the accuracy and resources consume. Accuracy |
There was a problem hiding this comment.
update docstring, including necessary Notes.
There was a problem hiding this comment.
Add docstring in ResourceEstimator, showing 3 cases when using it.
| self.units = units | ||
| self.disabled_counters = disabled_counters | ||
|
|
||
| def evaluate( |
1. add ResourceEstimator based on BaseEstimator; 2. add notes & examples for ResourceEstimator & EvaluatorLoop usage; 3. fix a bug of latency test. 4. minor changes according to comments.
| return resource_results | ||
|
|
||
| def export_subnet(self, model): | ||
| """Export current best subnet.""" |
|
|
||
|
|
||
| @LOOPS.register_module() | ||
| class EvaluatorLoop(ValLoop): |
There was a problem hiding this comment.
-> ResourceEvaluatorLoop would be better ?
There was a problem hiding this comment.
Shall the file name be changed?
There was a problem hiding this comment.
yes, and so do the releated UTs.
|
|
||
| return resource_results | ||
|
|
||
| def export_subnet(self, model): |
There was a problem hiding this comment.
is export_subnet sutable for all the NAS alogorithm?
There was a problem hiding this comment.
This method is called when it comes to those NAS algorithms that require building a supernet for training. For those algorithms, measuring subnet resources is more meaningful than supernet during validation, therefore this method is required to get the current searched subnet from the supernet.
| def get_model_complexity_info( | ||
| model: Module, | ||
| fix_mutable: Optional[ValidFixMutable] = None, | ||
| input_shape: Iterable[int] = (3, 224, 224), |
There was a problem hiding this comment.
delete the directory: subnet/estimators and update the corresponding refs.
| {'flops': 1.0, 'params': 0.7, 'latency': 0.0} | ||
|
|
||
| >>> # calculate mmrazor.model flops | ||
| NOTE: check 'EvaluatorLoop' in engine.runner.evaluator_val_loop |
There was a problem hiding this comment.
add more details for disabled_counters
| from abc import ABCMeta, abstractclassmethod | ||
|
|
||
|
|
||
| class BaseCounter(object, metaclass=ABCMeta): |
There was a problem hiding this comment.
Point that XXModuleCounter is responsible for XXModule, which could refers to flops_params_counter::get_counter_type().
08e9445 to
91bab7c
Compare
91bab7c to
15365df
Compare
0dfe636 to
bc3ed91
Compare
There was a problem hiding this comment.
- It seems to lack the function of counting flops with the specified scope.
- Better not use new registries without parents, it will be not used by other repos of OpenMMLab. You can use directly TASK_UTILS instead of
estimatorandop_counter estimator/is unsuitable to be understructures/. Suggestion location :mmrazor/models/task_modules/.- The file structure of
estimator/could be optimizer. Suggestion:
a. addcouters/inestimator
b. moveflops_params_counter.py,latency.py,op_spec_counters/tocounters/
c. renamelatency.pytolatency_counter.py
d. renameestimator/toestimators/
mmrazor/registry/registry.py
Outdated
| VISBACKENDS = Registry('vis_backend', parent=MMENGINE_VISBACKENDS) | ||
|
|
||
| ESTIMATORS = Registry('estimator') | ||
| OP_SPEC_COUNTERS = Registry('op_counter') |
There was a problem hiding this comment.
Better not use new registries without parents, it will be not used by other repos of OpenMMLab. You can use directly TASK_UTILS instead of 'estimator' and 'op_counter'
|
|
||
| >>> # calculate resources of mmrazor.models | ||
| NOTE: check 'ResourceEvaluatorLoop' in | ||
| engine.runner.resource_evaluator_val_loop for more details. |
There was a problem hiding this comment.
engine.runner.resource_evaluator_val_loop -> mmrazor.engine.runner.resource_evaluator_val_loop
to avoid ambiguity
|
|
||
|
|
||
| @LOOPS.register_module() | ||
| class ResourceEvaluatorLoop(ValLoop): |
There was a problem hiding this comment.
This loop should be for a specific algorithm, you had better name it with the algorithm. It is easy to be misunderstood that ResourceEvaluatorLoop is universal.
There was a problem hiding this comment.
ResourceEvaluatorLoop seems to be replaced with Hook, thus we need not maintain source valloop.
There was a problem hiding this comment.
Make this part a hook, done.
|
Now support counting flops with the specified scope. A list of scope names is required from users. |
| copied_model = copy.deepcopy(self.model) | ||
| load_fix_subnet(copied_model, fix_mutable) | ||
|
|
||
| estimator = ResourceEstimator() |
There was a problem hiding this comment.
Use estimator_cfg to build ResourceEstimator, and not use input_shape as fixed kwargs for ::estimate().
| copied_model = copy.deepcopy(self.model) | ||
| load_fix_subnet(copied_model, fix_mutable) | ||
|
|
||
| estimator = ResourceEstimator() |
There was a problem hiding this comment.
Use estimator_cfg to build ResourceEstimator, and not use input_shape as fixed kwargs for ::estimate.
|
|
||
| def get_model_complexity_info(model, | ||
| input_shape, | ||
| spec_modules=[], |
There was a problem hiding this comment.
spec_modules -> custom_keys to support prefix, ref to mmcv::mmcv/runner/optimizer/default_constuctor.py
There was a problem hiding this comment.
Now support counting flops with a specified scope, e.g. spec_modules = ['backbone']
| if len(spec_modules): | ||
| spec_modules_resources = dict() | ||
| accumulate_sub_module_flops_params(flops_params_model) | ||
| for name, module in flops_params_model.architecture.named_modules(): |
There was a problem hiding this comment.
Not all the flops_params_model have the architecture attribute.
| precision=precision)) + ' ' + units + 'FLOPs' | ||
| params_string = str( | ||
| params_units_convert( | ||
| accumulated_num_params, units='M', |
There was a problem hiding this comment.
Unify accumulated_flops_cost and accumulated_num_params with units
There was a problem hiding this comment.
A unit pair with FLOPs as 'G' and params as 'M' may be better.
| import sys | ||
| from functools import partial | ||
|
|
||
| import torch |
There was a problem hiding this comment.
Unify units for params and flops under the scope of flops_params_counter.py
There was a problem hiding this comment.
cancel unit convert in accumulate_sub_module_flops_params, remain the rest as the origin version.
Thanks for your contribution and we appreciate it a lot. The following instructions would make your pull request more healthy and more easily get feedback. If you do not understand some items, don't worry, just make the pull request and seek help from maintainers.
Motivation
Refactor Estimator for computing FLOPs/Params/Latency.
Modification
ResourceEstimatorto estimate model resources.mmcv.flops_counterasflops_params_counter.latency_counter.ConvCounter.EstimateResourcesHook.flops_params_counter&ResourceEstimator.FlopsEstimatorin mmrazor.BC-breaking (Optional)
Does the modification introduce changes that break the backward compatibility of the downstream repositories?
If so, please describe how it breaks the compatibility and how the downstream projects should modify their code to keep compatibility with this PR.
Use cases (Optional)
If this PR introduces a new feature, it is better to list some use cases here and update the documentation.
Checklist
Before PR:
After PR: