- В последнее время в проекте используется алгоритм Kmeans.Учитывая ограничение скорости реализации ЦП, необходимо использовать ускорение графического процессора, поэтому установлено, что
libKMCUDA
библиотека.- Запишите некоторые проблемы, возникающие при установке и использовании.
1. Введение в kmcuda
адрес проекта:kmcuda
Содержание проекта: Крупномасштабная реализация K-means и K-nn на NVIDIA GPU / CUDA
Подробное знакомство с проектом см.github
описание выше.
Производительность выглядит следующим образом:
Технически проект представляет собой разделяемую библиотеку, которая экспортируетkmcuda.h
Две функции, определенные в :kmeasn_cuda
иknn_cuda
. Он имеет встроенную поддержку расширений языка Python3 и R, поэтому его можно загрузить сlibKMCUDA
Импортироватьkmeans_cuda
илиdyn.load("libKMCUDA.so")
.
2. Установка
Github
Команда установки, приведенная выше:
git clone https://github.com/src-d/kmcuda
cd src
cmake -DCMAKE_BUILD_TYPE=Release . && make
Есть несколько параметров, на которые стоит обратить внимание:
-
-D DISABLE_PYTHON
: если вы не хотите компилироватьPython
Модуль поддержки, установите это значение какy
, то есть увеличить-D DISABLE_PYTHON=y
-
-D DISABLE_R
: если вы не хотите компилироватьR
Модули поддержки, добавить-D DISABLE_R=y
-
-D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.0(修改为自己的路径)
:еслиCUDA
Если он не может быть найден автоматически, добавьте этот элемент -
-D CUDA_ARCH=52
: укажите вычислительные возможности CUDA текущей машины (вычислительные возможности графического процессора). -
gcc
: В статье упоминалось, что младшая версия компилятора gcc не поддерживает его.Моя текущая версия 5.4, которая может удовлетворить потребности.
1. Запросить версию gcc
Если версия слишком низкая, вы можете установить gcc-5.4. Для конкретной установки обратитесь к следующему сообщению в блоге:
Подробная установка gcc под linux
2. Запросить вычислительную мощность графического процессора
Проверьте вычислительную мощность графического процессора вашего графического сервера на официальном веб-сайте NVIDIA по следующему адресу:
Сервер, который я сейчас использую,GeForce RTX 2070
, соответствующая вычислительная мощность равна7.5
.
следовательно,CUDA_ARCH
установить на 75,-D CUDA_ARCH=75
3. Настройте путь графического процессора
Чтобы иметь возможность автоматически находить путь к нужной библиотеке, установитеcuda
Путь настраивается в файле конфигурации. Оболочка, используемая текущей системой,zsh
:
существует~/.zshrc
Добавьте следующие элементы в:
export PATH=$PATH:/usr/local/cuda/bin
export LD_LIBRARAY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
export CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda:$CUDA_TOOLKIT_BOOT_DIR
export CUDA_INCLUDE_DIRS=/usr/local/cuda/include
Активация вступает в силу:
source ~/.zshrc
3. Выполните команду установки
Текущие параметры оборудования:
- gcc: версия 5.4
- Вычислительная мощность графического процессора: 7,5
- Требуется только поддержка версии Python
Полная команда установки:
git clone https://github.com/src-d/kmcuda
cd src
cmake -DCMAKE_BUILD_TYPE=Release -D DISABLE_R-y -D CUDA_ARCH=75 . && make
контрольная работа:
4. Проблемы, возникающие при установке
1. Установить с помощью pip
Команда установки выглядит следующим образом:
CUDA_ARCH=75 pip install libKMCUDA
Произошла ошибка:
2. Не указывайте вычислительную мощность графического процессора или используйте значение по умолчанию.
-
Установить исходные файлы с помощью pip
Команда установки:
pip install git+https://github.com/src-d/kmcuda.git#subdirectory=src
Возникает следующая ошибка:
Эту ошибку можно увидеть, используя этот метод для установки, по умолчанию используется
-DCUDA_ARCH
61 год, что не соответствует действительности. -
Вычислительная мощность графического процессора не указана
Команда установки:
cmake -DCMAKE_BUILD_TYPE=Release -D DISABLE_R=y . && make
Как показано на рисунке ниже, установка прошла успешно
При тестировании возникает следующая ошибка:
Указывает, что вычислительная мощность не соответствует устройству.
5. Тестовые примеры Python
1. K-means, L2 (Euclidean) distance
import numpy
from matplotlib import pyplot
from libKMCUDA import kmeans_cuda
numpy.random.seed(0)
arr = numpy.empty((10000, 2), dtype=numpy.float32)
arr[:2500] = numpy.random.rand(2500, 2) + [0, 2]
arr[2500:5000] = numpy.random.rand(2500, 2) - [0, 2]
arr[5000:7500] = numpy.random.rand(2500, 2) + [2, 0]
arr[7500:] = numpy.random.rand(2500, 2) - [2, 0]
centroids, assignments = kmeans_cuda(arr, 4, verbosity=1, seed=3)
print(centroids)
pyplot.scatter(arr[:, 0], arr[:, 1], c=assignments)
pyplot.scatter(centroids[:, 0], centroids[:, 1], c="white", s=150)
pyplot.show()
2. K-means, angular (cosine) distance + average
import numpy
from matplotlib import pyplot
from libKMCUDA import kmeans_cuda
numpy.random.seed(0)
arr = numpy.empty((10000, 2), dtype=numpy.float32)
angs = numpy.random.rand(10000) * 2 * numpy.pi
for i in range(10000):
arr[i] = numpy.sin(angs[i]), numpy.cos(angs[i])
centroids, assignments, avg_distance = kmeans_cuda(
arr, 4, metric="cos", verbosity=1, seed=3, average_distance=True)
print("Average distance between centroids and members:", avg_distance)
print(centroids)
pyplot.scatter(arr[:, 0], arr[:, 1], c=assignments)
pyplot.scatter(centroids[:, 0], centroids[:, 1], c="white", s=150)
pyplot.show()
Результат выглядит следующим образом:
6. API-интерфейс Python
1. kmeans_cuda()
def kmeans_cuda(samples, clusters, tolerance=0.01, init="k-means++",
yinyang_t=0.1, metric="L2", average_distance=False,
seed=time(), device=0, verbosity=0)
параметр:
-
samples
: массив numpy с формой [количество выборок, количество функций] или кортеж (необработанный указатель устройства (int), индекс устройства (int)- Примечание: «образцы» должны быть двумерными массивами float32 или float16 numpy.
-
clusters
:int
тип, количество кластеров- Примечание: «кластеры» должны быть больше 1 и меньше (1
-
tolerance
:float
алгоритм останавливается, если относительная сумма перераспределения падает ниже этого значения. -
init
:string
или массив numpy, установите метод инициализации центроида, который может бытьk-means++
,afk-mc2
,random
Или массив numpy указанной формы [кластер, количество признаков], тип должен бытьfloat32
-
yinynag_t
:float
тип, обычно устанавливается равным 0,1 -
metric
:str
Тип, имя используемой метрики расстояния. По умолчаниюDuclidean(L2)
, который можно изменить наcos
. Обратите внимание, что в последнем случае образцы должны быть нормализованы. -
average_distance
:boolean
Type, это значение указывает, следует ли вычислять среднее расстояние между элементами в классе и соответствующими центроидами, полезное для нахождения оптимального K, возвращенного как третий элемент кортежа. -
seed
:int
Type, начальное число генератора случайных чисел, используемое для воспроизведения результатов. -
device
:int
Тип, индекс устройства CUDA, например 1 для первого устройства, 2 для второго и 3 для использования первого и второго. Укажите 0, чтобы включить все устройства, по умолчанию 0. -
verbosity
:int
Тип, 0 означает отсутствие вывода, 1 означает только ведение журнала, 2 означает много вывода.
возвращаемое значение: кортеж(centroids, assignments, [average_distance])
.
еслиsamples
представляет собой кортеж указателя хоста с четным массивом numpy, тип представляет собой массив numpy, в противном случае необработанный указатель (целое число) размещается на том же устройстве.
еслиsamples
даfloat16
, то возвращаемый центроид такжеfloat16
.
2. knn_cuda()
def knn_cuda(k, samples, centroids, assignments, metric="L2", device=0, verbosity=0)
параметр:
-
k: целое число, количество соседей для поиска каждой выборки. Должно быть ≤ 116.
-
samples: пустой массив формы [количество выборок, количество функций] или кортеж (необработанный указатель устройства (int), индекс устройства (int), форма (кортеж (количество выборок, количество функций [ маркер fp16x2]))). В последнем случае отрицательный индекс устройства означает указатель хоста. При необходимости кортеж может быть на 1 элемент длиннее с предварительно выделенным указателем устройства для соседей. Тип dtype должен быть либо с плавающей точкой16, либо с возможностью преобразования в число с плавающей запятой32.
-
centroids: массив numpy с предварительно рассчитанными центроидами кластеров (например, с использованием K-means/kmcuda/kmeans_cuda()). Тип dtype должен соответствовать сэмплам. Если сэмплы — кортеж, то центроиды должны быть кортежем длины 2, первый элемент — указатель, а второй - количество кластеров Форма (количество кластеров, количество признаков).
-
assignments: массив numpy с ассоциациями выборки-кластера. Ожидается, что dtype будет совместим с uint32. Если образцы - это кортеж, то назначения - это указатель. Форма (количество выборок).
-
metric: str, имя используемой метрики расстояния. По умолчанию используется евклидово (L2), его можно изменить на «cos», чтобы изменить алгоритм на сферические K-средние с угловым расстоянием. Обратите внимание, что выборки должны быть нормализованы в последний случай.
-
device: целое число, индексы устройств CUDA с побитовым ИЛИ, например, 1 означает первое устройство, 2 означает второе устройство, 3 означает использование первого и второго устройств. Специальное значение 0 включает все доступные устройства. Значение по умолчанию — 0.
-
verbosity: целое число, 0 означает полную тишину, 1 означает просто регистрацию прогресса, 2 означает много вывода.
возвращаемое значение: соседние индексы. Если образцы были пустым массивом или кортежем указателя хоста, тип возвращаемого значения — пустой массив, в противном случае — необработанный указатель (целое число), размещенный на том же устройстве. Форма (количество выборок, k).