Научно-технический вебинар «Эффективные Трансформеры для длинных последовательностей»

14 сентября 2021, 17:00 MCK

О вебинаре

  • Спикер

    Валерий Лихошерстов, Кембриджский университет, Кембридж, Великобритания; рисерч Google

  • Тема

    Научно-технический вебинар «Эффективные Трансформеры для длинных последовательностей»

  • Подробнее про вебинар

    Спикер о работе:

    Последние годы Трансформеры показывают очень хорошие результаты в различных задачах, включая анализ естественных языков, компьютерное зрение, моделирование протеинов, и т д. К сожалению, сложность вычисления Трансформеров растет квадратично (O(L^2)) с ростом длины последовательности L. В данной презентации, мы обсудим зоопарк недавно предложенных методов для уменьшения вычислительной сложности Трансформеров по времени и памяти вплоть до O(L) и даже O(1).

    Презентация: https://drive.google.com/file/d/1CNnxNFX4RrKI7ieCm-fCbkvT6te1AEoj/view?usp=sharing

    Запись: https://youtu.be/0Ju6ZdzqMnU

    (00:00:00) (Начало записи)

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

    Начнем. Операция self-attention имеет следующий вид. У нас есть последовательность длины L, тогда self-attention – это операция, которая принимает на вход три матрицы: queries, keys and values; запросы, ключи и значения; Q, K, V. Матрицы размера L х d. L для последовательности d – это длина векторов. У всех трех матриц в строках записаны номера запросов, ключей и значений. И d – это длина этих векторов. Тогда операция self-attention – это запрос – дифференцируемый словарь. То есть операция, которая на выход возвращает тоже матрицу в размерах L х t, где каждая строка соответствует запросу, который поступают на вход в соответствующем месте матрицы Q. И мы используем этот вектор, чтобы делать запрос в дифференцируемый словарь.

    И это производится следующим образом. Мы берем скалярное произведение всех ключей в словаре с этим запросом, затем делим это на корень из d. Это просто нужно для стабильности на практике. Затем берем экспоненту от всех скалярных произведений и затем это нормализуем, чтобы суммировалось в единицу. И потом мы эти веса используем, чтобы взять взвешенную сумму всех значений в словаре.

    И есть два типа self-attention: это undirectional self-attention, однонаправленный self-attention, и bidirectional self-attention, двусторонний self-attention. Они отличаются это тем, что undirectional self-attention – это когда мы берем значения и ключи только на префиксе последовательности до данного элемента, в котором мы стоим, до данного запроса. А bidirectinal self-attention – это когда мы берем ключи и значения по всей последовательности.

    Можете меня перебивать, если что-то непонятно. Если это, возможно, в чате как-то.

    Далее. Это просто матричная иллюстрация операции self-attention. Мы берем матрицу Q и K, берем их матричное произведение, получаем матрицу размера L на L. Затем  мы берем экспоненту, не матричную экспоненту, а просто в каждом элементе матрицы берем экспоненту. Далее мы это нормализуем по строкам и умножаем на матрицу V. Это будет bidirectinal self-attention. Чтобы получить undirectional self-attention, мы опять берем произведение Q на K, затем мы берем экспоненту по-элементно, затем мы применяем к получившейся матрице размера L на L операцию tril. Tril – это когда мы просто зануляем все элементы выше главной диагонали. После этого мы снова нормализуем и получаем матрицу, в которой ненулевые элементы только могут толька на диагонали или ниже и снова умножаем на V.

    Далее. Определение трансформера. Еще могу прокомментировать, в чем различия bidirectinal и undirectional self-attention. Undirectional self-attention обычно используется для авторегрессивного моделирования последовательности, то есть когда мы моделируем, вводим некоторое вероятностное распределение на каждый элемент последовательности при заданном префиксе последовательность да заданного элемента. И таким образом авторегрессивное моделирование – когда мы генерируем строку, итерируемся по каждому элементу и генерируем каждый элемент при условии данных элементов до него.

    (00:04:51)

    Далее. Слой трансформера имеет следующий вид.  выражение 3 – 6. Слой трансформера состоит из двух частей. Первая часть – MultiHeads of Attention и вторая часть – fit forward network (00:05:07). MultiHeads of Attention – здесь записано так, что мы из X с чертой получаем X в результате применения слоя. Сначала в первой части мы берем MultiHeads of Attention от X с чертой, когда мы применяем несколько операций self-attention, в которых Q, K и V мы берем просто линейные проекции проекции X с чертой. Линейные проекции при этом мы считаем так: просто берем каждую строку X с чертой и применяем линейную проекцию. Таким образом мы берем разные веса этих линейных проекций и получаем разные матрицы Q, K и V.

    И далее еще в MultiHeads of Attention мы применяем комплектацию сколько даже несколько раз и каждый раз мы берем разные веса, которые обучаются. Затем мы это все конкретизируем, применяем layer-нормализацию и добавляем skip connection (00:06:15).

    Во второй части мы берем полученное представление H – выражение 4 – r нему применяем fit forward network. Это просто применение персептрона с одним скрытым слоем и GeLU-функция активации. Мы применяем такой персептрон к каждой строке, затем мы делаем layer normalization и опять skip connection добавляем. Такой вид имеет слой трансформера. А сам трансформер – это просто композиция нескольких таких слоев с разными параметрами.

    Также существуют разные виды топологии трансформеров. Первая топология – это декодерованная топология. Это описанный только что мной трансформеры, в котором в качестве self-attention мы используем undirectional self-attention. И такой трансформер используется как раз, как я уже сказал, для задач авторегрессивного моделирования, например, language modeling, потому что нам нужно использовать undirectional self-attention, чтобы аутпут в каждой позиции последовательности зависел только от инпутов на префиксе до данной позиции. И аутпут будет задавать вероятность распределения на выход следующей последовательности.

    Далее еще есть энкодер/декодер – это когда у нас есть инпут, он поступает сначала в энкодер. Энкодер – это тоже несколько слоев трансформера, в которых мы используем bidirectional self-attention. Затем есть еще вторая часть – это декодер, который опять же последовательность слоев трансформера, который чуть другой. Там уже есть три компоненты. Сначала идет undirectional self-attention, замет cross-attention. Сross-attention отличается от self-attention тем, что запросы поступают из декора, а ключи и значения поступают из энкодера.

    Есть несколько таких слов в декодере. И таким образом с помощью такой топологии мы можем моделировать авторегрессивное расстояние на выходе при условии заданного  входа, инпута. Такая топология используется в задачах sequence to sequence, например, машинный перевод, когда у нас есть заданная строка на одном языке, и нам нужно ее перевезти в сроку на другом языке.

    Далее последний тип – это encorder only. Это похожий на decoder only c тем отличием, что используется bidirectional self-attention. На практике такое используется для задач классификации текста или любого другого входа. Мы берем текст и прогоняем его через такой трансформер. И на выходе получаем класс, который нужно было предсказать. Также encorder only архитектура используется в BERT. BERT – это алгоритм pretraining трансформера на большом корпусе текстов, когда на вход поступают строки, в которых случайно некоторые некоторые элементы последовательности заменены на специальные mask talking. И на выходе нам нужно восстановить, что на самом деле было вместо этого mask talking настоящий talking.

    (00:10:47)

    Модератор: И трансформеры важно изучать, потому что они state of the art качество на многих задачах, в разных доменах, на разных данных. Например, в NLP, в анализе естественных языков трансформер лучше всего работает для large-scale language modeling, известный GPT-3. Также они лучше всего работают в машинном переводе, question answering и  general language understanding и так далее, там много всего.

    Также трансформер применяется в компьютерном зрении и применяется все больше и больше. Трансформеры сейчас сравнимы или даже лучше по качеству, чем конвуляционные (00:11:44) нейросети в задаче классификации изображений. Также трансформеры используются в других задачах таких, как object detection, segmentation, generative modelling. То есть опять генерация изображений, авторегрессивная генерация, когда мы берем изображение, сначала выравниваем в строку, а затем генерируем каждый пиксель по очереди. Также трансформеры используются для point cloud processing, video prediction,  video classification и так далее.

    И третье: трансформеры используется в машинном в приложениях биологии. Например, protein folding plroblem – это задача, когда есть протеин, белок, заданный в виде последовательности аминокислот, и нужно предсказать матрицу расстояние между элементами белка. То есть как он будет в пространстве выглядеть. Также существует задача protein modelling, который просто белок, представленный в виде последовательности аминокислот. И таких белков очень много, просто нужно научиться моделировать, делать language modelling таких белков.

    Еще есть protein structure and function prediction – когда на вход подается белок в виде последовательности, и нам можно предсказать его структуру либо функции. Везде в таких задачах используются трансформеры.

    Давайте еще раз посмотрим на определение self-attention. И легко видеть, что чтобы нам посчитать self-attention, нам нужно… Допустим, мы стоим в данном элементе последовательности, и нам нужно либо посмотреть, обойти весь префикс последовательности, то O от L элементов,  либо всю последовательность, L элементов. И так как таких операций нам нужно привести для каждого элемента последовательности, получается, что чтобы посчитать self-attention, нам нужно потратить O от dL квадрат времени. И это сложно, когда L для последовательности очень большая. Но при этом такие ситуации могут возникать на практике, например, в анализе естественных языков мы можем хотеть анализировать длинные тексты. Есть PG-19 – это датасет произведений классической литературы, в котором средняя длина последовательности 69 000. И понятно, что 69 000 в квадрате это немного многовато, и мы будем очень долго ждать, когда self-attention посчитается.

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

    (00:15:30)

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

    Первый эффективный трансформер – это Sparse transformer. Его удобнее объяснять на примере генерации изображений. Картинка (a) сверху – это то,  как мы генерируем изображение, просто идем по пикселям и генерируем каждый, при том, что предыдущий пиксели уже сгенерированны. Понятно, что для каждого пикселя нам нужно посмотреть на все предыдущие пиксели. И в результате получается, снизу нарисована, матрица внимания. И понятно, что это тоже квадрат от L, то O от L квадрат вычислений.

    Что предлагается в Sparse transformer? Давайте вместо того, чтобы смотреть на все пиксели, будем смотреть только на предыдущую, как здесь показано, строку либо только на столбец над этим пикселем, либо на самый крайний правый столбец до этого киселя. И таким образом, понятно, что в каждой строке у нас вместо O от L, недолевых элементов матрицы внимания будет O от корень из L. Итого получается O от L корень из L вычислений, чтобы почитать self-attention, что уже гораздо быстрее.

    И авторы показывают, что Sparse transformer работает хорошо на различных задачах генерации, например, генерация изображений на датасетах CIFAR-10 и ImageNet, также генерация текстов на Enwik8 и даже генерация классической музыки.

    Далее у нас идет трансформер XL, который борется с так называемой проблемой фрагментацией контекста. Самый простой вариант, как можно скармливать длинную последовательность в трансформер – это просто порезать на куски и скармливать каждый отдельный кусок. Здесь на иллюстарции последовательность состоит из восьми элементов. Допустим, восемь это много, тогда мы делим последовательность на два части по четыре элемента и скармливаем их отдельно трансформеру. Тогда получается проблема фрагментации контекста, потому что когда мы анализируем, скармливаем трансформеру второй кусок, у нас есть первый элемент второго отрезка, который не получает на вход… который мы считаем undirectional self-attention, и он не смотрит ни на какие предыдущие элементы из того, что мы разрезали последовательность.

    И это проблема, потому что во время обучения получается, что мы теряем полезную информацию. Далее во времени инференса тоже есть проблема, возникающая из-за того, как мы генерируем последовательность. У нас был отрезок из четырех элементов. Сначала мы генерируем первые четыре элемента, затем берем последние три из этих четырех. И при условии этих трех генерируем следующий пятый элемент и так далее. И таким образом, чтобы сгенентренировать каждый элемент, нам нужно прогнать трансформер по всему этому отрезку длины 4, что может быть долго.

    Поэтому в трансформере XL предлагается следующая идея: давайте вместо такого подхода будем делать следующее. Мы взяли последовательность, ее раздели на отрезки. Теперь будем опять итерироваться по каждому отрезку, но когда мы будем прогонять трансформер, мы будем прогонять не только по этому отрезку, а по нему плюс предыдущий отрезок. При это loss, а также градиент мы будем только считать по второму отрезку.

    (00:20:19)

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

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

    Авторы проверяют то, что их метод работает хорошо на генерации текста на датасетах WikiText, Enwik8, Text8 и One Billion Words Benchmark.

    Следующее по очереди – это Reformer. Давайте перепишем определение undirectional self-attention следующим образом. Сначала введем матрицу А, которая вводится так – берем Q и K transposed произведение, делить на корень из d, а затем экспоненту. И такая матрица A размера L на L – неотнормализованная матрица внимания.

    Тогда определение undirectional self-attention можно переписать следующим образом. Мы берем, во-первых, трил от А, измеряем все элементы выше диагонали и затем мы нормализуем все элементы А по строкам. Это можно представить просто как умножение трил от А слева на инвертированную диагональную матрицу трил А, где по диагонали стоят элементы трил А, умноженные на вектор из единицы. То есть легко понять, что мы просто посчитали сумму всех элементов в каждой строке. И затем мы эту сумма инвертировали, сделали 1 делить на эту сумму и умножили на каждую строку трил А. И затем все это получившееся умножаем на матрицу V, матрицу значений.

    Из такой записи легко понять, что нам нужно применять линейный оператор трил А быстро и эффективно, чтобы быстро считать self-attention. Мы будем использовать следующий подход. Мы будем патинировать эту матрицу А с помощью sparse-разреженной матрицы. В Sparse transformer мы делали то же самое с отличием, что здесь sparse-матрица будет зависеть от входа. Она будет зависеть от матриц Q и K. То есть она динамическая, а не статическая как в Sparse transformer.

    Как это делать? Мы будем аппроксимировать трил А sparse-матрицей, в котором будем замерять просто все элементы изначальной матрицы, которые не очень большие, они меньше, чем другие элементы. Так как экспонента – это монотонная функция, нам нужно таким образом искать пары запросов и ключей, скалярное произведение, которых сравнительно большое по отношению ко всем остальным элементам. То есть нам нужно искать ближайших соседей Q и K.

    Для поиска ближайших соседей будем использовать locality sensitive hashing. Это следующая техника. Чтобы ее использовать, нужны, во-первых, два ограничения. Нам нужно, чтобы матрица Q совпадала смотрится с матрицей K. И это ограничение легко соблюсти в трансформере. Для этого нам нужно просто приравнять соответствующие проекции. Матрицы Q и K получаются из одного представления просто применения линейной проекции. Мы просто можем просто приравнять эти линейные проекции.

    И второе условие – каждый вектор запросов у нас должен быть равен единице. Это тоже легко соблюсти, просто разделив вектор запроса на его длину.  Тогда LSH считается так: чтобы почитать значение локального хэша, мы берем каждый вектор запроса и его умножаем на некоторую случайную матрицу просто со случайными гауссовскими значения. И затем берем артмакс к получившемуся вектору. Артмакс как раз задает хэш.

    (00:25:50)

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

    И мы можем повторять такую процедуру вычисления процедуры. Мы можем повторить процедуру аппроксимации А несколько раз, сделать несколько раундов. И потом просто объединить все эти аппроксимации и получить матрицу, в которой мы имеем более точную аппроксимацию ценой того, что мы делаем больше вычислений.

    И вторая идея, которая предложена в Reformer, что можно сэкономить память, которая тратится на вычисление градиентов причем неинвертируемых слоев. То есть те слои в Reformer имеют следующих вид – выражение 11. То есть мы разделяем каждый выход слоя и вход на две части: X1 и X2 – это вход и Y1 и Y2. Происходит следующее вычисление. Y1 мы сначала считаем X1 плюс MultiHeads of Attention от X2. И Y2 – это X2 плюс FFN от Y1. И легко понять, что такой порядок вычислений инвестируемый. Зная Y1 и Y2 мы можем получить значение X1 и X2 следующим образом, как написано в выражении 12. И таким образом, мы экономим память, потому что когда мы считаем градиент, нам не нужно сохранять промежуточные значения в трансформере.

    Потому что сначала мы делаем forward pass, мы ничего не запоминаем. А чтобы делать backward pass, нам нужно знать эти промежуточные значения. Их мы можем просто посчитать путем формулы инвертирования. И таким образом, получается экономия по памяти.

    Авторы Reformer проверяют, что идея использования спарс-аппроксимации attention-матрицы хорошая. Они проверяют на эстетической задачи – копирование строки. То есть это задача, в которой на вход трансформера поступает строка вида 0ω0ω, где ω – это случайная строка со значениями от 1 до N. И loss считается на второй половине строки у нашего трансформеры, который делат autoregressive modelling. И таким образом получается, что задача трансформера – видя первую половину строки, скопировать ее во второй половине строки.

    И авторы проверяет, если трансформер на такой задаче обучить с помощью full attention, то есть полного квадратного вычисления attention, то затем во время evaluation, во время инференса можно получать хорошее качество аппроксимации. То есть чем больше LSH -раундов мы используем, тем лучше получается качество вплоть до, здесь показано, 94%.

    (00:29:55)

    Также они смотрят, если во время обучения использовать LSH с заданным некоторым количеством раундов, то во время инференса можно хорошо аппроксимировать. Можно использовать разное количество раундов, и чем больше мы используем, тем лучше получается результат на инференсе.

    Далее эта картинка – это авторы смотрят, что на задаче генерации текста на датасете Enwik8 и генерации изображений на датасете ImageNet их введенные ограничения –первое ограничение, что у нас Q и K должны совпадать, а второе, что новый дизайн слоя, который инвертируем, что введение этих ограничений не портит качество работы трансформера.

    А здесь авторы смотрят, что, если принять Reformer и сравнивать его с трансформером обычным, с квадратным self-attention, то чем больше LSH-раундов используется в Reformer, тем лучше получается результат генерации изображения на ImgaNet и текста на Enwik8. Также они показывают, что Reformer работает гораздо быстрее, чем обычный квадратичный трансформер.

    Сейчас мы пришли к Performer и FAVOR, FAVOR+. Это как раз то, чем мы занимаемся и занимались. Давайте снова запишем определение self-attention, теперь уже bidirectional self-attention через матрицу А, матрица ненормализованного self-attention. Это имеет следующий вид – выражение 14. И здесь видно, что чтобы считать двухсторонний self-attention, нам нужно применять линейный оператор А быстро. Здесь можно понять, что главная проблема – это softmax, потому что, если не было softmax, то у нас все было бы линейно. А матрица А – это было бы просто Q на K transposed, матрица низкого ранга. И тогда можно было бы использовать ассоциативность матричного умножения и записать следующим образом – выражение 15.

    То есть мы меняем порядок приложением матриц и получаем вместо сложности O(dL2) сложность O(d2L), потому что здесь в левой части матрица Q на K transposed имеет размер L на L, и получается, она имеет квадратное количество значений. А во втором варианте справа такой матрицы уже нет. И все получается гораздо быстрее. То есть O(d2L) в случае, если L сильно больше, чем d.

    Но, к сожалению, у нас есть softmax и экспонента, которые нелинейные операции. И что можно с этим сделать? Давайте возьмем произвольную пару запроса и ключа, и их скалярное произведение распишем следующим образом через квадрат нормы запроса, ключа и их разница, запрос минус ключ. И если есть такое разложение, тогда из этого разложения легко понять, что матрицу А можно разложить следующим образом: DQ на B на DK, где DQ и DK – это некоторые диагональные матрицы, в которых просто используются эти квадратные нормы Q и K из этого разложения из выражения 16. А матрица B – это матрица гауссовского ядра. Для гауссовских ядер для каждой пары включает запрос ключа.

    Так как мы разложили А следующим образом, и в этом разложение умножать  на диагональную матрицу легко, это занимает время L, здесь нам остается понять, как аппроксимировать линейный оператор B эффективно, потому что в матрице B нет нулевых элементов, она полностью не нулевая, и нужно как-то умножать на нее. И для того, чтобы аппроксимировать должным образом B, мы, во-первых, вспомним, что гауссовское ядро является положительным определенным. И будем использовать теорему Бокнера, который говорит, что любое ядро, которое имеет вид k(x,y) равно k(x-y), положительно определена только и только, если эта функция k – это разложение Фурье некоторой неотрицательной меры.

    (00:35:33)

    И понятно, что если k(x-y) правильным образом отнормировано, то эта мера является вероятностным распределением. И также мы будем использовать следующий факт, если наше ядро является гауссовским ядром, то такой мерой, таким распределением является многомерное гауссовское распределение. Здесь записали то, что мы только сейчас поняли. Мы взяли это гауссовское ядро и представили его как разложение Фурье просто гауссовского распределения. Здесь в разложение Фурье у нас присутствует комплексная экспонента, которую можно заменить просто на ее действительную часть. Так как левая часть здесь действительна, и здесь множитель тоже e-ω2, где ω – это вектор, по которому мы интегрируем. Это тоже действительная величина, поэтому можем вставить действительную часть, которая просто косинус.

    И так у нас здесь нетермированное гауссовское распределение, просто вынесем константу и представим интеграл как матожидание по гауссовскому вектору ω следующий величины  – косинус от ω transposed на разность Q и K. Также мы расспишем этот косинус разности следующим образом: как матожидание по случайной величине, которая просто равномерная случайная величина от 0 до 10, то есть просто некоторый угол. И легко доказать, что такое разложение имеет место.

    Дальше мы будем аппроксимировать эти два матожидания с помощью Монте-Карло, то есть мы будем аппроксимировать пары ω и θ некоторое количество раз и приблежать с помощью этих семплов матожидание как среднее. И это записано здесь, и это так называемый random feature approach, метод рандомных, случайных фичей. Мы будем использовать M семплов в нашей Монте-Карло аппроксимации, то аппроксимация состоит в следующей процедуре. Сначала мы заводим такие матрицей кустарником ok с домиком, который имеет следующий вид выражения 25 просто косинусы этих значений, то есть матрица зависит только от матрицы: Q с домиком и K с домиком, которые имеют следующий вид – выражение 25, просто косинусы от этих значений. То есть матрица Q с домиком зависит только от матрицы Q, а K с домиком зависит только от матрицы K.

    В этих матрицах еще используются наши семплы ω и θ. Из того, что мы обсудили легко понять, что отскалированное матожидание Q с домиком на K с домиком транспонированное равно B. Далее мы вводим матрицы Q’ и K’, просто умножаем Q с домиком и K с домиком на эти диагональные матрицы, которые были до этого. И в конце концов мы получаем, что матожидание Q’ на K’ транспонированное умножить на некоторую константу равно матрице А. И Q’ и K’ – это некоторые величины, которые мы насемплировали, мы просто берем эту матожидание и будем аппроксимировать этим произведением матриц.

    И здесь нужно понять, что эти Q’ и K’ матрицы имеют размер L на M. И если М – это количество семплов, оно небольшое в сравнении с размером последовательности, то наша аппроксимация является низкоранговой аппроксимацией матрицы А. И низкоранговый линоператор легко применять с ассоциативностью матричного умножения. И это мы здесь записали – выражение 26 и 27. То есть мы аппроксимируем двухсторонний self-attention, просто заменяя матрицу А на произведение Q’ и K’ и используем ассоциативность матричного умножения. И получаем сложность O от МdL по времени и памяти.

    (00:40:38)

    И если M сильно меньше, чем L, то это сильно лучше, чем d на L2. И далее можно спросить, насколько хороша такая аппроксимация. И здесь можно доказать теоретически, что, во-первых, наша аппроксимация несмещенная. Матожидание аппроксимации равно реальному значению, а также аппроксимация матрицы А ограничена из-за того, что мы используем косинусы, которые ограниченная функция от 1 до -1. Можно получить некоторую хорошую концентрацию около правильного ответа нашей аппроксимации.

    Также можно получить, что чтобы получить аппроксимацию заданного качества, нам нужно всего лишь O от L на логарифм d Монте-Карло семплов. Понятно, что у нашей аппроксимации есть некоторая дисперсия, и разумный вопрос, как можно еще уменьшить дисперсию? И можно ли это сделать? Ответ –  да, можно. Для этого нам вместо того, чтобы семплировать наши Монте-Карло семплы ω просто из независимого гауссовского распределения, нам нужно их семплировать так, чтобы они были ортогональные, то есть между каждой парой ω угол должен быть 90°. И тогда можно доказать, что полученная аппроксимация имеет меньшую дисперсию. И это как раз мы называем FAVOR – fast attention via orthogonal random features.

    Идем дальше. Если мы снова все это запишем, всю FAVOR аппроксимацию, как она записана здесь, мы можем заметить некоторые проблему. Проблема состоит в том, что  функция косинуса может принимать негативные значение, отрицательные, и из-за этого здесь в матрице Q и K с домиком может быть отрицательные значения. И из-за этого могут быть отрицательные значения в Q’ и K’. И далее в этом месте множители, где мы нормализуем каждую строку, чтобы она суммировалась в единицу, константа нормализации тоже может принимать отрицательное значение. Либо, так как мы в ней суммируем положительные и отрицательные числа, она может быть очень мала. И если мы на нее делим, понятно, возникают численные нестабильности и различные проблемы на практике. И мы это действительно видим на практике.

    Поэтому вместо такой аппроксимации нам хотелось бы получить другую аппроксимацию, то есть нам хотелось бы получить некоторые разложения этого скалярного произведения, получить разложение следующего вида – выражение 32. То есть нам хотелось бы его разложить на матожидание по объекту ω. Матожидание – произведения двух множителей, где каждый множитель зависит либо от Q, либо от K. Причем эти множители должны быть положительными всегда.

    Можно ли такое разложение получить? Оказывается, что можно. Для этого вспомним определение moment generating function для многомерного гауссовского распределения, оно имеет следующий вид – выражение 33. То есть просто выполняется следующее тождество: для любого вектора d у нас матожидание по многомерному гауссовскому вектору ω величины экспоненты от омега транспонированной на t, просто скалярное произведение ω и t, равно экспоненте нормы t2 делить на 2. И это выполняется для всех t.

    Поэтому давайте приравняем t к следующей величине – сумма Q и K делить на d1/4. Тогда если мы перепишем выражение 33 в таком виде, мы видим, что слева у нас будет матожидание ω от двух множителей, где каждый пользователь зависит либо только от Q, либо только от K. А справа у нас будет как раз экспонента скалярного произведения Q и K , умножить на два множителя, каждый который зависит либо от Q, либо от K.

    (00:45:30)

    И отсюда понятно, что искомая функция f имеет следующий вид – просто некоторая экспонента. Экспонента – это всегда положительное число. И такую аппроксимацию self-attention мы называем fast attention via positive orthogonal random features или FAVOR+.

    Все, что мы рассматривали до это в контексте FAVOR+ и FAVOR – это было для случая bidirectional self-attention. И вопрос, можно ли это получить для undirectional self-attention. То есть когда у нас вместо того, чтобы аппроксимировать линейный оператор А, нам нужно аппроксимировать линейный оператор трил от А. То есть когда мы зануляем все элементы выше диагонали. И если мы возьмем нашу низкоранговую аппроксимацию Q’ на K’ транспонированное, и возьмем от нее трил, то полученная матрица уже не будет низкоранговой.

    И не совсем понятно, можно ли в этом случае считать self-attention быстро. И давайте еще раз это запишем, наша полученная аппроксимация имеет следующий вид. Здесь уже мы не можем поменять ассоциативность, так у нас есть операция трил. И можем ли мы все равно сделать это эффективным? Ответ – да, можем. Для этого, чтобы понять, как посчитать в такой ситуации эффективно, мы просто можем записать выражение 39. Мы умножаем трил этой низкоранговой матрицы на матрицу V и смотрим результат в какой-то строке L. И можно понять, что этот результат – на самом деле сумма по всем предыдущим строкам – сумма векторов V, умножить на скалярное произведение запроса и ключа.

    И далее мы опять внутри этой суммы можем применить ассоциативность умножения, то есть мы скобочки можем переставить местами. И затем можем использовать дистрибутивность и вынести множитель Q за сумму. И здесь возникает эта сумма, это выражение предлагает алгоритм эффективного вычисления аппроксимации. Алгоритм имеет следующий вид. Мы будем поддерживать некую матрицу, которая будет в себе накапливать эту сумму, которая здесь указано в выражении 39 справа. То есть мы итерируемся по L по нашей последовательности. Обновляем сумму, берем этот R и прибавляем к этой матрицы R аутопродакт вектора V и K. И затем мы эту обновленную агрегацию умножаем на вектор Q, чтобы получить результат в данном элементе последовательности.

    Такой алгоритм имеет сложность про времени O от LdM, то есть так же, как и для bidirectional self-attention. И занимает памяти O от Ld плюс LM плюс dM. С таким алгоритмом есть некоторая проблема – это то, что он не параллельный. То есть нам нужно итерироваться по всей последовательности последовательно. И это может занимать много времени на практике, потому что если последовательность длинная, такая итерация может занимать много времени.

    Можем ли мы как-то этот алгоритм распараллелить? И ответ – да, можем. Для этого мы просто можно заметить, что эти векторы R, эти агрегации – это  префикс суммы. То есть у нас есть некоторая последовательность этих аутопродактов, и R – это просто префиск суммы этой последовательности. А операцию префикс суммы можно вычислять эффективно и правильно, как здесь показано на иллюстрации.

    (00:50:09)

    То есть сверху у нас вход и снизу выход. И нам нужно посчитать префикс-сумму. Давайте делать операции плюс, как здесь показано, по такому паттерну. И легко понять, что глубина такого вычисления, то есть если мы посчитаем количество шагов, то оно логaрифмическое от L, от длины последовательности. Таким образом, мы получили параллельные алгоритмы O от логарифм от L – вычисление префикс-суммы. И таким образом, мы можем аппроксимировать self-attention параллельно за O от логарифм L времени и это будет занимать памяти O от LdM.

    O от LdM – было для последовательного алгоритма, а у нас было O от LdM плюс dM плюс LM. Это просто очень частая ситуация, что чтобы что-то ускорить, нам нужно пожертвовать памятью.

    Далее мы можем эти механизмов FAVOR и FAVOR обобщить. Можем заметить, что в этих механизмах мы брали матрицу Q, ее переводили в матрицу Q’ просто путем преобразования каждой строки матрицы. И то же самое с K и K’. И вместо заданного преобразования мы можем рассматривать любое преобразование, просто функцию g, которая приводится вектор в вектор из положительных значений. Положительные значения нужны, когда мы нормализуем строки, чтобы не получилось цельное число и все было стабильно на практике.

    То есть будем применять такое отображение g. Примером этого отображения g может быть просто полинейное применение функции ReLU. И такой вид attention мы будем называть generalized attention. И архитектуру, которая использует такой attention мы будем называть Performer.

    Далее эксперименты, которые мы делали здесь мы просто измеряем время. Мы меняем длину последовательности и измеряем время forward либо past. И мы видим, что время для Performer значительно меньше становится, чем для квадратичного трансформера. И улучшение становится больше с увеличением длины последовательности. Далее мы сравнивали все возможные аппроксимации, которые мы предлагали. Первая картинка слева – мы берем random feature aproximation и сравниваем генерацию фичей независимо и ортогональную генерация ключей.

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

    Далее здесь мы просто поменяем Performer на бенчмарке LN1P и PG-19. Это текстовые датасеты с большой длиной последовательности. И Performers работают хорошо в сравнение с обычным квадратичным трансформером. Здесь мы сравнивали с Reformer.

    Следующее – это эксперименты на TrEMBL, это датасет протеинов. Здесь мы сравнивали с Reformer и с трансформер. И опять Performer имеет очень хорошее качество в сравнении с этими вариантами. Здесь результаты для генерации изображений на ImageNet и опять генерация протеинов. Опять мы сравнивали с реформами и трансформерами, и получается либо сравнимое качество, либо Performer лучше работает.

    (00:55:10)

    Есть статья Long Range Arena – это статья, в которой сравнивают все эти варианты эффективных трансформеров, предложенных в литературе. И предлагается универсальный набор задач, в которых такие архитектуры сравниваются. И в конце концов вычисляется LRA score, то есть средний score по всем задачам. И получается диаграмма. Здесь горизонталь – это скорость работы трансформера, по вертикали этот score. И по ним Performer получается, что работает быстрее всех, по этому score они где-то посередине.

    Далее последняя часть нашей презентации – это SLiM Performer. Здесь, наверное, не буду сильно вдаваться в детали, просто эти уровни объясню. Идея здесь в том, что Performer, который только что обсуждали, у него время и память растут как O от L, имеют линейный рост. И можно еще дальше улучшить вычислительную сложность, можно Performers вычислять за линейное время, но используя константную память от 1. Идея здесь в том, что можно переписать каждый слой Performer таким образом, что весь propagation, весь сигнал, который идет вдоль последовательности, можно взять, что идет внутри операции перфикс-суммы.

    Получается, что эта операция префикс-суммы хорошая в том смысле, что, во-первых, она дает некоторый _____ (00:57:14). То есть каждый элемент префикс-суммы можно рассматривать как bottle neck, например, в рекурентных нейросетях есть промежуточное значение. А, во-вторых, она еще инвертируемая в некотором смысле. То есть можно использовать следующий алгоритм. Похоже на трансформер XL, только в трансформере XL используется аппроксимация, а здесь нет никакой аппроксимации. Мы можем точно вычислять градиент по всей последовательности.

    Мы берем последовательность, ее опять делим на подотрезки. И затем будем вычислять чтобы отрезки константной длины. Затем мы итерируемся по каждому отрезку и сначала делаем forward pass, мы делаем проход по трасформеру по этому отрезку и сохраняем значение префикс-суммы, которое получается после этого отрезка. Затем на втором отрезке мы можем переиспользовать промежуточное значение префикс-суммы, чтобы его обновить и получить следующее значения. То есть некоторый алгоритм динамического программирования.

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

    А также мы можем посчитать градиент по параметрам и градиент по префикс-сумму и также его обновить, потому что во время back propagation мы также поддерживает значение градиента по префикс сумме, мы его обновляем. И таким образом, мы итерируемся сначала вперед, потом назад, но мы никогда не храним в памяти представления для всей последовательности. Мы только храним для каждого отрезка в отдельности, которой имеет константную длину. Таким образом, мы получаем О от dL по памяти, но при этом время алгоритма также линейно. И в этом идея.

    (01:00:07)

    Это интересно с той точки зрения, что для того же Performer мы поняли, что у нас время и память от L. Также для рекуррентных нейросетей тоже легко понять, чтобы просто посчитать градиент, нам нужно O от L времени по памяти. Для квадратичного трансформера у нас получается O от L2, а для этого алгоритма получается O от L по времени и O от L по памяти, некоторое улучшение.

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

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

    Второе – это кватизация. Это когда у нас есть параметры, которые хранятся в off-load, то есть на каждый параметр тратится 4 байта. Давайте вместа переведем его в half precision: будем 2 байта либо 1 байт, либо 1 бит вообще. Понятно, если мы так сконвертируем, то качества работы сети упадет. И поэтому там нужно еще применять некоторые трюки, чтобы получить такое же количество, как-то дообучать.

    Четвертое – это neural architecture search – это автоматизированный поиск архитектуры, которая работает лучше всего и которая также наиболее быстрая, занимает меньше вычислений.

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

    Модератор: Валерий, спасибо большое. У нас есть некоторые вопросы. Но до того, как мы перейдем к вопросам, я попробую коротенько в трех предложениях изложите суть вашей работы, а вы скажете, правильно или нет. Никто не знает, почему авторы трансформеров вставили туда экспоненту, но вроде работает. Давайте попробуем эту экспоненту заменить на что-нибудь, что вычисляется попроще. Оно будет все равно работать, может быть, работать похуже, но зато быстрее. Правильно я понимаю?

    Валерий Лихошеров: Если мы экспоненту заменяем на любую нелинейную функцию, то непонятно, как аппроксимировать, то есть как это считать быстрее.

    Модератор: Вы заменили на нелинейную функцию, которая ReLU, и ее понятно, как считать быстрее, но теоретически могли бы заменить на другую любую функцию.

    Валерий Лихошеров: Если просто заменить экспоненту на ReLU, то все равно будет квадратичная скорость, потому что надо все равно будет все перевычислять. Скорее мы вместо экспоненты или другой функциям просто берем линейную функцию. Просто не применяем никакую функцию, и тогда у нас нет этого Q на K транспонированное, а затем нелинейность. То есть у нас просто есть Q на K транспонированное. И так как нет никакой транспоненты, никакое нелинейности, то мы можем применить, когда мы потом еще умножаем на V, то есть у нас произведение трех матриц, мы можем использовать ассоциативность матричного умножения. И в результате нам не нужна считать матрицу размера L на L, потом на нее умножать.

    Модератор: Окей, спасибо. Давайте тогда пойдем к вопросам. У нас в Q&A есть ряд вопросов. Никита барсуков спрашивает: «Когда мы работаем с длинными последовательностями, мы хотим учитывать большой контекст. Трансформер XL, получается, обрезает этот контекст, и мы его не используем. Это не идет в противоречие с задачей?»

    Валерий Лихошеров: Хороший вопрос. На самом деле трансформер XL можно сказать, что хоть мы и рассматриваем данный отрезок и предыдущий, а еще дальше в прошлое мы не смотрим. И поэтому можно сказать, что мы все равно в некотором смысле обрезаем. Я согласен. Единственное, что что лучше в трансформер XL по сравнению со стандартным подходом, который был до этого, это то, что действительно решается проблема фрагментации контекста, потому что, как я уже говорил, есть первый элемент в отрезке, и здесь он вообще ни на что не смотрит.

    И это проблема, потому что мы теряем полезную информацию, потому что существуют элементы до него в последовательности. А в трансформере XL эта задача решается, потому что здесь мы смотрим на предыдущие отрезки. Так мы берем два отрезка и конкретизируем, вычисляем трансформер. Но loss и back-propagation мы только считаем по второй части отрезка. И поэтому во второй части отрезка для каждого элемента у нас существует достаточное количество элементов до него. И поэтому проблема фрагментации контекста решается.

    А действительно, существует ли у нас propgation сигнала по всей последовательности, здесь я согласен, что его нет.

    Модератор: Спасибо. Юлия Гусак спрашивает: «Упомянули, что матрица Q и K транспонированная является малоранговой. Это всегда независимо от задачи?»

    Валерий Лихошеров: Да, это не всегда так, потому что у Q и K, если мы говорим не про FAVOR, а просто про Q и K, то у них размер L на d, L – это длина последовательности, а d – обычно на практике всегда 64. То есть если предположить, что длина последовательности меньше 64, то, конечно, у нас не получается малоранговой матрицы. Но на практике, конечно, обычно длинее, чем 64. Обычно длина начинается от 512.

    Если мы говорим про FAVOR аппроксимацию и FAVOR+, то уже нужно говорить не про Q и K, а про Q’ и K’, у которых размер L на M, где M – это количество Монте-Карло семплов.  Здесь уже на практике мы обычно использовали количество семплов 384, по-моему, стандартное количество было. То есть, когда длина последовательности больше, чем 384, в теории должно получаться улучшение по времени. Если меньше, то нет смысла использовать.

    Модератор: Спасибо. Прохор Гладких спрашивает: «В статьях про эффективные трансформеры часто бенчмарки ставяся на не совсем традиционных датасетах. Есть ли эффективные трансформеры, которые показывают хорошие результаты на NLP задачках?»

    (00:01:05)

    Валерий Лихошеров: То есть авторы используют language modelling, который, наверное, можно назвать NLP. Я согласен, что применение всех этих эффективных трансформеров… То есть нам всегда нужно рассматривать длинные последовательности. Обычно до обсуждения всех этих эффективных трансформеров обычные последовательности были не очень длинные: 512, 1024 и вроде того. Но понятно, что, наверное, существуют задачи, в которых последовательности будут гораздо длиннее. И в них обычный квадратичный трансформер будет просто невозможно использовать, потому что будет очень долго, у нас не хватит памяти, будут memory errors. И там уже нужно будет уже использовать все эти техники. Я согласен, что еще все впереди. И появятся такие проблемы, где это будет очень нужно использовать.

    Модератор: Тут Артур Паняков задает связанный вопрос: «В каких приложениях действительно нельзя обойтись без длинного контекста? В NLP можно разбить текст, в _____ (01:11:38) необязательно обрабатывать изображения попиксельно. В биологии, видимо, нужно действительно учитывать весь контекст. Есть ли еще что-нибудь?»

    Валерий Лихошеров: Как раз биология то, о чем я думаю. Там действительно нужно учитывать весь контекст, потому что в этом протеине или в геноме так получается, что аминокислоты очень локально могут располагаться. И две аминокислоты, которые очень далеко друг от друга расположены, они как-то друг на друга очень влияют. И я бы сказал, что это одна задача, и она уже сама по себе, все эти приложения в биологии – это уже очень важно. И мы тоже этим занимаемся.

    Модератор: Здесь я могу какие-нибудь еще примеры привести. Например, есть задача minutiong, когда у нас есть транскрипт какого-то совещания, и мы хотим из него построить протокол совещания. Поскольку совещания бывают очень длинными, по нескольку часов, а протоколы у них все равно довольно короткие. То понятно, что в подобных задачах длинный контекст тоже может быть полезен.

    Прохор Гладких в ту же сторону говорит: «Нам интересно в частности использование эффективных трансформеров для name ______ recognition (01:13:28) из-за длинных контекстов. Пока у нас успешно используется только Longformer. Какие эффективные трансформеры еще посоветуете использовать для name ______ recognition?»

    Валерий Лихошеров: Так сложно сказать, не поставив эксперимент. Я бы сказал, что просто можно пробовать все, что есть, и что-то будет лучше работать. Чем больше попробуете, тем результат может только улучшиться. Сложно сказать, какой из них будет лучше всего работать. Нужно пробовать, все зависит от имплементации, от разных тонкостей. Могу, конечно, посоветовать Performer. Я им тоже занимался. И то, что мне нравится в Performer по сравнению с другими вариантами, по сравнению с Reformer, со sparse-решениями, что его очень легко реализовать – буквально перемножение матриц некоторое. В любом _____ (01:14:39), везде это присутствует и очень легко, просто будет десять строк кода.

    Модератор: А у Hagen Face есть уже реализованные Performer?

    Валерий Лихошеров: Да, есть.

    Модератор: Видите, как здоровье. Спасибо. Юлия Гусак спрашивает… Извините, Юля, только дошли до вашего вашего вопроса, перескакивая с одного места на другое. «Не могли бы пояснить, пожалуйста, почему SLiM Performer отличается от простого применения техники сheck pointing трансформер, когда часть активов активации на форварде сохраняется, чтобы уменьшить память для хранения графа, необходимого на бэкворде?»

    (01:15:23)

    Валерий Лихошеров: Можно было проще всего объяснить идею SLiM Performer, если начинать от сheck pointing. Сheck pointing – это когда мы идем по последовательности и опять же разбиваем последовательность на чанки некоторые, на подотрезки, и сохраняем это значение префикс-суммы только в конце чанка. И в результате, когда мы сделали forward pass, у нас будет сохранено количество промежуточных префикс-сумм столько же, сколько этих чанков. Это сheck pointing.

    А затем в back propagation мы используем сохраненные значения, чтобы восстановить значения там, где мы не сохранили. Отличия в том, SLiM Performer лучше тем, что нам не нужно сохранять эти промежуточные значения, потому что мы можем их пересчитать. У нас есть последовательность промежуточных значений, и мы их не храним, а храним только одно, которое в конце. И по нему с помощью инвестируемости префикс-суммы можем восстановить все значения предыдущей префикс-суммы. И так далее. То есть сложность теоритическая – это корень из N – это если мы берем все отрезки размером корень из N, и получается, нам нужно хранить корень из N префикс-сумм. То есть это сложность по памяти.

    А у  SLiM Performer сложность памяти от одного, потому что нам не нужно хранить. Мы храним только один. И в этом отличия.

    Модератор: Спасибо. Есть у вас еще вопросы? В чате Сергей Аверкиев спрашивает: «То есть 69 000  – это длина всего произведения? А для чего считать attention сразу на всем тексте?»

    Валерий Лихошеров: Как мы уже обсуждали, если мы просто будем считать только локальный attention, возможно, упустим какую-то важную информацию, контекст, который есть, важную информацию, которая расположена дальше нашего локального контекста. И поэтому хочется это учитывать.

    Модератор: Андрей Ануфриев спрашивает: «Где можно узнать про look-ahead для трансформера, например для задач speech recognition?»

    Валерий Лихошеров: Что такое look-ahead, не совсем понял?

    Модератор: Андрей, поднимите руку, если вы еще с нами, я дам вам возможность говорить. Но кажется, его с нами уже нет. А, есть. Нет, это не он. Это Роман Шуцкий поднимает руку и хочет что-то сказать. Роман, пожалуйста.

    Роман Шуцкий: Я как раз speech recognition занимался и разбирал эти трансформерные архитектуры. Look-ahead, то есть задачи распознавания речи — обычно, что люди хотят, чтобы как только к ним приходил аудиосигнала, они сразу же получали его расшифровку, моментально. Но для моделей получается сделать это довольно сложно, потому что не всегда хватает только прошлого контекста для того, чтобы без ошибок предсказать, что это за буква будет в данный момент времени.

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

    (01:20:00)

    Модератор: Роман, это вы в рамках не CTC loss, a sequence-to-sequence loss?

    Роман Шуцкий: Да, это именно в sequence-to-sequence loss есть, а CTC loss как раз и отличается тем, что он предсказывает сразу же в данную минуту.

    Модератор: Да.

    Валерий Лихошеров: Я могу прокомментировать. Наверное, вопрос про то, можно ли обобщить — мы  рассмотрели bidirectional и unidirectional self-attention — еще одну такую маску attention? И понятно, что можно обобщить sparse-трансформер, реформеры. Кажется, понятно, что можно. И можно и в Performer тоже. Для этого, что нужно делать? Как это объяснить…

    Модератор: Проще всего, наверное, на Sparse-трансформере объяснить, потому что есть ленточные матрицы, у которых вне диагональные элементы равны нулю вне некой ленты вокруг диагонали, поэтому, если мы для Sparse-трансформера возьмем такую ленту, по всей видимости, это будет являться как раз такого рода обобщение с ограниченным заглядываем вперед.

    Валерий Лихошеров: Я бы сказал, что это просто можно представить как обычный unidirectional трансформер весь этот look-ahead, потому что просто мы считали префикс последовательности. Неважно, где он останавливается, мы считали с этим look-ahead, и нам нужно что-то вернуть.

    Как будто мы сделали некоторый shift, и можно использовать такой же трансформер обычный.

    Модератор: Идея интересная, забавная, можно пробовать. На распознавание речи, по-моему, такого… Роман, вспомните что-нибудь такое в распознавание речи?

    Роман Шуцкий: Да, есть, конечно, статьи про применении трансформеров в распознавании речи…

    Модератор: С фиксированным заглядываем вперед.

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

    Модератор: Нет, по идее конформеры довольно широко сейчас, модная тема в распознавание речи.

    Роман Шуцкий: Да, в основном использование трансформеров в распознавание речи происходит так: берется backbon модель, она постепенно обрабатывает фичи, стоят несколько слоев self-attention. И в итоге все агрегируется и подается в тот же CTC loss на выходе или в другую схему sequence-to-sequence. То есть не используется sequence-to-sequence, а возможность трансформера самого. Там он не так применяется.

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

    Алексей Пискунов спрашивает: «Извините, может быть, некорректно понимаю, но к моменту про длинные последовательности, например, с совещанием, можно ли алгоритм использовать несколько раз поэтапно, уменьшая результатность?  Например, три часа сначала ужмем до часа, потом до 20 минут и так далее?»

    Можно по-разному пытаться делать, раз уж мы про minuting заговорили. Можно делать и так, и эдак. Как правильно и хорошо делать, никто толком не знает, поскольку задача достаточно свежая, всплывшая в научное сообщество. У нас на Interspeech последнем было первое соревнование по minuting. Из общих соображений end-to-end модели на таких задачах должны бы работать получше, чем такого рода ужимание. Хотя, конечно, никто не знает, следует экспериментировать и пробовать. Много нерешенных задач осталось.

    Коллеги, пожалуйста, еще вопросы, соображения, предложения, замечания. Тогда раз нет других вопросов, Валерий, спасибо большое за рассказ. И через две недели жду всех на следующем вебинаре с Денисом Катаринчуком из City University of New York.

    Валерий Лихошеров: Спасибо за приглашение.

    (01:25:55) (Конец записи.)