Skip to content

Support temporary implicit input #202

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

Merged
merged 15 commits into from
Jul 31, 2019
Merged

Conversation

disktnk
Copy link
Member

@disktnk disktnk commented Jul 25, 2019

fixes #201

def forward(self, x):
    x + chainer.Variable(...)

Then, second value's reference is lost when convert to graph, so converter cannot set the value into ONNX graph .

To keep such a value reference, exporter retains input values in forwarding using LinkHook and patched apply. By introducing LinkHook, the hook function only retains temporary values to reduce memory usage, but the target model is required to use forward function, not __call__ function.

  • temporary implicit inputs are set as "value"(initializer), not as "constant".
  • drop export_implicit_inputs_public option, because converter cannot distinguish the temporary value is covered by converter or not. For example, beta of batch-normalization is sometimes None but followed by converter.

@@ -103,11 +103,28 @@ def rename_variable_name(
context.set_name(variables, new_name, pinned=True)


class InputCacheHook(chainer.FunctionHook):
Copy link
Member

Choose a reason for hiding this comment

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

How about RetainInputHook? "cache" sounds like we have the real copy of the inputs

@@ -103,11 +103,28 @@ def rename_variable_name(
context.set_name(variables, new_name, pinned=True)


class InputCacheHook(chainer.FunctionHook):
"""cache raw inputs
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"""cache raw inputs
"""Retain raw inputs


def forward_postprocess(self, fn, in_data):
# in_data is ndarray, not variable
self.func_inputs[id(fn)] = in_data
Copy link
Member

Choose a reason for hiding this comment

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

I think this will increase memory consumption. I think what we need to keep here is in_data which is not wrapped by chainer.Variable in inputs of FunctionNode.forward. However, it seems to be impossible to check this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Exactly! I tried LinkHook instead.

@codecov-io
Copy link

codecov-io commented Jul 29, 2019

Codecov Report

Merging #202 into master will increase coverage by 0.18%.
The diff coverage is 97.05%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #202      +/-   ##
==========================================
+ Coverage   89.69%   89.88%   +0.18%     
==========================================
  Files          24       24              
  Lines        1417     1473      +56     
==========================================
+ Hits         1271     1324      +53     
- Misses        146      149       +3
Impacted Files Coverage Δ
onnx_chainer/graph.py 95.65% <100%> (ø) ⬆️
onnx_chainer/export.py 91.47% <97.01%> (+1.47%) ⬆️
onnx_chainer/functions/normalization.py 86.44% <0%> (-6.78%) ⬇️
onnx_chainer/functions/math.py 85.71% <0%> (-0.54%) ⬇️
onnx_chainer/functions/__init__.py 100% <0%> (ø) ⬆️
onnx_chainer/mapping.py 90% <0%> (ø) ⬆️
onnx_chainer/functions/pooling.py 88.73% <0%> (+5.59%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 88994fb...8148f6e. Read the comment docs.

@disktnk disktnk changed the title [WIP] Support implicit input as constant Support temporary implicit input Jul 29, 2019
@disktnk disktnk marked this pull request as ready for review July 29, 2019 08:15
@disktnk disktnk force-pushed the fix/implicit-weakref branch from f8f6014 to 0a2d8ab Compare July 29, 2019 10:55
@disktnk
Copy link
Member Author

disktnk commented Jul 30, 2019

/test

@pfn-ci-bot
Copy link
Collaborator

Successfully created a job for commit 0a2d8ab:

@shinh
Copy link
Member

shinh commented Jul 30, 2019

Sorry if I'm confused, but this does not work for the following case?

    def test_implicit_input_value(self):
        class Model(chainer.Chain):

            def __init__(self):
                super(Model, self).__init__()
                self.frac = np.array(4, dtype=np.float32)

            def forward(self, x):
                return x / self.frac

        x = chainer.Variable(np.array(1, dtype=np.float32))
        self.expect(Model(), x, name='implicit_input_value')

@disktnk
Copy link
Member Author

disktnk commented Jul 30, 2019

Good catch. If inputs are ndarray type, function node converts them to chainer.Variable within itself, and will be lost out of function node (apply). I fixed it.

Copy link
Member

@shinh shinh left a comment

Choose a reason for hiding this comment

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

LGTM!!

if referenced_var is None:
# This variable is created within function node and weakref
# is lost. Make temporary variable and retain it.
if isinstance(inputs[i], chainer.Variable):
Copy link
Member

Choose a reason for hiding this comment

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

temp_var = chainer.as_variable(inputs[i]) ?

@disktnk disktnk added this to the 1.5.0 milestone Jul 31, 2019
@disktnk
Copy link
Member Author

disktnk commented Jul 31, 2019

/test

@pfn-ci-bot
Copy link
Collaborator

Successfully created a job for commit 8148f6e:

@disktnk disktnk merged commit b1a1abe into chainer:master Jul 31, 2019
@disktnk disktnk deleted the fix/implicit-weakref branch July 31, 2019 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Export error with temporary variable
4 participants