Сейчас уже многие используют библиотеку numpy в своих python-программах, поскольку она заметно ускоряет работу с данными и выполнение математических операций. Однако во многих случаях numpy работает в разы медленнее, чем она может… потому что использует только один процессор, хотя могла бы использовать все, что у вас есть.
Дело в том, что для выполнения многих операций numpy вызывает функции из библиотеки линейной алгебры. Вот в ней-то обычно и кроется проблема. К счастью, все довольно легко исправимо.
Итак, возможно три ситуации:
- у вас не установлены никакие библиотеки линейной алгебры и тогда numpy использует встроенную библиотеку, и она, надо сказать, весьма медленная;
- у вас уже установлены классические библиотеки типа ATLAS и BLAS, и они умеют использовать только один процессор;
- у вас установлена современная библиотека OpenBLAS, MKL и им подобные.
Проведем простой тест. Запустите вот эту программу:
import numpy as np
size = 10000
a = np.random.random_sample((size, size))
b = np.random.random_sample((size, size))
n = np.dot(a,b)
После чего, если работаете в Linux, то запустите top, а если вы работаете в Windows, зайдите на вкладку в “Быстродействие” в диспетчере задач (вызывается по Ctrl+Shift+Esc)… Если top показывает загруженность на уровне 100%, а индикатор “Загрузка ЦП” на вкладке “Быстродействие”, наоборот, показывает значение многократно ниже 100%, значит вычислениями занято лишь одно ядро — и эта статья для вас. Те, у кого задействованы все процессоры, могут радоваться — у них все в порядке — и дальше можно не читать.
Решение для Windows
Теоретически, можно, конечно, найти исходники библиотек, перекомпилировать их и пересобрать numpy. Я даже слышал, что кто-то писал, что он видел людей, которые говорили, что им это удалось… В общем, самый простой способ — это установить научный дистрибутив Python, например, Anaconda или Canopy. В дистрибутив входит не только python и numpy, но и целая куча полезных библиотек для расчетов и визуализации.
После чего можете перезапустить начальный тест, чтобы убедиться, что скорость возросла в разы.
Решение для Linux
На самом деле вы также можете установить готовый дистрибутив Anaconda, Canopy или что-то другое сразу со всеми библиотеками. Но если предпочитаете собирать своими руками, то читайте дальше — там есть все рецепты.
Проверка библиотек
Как вы помните, возможны два варианта:
- у вас установлены “олдскульные” (или “устаревшие”, кому как нравится) библиотеки (например, ATLAS);
- у вас не установлены библиотеки, и numpy использует встроенную библиотеку (которая еще медленнее)
Если у вас стоит свежая версия numpy (>1.10), то, зайдя в каталог, куда установлен numpy (обычно это /usr/local/lib/python2.7/dist-packages/numpy, но в зависимости от версии Linux и Python путь может меняться) и выполните следующие команды в консоли:
cd core
ldd multiarray.so
В более ранних версиях numpy библиотеки multiarray.so нет, зато есть _dotblas.so:
ldd _dotblas.so
Вывод команды ldd покажет вам, использует ли numpy сторонние библиотеки линейной алгебры.
linux-vdso.so.1 => (0x00007fffe58a2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8adbff4000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8adbdd6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8adba10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8adc68c000)
Если в листинге вы не видите libblas.so, значит ваша numpy использует свою внутреннюю библиотеку. Если видите, значит у вас стоит ATLAS или BLAS.
В любом случае сначала вам нужна правильна библиотека линейной алгебры.
Установка OpenBLAS
OpenBLAS — хорошая библиотека алгоритмов и функций линейной алгебры, которые лежат в основе современных методов анализа данных и машинного обучения.
Прежде всего вам потребуется компилятор Фортрана, поскольку OpenBLAS не совместим со стандартным компилятором g77.
sudo apt-get install gfortran
Загрузите OpenBLAS с github’а (предварительно вернувшись в подходящий для установки каталог):
git clone https://github.com/xianyi/OpenBLAS.git
Теперь зайдите в каталог и запустите сборку:
cd OpenBLAS
make FC=gfortran
Когда компиляция и сборка успешно завершатся, установите библиотеку.
sudo make install
По умолчанию, библиотека будет установлена в /opt/OpenBLAS. Если вы хотите установить ее в другое место, запустите make install с ключом PREFIX:
sudo make install PREFIX=/your/preferred/location
Переназначение библиотек
Если ранее вы выяснили, что у вас уже установлена какая-то библиотека линейной алгебры, то вам достаточно запустить команду переназначения библиотек:
sudo update-alternatives --install /usr/lib/libblas.so.3 libblas.so.3
/opt/OpenBLAS/lib/libopenblas.so 50
После этого OpenBLAS по умолчанию станет библиотекой линейной алегбры не только для numpy, а вообще для всех ваших программ и библиотек.
И снова запустите тест, чтобы увидеть, как у вас при вычислениях теперь задействованы все процессоры.
Собираем правильный numpy
Если у вас numpy работал на встроенной библиотеке, то вам придется его пересобрать, чтобы он подхватил только что установленный OpenBLAS.
Сначала избавьтесь от дефектной библиотеки:
sudo pip uninstall numpy
После чего создайте в домашнем каталоге файл .numpy-site.cfg следующего содержания:
[default]
include_dirs = /opt/OpenBLAS/include
library_dirs = /opt/OpenBLAS/lib
[openblas]
openblas_libs = openblas
include_dirs = /opt/OpenBLAS/include
library_dirs = /opt/OpenBLAS/lib
[lapack]
lapack_libs = openblas
[atlas]
atlas_libs = openblas
libraries = openblas
Если вы ранее выбрали нестандартное расположение для OpenBLAS, то измените пути в файле. А теперь установите numpy заново:
sudo pip install numpy
Когда компиляция и установка завершатся, запустите начальный тест, чтобы убедиться, что теперь процессоры не простаивают. Вот и все.
Автор: Roman_Kh