Как ускорить умножение матриц в Python?
Я разрабатываю небольшую нейронную сеть, параметры которой требуют большой оптимизации, а значит, и большого времени обработки. Я профилировал свой сценарий с помощью cProfile, и то, что занимает 80% времени процессора, - это функция NumPy dot, остальное-инверсия матрицы с помощью функции numpy.linalg.solve.
Моя текущая версия numpy использует blas, или это то, что кажется, так как numpy.core._dotblas.dot появляется как функция, которая занимает 80% от общего времени обработки.
Поскольку это ядро моей нейронной сети и поскольку я должен запускайте это много, любое незначительное увеличение скорости может сэкономить мне много времени на многочисленных повторных оптимизациях параметров.
Еще уточнение: умножение матрицы производится на матрицы, имеющие форму от минимум 100*100 до 500*500. У меня есть компьютер с 12 ядрами, и я использую их до сих пор для параллельной оптимизации различных параметров нейронной сети, но, может быть, умножение матрицы можно было бы сделать параллельно?
Спасибо, что уделили мне время!
Ответ:
Я потратил несколько дней тестирования и установки деинсталляционных библиотек... Вот результат того, что я проверил:
По умолчанию в моей версии Ubuntu (12.04) и соответствующей установленной версии Numpy библиотеки BLAS являются библиотеками ATLAS. Я сделал несколько тестов, которые отражают улучшение именно на тех вычислениях, которые меня интересуют, поэтому эти результаты не должны интерпретироваться как окончательный ответ. Эти вычисления включают в себя умножение матрицы (точечное произведение) в цикле 55000 итераций, с 500*500 и Матрица 1000*1000. Я использую рабочую станцию HP Z800 с Xeon X5675 @ 3,07 ГГц с 12 ядрами. Все результаты (в процентах) являются сравнением между описанным условием и ссылкой, которая здесь является упакованной библиотекой атласа.
Scipy.sparse module: я не знаю, правильно ли я установил его, но с 10% разреженностью, использование этого модуля становится полезным, начиная с матриц 1500*1500 С OpenBLAS и MKL. Если у вас есть предложения о том, как их правильно использовать, я заинтересован!- С OpenBlas I получает увеличение скорости на 33% для матриц 500*500 и 160% для матриц 1000*1000. Но с Опенбласом, Сципионом.разреженный модуль работает не лучше, а хуже на самом деле.
- главным победителем здесь являются библиотеки MKL. Ускорение достигает 230% при использовании матриц 1000*1000 из оригинальных библиотек ATLAS! Для матриц 500*500 ускорение более скромное (100%), но все равно очень хорошее. Кроме того, при компиляции с OpenMP умножение матриц может выполняться на моих 12 процессорах и здесь он вдвое быстрее, чем на одном процессоре с библиотеками MKL. Но это пустая трата вычислительной мощности, гораздо эффективнее использовать многопроцессорные модули для параллельного выполнения сценариев / матриц-умножения.
2 ответов:
Если вы еще не сделали этого, вы можете попробовать связать numpy с очень оптимизированной библиотекой BLAS, такой как Intel MKL (которая является бесплатной как пиво для некоммерческого использования или со скидкой для академического использования, которая, по-видимому, не считается некоммерческой; Инструкции Intel для использования ее с numpy) или OpenBLAS (free-как-в-речи). Есть такжеEnthought Python Distribution , который предварительно связан с MKL и free-as-in-beer для академиков. Тот может автоматически распараллеливать ваши умножения матриц и может быть намного быстрее, чем типичная эталонная установка BLAS / ATLAS на большинстве дистрибутивов Linux, или что бы вы ни использовали.
В противном случае, единственное, что я знаю, что вы могли бы сделать, - это некоторые математические трюки, чтобы не вычислять столько умножений / решений. Не зная точно, что вы делаете, трудно дать какие-либо предложения там.Я предполагаю, что ваши матрицы плотны, так как они обычно они находятся в нейронных сетях, но если вы делаете что-то необычное,
scipy.sparseтоже может помочь.
Numpy использует очень быстрые внутренние алгоритмы и представления, основанные на сторонних библиотеках (таких как BLAS, как вы его назвали), уже использующих оптимизацию SSE среди других. Поскольку исходный BLAS немного медленный (потому что он стремится быть эталонной реализацией, фокусируясь на точности, а не на производительности), вы можете использовать другой аромат, ориентированный на производительность, такой как OpenBLAS. Чтобы использовать OpenBLAS, вам нужно либо найти готовый пакет Numpy с поддержкой OpenBLAS, либо перекомпилировать его. версия, связанная с OpenBLAS. После того, как вы используете эффективную реализацию BLAS, вы не найдете лучшего варианта ускорения в чистом python, если только вы не напишете библиотеку на C и не потратите много времени на ее оптимизацию.
С другой стороны, вы можете проверить, насколько эффективно ваша библиотека Numpy и BLAS компилируется на вашей архитектуре. Например, если вы можете активировать библиотеку OpenMP на компиляции Numpy, это позволит нескольким ядрам работать над вашей проблемой, используя уровень данных параллелизм. Это может быть существенным источником ускорения, если у вас есть несколько ядер на вашем компьютере и ваши вычисления связаны с процессором. Если ваш тип задач позволяет это, вы можете даже использовать библиотеку параллельного программирования на основе задач (SCOOP [Disclamer: I written it], Celery и т. д.) для распространения Вашей работы на нескольких компьютерах.
В качестве последнего средства можно было бы купить новое оборудование. Это делает программное обеспечение потенциально быстрее, не изменяя ни одной строки из кодекса.
Comments