-
Notifications
You must be signed in to change notification settings - Fork 0
Profiling of neural networks #26
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
Conversation
FloopCZ
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice functionality, thank you @bedapisl for pointing it out!
Can you please add the guidelines on how to use it? It should be visible here: http://emloop.org/advanced/model.html
emloop_tensorflow/frozen_model.py
Outdated
| outputs = self._session.run(fetches=fetches, feed_dict=feed_dict, | ||
| options=run_options, run_metadata=run_metadata) | ||
|
|
||
| with open(path.join(self._log_dir, "profile.json"), "w") as ofile: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| with open(path.join(self._log_dir, "profile.json"), "w") as ofile: | |
| with open(path.join(self._log_dir, 'profile.json'), 'w') as ofile: |
emloop_tensorflow/model.py
Outdated
| options=run_options, run_metadata=run_metadata) | ||
|
|
||
| if self._profile: | ||
| with open(path.join(self._log_dir, "profile.json"), "w") as ofile: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| with open(path.join(self._log_dir, "profile.json"), "w") as ofile: | |
| with open(path.join(self._log_dir, 'profile.json'), 'w') as ofile: |
| """Test frozen model restoration.""" | ||
| with pytest.raises(ValueError): | ||
| FrozenModel(inputs=[], outputs=[], restore_from=tmpdir) # there is no .pb file yet | ||
| FrozenModel(log_dir="/dev/null", inputs=[], outputs=[], restore_from=tmpdir) # there is no .pb file yet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| FrozenModel(log_dir="/dev/null", inputs=[], outputs=[], restore_from=tmpdir) # there is no .pb file yet | |
| FrozenModel(log_dir='/dev/null', inputs=[], outputs=[], restore_from=tmpdir) # there is no .pb file yet |
|
|
||
| # restore from directory | ||
| FrozenModel(**_IO, restore_from=tmpdir) | ||
| FrozenModel(log_dir="/dev/null", **_IO, restore_from=tmpdir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| FrozenModel(log_dir="/dev/null", **_IO, restore_from=tmpdir) | |
| FrozenModel(log_dir='/dev/null', **_IO, restore_from=tmpdir) |
|
|
||
| # restore from file | ||
| FrozenModel(**_IO, restore_from=path.join(tmpdir, 'model.pb')) | ||
| FrozenModel(log_dir="/dev/null", **_IO, restore_from=path.join(tmpdir, 'model.pb')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| FrozenModel(log_dir="/dev/null", **_IO, restore_from=path.join(tmpdir, 'model.pb')) | |
| FrozenModel(log_dir='/dev/null', **_IO, restore_from=path.join(tmpdir, 'model.pb')) |
|
|
||
| # restore from directory | ||
| frozen_model = FrozenModel(**_IO, restore_from=tmpdir, session_config={'allow_soft_placement': True}) | ||
| frozen_model = FrozenModel(log_dir="/dev/null", **_IO, restore_from=tmpdir, session_config={'allow_soft_placement': True}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| frozen_model = FrozenModel(log_dir="/dev/null", **_IO, restore_from=tmpdir, session_config={'allow_soft_placement': True}) | |
| frozen_model = FrozenModel(log_dir='/dev/null', **_IO, restore_from=tmpdir, session_config={'allow_soft_placement': True}) |
| model.save('') | ||
|
|
||
| frozen_model = FrozenModel(inputs=['input'], outputs=['output'], restore_from=tmpdir) | ||
| frozen_model = FrozenModel(log_dir="/dev/null", inputs=['input'], outputs=['output'], restore_from=tmpdir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| frozen_model = FrozenModel(log_dir="/dev/null", inputs=['input'], outputs=['output'], restore_from=tmpdir) | |
| frozen_model = FrozenModel(log_dir='/dev/null', inputs=['input'], outputs=['output'], restore_from=tmpdir) |
|
|
||
| # restore from directory | ||
| frozen_model = FrozenModel(**_IO, restore_from=tmpdir, session_config={'allow_soft_placement': True}) | ||
| frozen_model = FrozenModel(log_dir="/dev/null", **_IO, restore_from=tmpdir, session_config={'allow_soft_placement': True}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line too long.
emloop_tensorflow/model.py
Outdated
| if self._profile: | ||
| with open(path.join(self._log_dir, "profile.json"), "w") as ofile: | ||
| tl = timeline.Timeline(run_metadata.step_stats) | ||
| ofile.write(tl.generate_chrome_trace_format()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to overwrite the profile file on every call to run with only the statistics from this single call. Shouldn't it rather create the run_metadata variable in the constructor and consider the statistics from all the calls to run?
emloop_tensorflow/frozen_model.py
Outdated
|
|
||
| with open(path.join(self._log_dir, "profile.json"), "w") as ofile: | ||
| tl = timeline.Timeline(run_metadata.step_stats) | ||
| ofile.write(tl.generate_chrome_trace_format()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto statistics from a single call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this is a bit tricky. Both first (warm-up) and last (possibly smaller batch) profiles may be inaccurate. So what do we want to actually save? I guess keeping last keep_profiles: int = 5 is reasonable.
|
Whoa, @FloopCZ I thought we already gave up the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the code @bedapisl , I am sure it will be eventually very useful in other cases. Lets just pay a bit more attention to it so that we can marge it to this rather stable (well tested) project.
- make
log_diroptional in both models (and avoid modifying the tests) - implement reasonable behaviour with respect to multiple run calls (you have two suggestions from me and @FloopCZ )
- restructure the code so that duplicities are avoided
- explain this feature to @gdynusa and ask her for tests once you do the above
- mention this feature in the docs as @FloopCZ suggests
Anyways, thank you again!
emloop_tensorflow/frozen_model.py
Outdated
| def __init__(self, | ||
| inputs: List[str], outputs: List[str], restore_from: str, | ||
| session_config: Optional[dict]=None, n_gpus: int=0, **_): | ||
| log_dir: str, inputs: List[str], outputs: List[str], restore_from: str, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log_dir argument should be rather optional as it was previously if I am not mistaken. Of course, we should sanitize arguments similarly to this
if profile and not log_dir: # works for both None and empty string
raise ValueError('log_dir has to be specified with profile set to True')
emloop_tensorflow/frozen_model.py
Outdated
| """ | ||
| Initialize new :py:class:`FrozenModel` instance. | ||
| :param log_dir: path to the logging directory (wherein models should be saved) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This docstring is inaccurate as FrozenModel cannot be saved. It is solely for the profile or is it not?
emloop_tensorflow/frozen_model.py
Outdated
| :param restore_from: restore model path (either a dir or a .pb file) | ||
| :param session_config: TF session configuration dict | ||
| :param n_gpus: number of GPUs to use (either 0 or 1) | ||
| :param profile: whether profile.json should be saved to log_dir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| :param profile: whether profile.json should be saved to log_dir | |
| :param profile: if true, profile the speed of model inference and save profile.json to the specified log_dir |
emloop_tensorflow/frozen_model.py
Outdated
| self._graph = tf.Graph() | ||
| if session_config: | ||
| session_config = tf.ConfigProto(**session_config) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this intentional?
emloop_tensorflow/frozen_model.py
Outdated
|
|
||
| with open(path.join(self._log_dir, "profile.json"), "w") as ofile: | ||
| tl = timeline.Timeline(run_metadata.step_stats) | ||
| ofile.write(tl.generate_chrome_trace_format()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this is a bit tricky. Both first (warm-up) and last (possibly smaller batch) profiles may be inaccurate. So what do we want to actually save? I guess keeping last keep_profiles: int = 5 is reasonable.
| """Name of the monitored signal variance tensor/output.""" | ||
|
|
||
| def __init__(self, # pylint: disable=too-many-arguments | ||
| dataset: Optional[el.AbstractDataset], log_dir: Optional[str], inputs: List[str], outputs: List[str], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make the log_dir indeed optional with default None.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this in some way related to this pull request?
emloop_tensorflow/model.py
Outdated
| :param monitor: monitor signal mean and variance of the tensors which names contain the specified value | ||
| :param restore_fallback: ignored arg. (allows training from configs saved by emloop where it is added) | ||
| :param clip_gradient: limit the absolute value of the gradient; set to None for no clipping | ||
| :param profile: whether profile.json should be saved to log_dir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto description
emloop_tensorflow/model.py
Outdated
| for output_name in self.output_names: | ||
| fetches.append(tower[output_name]) | ||
|
|
||
| run_options = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more or less the same code as in FrozenModel. Can you perhaps wrap session.run to some util function which would be utilized in both classes?
| project = 'emloop-tensorflow' | ||
| copyright = '2018, Iterait a.s.' | ||
| author = 'Blazek Adam, Belohlavek Petr, Matzner Filip' | ||
| author = 'Blazek Adam, Belohlavek Petr, Matzner Filip, Bedrich Pisl' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice except that Beda's name and surname are in the wrong order. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whatever
| @@ -0,0 +1,27 @@ | |||
| Profiling networks | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the docs.
Profiling is switch on by
model.profilevariable in YAML config:Profile is saved in the
log_dirof the model and can be viewed in Google Chrome at addresschrome://tracing/.