Как использовать gpu в python

Запуск скрипта Python на GPU.

У графических процессоров больше ядер, чем у процессоров, и, следовательно, когда дело доходит до параллельных вычислений данных, графические процессоры работают исключительно лучше, чем процессоры, даже несмотря на то, что у графических процессоров более низкая тактовая частота, и в нем отсутствуют некоторые функции управления ядром по сравнению с процессором.
Таким образом, выполнение сценария Python на графическом процессоре может оказаться сравнительно быстрым, чем на процессоре, однако следует отметить, что для обработки набора данных с помощью графического процессора данные сначала будут перенесены в память графического процессора, что может потребовать дополнительного времени, поэтому, если данные Набор мал, тогда процессор может работать лучше, чем GPU.
Начиная:
На данный момент поддерживаются только графические процессоры NVIDIA, перечисленные на этой странице. Если ваша видеокарта имеет ядра CUDA, вы можете продолжить настройку.
Установка:
Сначала убедитесь, что драйверы Nvidia обновлены, и вы можете явно установить cudatoolkit отсюда. затем установите Anaconda, добавьте anaconda в среду при установке.
После завершения всех установок выполните следующие команды в командной строке.

ПРИМЕЧАНИЕ. Если Anaconda не добавлена в среду, перейдите к установке anaconda, найдите каталог Scripts и откройте там командную строку.

КОД:

Мы будем использовать декоратор numba.jit для функции, которую мы хотим вычислить на GPU. Декоратор имеет несколько параметров, но мы будем работать только с целевым параметром. Target указывает jit скомпилировать коды для какого источника («CPU» или «Cuda»). «Cuda» соответствует GPU. Однако, если CPU передается в качестве аргумента, jit пытается оптимизировать код, работающий быстрее на CPU, и повышает скорость.

from numba import jit, cuda

import numpy as np

# измерить время выполнения

from timeit import default_timer as timer

# нормальная функция для запуска на процессоре

for i in range ( 10000000 ):

# функция оптимизирована для работы на GPU

for i in range ( 10000000 ):

if __name__ = = «__main__» :

a = np.ones(n, dtype = np.float64)

b = np.ones(n, dtype = np.float32)

Выход: на основе CPU = i3 6006u, GPU = 920M.

Тем не менее, следует отметить, что массив сначала копируется из оперативной памяти в графический процессор для обработки, и если функция возвращает что-либо, возвращаемые значения будут скопированы из графического процессора в центральный процессор обратно. Поэтому для небольших наборов данных скорость ЦП сравнительно выше, но скорость может быть дополнительно улучшена даже для небольших наборов данных путем передачи цели в качестве «ЦП». Особую осторожность следует соблюдать, когда функция, написанная в jit, пытается вызвать любую другую функцию, тогда эта функция также должна быть оптимизирована с помощью jit, иначе jit может генерировать еще более медленные коды.

Источник

Глубокое обучение и нейронные сети с Python и Pytorch. Часть VII: запускаем обучение на GPU

Данная статья предполагает, что у вас есть доступ к GPU либо локально, либо через облако.

Если вы используете сервер, вам нужно будет загрузить данные, извлечь, а также установить jupyter notebook :

Далее вы можете запустить его следующим образом:

После этого вы увидите что-то вроде этого:

Затем вам нужно будет перейти по указанному выше URL-адресу, заменив 127.0.0.1 на IP-адрес вашего сервера.

Наш код на настоящий момент имеет следующий вид:

Результат:

Мы пошли несколько дальше и сделали быструю функцию для обработки процесса обучения, в основном для того, чтобы не запускать заново тренировочную часть нашего кода. Вместо этого мы хотим поговорить про работу на GPU.

Для начала вам понадобится версия Pytorch для GPU. А чтобы использовать Pytorch на графическом процессоре, вам понадобится графический процессор NVIDIA с поддержкой технологии CUDA.

Если его нет, то потребуются облачные провайдеры, например Linode. Прим. переводчика — отлично подойдут Google Colaboratory или Kaggle. Они абсолютно бесплатны.

Для работы на локальном компьютере вам нужно загрузить CUDA toolkit.

После этого необходимо загрузить и распаковать CuDNN, переместив содержимое CuDNN в каталог Cuda Toolkit. Когда вы распакуете архив CuDNN, у вас будет 3 каталога внутри каталога cuda. Вам просто нужно переместить содержимое этих каталогов (bin, include и lib) в одноименные директории, находящиеся в каталоге Cuda Toolkit.

Сделав это, вам надо будет убедиться что у вас установлена версия Pytorch для GPU. Ее можно найти на стартовой странице фреймворка Pytorch. Также надо сказать, что если вы используете пакет Anaconda, то в нем уже предустановлены все возможные версии Pytorch.

Убедиться, что CUDA установлена, можно следующим образом:

Результат:

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

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

Для начала давайте разместим на GPU нашу нейронную сеть. Для этого мы можем просто установить следующий флаг:

Результат:

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

Результат:

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

Результат:

Таким образом мы можем экстраполировать номера индексов и назначить конкретным графическим процессорам определенные слои нашей сети.

На данный момент мы пишем код, которому в действительности нужен только один графический (или обычный) процессор, поэтому мы будем использовать только одно устройство. И теперь, выяснив, какое устройство лучше всего использовать, мы можем приступить к его настройке. Сделать это очень просто, достаточно лишь выполнить следующий код:

Результат:

Выше мы уже определили нашу сеть, но обычно вы просто сразу ее определяете и отправляете на устройство, например следующим образом:

Теперь мы можем перейти к обучению, но на этот раз мы поместим наши батчи в GPU. В этом примере мы реально можем за один раз поместить все наши данные в GPU, так как у нас не очень большой объем данных. И это, конечно, сэкономит нам некоторое время, затрачиваемое на передачу данных из VRAM в GPU и обратно. Но обычно подобное невозможно, поэтому мы покажем вам, как это происходит в нормальных условиях.

Результат:

Как можно заметить, сейчас это работает намного быстрее. Теперь мы можем проверить нашу модель на тестовой выборке (это можно сделать как на CPU, так и на GPU). Поскольку эта выборка совсем небольшая, сделаем это тоже на GPU:

Результат:

А вот тоже самое с использованием батчей работает быстрее:

Результат:

Итак, по сравнению с тем, что было, мы добились значительного прогресса.

Мы научились создавать и обучать нейронные сети и уже получили приличный результат.

Но можем ли мы добиться большего, чем точность в 70%? Должны ли мы увеличивать количество эпох? И если да, то когда нам все же остановиться?

Что, если у нас есть несколько моделей, и чтобы их сравнить, нужно довести их до совершенства? Мы же не знаем, когда это произойдет!

В следующей статье мы рассмотрим некоторые базовые методы анализа и визуализации результатов. А также разберем несколько концепций, которые необходимо учитывать при анализе эффективности работы модели.

Источник

Сравнение производительности GPU-расчетов на Python и C

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

Введение

По роду деятельности я частенько занимаюсь задачами численного моделирования. Во многих случаях мы используем технологию CUDA для ускорения расчетов за счет использования возможностей параллельных вычислений на GPU, при этом программы пишутся на языке C. В то же время, в некоторых случаях хотелось бы иметь возможность реализовывать расчеты на питоне, потому что это удобно, быстро, гибко, лаконично, молодежно. При этом, однако, очень важно не терять в скорости выполнения программ, поскольку некоторые расчеты могут занимать от нескольких часов до суток. В статье продемонстрировано использование python-библиотек Numba и PyCUDA для реализации параллельных расчетов на GPU и приведены результаты сравнения их производительности на тестовой задаче.

Тестовая задача

Выбор тестовой задачи и условий тестирования был обусловлен характером реальных задач, для решения которых в дальнейшем планируется использование python. При этом была выбрана максимально простая задача, а именно задача решения двумерного уравнения теплопроводности с помощью явной конечно-разностной схемы. Задача рассматривалась на квадратной области с заданными значениями температуры на границах. Количество узлов расчетной сетки по x и y одинаково и равно n. На рисунке в начале статьи показано установившееся решение тестовой задачи.

Алгоритм и условия тестирования

Алгоритм решения задачи можно представить следующим псевдокодом:

Во всех тестах представленных ниже число узлов квадратной сетки в каждом направлении (n) варьировалось от 512 до 4096, а nstp = 5000.

Программное и аппаратное обеспечение

Тестирование проводилось на персональном компьютере:

Intel® Core(TM)2 Quad CPU Q9650 @ 3.00GHz, 8 Gb ОЗУ
GPU: Nvidia GTX 580
Операционная система: Ubuntu 16.04 LTS с установленной CUDA 7.5

Реализация на C

Все дальнейшие python-реализации сравнивались с результатами, полученными с помощью программы на C, описанной в этом разделе.

Расчеты показывают, что для N = 512 время выполнения C-программы распараллеленной на GPU составляет 0.27 секунд против 33.06 секунд для последовательной реализации алгоритма на CPU. То есть ускорение CPU/GPU составляет около 120 раз. С ростом N величина ускорения не убывает.

Python with Numba

Библиотека Numba предоставляет возможность jit (just-in-time) компиляции кода на питоне в байт-код сравнимый по производительности с C или Fortran кодом. Numba поддерживает компиляцию и запуск python-кода не только на CPU, но и на GPU, при этом стиль и вид программы, использующей библиотеку Numba, остается чисто питоновским.

Отметим тут несколько приятных особенностей. Во-первых, эта реализация намного короче и нагляднее. Здесь мы использовали двумерные массивы, что делает код намного более удобочитаемым. Во-вторых, если в C-реализации от нас требовалось передать все константы (например N) путем исполнения функций вроде cudaMemcpyToSymbol(dN, &N, sizeof(int)); то здесь мы просто пользуемся глобальными переменными как в обычной python-функции. Ну и наконец, реализация не требует никаких знаний языка C и архитектуры GPU.

Этот код легко переписать и для случая использования одномерных массивов размера n*n, как будет показано далее это существенно влияет на скорость выполнения.

PyCUDA

Второй из протестированных python-библиотек была библиотека PyCUDA. В отличии от Numba здесь от разработчика потребуется написать код ядра на C, поэтому без знания этого языка не обойтись. С другой стороны кроме собственно ядра на C ничего писать не надо.

Выглядит это все как чистый питон за исключением локальной вставки C-кода.

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

На Рисунке 1 и в Таблице 1 приведены зависимости времени выполнения тестовой программы (в секундах) от размера сетки n, полученные при запуске C-кода (кривая CUDA C) и python-реализаций с библиотекой Numba и двумерными массивами (Numba 2DArr), с библиотекой Numba и одномерными массивами (Numba 1DArr), с библиотекой PyCUDA (кривая PyCUDA).

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

Рисунок 1

Таблица 1

nCuda CNumba 2DArrNumba 1DArrPyCUDA
5120.250.80.660.216
10240.773.261.030.808
20482.7312.234.072.87
30736.127.39.126.6
409611.0555.8816.2712.02

На Рисунке 2 приведены отношения времени выполнения различных python-реализаций к времени выполнения C-кода. Как видно из рисунков, самой медленной, из рассмотренных, является реализация с помощью библиотеки Numba с использованием двумерных массивов. При этом, этот подход является самым наглядным и простым. Интересно, что развертка двумерных массивов в одномерные приводит к примерно троекратному ускорению кода. Самым быстрым решением оказалось использование библиотеки PyCUDA. В то же время, как отмечалось выше, использование этой библиотеки несколько более трудоемко, поскольку требует написания ядра на C. Однако затраты окупаются и скорость выполнения такой python-программы всего на 5-8% меньше чем программы, написанной полностью на C.

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

Выводы

Чудес не бывает и самые простые и наглядные решения оказываются одновременно и самыми медленными. В то же время, имеющиеся библиотеки позволяют добиться скорости выполнения python-программ, сравнимой со скоростью выполнения чистого C-кода. Существующие библиотеки дают разработчику выбор между более и менее высокоуровневыми решениями. Этот выбор, однако, всегда есть компромисс между скоростью разработки и скоростью выполнения программы.

Источник

Python, производительность и графические процессоры

Дата публикации Jun 28, 2019

Управляющее резюме

Мы улучшаем состояние масштабируемых вычислений на GPU в Python.

В этом посте изложено текущее состояние и описаны будущие работы. Он также суммирует и ссылается на несколько других постов за последние месяцы, которые углубляются в различные темы для заинтересованного читателя.

В общих чертах мы кратко рассмотрим следующие категории:

Производительность GPU-ускоренных библиотек Python

Многие пользователи знают библиотеки для глубокого изучения, такие как PyTorch и TensorFlow, но есть несколько других для более общих вычислений. Они имеют тенденцию копировать API популярных проектов Python:

Эти библиотеки создают ускоренные на GPU варианты популярных библиотек Python, таких как NumPy, Pandas и Scikit-Learn. Для того, чтобы лучше понять относительные различия в производительностиПетр энчевнедавно собралтестовый пакетчтобы помочь с сравнениями. Он создал следующее изображение, показывающее относительное ускорение между GPU и CPU:

Как использовать gpu в python. 0 193504 565367. Как использовать gpu в python фото. Как использовать gpu в python-0 193504 565367. картинка Как использовать gpu в python. картинка 0 193504 565367

Там много интересных результатов. Питер углубляется в это вего блог,

В более широком смысле, мы видим, что есть различия в производительности. Наша ментальная модель быстрого и медленного процессора не обязательно переносится на графический процессор. К счастью, благодаря согласованным API-интерфейсам пользователи, знакомые с Python, могут легко экспериментировать с ускорением графического процессора без изучения CUDA.

Numba: компиляция Python для CUDA

Встроенные операции в библиотеках графических процессоров, таких как CuPy и RAPIDS, охватывают наиболее распространенные операции. Однако в реальных условиях мы часто находим беспорядочные ситуации, требующие написания небольшого количества нестандартного кода. Переход на C / C ++ / CUDA в этих случаях может быть сложным, особенно для пользователей, которые в основном являются разработчиками Python. Это где Нумба может войти.

У Python такая же проблема и с процессором. Пользователи часто не могли научиться писать на C / C ++ быстрый пользовательский код. Для решения этой проблемы существуют такие инструменты, как Cython или Numba, которые позволяют программистам Python писать быстрый числовой код, не изучая многое за пределами языка Python.

Например, Numba ускоряет код стиля цикла for ниже примерно в 500 раз на процессоре, от медленных скоростей Python до быстрых скоростей C / Fortran.

Полезна возможность перехода к низкоуровневому производительному коду без переключения контекста из Python, особенно если вы еще не знаете C / C ++ или у вас установлена ​​цепочка компиляторов (что имеет место для большинства пользователей Python сегодня ).

Это преимущество еще более заметно на GPU. Хотя многие программисты на Python немного знают C, очень немногие знают CUDA. Даже если бы они это сделали, они, вероятно, столкнулись бы с трудностями при настройке инструментов компилятора и среды разработки.

Войтиnumba.cuda.jitБэкенд Numba для CUDA. Numba.cuda.jit позволяет пользователям Python интерактивно создавать, компилировать и запускать код CUDA, написанный на Python, не выходя из сеанса Python. Вот изображение записи трафаретного вычисления, которое сглаживает 2d-изображение все из Блокнота Jupyter:

Как использовать gpu в python. 0 641701 35601. Как использовать gpu в python фото. Как использовать gpu в python-0 641701 35601. картинка Как использовать gpu в python. картинка 0 641701 35601

Вот упрощенное сравнение кода CPU / GPU Numba для сравнения стиля программирования. Код GPU увеличивает скорость в 200 раз по сравнению с одним ядром процессора.

Numba.cuda.jit уже давно в дикой природе. Это доступно, зрело и весело играть. Если у вас есть компьютер с графическим процессором и любопытством, мы настоятельно рекомендуем вам попробовать.

Масштабирование с помощью Dask

Как упоминалось в предыдущих блогах (1,2,3,4) мы обобщалиДаск, для работы не только с массивами Numpy и панелями данных Pandas, но и с чем-либо, что выглядит достаточно похожим на Numpy (например,нять своиилиредкийилиJaxили достаточно как Панды (какRAPIDS cuDF) масштабировать эти библиотеки тоже. Это хорошо работает. Вот краткое видео, показывающее, как массив Dask параллельно обрабатывает SVD, и что происходит, когда мы заменяем библиотеку Numpy на CuPy.

Мы видим, что скорость вычислений увеличивается примерно в 10 раз Самое главное, что мы смогли переключаться между реализацией CPU и GPU с небольшим изменением в одну строку, но продолжали использовать сложные алгоритмы с Dask Array, такие как параллельная реализация SVD.

Мы также увидели относительное замедление в общении. В целом, почти вся нетривиальная работа Dask + GPU сегодня становится коммуникационной. Мы достаточно быстро освоили вычисления, и относительная важность общения значительно возросла.

Связь с UCX

Используя UCX и Dask вместе, мы можем добиться значительных ускорений. Вот след вычисления SVD от до и после добавления UCX:

До UCX:

Как использовать gpu в python. 0 344762 956494. Как использовать gpu в python фото. Как использовать gpu в python-0 344762 956494. картинка Как использовать gpu в python. картинка 0 344762 956494

После UCX:

Как использовать gpu в python. 0 564815 580976. Как использовать gpu в python фото. Как использовать gpu в python-0 564815 580976. картинка Как использовать gpu в python. картинка 0 564815 580976

Здесь еще многое предстоит сделать (ссылка на пост в блоге содержит несколько пунктов в разделе «Будущая работа»).

Люди могут попробовать UCX и UCX-Py с помощью экспериментальных пакетов conda:

Мы надеемся, что эта работа также повлияет на пользователей не-GPU в системах HPC с Infiniband или даже на пользователей аппаратного обеспечения из-за легкого доступа к общему использованию памяти.

упаковка

Впредыдущий постмы обсудили проблемы, связанные с установкой неправильных версий пакетов с поддержкой CUDA, которые не соответствуют драйверу CUDA, установленному в системе. К счастью, из-за недавней работыСтэн Сейберта такжеМайкл Сараханв Анаконде, Конда 4.7 теперь имеет специальный cuda метапакет, в котором указана версия установленного драйвера. Это должно упростить пользователям установку правильного пакета в будущем.

Конда 4.7 была только релиза и поставляется со многими новыми функциями, кроме cuda мета-пакет. Вы можете прочитать больше об этомВот,

В упаковочном пространстве еще много работы. Каждый, кто создает пакеты conda, делает это по-своему, что приводит к головной боли и неоднородности. Во многом это связано с отсутствием централизованной инфраструктуры для сборки и тестирования пакетов с поддержкой CUDA, как мыКонда Фордж, К счастью, сообщество Conda Forge работает вместе с Anaconda и NVIDIA, чтобы помочь решить эту проблему, хотя это, вероятно, займет некоторое время.

Резюме

В этом посте дается обновленная информация о некоторых усилиях, связанных с вычислениями на GPU в Python. Также предоставлены различные ссылки для дальнейшего чтения. Мы включим их ниже, если вы хотите узнать больше:

Источник

Как GPU-вычисления буквально спасли меня на работе. Пример на Python

Сегодня мы затрагиваем актуальнейшую тему — Python для работы с GPU. Автор рассматривает пример, тривиальный в своей монструозности, и демонстрирует решение, сопровождая его обширными листингами. Приятного чтения!

Как использовать gpu в python. . Как использовать gpu в python фото. Как использовать gpu в python-. картинка Как использовать gpu в python. картинка

Никого из нас в той или иной форме не обошел хайп вокруг GPU-вычислений, развернувшийся в последнее время. Прежде, чем вы станете читать далее, поясню: я не эксперт по GPU. Мой путь в мире GPU только начинается. Но эта технология сегодня достигла такой мощи, что, вооружившись ею, можно решать целую уйму задач. Мне на работе поручили задачу, на выполнение которой машина тратила целые часы, а прогресса так и не было видно. Но, стоило мне взяться за GPU – и проблема стала решаться за секунды. Задачу, на выполнение которой ориентировочно требовалось 2 суток, я смог решить всего за 20 секунд.

В следующих разделах я детально опишу эту задачу. Также мы обсудим, как и когда использовать GPU для решения любых подобных задач. Итак, читаем внимательно – поверьте, вы не пожалеете. Сначала мы вникнем в детали задачи, затем освоимся с GPU и, наконец, воспользуемся GPU для решения этой задачи. Я буду пользоваться библиотекой Python Numba и графическим процессором Nvidia Volta V100 16GB GPU.

1. Подробное описание задачи

В сфере розничной торговли часто приходится искать похожие или наиболее близкие объекты. Мне дали список позиций, каждая из которых была представлена k латентными атрибутами. Итак, мне было поручено найти топ-3 наиболее схожих позиций к каждой из позиций списка. Метрикой схожести в данной задаче было выбрано косинусное сходство. Вот как выглядели мои данные.

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

Список позиций данных с 64-латентными признаками

Мне дали список, в котором было около 10⁵ позиций. Поиск 3 наиболее схожих позиций для каждой из них потребовал бы проверить косинусное сходство с каждым без исключения элементов в списке. Получалось бы n * k операций, где n – количество позиций, а k – атрибуты на каждую позицию. Потребовалось бы получить скалярное произведение данной позиции с каждой из остальных позиций в списке.

Код для нахождения трех позиций, максимально подобных заданной

Теперь, при нахождении топ-3 схожих для всех позиций в списке, сложность умножается еще на n. Окончательная сложность оказывается равна O(n*n*k) = O(n²k).

Код для нахождения трех наиболее схожих позиций для каждой позиции в списке

Тестовый прогон и оценка времени

Я запустил код, попробовав найти 3 наиболее похожие позиции из подмножества, содержащего n = 10³ позиций с k = 64. На выполнение этой задачи при помощи Python потребовалось около 17 секунд со средней скоростью 3.7 *10⁶ операций в секунду. Код был хорошо оптимизирован с применением операций и массивов Numpy. Отмечу, что все эти операции последовательно выполняются на CPU.

Прогон для n = 10³ позиций

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

Вывод: время, потребовавшееся для n = 10³ позиций

Далее я увеличил тестовое подмножество до n =10⁴ позиций. Поскольку сложность равна O(n²k), длительность выполнения возросла в 100 раз (поскольку n возросла в 10 раз). На выполнение кода ушло 1700 секунд = 28,33 минуты.

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

Вывод: время, потребовавшееся на обработку n = 10⁴ позиций

Далее подходим к самому важному: оценке времени, которое потребуется на обработку полноценного списка из 10⁵ позиций. Посчитав, увидим, что временная сложность вновь возрастет в 100 раз, поскольку временная сложность алгоритма равна O(n²k).
Ориентировочное время = 1700 * 100 секунд = 2834 минуты = 47,2 часа

О, Господи! Так долго.

Вероятно, вы уже догадываетесь, что на самом деле мне удалось все сделать очень быстро, воспользовавшись силой GPU. На самом деле, выигрыш во времени при использовании GPU просто шокирует. Цифры я оставлю на закуску, а пока предлагаю вам познакомиться с миром GPU.

2. Сравнение CPU и GPU

Центральный процессор (CPU), в сущности, является мозгом любого вычислительного устройства: он выполняет записанные в программе инструкции, осуществляя управляющие, логические операции, а также операции ввода/вывода.

Правда, у современных CPU по-прежнему не так много ядер, и базовая структура и назначение CPU – обработка сложных вычислений – в сущности, не изменились. На самом деле, CPU лучше всего подходит для решения задач, заключающихся в разборе или интерпретации сложной логики, содержащейся в коде.

В свою очередь, графический процессор (GPU) обладает более мелкими логическими ядрами, которых, однако, гораздо больше (речь идет об арифметико-логических устройствах (АЛУ), управляющих элементах и кэш-памяти), которые спроектированы с расчетом на параллельную обработку в целом идентичных и сравнительно простых операций.

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

У GPU больше арифметических логических устройств (ALU), чем у типичного CPU, поэтому повышена способность параллельной обработки простых операций

Рисунок: сравнение CPU и GPU

3. Когда использовать вычисления на GPU

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

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

Представление об операциях с точки зрения CPU — есть такие операции, например, расчет ряда Фибоначчи, которые нельзя распараллелить. Ведь найти очередное число можно лишь после того, как вычислишь предыдущие два. Такие операции лучше всего подходят для CPU.
В свою очередь, такие операции, как сложение и перемножение матриц, легко выполняются с применением GPU, поскольку большинство из этих операций в матричных ячейках являются независимыми друг от друга, схожи по природе, и поэтому могут быть распараллелены.

4. Кратко о CUDA

CUDA – это платформа для параллельных вычислений и модель API, созданная компанией Nvidia. С помощью этого API можно использовать процессор с поддержкой CUDA-графики для широкого спектра вычислений. Такой подход получил название GPGPU (неспециализированные вычисления на графических процессорах). Здесь о них рассказано подробнеe.

Numba – это свободно распространяемый JIT-компилятор, транслирующий подмножество Python и NumPy в быстрый машинный код при помощи LLVM, это делается средствами пакета llvmlite на Python. В этом пакете предлагается ряд вариантов по распараллеливанию кода на Python для CPU и GPU, в самом коде при этом зачастую достаточно минимальных изменений. См. подробнеe.
Работая с процессором Nvidia Volta V100 16GB GPU, я пользовался библиотекой Numba.

потоки, блоки и гриды

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

Поток: поток CUDA – это назначенная цепочка инструкций, поступающих/текущих в ядро CUDA (на самом деле, это просто конвейер). На лету на одном и том же ядре CUDA может существовать до 32 потоков (в таком случае заполняются все звенья этого конвейера). Это выполнение ядра с заданным индексом. Каждый поток использует свой индекс для доступа элементов в массиве таким образом, что вся совокупность имеющихся потоков совместно обрабатывает все множество данных.

Грид: Это группа блоков. Между блоками отсутствует всякая синхронизация.

Как использовать gpu в python. image loader. Как использовать gpu в python фото. Как использовать gpu в python-image loader. картинка Как использовать gpu в python. картинка image loader

CUDA: потоки, блоки, гриды

Но где же именно выполняются потоки, блоки и гриды? В случае архитектуры G80 GPU от Nvidia, вычисления, по-видимому, распределены следующим образом:

Грид → GPU: Весь грид обрабатывается единственным GPU-процессором.
Блок → МП: Процессор GPU организован как коллекция мультипроцессоров, где каждый мультипроцессор отвечает за обработку одного или более блоков в гриде. Один блок никогда не делится между несколькими МП.
Поток → ПП: Каждый МП далее подразделяется на процессоры потоков (ПП), и каждый ПП обрабатывает один или более потоков в блоке.

Я позаимствовал некоторый материал из этой отлично написанной статьи. Рекомендую почитать ее внимательно.

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

Как я уже говорил в самом начале, суть данной статьи – помочь широкой аудитории понять силу GPU и приобрести интуитивное представление, как применять GPU для решения повседневных задач. Перед тем, как начинать писать код для GPU, возможно, придется провести некоторые предварительные исследования. Для этого давайте разберем в качестве примера программу для сложения массивов.

Допустим, у нас есть два массива, ‘a’ и ‘b’ размера ‘n’. Мы хотим сгенерировать массив ‘c’, такой, чтобы каждый элемент массива c являлся суммой элементов с теми же индексами из массивов ‘a’ и ‘b’. Но в данном случае для решения задачи мы применим не последовательные вычисления, а параллельные, которые делаются при помощи GPU.

Мы запустим n потоков/ядер. Индекс, под которым работает каждый конкретный поток, можно вывести из следующей формулы:

index = cuda.blockIdx.x * cuda.blockDim.x + cuda.threadIdx.x

В случае с двумерной матрицей в индексе присутствует два компонента, означающих строку и столбец, которые можно вывести следующим образом:

row = cuda.blockIdx.x * cuda.blockDim.x + cuda.threadIdx.x
col = cuda.blockIdx.x * cuda.blockDim.x + cuda.threadIdx.x

Также нам придется определить количество потоков на блок, скажем, tpb и блоков на грид, допустим bpg. Воспользуемся стандартными числами для них.

Ниже приведены реализации данного решения как для CPU, так и для GPU. Посмотрите оба листинга, чтобы уловить разницу.

Последовательная реализация для CPU.

Параллельная реализация для GPU

6. Нахождение 3 наиболее похожих позиций для каждой позиции в списке при помощи GPU

Хорошенько вникнув в теорию и практику, возвращаемся к исходно поставленной задаче: найти топ-3 похожих позиции для каждой позиции в списке при помощи вычислений на GPU.
В данном случае основная идея заключается в том, что у нас n позиций, и мы запустим n потоков. Каждый поток будет работать параллельно с остальными и независимо от них, вычисляя по 3 наиболее похожие позиции для каждой позиции в списке. За каждую позицию будет отвечать один поток.

Реализация для GPU

Код для нахождения 3 позиций, наиболее похожих на данную

Общее время, затраченное GPU для нахождения топ-3 схожих позиций для каждой позиции в списке, составило 481 мс (0,5 секунд). Еще 20 секунд потребовалось для копирования данных с устройства на хост и с хоста на устройство.

7. Вывод

Задача, решение которой на CPU потребовало бы около 2 дней, на GPU была решена за 20,5 секунд. Это оказалось возможно только благодаря природе задачи. Поиск 3 наиболее похожих позиций для ‘A’ не зависит от поиска 3 наиболее похожих позиций для ‘B’. Мы воспользовались этим фактом и применили параллелизм, предоставляемый GPU, для ускорения процесса. Также пример иллюстрирует, задачи какого типа удобнее всего решать при помощи могучего GPU.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *