tensorflow / tensorflow/probability
Softplus leaks memory (and is no longer needed)
Nobody has claimed this yet.
- Dominant language
- Jupyter Notebook
- Stars
- 4.4k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
The TensorFlow probability implementation of softplus leaks memory, and appears to no longer be needed. That is, I think the standard tf.nn.softplus implementation can be used now, as numerical stability issues appear to have been solved.
Currently the implementation of softplus is as follows (from here):
# TODO(b/155501444): Remove this when tf.nn.softplus is fixed.
if JAX_MODE:
_stable_grad_softplus = tf.nn.softplus
else:
@tf.custom_gradient
def _stable_grad_softplus(x):
"""A (more) numerically stable softplus than `tf.nn.softplus`."""
x = tf.convert_to_tensor(x)
if x.dtype == tf.float64:
cutoff = -20
else:
cutoff = -9
y = tf.where(x < cutoff, tf.math.log1p(tf.exp(x)), tf.nn.softplus(x))
def grad_fn(dy):
return dy * tf.where(x < cutoff, tf.exp(x), tf.nn.sigmoid(x))
return y, grad_fn
This leaks memory (in non-JAX mode) due to a couple of issues:
- The
grad_fnclosure captures the tensor represented byx. This closure then ends up in the gradient registry, which is never cleared. So the tensor represented byxhangs around forever. - For a similar reason TensorFlow's
custom_gradientimplementation also leaks memory. See 97697 for more details.
Here is a Colab notebook to demonstrate the memory leak.
However, I believe that the numerical stability issues with tf.nn.softplus have been solved. Specifically:
- The
tf.nn.softplusimplementation now useslog1pas of this commit on May 1 2020. - The gradient computation for
tf.nn.softplusnow usesmath_ops.sigmoidas of this commit on April 4 2019. - The Eigen implementation of sigmoid (which I think is here) computes this as
e^x / 1.0 + e^x, so using the approximation ofe^xin_stable_grad_softplusseems unnecessary to me. Ife^xis very small then1.0 + e^xwill be exactly 1.0, so this is equivalent toe^x. Ife^x> 1.0 then the result ofe^x / 1.0 + e^xwill be (I think) more accurate than just approximating the gradient toe^x. But I am not a numerical stability expert, so I may be wrong.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with tensorflow_probability/python/bijectors/softplus.py and reproduce the reported leak using the linked Colab notebook. Compare the current custom-gradient behavior with TensorFlow's tf.nn.softplus, checking numerical stability and memory usage; the work is done when the leak is addressed without regressing softplus behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- machine-learning, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100