Сильно увеличивается потребление памяти при использовании ELMo от Tensorflow-Hub

Сейчас я пытаюсь сравнить схожесть миллионов документов. Для первого теста на ЦП я сократил их примерно до 50 символов каждый и попытался получить ELMo Embedding для 10 из них за раз следующим образом:

ELMO = "https://tfhub.dev/google/elmo/2"
for row in file:
    split = row.split(";", 1)
    if len(split) > 1:
        text = split[1].replace("\n", "")
            texts.append(text[:50])
    if i == 300:
        break
    if i % 10 == 0:
        elmo = hub.Module(ELMO, trainable=False)
                 executable = elmo(
                 texts,
                 signature="default",
                 as_dict=True)["elmo"]

    vectors = execute(executable)
    texts = []
    i += 1

Однако даже в этом небольшом примере после примерно 300 предложений (и даже без сохранения векторов) программа потребляет до 12 ГБ ОЗУ. Это проблема со знанием дела (другие проблемы, которые я обнаружил, предполагают нечто подобное, но не настолько серьезное), или я допустил ошибку?


person Daniel Töws    schedule 07.06.2019    source источник
comment
Вы передаете переменную sentences, но мы не видим, где она определена.   -  person Stewart_R    schedule 07.06.2019
comment
Извините, это моя ошибка. это должны были быть тексты, а не предложения (в моем коде часть elmo является частью собственного метода, где параметр называется senteces). Я отредактировал это   -  person Daniel Töws    schedule 07.06.2019


Ответы (1)


Я полагаю, это для TensorFlow 1.x без режима Eager (иначе использование hub.Module, вероятно, приведет к более серьезным проблемам).

В этой модели программирования вам нужно сначала выразить свои вычисления в виде графа TensorFlow, а затем повторно выполнять этот граф для каждого пакета данных.

  • Создание модуля с hub.Module() и его применение для сопоставления входного тензора с выходным тензором - это обе части построения графа и должны происходить только один раз.

  • Цикл по входным данным должен просто вызывать session.run () для подачи входных и выборочных данных из фиксированного графа.

К счастью, уже есть служебная функция, которая сделает все это за вас:

import numpy as np
import tensorflow_hub as hub

# For demo use only. Extend to your actual I/O needs as you see fit.
inputs = (x for x in ["hello world", "quick brown fox"])

with hub.eval_function_for_module("https://tfhub.dev/google/elmo/2") as f:
  for pystr in inputs:
    batch_in = np.array([pystr])
    batch_out = f(batch_in)
    print(pystr, "--->", batch_out[0])

То, что это дает вам с точки зрения необработанного TensorFlow, примерно следующее:

module = Module(ELMO_OR_WHATEVER)
tensor_in = tf.placeholder(tf.string, shape=[None])  # As befits `module`.
tensor_out = module(tensor_in)

# This kind of session handles init ops for you.
with tf.train.SingularMonitoredSession() as sess:
  for pystr in inputs:
    batch_in = np.array([pystr])
    batch_out = sess.run(tensor_out, feed_dict={tensor_in: batch_in}
    print(pystr, "--->", batch_out[0])

Если ваши потребности слишком сложны для with hub.eval_function_for_module ..., вы можете построить этот более явный пример.

Обратите внимание, что hub.Module не создается и не вызывается в цикле.

PS: Устали беспокоиться о построении графиков и текущих сессиях? Тогда TF2 и нетерпеливое исполнение для вас. Ознакомьтесь с https://colab.research.google.com/github/tensorflow/hub/blob/master/examples/colab/tf2_text_classification.ipynb

person arnoegw    schedule 07.06.2019
comment
Это сработало, я все еще получаю увеличение (с 1,5 ГБ до 2 ГБ), что я не могу объяснить, но это кажется гораздо более управляемым. Но как это работает? Я думал, что у python есть своя собственная форма сборки мусора, когда, если на объект больше не ссылаются, он будет удален. Разве это не должно было случиться? - person Daniel Töws; 07.06.2019
comment
Мой первый ответ был неполным. Теперь должно быть намного лучше. - person arnoegw; 07.06.2019
comment
Пример кода с eval_function_for_module у меня не работал: я получил InternalError: Dst tensor is not initialized. [[{{node checkpoint_initializer_14}}]] - person Yu Shen; 23.09.2019