Фон
Я работаю над довольно интенсивным вычислительным проектом для проекта вычислительной лингвистики, но проблема, которую я имею, довольно общая, и поэтому я ожидаю, что решение будет интересно и другим.
Требования
Ключевым аспектом этой конкретной программы я должен написать, что она должна:
- Прочитайте большой корпус (между 5G и 30G и потенциально более крупным материалом по линии).
- Обработать данные в каждой строке.
- Из этих обработанных данных постройте большое количество векторов (размерность некоторых из этих векторов составляет > 4 000 000). Обычно он создает сотни тысяч таких векторов.
- Эти векторы должны быть сохранены на диск в каком-либо формате.
Шаги 1 и 2 не очень эффективны: просто используйте генераторы и конвейер анализа данных. Большой проблемой является работа 3 (и по соединению 4)
Скобки: Технические детали
В случае, если фактическая процедура создания векторов влияет на решение:
Для каждой строки в корпусе один или несколько векторов должны обновлять базовые веса.
Если вы думаете о них в терминах списков python, каждая строка при обработке обновляет один или несколько списков (при необходимости создавая их), увеличивая значения этих списков по одному или нескольким индексам на значение (которое может отличаться основанный на индексе).
Векторы не зависят друг от друга, и не имеет значения, в каком порядке считываются строки корпуса.
Попытки решения
Есть три экстремума, когда дело доходит до того, как это сделать:
- Я мог бы построить все векторы в памяти. Затем напишите их на диск.
- Я мог бы построить все векторы непосредственно на диске, используя полку рассола или некоторую такую библиотеку.
- Я мог бы создавать векторы в памяти по одному и записывать их на диск, проходя через корпус один раз на вектор.
Все эти варианты довольно трудноразрешимы. 1 просто использует всю системную память, и она паникует и замедляется до обхода. 2 слишком медленный, поскольку операции ввода-вывода выполняются не быстро. 3, возможно, даже медленнее, чем 2 по тем же причинам.
Цели
Хорошее решение будет включать:
- Построить как можно больше в памяти.
- Как только память будет заполнена, сбросьте все на диск.
- Если бит снова нужен с диска, верните их обратно в память, чтобы добавить материал к этим векторам.
- Вернитесь к 1, пока не будут созданы все векторы.
Проблема в том, что я не совсем уверен, как это сделать. Кажется немного нерегулярным беспокоиться об атрибутах системы, таких как ОЗУ, но я не вижу, как можно решить эту проблему без ее учета. В результате я не знаю, как начать работу с такими вещами.
Вопрос
Кто-нибудь знает, как решить эту проблему? Я питон просто не правильный язык для такого рода вещей? Или существует простое решение для максимизации того, сколько сделано из памяти (в пределах разумного), минимизируя, сколько раз данные должны считываться с диска или записываться на него?
Большое спасибо за внимание. Я с нетерпением жду встречи с тем, что яркие умы stackoverflow могут бросить мой путь.
Дополнительные сведения
Тип машины, на которой запущена эта проблема, обычно имеет 20+ ядер и ~ 70 ГБ ОЗУ. Проблема может быть распараллелирована (à la MapReduce) в том, что отдельные векторы для одного объекта могут быть построены из сегментов корпуса и затем добавлены для получения вектора, который был бы построен из всего корпуса.
Часть вопроса включает определение предела того, сколько можно построить в памяти до того, как возникнет необходимость записи на диск. Предоставляет ли python какой-либо механизм определения объема оперативной памяти?