Многопоточность в машинном обучении — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Параллелизм GPU)
(Добавил больше примеров для GPU)
Строка 40: Строка 40:
  
 
Фреймворки машинного обучения, такие как TensorFlow, PyTorch и MxNet используют эти возможности через библиотеки от компаний производителей графических ускорителей и открытые фреймворки:
 
Фреймворки машинного обучения, такие как TensorFlow, PyTorch и MxNet используют эти возможности через библиотеки от компаний производителей графических ускорителей и открытые фреймворки:
* [https://developer.nvidia.com/cublas cuBLAS] - библиотека от Nvidia позволяющая эффективно перемножать матрицы.
 
 
* [https://developer.nvidia.com/cuda-toolkit CUDA] - язык параллельного программирования/вычислительная платформа для вычислений общего назначения на графическом процессоре
 
* [https://developer.nvidia.com/cuda-toolkit CUDA] - язык параллельного программирования/вычислительная платформа для вычислений общего назначения на графическом процессоре
 +
* [https://developer.nvidia.com/cublas cuBLAS] - библиотека представляет собой реализацию BLAS (базовых подпрограмм линейной алгебры) поверх среды выполнения CUDA.
 
* [https://www.khronos.org/opencl/ OpenCL] - фреймворк для написания компьютерных программ, связанных с параллельными вычислениями на различных графических и центральных процессорах, а также FPGA
 
* [https://www.khronos.org/opencl/ OpenCL] - фреймворк для написания компьютерных программ, связанных с параллельными вычислениями на различных графических и центральных процессорах, а также FPGA
 +
 +
Пример перемножения матриц на cuBLAS
 +
  void gpu_blas_mmul(cublasHandle_t &handle, const float *A, const float *B, float *C, const int m, const int k, const int n) {
 +
      int lda = m, ldb = k, ldc = m;
 +
      const float alf = 1;
 +
      const float bet = 0;
 +
      const float *alpha = &alf;
 +
      const float *beta = &bet;
 +
      // Do the actual multiplication
 +
      cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
 +
  }
 +
 +
Пример перемножения матриц на PyCUDA
 +
  import pycuda.gpuarray as gpuarray
 +
  import numpy as np
 +
  import skcuda.linalg as linalg
 +
  # --- Initializations
 +
  import pycuda.autoinit
 +
  linalg.init()
 +
 
 +
  A = np.array(([1, 2, 3], [4, 5, 6])).astype(np.float64)
 +
  B = np.array(([7, 8, 1, 5], [9, 10, 0, 9], [11, 12, 5, 5])).astype(np.float64)
 +
 
 +
  A_gpu = gpuarray.to_gpu(A)
 +
  B_gpu = gpuarray.to_gpu(B)
 +
 
 +
  C_gpu = linalg.dot(A_gpu, B_gpu)
 +
 
 +
  print(np.dot(A, B))
 +
  print(C_gpu)
  
 
=== Параллелизм SGD ===
 
=== Параллелизм SGD ===
Строка 51: Строка 81:
 
== Источники информации ==
 
== Источники информации ==
 
# [http://www.cs.cornell.edu/courses/cs4787/2019sp/notes/lecture1.pdf Principles of Large-Scale Machine Learning]
 
# [http://www.cs.cornell.edu/courses/cs4787/2019sp/notes/lecture1.pdf Principles of Large-Scale Machine Learning]
 
+
# [https://docs.nvidia.com/cuda/pdf/CUBLAS_Library.pdf cuBLAS library user guide]
 +
# [https://solarianprogrammer.com/2012/05/31/matrix-multiplication-cuda-cublas-curand-thrust/ Matrix multiplication on GPU using CUDA with CUBLAS]
 +
# [https://medium.com/@CIulius/a-short-notice-on-performing-matrix-multiplications-in-pycuda-cbfb00cf1450 A short notice on performing matrix multiplications in PyCUDA]
 +
# [https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html CUDA C++ Programming Guide]
 
[[Категория: Машинное обучение]]
 
[[Категория: Машинное обучение]]

Версия 20:49, 22 апреля 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 легко распараллеливаются на несколько потоков, каждый из которых работает на своем разбиении данных

ParallelCrossValidation.png

Параллелизм GPU

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

Фреймворки машинного обучения, такие как TensorFlow, PyTorch и MxNet используют эти возможности через библиотеки от компаний производителей графических ускорителей и открытые фреймворки:

  • CUDA - язык параллельного программирования/вычислительная платформа для вычислений общего назначения на графическом процессоре
  • cuBLAS - библиотека представляет собой реализацию BLAS (базовых подпрограмм линейной алгебры) поверх среды выполнения CUDA.
  • OpenCL - фреймворк для написания компьютерных программ, связанных с параллельными вычислениями на различных графических и центральных процессорах, а также FPGA

Пример перемножения матриц на cuBLAS

 void gpu_blas_mmul(cublasHandle_t &handle, const float *A, const float *B, float *C, const int m, const int k, const int n) {
     int lda = m, ldb = k, ldc = m;
     const float alf = 1;
     const float bet = 0;
     const float *alpha = &alf;
     const float *beta = &bet;
     // Do the actual multiplication
     cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
 }

Пример перемножения матриц на PyCUDA

 import pycuda.gpuarray as gpuarray
 import numpy as np
 import skcuda.linalg as linalg
 # --- Initializations
 import pycuda.autoinit
 linalg.init()
  
 A = np.array(([1, 2, 3], [4, 5, 6])).astype(np.float64)
 B = np.array(([7, 8, 1, 5], [9, 10, 0, 9], [11, 12, 5, 5])).astype(np.float64)
  
 A_gpu = gpuarray.to_gpu(A)
 B_gpu = gpuarray.to_gpu(B)
  
 C_gpu = linalg.dot(A_gpu, B_gpu)
  
 print(np.dot(A, B))
 print(C_gpu)

Параллелизм SGD

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

Еще более интересная идея (называемая асинхронным SGD или Hogwild): Несколько потоков запускают SGD параллельно без какой-либо синхронизации. Теперь условия гонки могут возникнуть, но оказывается, что во многих случаях это хорошо, шум/ошибка в условиях гонки просто добавляет небольшое количество к шуму/ошибке, уже присутствующей в алгоритм из-за случайной выборки градиента.

Источники информации

  1. Principles of Large-Scale Machine Learning
  2. cuBLAS library user guide
  3. Matrix multiplication on GPU using CUDA with CUBLAS
  4. A short notice on performing matrix multiplications in PyCUDA
  5. CUDA C++ Programming Guide