Ускорьте Gensim's Word2ve c для массивного набора данных - PullRequest
0 голосов
/ 26 января 2020

Я пытаюсь построить модель Word2ve c (или FastText) с использованием Gensim для массивного набора данных, состоящего из 1000 файлов, каждый из которых содержит ~ 210 000 предложений, и каждое предложение содержит ~ 1000 слов. Обучение проводилось на 185 ГБ ОЗУ, 36-ядерном компьютере. Я подтвердил, что

gensim.models.word2vec.FAST_VERSION == 1

Сначала я попробовал следующее:

files = gensim.models.word2vec.PathLineSentences('path/to/files')
model = gensim.models.word2vec.Word2Vec(files, workers=-1)

Но через 13 часов я решил, что он работает слишком долго, и остановил его.

Затем я попытался построить словарь на основе одного файла и обучиться на основе всех 1000 файлов следующим образом:

files = os.listdir['path/to/files']
model = gensim.models.word2vec.Word2Vec(min_count=1, workers=-1)
model.build_vocab(corpus_file=files[0])
for file in files:
    model.train(corpus_file=file, total_words=model.corpus_total_words, epochs=1)

Но я проверил выборку векторов слов до и после обучения, и было без изменений, что означает, что никакое фактическое обучение не было проведено.

Я могу воспользоваться некоторыми советами о том, как быстро и успешно выполнить его. Спасибо!

Обновление № 1:

Вот код для проверки обновлений вектора:

file = 'path/to/single/gziped/file'
total_words = 197264406 # number of words in 'file'
total_examples = 209718 # number of records in 'file'
model = gensim.models.word2vec.Word2Vec(iter=5, workers=12)
model.build_vocab(corpus_file=file)
wv_before = model.wv['9995']
model.train(corpus_file=file, total_words=total_words, total_examples=total_examples, epochs=5)
wv_after = model.wv['9995']

, поэтому векторы: wv_before и wv_after точно такие же

1 Ответ

0 голосов
/ 27 января 2020

Нет возможности в gensim Word2Vec принять отрицательное значение для workers. (Откуда у вас идея, которая будет иметь смысл?)

Итак, вполне возможно, что что-то нарушает, возможно, предотвращает попытки обучения.

Были ли заметные результаты регистрации (на уровне INFO), свидетельствующие о том, что тренировки проходили в ваших пробных заездах против PathLineSentences или вашей второй попытки? Утилиты типа top показывали занятые темы? Предлагали ли выходные данные определенный темп прогресса и позволяли ли вы спроецировать вероятное время окончания?

Я бы предложил использовать положительное значение workers и наблюдать за журналированием на уровне INFO, чтобы получить лучшее представление что происходит.

К сожалению, даже с 36 ядрами при использовании итерируемой последовательности корпуса (например, PathLineSentences) в модели используется gensim Word2Vec, где вы, скорее всего, получите максимальную пропускную способность со значением workers в 8- 16 диапазон, используя гораздо меньше, чем все ваши темы. Но он будет работать правильно, на корпусе любого размера, даже если он собирается на лету повторяемой последовательностью.

Использование режима corpus_file может насытить гораздо больше ядер, но вы все равно должны указать фактическое количество рабочих потоков для использования - в вашем случае workers=36 - и оно рассчитано на работу с одного файл со всеми данными.

Ваш код, который пытается train() много раз с corpus_file, имеет много проблем, и я не могу придумать, как адаптировать режим corpus_file для работы с множеством файлов. Вот некоторые из проблем:

  • Вы строите словарь только из 1-го файла, что означает, что любые слова, встречающиеся только в других файлах, будут неизвестны и игнорируются, а любое слово Частотно-управляемые части алгоритма Word2Vec могут работать на непредставительной

  • модель строит свою оценку ожидаемого размера корпуса (например: model.corpus_total_words) из build_vocab() шаг, так что каждый train() будет вести себя так, как если бы этот размер был общим размером корпуса, в своих отчетах о прогрессе и управлении внутренним падением скорости обучения alpha. Таким образом, эти журналы будут неправильными, alpha будет неправильно управляться в распаде fre sh каждый train(), что приведет к бессмысленной мозаике вверх-вниз alpha по всем файлам.

  • вы перебираете содержимое каждого файла только один раз, что не типично. (Это может быть разумно в гигантском корпусе из 210 миллиардов слов, однако, если текст каждого файла одинаково и случайным образом представляет домен. В этом случае полный корпус может быть так же хорош, как итерация по корпусу, который составляет 1/5 размер в 5 раз. Но было бы проблемой, если бы некоторые слова / шаблоны использования были объединены в определенные файлы - лучшее обучение чередует контрастные примеры в каждой эпохе и во всех эпохах.)

  • min_count=1 почти всегда неразумно с этим алгоритмом, особенно в больших корпусах типичных частот слов на естественном языке. Редкие слова, особенно те, которые появляются только один или несколько раз, делают модель гиганти c, но эти слова не получат хороших векторов слов, и удержание их в действиях подобно шуму мешает улучшению других более распространенных слов ,

Я рекомендую:

Попробуйте режим итеративной последовательности корпусов с регистрацией и разумным значением workers, чтобы хотя бы получить точное представление о том, как долго это может продолжаться. брать. (Самым длинным шагом будет начальное сканирование словаря, которое по существу является однопоточным и должно посещать все данные. Но вы можете .save() модель после этого шага, чтобы затем позже повторно .load() это, переделать с настройками, и попробуйте разные train() подходы, не повторяя медленный словарный запас.)

Попробуйте агрессивно более высокие значения min_count (отбрасывание более редких слов для маленькой модели и более быстрое обучение). Возможно, попробуйте также агрессивно-меньшие значения sample (например, 1e-05, 1e-06 и т. Д. c), чтобы отбросить большую часть наиболее часто употребляемых слов, для ускорения обучения, что также часто улучшает общее качество словосочетания. (потратив относительно больше усилий на менее частые слова).

Если он все еще слишком медленный, подумайте, возможно, вам будет достаточно использовать меньший подобразец вашего корпуса.

Рассмотрите метод corpus_file, если вы можете свернуть большую часть или все свои данные в один требуемый файл.

...