hpcs-16-mic-v2

Speedup of deep neural network learning on the MIC-architecture
git clone https://git.igankevich.com/hpcs-16-mic-v2.git
Log | Files | Refs

main-old.tex (23950B)


      1 \documentclass{article}
      2 \usepackage{pmstyle}
      3 
      4 \begin{document}
      5 %\hyphenation{СПбГУ}
      6 
      7 % УДК для статьи берется со страницы http://udc.biblio.uspu.ru/
      8 \udk{УДК 004.051}
      9 
     10 \author{Милова~Е.\:А., Свешникова~С.\:Ю., Ганкевич~И.\:Г.}
     11 %, Дегтярев~А.\:Б.
     12 %%%%%%%%%   Название статьи
     13 \title{Ускорение обучения глубокой нейронной сети \\ путем оптимизации алгоритма \\ для запуска на MIC архитектуре}
     14 
     15 %подпись внизу страницы
     16 \renewcommand{\thefootnote}{ }
     17 {\footnotetext{{\it Милова Евгения Андреевна} -- студент, Санкт-Петербургский государственный университет; e-mail: milova.evg@gmail.com, тел.: +7(911)038-38-35}}
     18 {\footnotetext{{\it Свешникова Светлана Юрьевна} -- студент, Санкт-Петербургский государственный университет; e-mail: svetasvesh@yandex.ru, тел.: +7(812)428-47-83}}
     19 {\footnotetext{{\it Ганкевич Иван Геннадьевич} -- аспирант, Санкт-Петербургский государственный университет; e-mail: i.gankevich@spbu.ru, тел.: +7(812)428-47-83}}
     20 %{\footnotetext{{\it Дегтярев Александр Борисович} -- профессор, Санкт-Петербургский государственный университет; e-mail: deg@csa.ru, тел.: +7(812)428-47-83}}
     21 
     22 %сборка заголовка
     23 \maketitle
     24 
     25 %рекомендация научрука
     26 \recprof{Дегтяревым~А.\:Б.}
     27 
     28 \razdel[n]{Введение}
     29 Глубокой нейронной сетью называют перцептрон с более, чем одним скрытым (обучающим) слоем. Для обучения такой сети обычно применяется метод обратного распространения ошибки~\cite{learning-deep-architectures}. Метод обратного распространения ошибки --- итеративный градиентный алгоритм, целью которого является минимизация ошибки при обучении нейронной сети. Итерация алгоритма состоит из трех основных шагов-функций: dnnForward прогоняет через сеть обучающую выборку, получая на выходе некоторый результат; dnnBackward вычисляет ошибку,
     30 %(разницу между результатом выполнения обучающей выборки и правильным ответом)
     31 затем в каждом слое сети, начиная с предпоследнего, для каждого узла вычисляет коррекцию весовых коэффициентов; dnnUpdate обновляет веса нейронов в соответствии с вычисленной ранее поправкой. Обучение сети заканчивается, когда ошибка достигает заданного минимально допустимого значения. 
     32 Такая сеть показывает прекрасные результаты во многих областях, в том числе таких, как распознавание изображений и голоса. Однако ее недостатком является очень длительный процесс обучения. В связи с этим, было решено исследовать вопрос об эффективности работы такого вида сетей на параллельных вычислительных архитектурах.
     33 Для тестирования была взята нейронная сеть из 8 слоев (1 входящий, 6 скрытых, 1 выходящий). Для анализа результатов были выбраны такие параметры, как скорость обучения нейронной сети и точность распознавания объектов. %Сеть считается правильно обученной, если точность $\geq19$.
     34 
     35 Запуск задачи производился на процессоре Intel Xeon (спецификация указана в Таблице~1). Сначала был произведен запуск задачи с использованием только одного ядра. Затем была произведена оптимизация кода для запуска на параллельной архитектуре. Также было принято решение протестировать эффективность MIC-архитектуры для решения данной задачи. MIC (Many Integrated Core) --- архитектура, основой которой является использование большого количества вычислительных ядер архитектуры x86 в одном сопроцессоре, подключаемом к основному процессору. Характеристики используемого сопроцессора Intel Xeon Phi также указаны в Таблице~1.
     36 
     37 \Table{Характеристики вычислителей, используемых для запуска задачи.}{l p{0.7\textwidth}}{
     38 Процессор & 2$\times$Intel Xeon CPU E5-2695 v2 (12 ядер, 2 потока на ядро, 2.40ГГц ) \\
     39 Сопроцессор & Intel Xeon Phi-5110P (60 ядер, 4 потока на ядро, 1.053ГГц) \\
     40 \hline
     41 }
     42 %old-введение
     43 %В данной статье описываются методики преобразования исходного кода программы обучения нейронной сети с алгоритмом обратного распространения ошибки для запуска на архитектуре MIC. Также проведено сравнение эффективности MIC архитктуры и обычного многоядерного процессора. 
     44 %В алгоритме определены два потока: в прямом направлении передаются входные сигналы, после этого определяется выходной сигнал, из которого получается значение ошибки. Величина ошибки распространяется в обратном направлении для корректировки весовых коэффициентов сети. Выделяются три главные функции: прямой ход (dnnForward), обраный ход (dnnBackward), обновление весовых коэффициентов (dnnUpdate). Каждая следующая функция зависит от предыдущей, алгоритм обучения нейронной сети является последовательным и к нему нельзя применить стандартные методы распараллеливания. В результате основной акцент был сделан на оптимизации не в целом всего цикла обучения, а каждой функции обучения в отдельности. В ходе оптимизации необходимо было соблюдать определенную точность распознавания после обучения $\geq19$, а также анализировать скорость обучения нейронной сети.
     45 
     46 %\razdel{Подготовка к портированию}
     47  %Для получения максимального ускорения работы программы необходимо переписать код так, чтобы добиться максимального степени параллелизации.
     48 %Параметры используемых для запуска задачи CPU и сопроцессора указаны в таблице.
     49 
     50 %\podrazdel{Определение узких мест}
     51 %Для успешной оптимизации программы, необходимо сначала определить функции, на выполнение которых тратится больше всего времени. Именно эти функции следует оптимизировать в первую очередь.
     52 %Запуск исходной программы на CPU показал, что наибольшее время тратится на выполнение функций балансировки весов для минимизации средней ошибки. 
     53 %Эти функции работают с массивами. Для определения возможности векторизации, программа была запущена на исполнение в нескольких потоках с директивой OpenMP для цикла, выполняющего эти функции. Время по каждому из потоков измерялось функцией \verb=omp_wget_time=. Анализ логов показал, что время выполнения по каждому из потоков одинаковое, следовательно, можно векторизовать внутренние функции, непосредственно выполняющие работу с массивами.
     54 
     55 %\podrazdel{Векторизация внутренних функций}
     56 \razdel{Оптимизация для запуска на параллельных архитектурах}
     57 Каждое ядро процессора Intel Xeon и сопроцессора Intel Xeon Phi содержит блок векторных вычислений. За один такт процессора возможна обработка 16 32-битных чисел или 8 64-битных чисел. Векторизация кода при обработке массивов дает большой потенциал для ускорения работы программы при запуске на параллельных архитектурах.
     58 Для векторизации использовалась технология Array Notation расширения Intel Cilk Plus. Intel Cilk Plus --- расширение языков С и С++ для поддержки параллелизма, реализованное в компиляторе Intel.
     59 
     60 Для работы с массивом вместо цикла for в Array Notation используется следующая конструкция
     61 \verb=array[start_index : length]=
     62 Например, следующий код к каждому i-му элементу массива W прибавляет i-й элемент массива Wdelta
     63 \begin{verbatim}W[0:count] += Wdelta[0:count]; \end{verbatim}
     64 С помощью Array Notation можно векторизовать выполнение и более сложных операций. 
     65 Поиск максимального элемента в массиве выполняется при помощи выражения \verb=__sec_reduce_max=
     66 \begin{verbatim}const float max = __sec_reduce_max(in_vec[base:ncols]); \end{verbatim}
     67 Для суммирования элементов массива используется \verb=__sec_reduce_add=
     68 \begin{verbatim}const float sumexp = __sec_reduce_add(in_vec[base:ncols]); \end{verbatim}
     69 
     70 После проведенной векторизации, код был запущен на процессоре Intel Xeon на 12 ядрах (24 потока). Программа ускорилась в 14.5 раз, по сравнению с запуском невекторизованного кода на 1 ядре.
     71 
     72 %Запуск векторизованной версии программы на CPU показал, что векторизация не улучшила время работы. Но она дает программе большой потенциал для ускорения работы программы при запуске на MIC архитектуре. Чтобы это понять, рассмотрим некоторые особенности архитектуры сопроцессора Intel Xeon Phi.
     73 %Сопроцессор Intel Xeon Phi состоит из 60 ядер. Каждое ядро содержит блок векторных вычислений. За один такт процессора возможна обработка 16 32-битных чисел или 8 64-битных. Таким образом, векторизация кода дает теоретическое ускорение в 8-16 раз для каждого ядра.
     74 
     75 \razdel{Портирование кода на архитектуру MIC}
     76 Для работы с Intel Xeon Phi была использована offload-модель передачи данных. В режиме offload блок кода, выделенный директивой \verb=#pragma offload= \verb=target (mic)= выполняется на сопроцессоре, остальной код выполняется на основном процессоре. Также для каждой переменной необходимо указать сопроцессору размер выделяемой под нее памяти. Режим offload поддерживает 2 модели передачи данных: явную и неявную. 
     77 
     78 \podrazdel{Явная модель передачи данных}
     79 При использовании явной модели программист указывает какие именно переменные должны быть скопированы на сопроцессор. Также указывается направление копирования. Достоинством данной модели является возможность успешной компиляции кода любым компилятором, а не только Intel Compiler. Неизвестные директивы будут просто проигнорированы, без генерации ошибок, код будет скомпилирован для работы только на центральном процессоре. 
     80 
     81 Функции обучения нейронной сети вызываются внутри двух вложенных циклов. Внутренний цикл был помечен для выполнения на сопроцессоре. 
     82 % \begin{verbatim}
     83 % while ((readSize = FetchOneChunk(cpuArg, oneChunk))) {
     84 %     ...
     85 %     #pragma offload target (mic:0)
     86 %     while (FetchOneBunch(oneChunk, nodeArg)) {
     87 %         dnnForward (nodeArg);
     88 %         dnnBackward(nodeArg);
     89 %         dnnUpdate  (nodeArg);
     90 %     }
     91 % }
     92 % \end{verbatim}
     93 К сожалению, у явной модели работы с памятью есть существенный недостаток. Она поддерживает лишь побитовое копирование данных. Структура, содержащая поля-указатели, не может быть скопирована таким образом. В данной программе, все характеристики нейронной сети содержатся в структуре nodeArg. Она указывается в качестве аргумента для отправляемых на исполнение сопроцессору функций. Эта структура содержит поля-указатели.
     94 Для корректного копирования структуры nodeArg на сопроцессор необходимо скопировать по отдельности каждое ее поле, и уже на сопроцессоре собрать структуру заново.
     95 
     96 Запуск на кластере показал, что такая модель передачи данных не подходит для данной задачи. Программа выполняется лишь немного быстрее, чем на одном ядре процессора и в 12 раз медленнее, чем на всех ядрах (Таблица~2). В связи с этим, было принято решение использовать неявную модель передачи данных на сопроцессор.
     97 
     98 \podrazdel{Неявная модель передачи данных}
     99 Основным принципом работы неявной модели является использование разделяемой между CPU и MIC памяти в рамках единого виртуального адресного пространства. Данный подход позволяет работать со сложными типами данных. Таким образом отпадает ограничение, связанное с побитовым копированием, возникающее при использование явной модели. Преобразование программы осуществлялось следующим образом.
    100 \begin{enumerate}
    101 \item Используемые данные были отмечены ключевым словом\linebreak \verb=_Cilk_shared=, которое позволяет размещать их в разделяемой памяти.
    102 \begin{verbatim}
    103 nodeArg.d_B[i-1]=(_Cilk_shared
    104 float*)_Offload_shared_malloc(N*sizeof(float));
    105 \end{verbatim}
    106 \item Используемые внутри цикла обучения функции  были отмечены также как разделяемые:
    107 \begin{verbatim}
    108 #pragma offload_attribute (push, _Cilk_shared)
    109 ..
    110 #pragma offload_attribute (pop)
    111 \end{verbatim}
    112 \item Была создана отдельная функция для цикла обучения нейронной сети для ее использования в разделяемой памяти:
    113 \begin{verbatim}
    114 _Cilk_shared void dnn(NodeArg&, ChunkContainer&) {...}
    115 \end{verbatim}
    116 \item Функция, отправляемая для выполнения на сопроцессор была помечена командой \verb=_Cilk_offload:=
    117 \begin{verbatim}
    118 _Cilk_offload dnn(nodeArg, oneChunk);
    119 \end{verbatim}
    120 \end{enumerate}
    121 Стоит отметить, что неявная схема работы оказалась более проста в использовании, по сравнению с явной схемой, и позволила достичь приемлемого времени обучения. Было получено ускорение в 13.5 по сравнению с последовательной версией.
    122 
    123 \Table{Сравнение времени работы и точности обучения.}{l l p{1.2cm} p{1.5cm}l l}{
    124 Арх. & Версия программы & Кол-во потоков & Время, сек. & Ускорение & Точность \\
    125 \hline
    126 x86 & Исходная     & \noindent\hphantom{00}1 & 7952                      & $\times$\noindent\hphantom{0}1 & 19.19 \\
    127 x86 & Параллельная & \noindent\hphantom{0}48 & \noindent\hphantom{0}542  & $\times$14.7 & 18.99 \\
    128 MIC & Offload      & 240                     & 6889                      & $\times$\noindent\hphantom{0}1.2  & 20.05 \\
    129 MIC & Cilk         & 240                     & \noindent\hphantom{0}589  & $\times$13.5 & 20.05   \\
    130 \hline
    131 }
    132 
    133 \razdel[n]{Выводы}
    134 В ходе исследования было проведено тестирование задачи обучения глубоких нейронных сетей на различных вычислительных архитектурах. Результаты представлены в Таблице~2. Версия для MIC не дает прироста производительности по сравнению с параллельной версией для процессора. На это влияет много факторов, которые связаны как с особенностями алгоритма, так и с теми ограничениями, которые были поставлены при решении данной задачи. Итеративность выполнения алгоритма не дает большого потенциала для распараллеливания. Оптимизации поддается только каждый его шаг, связанный с вычислениями на матрице.
    135 %Увеличения скорости работы возможно добиться, увеличивая количество обучающих примеров, после которого производится обновление весов, но нашей целью было исследование ускорения задачи без изменения исходных данных.
    136 Полученное ускорение в 13.5 раз при запуске на MIC архитектуре по сравнению с последовательной версией в целом кореллирует с результатами, полученными в других исследованиях~\cite{dnn-xeon-phi-thesis, dnn-xeon-phi-finance}. Кроме того, не был рассмотрен native-режим работы с сопроцессором, при котором весь код запускается на сопроцессоре без использования основного процессора.  Возможно, это позволит добиться большего ускорения, но данный вопрос оставлен для последующих исследований.
    137 
    138 \razdel[n]{Заключение}
    139 Был исследован вопрос о возможности ускорения работы нейронных сетей с последовательным алгоритмом обучения, произведена оптимизация алгоритма для параллельных архитектур, указаны причины, влияющие на эффективность распараллеливания данной задачи. Также был рассмотрен вопрос эффективности MIC-архитектуры для решения данной задачи.
    140 
    141 %список литературы
    142 \begin{thebibliography}{3}
    143 \bibitem{learning-deep-architectures} Bengio~Y. Learning deep architectures for AI // Foundations and trends in Machine Learning. 2009. Vol. 2. No. 1. P. 1-127.
    144 \bibitem{dnn-xeon-phi-thesis} Viebke~A. Accelerated Deep Learning using Intel Xeon Phi. 2015.
    145 \bibitem{dnn-xeon-phi-finance} Dixon~M., Klabjan~D., Bang~J.\:H. Implementing deep neural networks for financial market prediction on the Intel Xeon Phi // Proceedings of the 8\textsuperscript{th} Workshop on High Performance Computational Finance. 2015. P.~6.
    146 \end{thebibliography}
    147 
    148 \end{document}
    149 % that's all folks