>>1.00<<>>1.00<<Видео проигрыватель загружается.Воспроизвести видеоВоспроизвестиБез звукаТекущее время 0:00/Продолжительность 5:49Загрузка: 0.00%0:00Тип потока ОНЛАЙНSeek to live, currently behind liveОНЛАЙНОставшееся время -5:49 1xСкорость воспроизведения2x1.75x1.5x1.25x1x, выбрано0.75x0.5xГлавыГлавыОписанияОтключить описания, выбраноСубтитрынастройки субтитров, откроется диалог настройки субтитровСубтитры выкл., выбраноЗвуковая дорожкаPicture-in-PictureПолноэкранный режимThis is a modal window.Начало диалоговго окна. Кнопка Escape закроет или отменит окноТекстColorБелыйЧерныйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачностьПолупрозрачныйФонColorЧерныйБелыйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачностьПолупрозрачныйПрозрачныйОкноColorЧерныйБелыйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачныйПолупрозрачныйПрозрачностьРазмер шрифта50%75%100%125%150%175%200%300%400%Стиль края текстаНичегоПоднятыйПониженныйОдинаковыйТеньШрифтПропорциональный без засечекМоноширинный без засечекПропорциональный с засечкамиМоноширинный с засечкамиСлучайныйПисьменныйМалые прописныеСбросить сбросить все найстройки по умолчаниюГотовоЗакрыть модальное окноКонец диалогового окна.
Как обычно, давайте создадим специальную структуру данных — Dataset, который будет готовить обучающие примеры для того, чтобы подавать их в pytorch для обучения. Для этой цели мы написали специальный класс "LanguageModelDataset", который принимает на вход список токенизированных предложений, в которых токены заменены на их номера. А также он принимает длину фрагмента которую нужно подавать в модель за раз. То есть, это наибольшее количество токенов, которые модель будет видеть за раз. Давайте посмотрим, как этот Dataset работает. Как обычно, наш Dataset реализует два основных метода — это получение длины датасета (то есть, количества примеров) и "get_item" — это получение одного конкретного примера по его порядковому номеру. Когда мы готовим очередной пример для модели, мы выбираем по индексу фрагмент текста, затем из всего текста мы выбираем какой-то случайный подфрагмент, непрерывный. И делаем из этого фрагмента ещё два кусочка — первый кусочек (здесь это переменная "seed part") — это весь текст, кроме последнего символа. А "target_part" — это весь текст, кроме первого символа. Таким образом, мы получаем, как бы, два текста — "seed_part" у нас выполняет роль входа в модель, а "target_part" — это то, что мы ожидаем на выходе модели. Таким образом, если у нас есть, например, текст "ABCD", тогда "seed-part" — это "ABC", а "target_part" — это "BCD". Физический смысл у этих последовательностей — следующий. На очередной позиции в "target" стоит токен, который модель должна предсказать, прочитав столько же токенов из входной последовательности. Таким образом, токен "B" она должна уметь предсказать только лишь по токену "A", токен "C" модель должна уметь предсказывать из "AB", а токен "D" она должна уметь предсказывать из всей входной последовательности, то есть "ABC". На экране вы видите один пример, сгенерированный нашим Dataset. Мы видим что здесь токены, как бы, смещены на одну позицию влево всегда, и на очередной позиции вектора "target" у нас стоит токен, который нужно уметь предсказывать после прочтения всех предыдущих токенов. Токенайзер из библиотеки "YouTokenToMe" умеет и декодировать тексты. То есть, обратно преобразовывать их в текст (то есть в строку). На экране вы видите пример детокенизации, то есть мы взяли тот же самый обучающий пример и прогнали его через детокенизатор. Мы видим, что две последовательности, входная и выходная, сдвинуты относительно друг друга на один токен, на одну N-грамму. Тут вы можете задать вопрос: "Как же так?" Мы подаём на вход в модель весь текст и просим, чтобы она практически этот же текст нам и вернула, сдвинув на один токен влево". Это, кажется, очень простая задача, модель же ничего не выучит... В самом деле, если мы будем просто в лоб подавать текст и на выходе просить его же — действительно, модель ничего не выучит. Нам нужно усложнить ей задачу, нам нужно сделать так, чтобы при предсказании i-го токена она принципиально не могла учитывать токены, стоящие справа от этой позиции. Для этого мы будем использовать специальную маску. На экране вы видите функцию, которая генерирует такую маску и, собственно, пример этой маски — давайте разберём, какой физический смысл у этой маски. Это так называемая "маска зависимости позиций". Для примера мы сгенерировали эту маску для достаточно короткой последовательности длины 10. Маска имеет размер 10 на 10, это квадратная матрица, строка соответствует номеру позиции в выходной последовательности, а столбцы соответствуют номерам позиций во входной последовательности, и на пересечении столбца и строки стоит 0, если при предсказании токена на позиции "i" можно учитывать токен на позиции "j". То есть, если учитывать можно — тогда стоит 0, а если учитывать нельзя — тогда стоит -∞. Таким образом, мы "запрещаем" модели смотреть на все токены справа. И, например, для самого первого токена (это первая строчка) мы можем использовать только самый первый входной токен. Для второго токена в выходной последовательности мы можем использовать уже два токена, а для последнего выходного токена мы можем использовать всю входную последовательность. Если в двух словах — то эти маски подаются в механизм внимания для того, чтобы занулить веса определённых элементов, чтобы мы не учитывали определённые входные позиции при расчёте выходных позиции. Она используется именно в механизмах внимания. Как именно она там используется, мы рассмотрим чуть позже.
К сожалению, у нас пока нет статистики ответов на данный вопрос,
но мы работаем над этим.