<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _build(self, ids):
 """Lookup embeddings. Looks up an embedding vector for each value in `ids`. All ids must be within [0, vocab_size), else an `InvalidArgumentError` is raised at runtime. Args: ids: Tensor of dtype int64. Returns: Tensor of tf.shape(ids) + [embedding_dim] and dtype float32. """

    # Construct embeddings.
    if self._existing_vocab is None:
      if self.EMBEDDINGS not in self._initializers:
        self._initializers[self.EMBEDDINGS] = tf.initializers.random_normal()
      self._embeddings = tf.get_variable(
          "embeddings",
          shape=[self._vocab_size, self._embed_dim],
          dtype=tf.float32,
          initializer=self._initializers[self.EMBEDDINGS],
          partitioner=self._partitioners.get(self.EMBEDDINGS, None),
          regularizer=self._regularizers.get(self.EMBEDDINGS, None),
          trainable=self._trainable)
    else:
      self._embeddings = tf.get_variable(
          "embeddings",
          dtype=tf.float32,
          initializer=self._existing_vocab,
          regularizer=self._regularizers.get(self.EMBEDDINGS, None),
          trainable=self._trainable)

    if self._densify_gradients:
      # On the backwards pass, we convert the gradient from indexed-slices to a
      # regular tensor before sending it back to the parameter server.
      # This avoids excess computation on the parameter server.
      # In eager mode we do not need the conversion.
      # Add a check whether we are in eager mode when it is supported.
      embeddings = util.convert_gradient_to_tensor(self._embeddings)
    else:
      embeddings = self._embeddings

    # Lookup embeddings
    return tf.nn.embedding_lookup(embeddings, ids, name="embedding_lookup")