-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Add typing annotations to models/quantization #4232
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
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.
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.
Thanks for the PR!
Though, I have to say: have you run mypy over this to check if this works? perhaps focus on part where you are almost positive about the typing, otherwise it takes a really long time for reviewers to go over your work 😅
My review isn't finished, but I'm already getting the feeling that this should be split into different PRs considering the volume of modifications. But @pmeier is the authority on this matter :)
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.
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.
@@ -1,11 +1,15 @@ | |||
import torch | |||
import torch.nn as nn | |||
from torch import Tensor | |||
from typing import Any | |||
|
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 had to do a slight rewrite to make mypy happy. Let me know if this is fine.
Here are the errors and what are being suppressed.
The cat cat errors
The init errors, this probably has a nice workaround
Assigning a layer of model to None error
For now I have skipped the errors (except init error) by specifying return type @frgfm can you have a look ? |
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.
Hey @oke-aditya and sorry for the delay. Apart from your questions I've added two more comments inline.
torchvision/models/quantization/utils.py:31: error: Incompatible types in assignment (expression has type "QConfig", variable has type "Union[Tensor, Module]") [assignment] model.qconfig = torch.quantization.QConfig( ^
The ignore is justified, because we are adding an attribute to a live object and mypy
can't deal with that.
torchvision/models/quantization/utils.py:35: error: "Tensor" not callable [operator] model.fuse_model() ^
mypy
complains, because it correctly can't find a callable fuse_model
parameter on an nn.Module
. Thus, we need make the input type annotation more precise. I'm guessing we only accepting the quantized models that we have built-in? If yes, we could create a custom class mixin (for example QuantizedModuleMixin
) that also inherits from nn.Module
and adds this as abstract method. All our models could inherit from making fuse_model
also available for checking.
The cat cat errors
torchvision/models/quantization/shufflenetv2.py:33: error: Argument 1 to "cat" of "FloatFunctional" has incompatible type "Tuple[Tensor, Any]"; expected "List[Tensor]" [arg-type] out = self.cat.cat((x1, self.branch2(x2)), dim=1) ^ torchvision/models/quantization/shufflenetv2.py:35: error: Argument 1 to "cat" of "FloatFunctional" has incompatible type "Tuple[Any, Any]"; expected "List[Tensor]" [arg-type] out = self.cat.cat((self.branch1(x), self.branch2(x)), dim=1) ^
There are actually two errors here:
- We are passing a tuple when a list is expected. We should be able to replace the parentheses with brackets:
(x1, self.branch2(x2))
to[x1, self.branch2(x2)]
. self.branch*()
has no proper return type, so we need to cast ourselves:self.branch2(x2)
tocast(torch.Tensor, self.branch2(x2))
The init errors, this probably has a nice workaround
torchvision/models/quantization/inception.py:111: error: "__init__" of "InceptionA" gets multiple values for keyword argument "conv_block" [misc] super(QuantizableInceptionA, self).__init__(conv_block=QuantizableBasicConv2d, *args, **kwargs) ^ torchvision/models/quantization/inception.py:184: error: "__init__" of "InceptionAux" gets multiple values for keyword argument "conv_block" [misc] super(QuantizableInceptionAux, self).__init__(conv_block=QuantizableBasicConv2d, *args, **kwargs) ^
I don't think so, because we currently make the hard assumption that no one passes conv_block
as keyword argument. If someone would do, we would get an error at runtime, because we also pass it.
If we insist on using **kwargs
here, I'm afraid there is no clean way to do it. One workaround would be to add a conv_block: None = None
before the **kwargs
and bail out if we encounter anything else than None
. cc @fmassa @datumbox
Note that there are a lot more of these in the CI failure.
Assigning a layer of model to None error
torchvision/models/quantization/googlenet.py:81: error: Incompatible types in assignment (expression has type "None", variable has type Module) [assignment] model.aux1 = None ^
Porbably fine, because we do the same thing in the regular GoogLeNet
.
vision/torchvision/models/googlenet.py
Lines 56 to 57 in db530d8
model.aux1 = None # type: ignore[assignment] | |
model.aux2 = None # type: ignore[assignment] |
Not sure if this is a jit issue, but maybe we can type them as Optional[nn.Module]
in the first place?
Hi Phillip! Thanks a lot for detailed analysis! Such work teaches a lot to a newbie developer like me. 🙏 As you said there isn't a very neat workaround for the init errors, so probably we can take that in a new PR after some discussion. Hence, I think that we can suppress the bunch of init errors we are getting in CI Let me know further steps 😄 |
That is fair in the scope of this PR. Can you open an issue afterwards so we can track this? Maybe also add a quick The same (ignore + issue) holds for the
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.
LGTM, thanks a lot @oke-aditya! I've cleaned up the #TODO
comments to always be directly over the def __init__
line. Plus, I've added one the .fuse_model()
call.
Just pinging for visibility @datumbox (Probably he was busy in other PRs 😃) |
Hey @oke-aditya, Vasilis' review will be delayed until next week. Unfortunately, besides me no one has time to review now, so we'll have to wait. Sorry for that. |
No problem Philip ! 🙂 |
Hmm unsure if it is appropriate. But just re-tagging @datumbox Edit: Sorry, I pinged on Weekend. :( |
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.
@oke-aditya Apologies for the late response. The addition of EfficientNets took most of my time last week. I think we are good to merge this one. I'll wait for the green tests.
Concerning the valid remarks that @pmeier raised for the conv_block
, I believe we can consider this internal only for now. There some new developments on quantization so we might revisit how we do it.
Summary: * fix * add typings * fixup some more types * Type more * remove mypy ignore * add missing typings * fix a few mypy errors * fix mypy errors * fix mypy * ignore types * fixup annotation * fix remaining types * cleanup #TODO comments Reviewed By: fmassa Differential Revision: D30793343 fbshipit-source-id: 0448f6f24f406827abc9e1825489c786b6f0eb11 Co-authored-by: Philip Meier <[email protected]> Co-authored-by: Vasilis Vryniotis <[email protected]>
Following up on #2025, this PR adds missing typing annotations in models/quantization.
Any feedback is welcome!