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