diff options
author | Alexandre Passos <apassos@google.com> | 2018-09-19 10:49:11 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-09-19 10:58:19 -0700 |
commit | a1b64cf2a6a995ffaaf384cf8643221f1c27db48 (patch) | |
tree | c3cb77b8f71029c77bd8cb122d7db087aa03af14 /tensorflow/python/keras | |
parent | 05ec322172958f6e67e4bcaef4681e6aa54fabeb (diff) |
Force-place embedding variables on CPUs ein eager mode.
This avoids problems which happen because most optimizers do not have sparse updating gpu kernels implemented.
Fixes #22042
PiperOrigin-RevId: 213654354
Diffstat (limited to 'tensorflow/python/keras')
-rwxr-xr-x | tensorflow/python/keras/BUILD | 5 | ||||
-rw-r--r-- | tensorflow/python/keras/layers/embeddings.py | 29 | ||||
-rw-r--r-- | tensorflow/python/keras/layers/embeddings_test.py | 13 |
3 files changed, 38 insertions, 9 deletions
diff --git a/tensorflow/python/keras/BUILD b/tensorflow/python/keras/BUILD index b521b1430d..4a72c4b3f3 100755 --- a/tensorflow/python/keras/BUILD +++ b/tensorflow/python/keras/BUILD @@ -381,12 +381,11 @@ py_test( ], ) -py_test( +cuda_py_test( name = "embeddings_test", size = "medium", srcs = ["layers/embeddings_test.py"], - srcs_version = "PY2AND3", - deps = [ + additional_deps = [ ":keras", "//tensorflow/python:client_testlib", ], diff --git a/tensorflow/python/keras/layers/embeddings.py b/tensorflow/python/keras/layers/embeddings.py index 629a9ec9a1..c6df5f2e26 100644 --- a/tensorflow/python/keras/layers/embeddings.py +++ b/tensorflow/python/keras/layers/embeddings.py @@ -18,6 +18,8 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function +from tensorflow.python.eager import context +from tensorflow.python.framework import ops from tensorflow.python.keras import backend as K from tensorflow.python.keras import constraints from tensorflow.python.keras import initializers @@ -117,12 +119,27 @@ class Embedding(Layer): @tf_utils.shape_type_conversion def build(self, input_shape): - self.embeddings = self.add_weight( - shape=(self.input_dim, self.output_dim), - initializer=self.embeddings_initializer, - name='embeddings', - regularizer=self.embeddings_regularizer, - constraint=self.embeddings_constraint) + # Note: most sparse optimizers do not have GPU kernels defined. When + # building graphs, the placement algorithm is able to place variables on CPU + # since it knows all kernels using the variable only exist on CPU. + # When eager execution is enabled, the placement decision has to be made + # right now. Checking for the presence of GPUs to avoid complicating the + # TPU codepaths which can handle sparse optimizers. + if context.executing_eagerly() and context.context().num_gpus(): + with ops.device('cpu:0'): + self.embeddings = self.add_weight( + shape=(self.input_dim, self.output_dim), + initializer=self.embeddings_initializer, + name='embeddings', + regularizer=self.embeddings_regularizer, + constraint=self.embeddings_constraint) + else: + self.embeddings = self.add_weight( + shape=(self.input_dim, self.output_dim), + initializer=self.embeddings_initializer, + name='embeddings', + regularizer=self.embeddings_regularizer, + constraint=self.embeddings_constraint) self.built = True def compute_mask(self, inputs, mask=None): diff --git a/tensorflow/python/keras/layers/embeddings_test.py b/tensorflow/python/keras/layers/embeddings_test.py index cab176ee34..2e42e403aa 100644 --- a/tensorflow/python/keras/layers/embeddings_test.py +++ b/tensorflow/python/keras/layers/embeddings_test.py @@ -21,9 +21,11 @@ from __future__ import print_function import numpy as np from tensorflow.python import keras +from tensorflow.python.eager import backprop from tensorflow.python.framework import test_util as tf_test_util from tensorflow.python.keras import testing_utils from tensorflow.python.platform import test +from tensorflow.python.training import adagrad class EmbeddingTest(test.TestCase): @@ -78,6 +80,17 @@ class EmbeddingTest(test.TestCase): outputs = keras.backend.eval(layer(inputs)) self.assertAllClose(outputs, [[[1, 1], [2, 2], [1, 1]]]) + @tf_test_util.run_in_graph_and_eager_modes() + def test_eager_gpu_cpu(self): + l = keras.layers.Embedding(output_dim=2, input_dim=2) + l.build((None, 2)) + inputs = keras.backend.constant([[0, 1, 0]], dtype='int32') + with backprop.GradientTape() as tape: + output = l(inputs) + gs = tape.gradient(output, l.weights) + opt = adagrad.AdagradOptimizer(0.1) + opt.apply_gradients(zip(gs, l.weights)) + self.assertAllEqual(len(gs), 1) if __name__ == '__main__': test.main() |