Эффективный макет HDF5 / PyTables для сохранения и работы с большими тензорами - PullRequest
4 голосов
/ 18 октября 2019

Я пытаюсь определить наилучшее расположение данных для моего варианта использования (исследовательский проект). Это не моя специальность, поэтому, пока я могу сформулировать то, что хочу, и то, что, как мне кажется, может сработать, я стараюсь держаться подальше от путей отказа.

Пока предположим, что исходные данные похожи на несколько большихКорпуса текста, которые разбиты на последовательности (например, предложения), каждый из которых включает в себя несколько токенов (например, слов). Я извлекаю, обрабатываю и сохраняю информацию на основе токена предложения, но требую различных операций над ней в последующих анализах. В частности, каждый токен в каждом предложении связан с большим вектором (который может быть числовым), который подготовлен рядом операций, которые уже реализованы. Каждая последовательность связана с некоторыми метаданными. Эта операция и, следовательно, подготовка этих данных происходят только один раз.

Итак: выходной исходной операции является трехмерный тензор D [x, y, z] плюс метаданные, связанные с измерением x. Измерение x обозначает последовательность, y - положение токена в последовательности (но не уникальный идентификатор токена, например, кодирование слова, которое является частью метаданных последовательности), а z - столбцы (многие тысячи) информации. за этот знак. Таким образом, каждая последовательность связана с матрицей токенов в виде строк и информации в виде столбцов. Метаданные, вероятно, могут быть помещены в первый ряд, если это необходимо. Обратите внимание, что каждая последовательность имеет одинаковую длину.

Sequence 1
Meta-data: [..]
         Column 1 | Column 2 | ...
Token 1 |  [...]  |   [...]  | ...    
Token 2 |  [...]  |   [...]  | ...   
...
Token N |  [...]  |   [...]  | ... 

Sequence 2
Meta-data: [..]
         Column 1 | Column 2 | ...
Token 1 |  [...]  |   [...]  | ...    
Token 2 |  [...]  |   [...]  | ...   
...
Token N |  [...]  |   [...]  | ...

Эти данные вводятся несколько раз при различных последующих анализах. Поэтому мне требуются разные «представления» этих данных, а именно:

  1. Мне нужно иметь возможность запрашивать каждую последовательность и получать полную матрицу значений токена->. Это просто выходной трехмерный тензор, где я выполняю запрос по первому измерению. Было бы неплохо иметь возможность «нарезать» несколько последовательностей одновременно (например, случайные пакеты для моделей ML и т. Д.)

  2. Мне нужно иметь возможность запрашивать уникальный идентификатор токена(например, слово «привет»), отмечая, что каждый токен может встречаться в нескольких последовательностях и в разных позициях. Это не запрос в измерение тензора, а запрос данных, которые сопоставляют уникальные идентификаторы токенов с их позициями в последовательностях (или метаданными в каждой последовательности, разрешающей такой запрос).

  3. Наконец, я генерирую и сохраняю дополнительные итоговые значения для каждого токена для каждой последовательности, которые я стремлюсь запрашивать чрезвычайно быстро, когда другая информация из этой последовательности не имеет отношения.

Что все последующее моделированиеимеет общее значение:

  • Мне нужно как можно больше оперативной памяти для последующего анализа, или, другими словами, данные могут или не могут быть выгружены на диск. Вот почему я ищу решение, которое обеспечивает доступ как к памяти, так и к памяти. В частности, весь тензор может вообще не помещаться в память (он впоследствии создается по измерению x)

  • Учитывая фиксированную структуру, индексация и нарезка относительно просты, но ячасто может потребоваться выбрать несмежные записи, такие как токены из несвязанных последовательностей.

  • Все это не должно быть узким местом в последующем анализе. Также было бы полезно, если бы оно было несколько портативным и не требовало дополнительного программного обеспечения, чтобы результаты могли легко распространяться и воспроизводиться другими исследователями. На самом деле, я хотел бы сделать эти данные доступными для загрузки, если это окажется возможным (юридически)

  • Поскольку это входные данные, меня в первую очередь интересует скорость доступа к этимданные из python или других языков.

Исходя из этого, я предварительно остановился на использовании либо h5py, либо pyTables, но я открыт для других вариантов.

Несмотря на то, что данные велики, они не настолько велики, чтобы проблема была связана с дисковым пространством (на сервере среднего размера). Далее я перебираю каждую последовательность хотя бы один раз, чтобы выполнить начальные операции. Поэтому я планирую сохранить каждое необходимое «представление» в отдельных наборах данных, каждый из которых предназначен для обеспечения эффективного доступа.

Мой план следующий:

  1. Я сохраняю выходной тензор в виде многомерного массива в pyTables. Индексное измерение будет порядковым номером. Я могу запросить несколько последовательностей, но всегда глотать двумерную таблицу всей последовательности. Я надеюсь, что pyTables позволит мне сохранить весь трехмерный тензор на диске и считывать только необходимые данные в ОЗУ.

  2. Я сохраню новый набор данных с уникальным идентификатором токенав качестве индекса, идентификатор последовательности в качестве второго столбца, а затем необходимую информацию в виде массива. Таким образом, я могу выполнить запрос по идентификатору токена и получить все данные, связанные во всех последовательностях. Это включает в себя много дублирования, но должно позволить быстрые запросы (?)

  3. Наконец, я сделаю меньший набор данных со связанными сводными данными для каждого идентификатора токена (в качестве индекса) длякаждая последовательность.

Считаете ли вы, что это будет эффективно с точки зрения времени вычислений?

Другим маршрутом, который я вижу, будет реляционная база данных, такая как SQL. Здесь я мог бы просто сделать записи для каждого фактического слова в последовательности с соответствующим идентификатором токена, порядковым номером и данными, которые мне нужны. Затем можно использовать запрос SQL для получения данных любым способом, который я выберу. Кроме того, любые метаданные могут быть сохранены в других таблицах либо по порядку, либо по токену без особых ограничений.

Однако я не уверен, является ли это самым быстрым вариантом, поскольку мне не требуется много вещей, предоставляемых SQL, таких какдополнительная гибкость (мои запросы / представления фиксированы, а индексирование / секционирование всегда выполняются по фиксированному измерению) или все средства защиты доступа и все такое. Кроме того, переносимость лучше, если это просто некоторые файлы набора данных.

Я также не уверен, как SQL решает проблемы с памятью и из памяти. Могут быть случаи, когда большие объемы моих данных фактически помещаются в ОЗУ, поэтому я также хочу иметь гибкость.

Вопросы:

  • Как вы относитесь к лучшему подходу? Мой план звучит?

  • SQL кажется более гибким, возможно, даже быстрее?

  • Что я еще не понимаю в HDF5, так этокак куски и группы играют в это. Кажется, я не могу на самом деле разделить свои данные на части, потому что мне нужно иметь возможность запрашивать непоследовательные данные с высокой частотой. Правильно ли, что для моего варианта использования я не должен разбивать на части?

  • Аналогично группам и ссылкам. Моя структура данных не похожа на дерево, потому что каждый токен может встречаться во многих последовательностях, поэтому я решил просто создавать разные наборы данных. Будет ли эффективнее использовать жесткие ссылки или группы?

  • Как будет работать модель памяти HDF5 (реализованная в python)? Правда ли, что я могу запросить, скажем, 3D-тензор, и только сохранить результаты в памяти, но также иметь кэш для последовательностей или токенов, которые часто запрашиваются?

Если мойописание не ясно, пожалуйста, дайте мне знать. Спасибо, что нашли время, чтобы прочитать все это.

...