Skip to content

Conversation

@liym27
Copy link
Contributor

@liym27 liym27 commented Oct 13, 2020

PR types

New features

PR changes

Others

Describe

The next PR of #27471
Deal with the backward to support assignment to a Variable in dynamic mode.


What this PR do ?

1. Add a new attribute version for VarBase

version is used to check whether an inplace operation will result in an incorrect gradient calculation.
The version number is incremented whenever the current VarBase is modified through an inplace operation.

import paddle
var = paddle.ones(shape=[4, 2, 3], dtype="float32")
print(var.inplace_version)  # 0

var[1] = 2.2
print(var.inplace_version)  # 1

2. Raise error if an inplace operation can result in incorrect gradient computation.

  • What kind in-place operations will raise error in backward?
    1. The gradient computation uses the value of a Tensor and this Tensor is modified inplace after using it
      For example:
import paddle
var_a = paddle.ones(shape=[4, 2, 3], dtype="float32")
var_a.stop_gradient = False

var_b = var_a**2

# Here, the gradient computation will use the value of var_b
var_c = var_b**2
var_b[1:2] = 3.3  # var_b is modified inplace after using it

loss = paddle.nn.functional.relu(var_c)
loss.backward()
----------------------
Error Message Summary:
----------------------
PermissionDeniedError: Tensor 'eager_tmp_2' used in gradient computation in grad op 'elementwise_pow_grad' has been modified by an inplace operation. Its version is 1 but the expected version is 0. Please fix your code to void calling an inplace operator after using the Tensor.
  [Hint: Expected variable_version == wrapper_version, but received variable_version:1 != wrapper_version:0.] (at /paddle/Paddle_0722/Paddle/paddle/fluid/imperative/basic_engine.cc:229)
  • What kind in-place operations will NOT raise error in backward?
    1. The gradient computation does not use the value of a Tensor through this Tensor is modified inplace
    2. The gradient computation uses the value of a Tensor but this Tensor is modified inplace before using it

Example for i

var_a = paddle.ones(shape=[4, 2, 3], dtype="float32")
var_a.stop_gradient = False

var_b = var_a**2
var_b[1:2] = 3  # var_b is modified inplace before using it
var_c = var_b + var_b  # Here, the grad op of sum doesn't use the value of var_b
loss = var_c.sum()

var_b[1:2] = 3  # var_b is modified inplace after using it

loss.backward()

Example for ii

var_a = paddle.ones(shape=[4, 2, 3], dtype="float32")
var_a.stop_gradient = False

var_b = var_a**2
var_b[1:2] = 3  # var_b is modified inplace before using it

# Here, the gradient computation will use the value of var_b
var_c = var_b**2
loss = var_c.sum()
loss.backward()

3. Add a new interface _bump_inplace_version() for VarBase to bump the version whenever the Tensor is modified through an inplace operation.

4. For api assign, call _bump_inplace_version() when it's an inplace operation inn dynamic mode


Speed comparison

  • seq2seq :
    batch num: 20*100
    batch size: 32

  • resnet:
    batch num: 10*100
    batch size: 2

  • ptb:
    batch num: 200*100
    batch size:100

Modle without inplace (s/batch) with inplace (s/batch)
cpu seq2se 0.0650103 0.0661232 - 1.712%
cpu resnet 2.53313 2.54028 -0.282%
cpu ptb 0.0550649 0.0555787 -0.925%
gpu ptb 0.018393 0.0187718 -2.0179%

@paddle-bot-old
Copy link

Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

@liym27 liym27 force-pushed the slice_inplace_backward branch from a8b1295 to 9d143f7 Compare October 13, 2020 12:25
@liym27 liym27 force-pushed the slice_inplace_backward branch from 9d143f7 to 8fbcbc0 Compare October 13, 2020 13:43
paddle-bot-old bot referenced this pull request Oct 13, 2020
Change-Id: Iebc370376876ef1e7a86dfae455004d788efa7fe
@liym27 liym27 force-pushed the slice_inplace_backward branch from 2cade8c to 72f57e9 Compare October 14, 2020 08:26
@liym27 liym27 requested a review from zhhsplendid October 14, 2020 12:07
@liym27 liym27 force-pushed the slice_inplace_backward branch from 0fdf109 to e93b6b4 Compare October 15, 2020 06:39
@liym27 liym27 force-pushed the slice_inplace_backward branch 2 times, most recently from 815f59c to 3b4be7e Compare October 15, 2020 08:20
paddle-bot-old bot referenced this pull request Oct 16, 2020
@liym27 liym27 requested a review from phlrain November 2, 2020 06:50
@liym27 liym27 force-pushed the slice_inplace_backward branch from 33ee39c to 7a1f389 Compare November 9, 2020 17:01
@liym27 liym27 force-pushed the slice_inplace_backward branch from 7a1f389 to 55122db Compare November 10, 2020 13:07
Change-Id: I7832f3546b638de06fa991be3058571147f65ddc

Add bump_version and deal with api assign

Add doc for version and bump_version
…cation or Variable.

fix bug: Only supports Tensor, LoDTensor, SelectedRows and LoDTensorArray to have TensorInplaceVersion.

If the inplace_version is not changed, use original var_wrapper
@liym27 liym27 force-pushed the slice_inplace_backward branch from af9ca11 to 4447049 Compare November 18, 2020 09:51
zhhsplendid
zhhsplendid previously approved these changes Nov 20, 2020
Copy link
Member

@zhhsplendid zhhsplendid left a comment

Choose a reason for hiding this comment

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

LGTM

luotao1
luotao1 previously approved these changes Nov 20, 2020
Copy link
Contributor

@luotao1 luotao1 left a comment

Choose a reason for hiding this comment

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

LGTM for tensor.h! 注释写的太太太棒了!

@liym27 liym27 dismissed stale reviews from luotao1 and zhhsplendid via 623346f November 26, 2020 00:09
@liym27 liym27 force-pushed the slice_inplace_backward branch from 623346f to 5e7f67a Compare November 30, 2020 03:07
…rformane.

Put LoDTensor in the first to optimize speed.
@liym27 liym27 force-pushed the slice_inplace_backward branch from 5e7f67a to 6900046 Compare November 30, 2020 03:09
Copy link
Member

@zhhsplendid zhhsplendid left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@luotao1 luotao1 left a comment

Choose a reason for hiding this comment

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

LGTM

@phlrain phlrain self-requested a review November 30, 2020 08:15
@liym27 liym27 merged commit 865a459 into PaddlePaddle:develop Nov 30, 2020
@liym27 liym27 changed the title Support inplace backward Check whether there is any inplace operation affecting gradient calculation Nov 30, 2020
@liym27 liym27 changed the title Check whether there is any inplace operation affecting gradient calculation [Dynamic] Check whether there is any inplace operation affecting gradient calculation Dec 1, 2020
@liym27 liym27 deleted the slice_inplace_backward branch December 9, 2020 03:48
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.

7 participants