Использование мощности графических процессоров с помощью CuPy в Python

Максимальное использование мощности графических процессоров с CuPy в Python

Что такое CuPy?

CuPy – это библиотека Python, совместимая с массивами NumPy и SciPy, разработанная для ускоренных вычислений на графических процессорах (GPU). Заменяя синтаксис NumPy на синтаксис CuPy, вы можете запускать свой код на платформах NVIDIA CUDA или AMD ROCm. Это позволяет выполнять задачи, связанные с массивами, с использованием ускорения GPU, что приводит к более быстрой обработке более крупных массивов.

Заменяя всего лишь несколько строк кода, вы можете воспользоваться мощной параллельной обработкой графических процессоров для значительного ускорения операций с массивами, таких как индексирование, нормализация и умножение матрицы.

CuPy также позволяет использовать низкоуровневые функции CUDA. Он позволяет передавать ndarrays существующим программам CUDA C/C++ с использованием RawKernels, оптимизирует производительность с помощью Streams и позволяет прямой вызов API среды выполнения CUDA.

Установка CuPy

Вы можете установить CuPy, используя pip, но перед этим вам нужно узнать правильную версию CUDA с помощью следующей команды.

!nvcc --version

nvcc: NVIDIA (R) Cuda compiler driverCopyright (c) 2005-2022 NVIDIA CorporationBuilt on Wed_Sep_21_10:33:58_PDT_2022Cuda compilation tools, release 11.8, V11.8.89Build cuda_11.8.r11.8/compiler.31833905_0

Кажется, что текущая версия Google Colab использует версию CUDA 11.8. Поэтому мы продолжим установку версии cupy-cuda11x.

Если у вас установлена более старая версия CUDA, я предоставил таблицу ниже, чтобы вам помочь определить соответствующий пакет CuPy для установки.

После выбора правильной версии мы установим пакет Python с использованием pip.

pip install cupy-cuda11x

Вы также можете использовать команду conda, чтобы автоматически обнаружить и установить правильную версию пакета CuPy, если у вас установлен Anaconda.

conda install -c conda-forge cupy

Основы CuPy

В этом разделе мы сравним синтаксис CuPy с NumPy, и они на 95% похожи. Вместо использования np вы будете заменять его на cp.

Сначала мы создадим массив NumPy и CuPy с использованием списка Python. Затем мы вычислим норму вектора.

import cupy as cpimport numpy as npx = [3, 4, 5] x_np = np.array(x)x_cp = cp.array(x) l2_np = np.linalg.norm(x_np)l2_cp = cp.linalg.norm(x_cp) print("Numpy: ", l2_np)print("Cupy: ", l2_cp)

Как видно, мы получили похожие результаты.

Numpy:  7.0710678118654755Cupy:  7.0710678118654755

Чтобы преобразовать массив NumPy в массив CuPy, вы можете просто использовать cp.asarray(X).

x_array = np.array([10, 22, 30])x_cp_array = cp.asarray(x_array)type(x_cp_array)

cupy.ndarray

Или используйте .get(), чтобы преобразовать CuPy в массив NumPy.

x_np_array = x_cp_array.get()type(x_np_array)

numpy.ndarray

Сравнение производительности

В этом разделе мы сравним производительность NumPy и CuPy.

Мы будем использовать time.time() для измерения времени выполнения кода. Затем, мы создадим трехмерный массив NumPy и выполним некоторые математические операции.

import time# NumPy and CPU Runtimes = time.time()x_cpu = np.ones((1000, 100, 1000))np_result = np.sqrt(np.sum(x_cpu**2, axis=-1))e = time.time()np_time = e - sprint("Время выполнения NumPy: ", np_time)

Время выполнения NumPy: 0.5474584102630615

Аналогично, мы создадим трехмерный массив CuPy, выполним математические операции и замерим время выполнения для производительности.

# CuPy and GPU Runtimes = time.time()x_gpu = cp.ones((1000, 100, 1000))cp_result = cp.sqrt(cp.sum(x_gpu**2, axis=-1))e = time.time()cp_time = e - sprint("\nВремя выполнения CuPy: ", cp_time)

Время выполнения CuPy: 0.001028299331665039

Чтобы посчитать разницу, мы разделим время выполнения NumPy на время выполнения CuPy, и кажется, что при использовании CuPy мы получили увеличение производительности более чем в 500 раз.

diff = np_time/cp_timeprint(f'\nCuPy выполняется быстрее, чем NumPy в {diff: .2f} раз')

CuPy выполняется быстрее, чем NumPy в 532.39 раз

Примечание: Для достижения более точных результатов рекомендуется провести несколько прогревочных запусков, чтобы минимизировать флуктуации времени.

Помимо преимущества в скорости, CuPy предлагает превосходную поддержку множественных GPU, позволяя использовать совместную мощность нескольких GPU.

Также, вы можете ознакомиться с моим Colab- блокнотом, если хотите сравнить результаты.

Заключение

В заключение, CuPy предоставляет простой способ ускорения кода NumPy на графических процессорах NVIDIA. Просто внесите несколько изменений, заменив NumPy на CuPy, и вы сможете получить значительное увеличение производительности вычислений с массивами. Такой рост производительности позволяет работать с гораздо большими наборами данных и моделями, открывая новые возможности для применения машинного обучения и научных вычислений.

Ресурсы

****[Abid Ali Awan](https://www.polywork.com/kingabzpro)**** (@1abidaliawan) – сертифицированный профессионал в области науки о данных, который любит создавать модели машинного обучения. В настоящее время он сосредоточен на создании контента и написании технических блогов о технологиях машинного обучения и науки о данных. Абид имеет степень магистра по управлению технологиями и степень бакалавра в области телекоммуникационной инженерии. Его целью является создание продукта искусственного интеллекта с использованием графовых нейронных сетей для студентов, страдающих от психических расстройств.