Skip to content

[quant][graph] Add valueQuantizable function#36548

Closed
supriyar wants to merge 7 commits intogh/supriyar/84/basefrom
gh/supriyar/84/head
Closed

[quant][graph] Add valueQuantizable function#36548
supriyar wants to merge 7 commits intogh/supriyar/84/basefrom
gh/supriyar/84/head

Conversation

@supriyar
Copy link
Copy Markdown
Contributor

@supriyar supriyar commented Apr 14, 2020

Stack from ghstack:

Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

Differential Revision: D21048963

Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

[ghstack-poisoned]
@dr-ci
Copy link
Copy Markdown

dr-ci Bot commented Apr 14, 2020

💊 Build failures summary and remediations

As of commit 2077608 (more details on the Dr. CI page):


💚 💚 Looks good so far! There are no failures yet. 💚 💚


This comment was automatically generated by Dr. CI (expand for details).Follow this link to opt-out of these comments for your Pull Requests.

Please report bugs/suggestions on the GitHub issue tracker.

See how this bot performed.

This comment has been revised 17 times.

Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Comment on lines +992 to +995
if (n->kind() == prim::CallFunction &&
getFuncName(n->inputs()[0]) == "batch_norm") {
return use.offset == 1;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you refactor this further to take a list of tuple of (name, offset) and check if the use is matching the name and offset?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the list of tuple in the function itself. I didn't want to spend too much time refactoring the other code, so I used it in the best way I saw fit, given that the conditions we were returning on in both cases was different.

Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

[ghstack-poisoned]
Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Comment on lines +995 to +1006
for (const auto& func_arg : aten_func_args) {
if (n->kind() == Symbol::aten(func_arg.func_name)) {
return v == n->inputs().at(func_arg.arg_index);
}
}

for (const auto& func_arg : call_func_args) {
if (n->kind() == prim::CallFunction &&
getFuncName(n->inputs()[0]) == func_arg.func_name) {
return v == n->inputs().at(func_arg.arg_index);
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use isAtenFuncNthArg and isCallFunctionNthArg here, also you can refactor these functions to not take value as input, and just compare use.offset with the arg_index

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the logic seems a bit different here actually, and this is due to the convoluted check logic that we fall back to nodeQuantizable when the check fails. Can we add a default index for aten and call function in nodes in nodeQuantizable?

Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

[ghstack-poisoned]
@supriyar supriyar requested a review from jerryzh168 April 14, 2020 19:00
Comment thread torch/csrc/jit/passes/quantization.cpp
Comment thread torch/csrc/jit/passes/quantization.cpp
Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
// For each operator in this list observers are inserted for the input based
// on the index specified.
const AtenFuncArgs& aten_func_args = AtenFuncArgs({{"lstm", 2}});
const CallFuncArgs& call_func_args = CallFuncArgs({{"batch_norm", 1}});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change belongs to next PR

Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

[ghstack-poisoned]
Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

[ghstack-poisoned]
Comment thread torch/csrc/jit/passes/quantization.cpp
Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
// Special checks for ops that do not require observers for all input tensors.
// For each operator in this list observers are inserted for the input based
// on the index specified.
const AtenFuncArgs& aten_func_args = AtenFuncArgs({{"lstm", 2}});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need to check is_dynamic for "lstm" node..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that won't be necessary because for dynamic quant we insert observers at the input. Which should be same as static quant. We have a check for is_dynamic to insert observer at the output of node in the parent function.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, then do you need is_dynamic as argument here?

Copy link
Copy Markdown
Contributor

@jerryzh168 jerryzh168 Apr 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't support static quant for lstm right now though

Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

[ghstack-poisoned]
Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Comment thread torch/csrc/jit/passes/quantization.cpp Outdated
Comment on lines +995 to +996
const AtenFuncArgs& aten_func_args = AtenFuncArgs({});
const CallFuncArgs& call_func_args = CallFuncArgs({});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you expose these two lists in the beginning of the file so that it's easier to find and change?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, a follow up here is, can we remove the isBias check for conv and linear and put the special case in the list?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, a follow up here is, can we remove the isBias check for conv and linear and put the special case in the list?

I think we can do this separately, I also see isWeight check that uses these lists.

Copy link
Copy Markdown
Contributor

@jerryzh168 jerryzh168 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks! left a few more comments, please address them before landing

Node* node = use.user;
return node->kind() == prim::CallFunction &&
getFuncName(node->inputs()[0]) == func_name &&
(n.has_value() ? (n.value() == use.offset) : true);
Copy link
Copy Markdown
Contributor

@jerryzh168 jerryzh168 Apr 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually this can be changed to (!n.has_value() || n.value() == use.offset)

Summary:
Refactor to be able to observe based on inputs to ops

Test Plan:
test_quantize_script.py

Reviewers:

Subscribers:

Tasks:

Tags:

[ghstack-poisoned]
Comment on lines +125 to +126
AtenFuncArgs _aten_func_args = {};
CallFuncArgs _call_func_args = {};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you use better names for these?

@supriyar supriyar closed this Apr 17, 2020
@facebook-github-bot facebook-github-bot deleted the gh/supriyar/84/head branch May 17, 2020 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

oncall: jit Add this issue/PR to JIT oncall triage queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants