Многопоточность в машинном обучении — различия между версиями
(Статья, первый вид) |
|||
Строка 7: | Строка 7: | ||
== Идеи используемые для ускорения вычислений в ML == | == Идеи используемые для ускорения вычислений в ML == | ||
=== Параллелизм для ускорения линейной алгебры. === | === Параллелизм для ускорения линейной алгебры. === | ||
− | Мы можем значительно повысить производительность, создав ядра линейной алгебры (например, умножение матриц, векторное сложение и т.д.), которые используют параллелизм для ускорения работы. Поскольку умножение матриц занимает большую часть обучения нейронных сетей, это может привести к значительному сквозному ускорению обучающего конвейера. В основе этого лежит параллелизм ILP, SIMD а для больших матриц также может использоваться многопоточность. | + | Мы можем значительно повысить производительность, создав ядра линейной алгебры (например, умножение матриц, векторное сложение и т.д.), которые используют параллелизм для ускорения работы. Поскольку умножение матриц занимает большую часть времени обучения нейронных сетей, это может привести к значительному сквозному ускорению обучающего конвейера. В основе этого лежит параллелизм ILP, SIMD а для больших матриц также может использоваться многопоточность. |
Примеры оптимизаций: | Примеры оптимизаций: | ||
Строка 13: | Строка 13: | ||
* Алгоритмы в терминах матричных операций, а не векторных операций, насколько это возможно. | * Алгоритмы в терминах матричных операций, а не векторных операций, насколько это возможно. | ||
* Broadcast операции, а не циклы. | * Broadcast операции, а не циклы. | ||
− | * Распараллеленные реализации некоторых специальных операций (таких как свертки для CNN). | + | * Распараллеленные реализации некоторых специальных операций (таких как свертки для [[Сверточные нейронные сети | CNN]]). |
==== Параллелизм broadcast операций ==== | ==== Параллелизм broadcast операций ==== | ||
Строка 28: | Строка 28: | ||
=== Параллелизм в оптимизации гиперпараметров === | === Параллелизм в оптимизации гиперпараметров === | ||
− | Для параллельной оптимизации | + | Для параллельной [[Настройка гиперпараметров | оптимизации гиперпараметров]] можно использовать поиск по решётке или случайный поиск в которых мы можем оценить параметры независимо. |
Такая оптимизации часто встречаются в библиотеках машинного обучения. | Такая оптимизации часто встречаются в библиотеках машинного обучения. | ||
− | === Параллелизм кросс-валидации === | + | === Параллелизм [[Кросс-валидация | кросс-валидации]] === |
Полная кросс-валидация, k-fold, t×k-fold, Leave-One-Out легко распараллеливаются на несколько потоков, каждый из которых работает на своем разбиении данных | Полная кросс-валидация, k-fold, t×k-fold, Leave-One-Out легко распараллеливаются на несколько потоков, каждый из которых работает на своем разбиении данных | ||
Строка 38: | Строка 38: | ||
=== Параллелизм GPU === | === Параллелизм GPU === | ||
Типичное число потоков обработки графического процессора - десятки тысяч, что позволяет вычислять одну и ту же операцию параллельно на множестве элементов. | Типичное число потоков обработки графического процессора - десятки тысяч, что позволяет вычислять одну и ту же операцию параллельно на множестве элементов. | ||
+ | |||
Фреймворки машинного обучения, такие как TensorFlow, PyTorch и MxNet используют эти возможности через библиотеки от компаний производителей графических ускорителей: | Фреймворки машинного обучения, такие как TensorFlow, PyTorch и MxNet используют эти возможности через библиотеки от компаний производителей графических ускорителей: | ||
− | cuBLAS - библиотека от Nvidia позволяющая эффективно перемножать матрицы. | + | * cuBLAS - библиотека от Nvidia позволяющая эффективно перемножать матрицы. |
− | CUDA - язык параллельного программирования/вычислительная платформа для вычислений общего назначения на графическом процессоре | + | * CUDA - язык параллельного программирования/вычислительная платформа для вычислений общего назначения на графическом процессоре |
=== Параллелизм SGD === | === Параллелизм SGD === | ||
− | Запускаем внешний цикл SGD параллельно в пуле потоков и используем конструкции синхронизации, такие как блокировки, чтобы предотвратить состояние гонки. Но это может работать медленно из-за накладных расходов на синхронизацию. | + | Запускаем внешний цикл [[Стохастический градиентный спуск|SGD]] параллельно в пуле потоков и используем конструкции синхронизации, такие как блокировки, чтобы предотвратить состояние гонки. Но это может работать медленно из-за накладных расходов на синхронизацию. |
+ | |||
Еще более интересная идея (называемая асинхронным SGD или Hogwild): Несколько потоков запускают SGD параллельно без какой-либо синхронизации. Теперь условия гонки могут возникнуть, но оказывается, что во многих случаях это хорошо, шум/ошибка в условиях гонки просто добавляет небольшое количество к шуму/ошибке, уже присутствующей в алгоритм из-за случайной выборки градиента. | Еще более интересная идея (называемая асинхронным SGD или Hogwild): Несколько потоков запускают SGD параллельно без какой-либо синхронизации. Теперь условия гонки могут возникнуть, но оказывается, что во многих случаях это хорошо, шум/ошибка в условиях гонки просто добавляет небольшое количество к шуму/ошибке, уже присутствующей в алгоритм из-за случайной выборки градиента. | ||
Версия 14:13, 20 апреля 2020
Следует выделить следующие виды параллелизма:
- Параллелизм на уровне инструкций (ILP): запускать несколько инструкций одновременно.
- Параллелизм одна инструкция множество данных(SIMD): одна инструкция работает с вектором чисел
- Многопоточный параллелизм: несколько независимых рабочих потоков взаимодействуют через абстракцию совместно используемой памяти.
- Распределенные вычисления: несколько независимых рабочих компьютеров взаимодействуют по сети. (MLlib на Spark, Mahout на Hadoop)
Содержание
Идеи используемые для ускорения вычислений в ML
Параллелизм для ускорения линейной алгебры.
Мы можем значительно повысить производительность, создав ядра линейной алгебры (например, умножение матриц, векторное сложение и т.д.), которые используют параллелизм для ускорения работы. Поскольку умножение матриц занимает большую часть времени обучения нейронных сетей, это может привести к значительному сквозному ускорению обучающего конвейера. В основе этого лежит параллелизм ILP, SIMD а для больших матриц также может использоваться многопоточность.
Примеры оптимизаций:
- Высоко оптимизированные тензорные библиотеки для арифметики.
- Алгоритмы в терминах матричных операций, а не векторных операций, насколько это возможно.
- Broadcast операции, а не циклы.
- Распараллеленные реализации некоторых специальных операций (таких как свертки для CNN).
Параллелизм broadcast операций
Просмотрите код наивной реализации поэлементное произведение двух векторов на Python
def elementwise_product(x, y): assert(len(x) == len(y)) z = numpy.zeros(len(x)) for i in range(len(x)): z[i] = x[i] * y[i] return z
Такой код лучше заменять на broadcast операции из numpy, которые выигрывают от векторизации и ILP. Также такой код может быть легко распараллелен для больших векторов
Параллелизм в оптимизации гиперпараметров
Для параллельной оптимизации гиперпараметров можно использовать поиск по решётке или случайный поиск в которых мы можем оценить параметры независимо. Такая оптимизации часто встречаются в библиотеках машинного обучения.
Параллелизм кросс-валидации
Полная кросс-валидация, k-fold, t×k-fold, Leave-One-Out легко распараллеливаются на несколько потоков, каждый из которых работает на своем разбиении данных
Параллелизм GPU
Типичное число потоков обработки графического процессора - десятки тысяч, что позволяет вычислять одну и ту же операцию параллельно на множестве элементов.
Фреймворки машинного обучения, такие как TensorFlow, PyTorch и MxNet используют эти возможности через библиотеки от компаний производителей графических ускорителей:
- cuBLAS - библиотека от Nvidia позволяющая эффективно перемножать матрицы.
- CUDA - язык параллельного программирования/вычислительная платформа для вычислений общего назначения на графическом процессоре
Параллелизм SGD
Запускаем внешний цикл SGD параллельно в пуле потоков и используем конструкции синхронизации, такие как блокировки, чтобы предотвратить состояние гонки. Но это может работать медленно из-за накладных расходов на синхронизацию.
Еще более интересная идея (называемая асинхронным SGD или Hogwild): Несколько потоков запускают SGD параллельно без какой-либо синхронизации. Теперь условия гонки могут возникнуть, но оказывается, что во многих случаях это хорошо, шум/ошибка в условиях гонки просто добавляет небольшое количество к шуму/ошибке, уже присутствующей в алгоритм из-за случайной выборки градиента.