Представление информации для нейронок
В одном из прошлых постов мне задали вопрос про Bark. Да и про токенизацию я часто вижу вопросы. Это натолкнуло меня на мысль, что неплохо бы разобраться, а как вообще информация представляется на входе и выходе современных моделей.
💻 Биты и байты
Основной формат представления любой информации в компьютерах.
Бит = 0 или 1. Байт = 8 бит (но это не точно, тут большая история и контекст).
Есть современные модели, которые оперируют напрямую байтами:
Beyond Language Models: Byte Models are Digital World Simulators
MEGABYTE: Predicting Million-byte Sequences with Multiscale Transformers
ByT5: Towards a token-free future with pre-trained byte-to-byte models
Идея оперировать всей информацией одинаковым образом очень соблазнительная, но пока не особо практичная.
🔤 Текст / Символы
Юникод — это стандарт, который пронумеровывает все существующие символы в письменности человечества. Всего описывает около 150к символов, но может до 1.1кк. Конкретные кодировки описывают каждый символ с помощью от 1 до 4 байтов. UTF-8 и UTF-16 — кодировки переменной длины, то есть разные символы могут занимать разное число байтов.
Для уменьшения словаря можно хэшировать (то есть одинаково кодировать) разные символы, особенно если они из разных систем письменности и вряд ли встречаются рядом.
Современные модели такого типа довольно редки, см. например CANINE: Pre-training an Efficient Tokenization-Free Encoder for Language Representation. Кроме игрушечных примеров и исторической ценности, символы как входы полезны в узких задачах, типа расстановки ударений или генерации названий и имён. И как альтернативный вариант там, где токены найти не удалось.
🔤 Текст / Слова
Разбиваем на слова. Обычно по пробелам и знакам препинания, но не во всех языках это так работает. Основная проблема в том, что существующих слов слишком много, и они регулярно создаются.
В истории такое было здесь, например. Опять же, сейчас нигде не используется, кроме специфичных случаев, типа автодополнения.
🔤 Текст / Токены
Мы можем соединять символы в n-граммы и нумеровать уже эти n-граммы. Теперь задача такая: минимизировать среднюю длину закодированных текстов при фиксированном размере словаря. Есть несколько основных алгоритмов, которые делают это для заданного набора текстов: BPE, Unigram, SentencePiece. Какой из них использовать — зависит от специфики языков.
Чуть подробнее почитать можно тут.
Этот тип входов для современных текстовых моделей является основным, потому что словарь получается компактным, как и закодированные тексты.
🖼️ Картинки / Пиксели
Если упрощенно, то картинка — это двумерный набор пикселей, чаще всего трёхканальных 8-битных чисел. Самое важное слово тут — “двумерный”, что и отличает картинки от текстов.
Напрямую трансформеры над пикселями использовать проблематично, потому что их много, для больших картинок сотни тысяч или миллионы.
🖼️ Картинки / Патчи
Нарезаем картинку на маленькие квадратные кусочки, каждый кусочек представляем в виде одномерной последовательности пикселей, после чего прогоняем её через обучаемый линейный слой. Добавляем позиционные эмбеддинги.
Это основной формат, которым оперируют энкодеры типа ViT.
🖼️ Картинки / Латенты
Учим отдельный автоэнкодер сжимать и восстанавливать картинки, причём с хитрыми лоссам и регуляризациями, которые учитывают глобальную и локальную схожесть предсказанной и оригинальной картинок. Сжатые картинки всё ещё двумерные.
Это основной формат, которым оперирует Stable Diffusion.
Про звук и видео напишу в следующем посте.
В одном из прошлых постов мне задали вопрос про Bark. Да и про токенизацию я часто вижу вопросы. Это натолкнуло меня на мысль, что неплохо бы разобраться, а как вообще информация представляется на входе и выходе современных моделей.
Основной формат представления любой информации в компьютерах.
Бит = 0 или 1. Байт = 8 бит (но это не точно, тут большая история и контекст).
Есть современные модели, которые оперируют напрямую байтами:
Beyond Language Models: Byte Models are Digital World Simulators
MEGABYTE: Predicting Million-byte Sequences with Multiscale Transformers
ByT5: Towards a token-free future with pre-trained byte-to-byte models
Идея оперировать всей информацией одинаковым образом очень соблазнительная, но пока не особо практичная.
🔤 Текст / Символы
Юникод — это стандарт, который пронумеровывает все существующие символы в письменности человечества. Всего описывает около 150к символов, но может до 1.1кк. Конкретные кодировки описывают каждый символ с помощью от 1 до 4 байтов. UTF-8 и UTF-16 — кодировки переменной длины, то есть разные символы могут занимать разное число байтов.
Для уменьшения словаря можно хэшировать (то есть одинаково кодировать) разные символы, особенно если они из разных систем письменности и вряд ли встречаются рядом.
Современные модели такого типа довольно редки, см. например CANINE: Pre-training an Efficient Tokenization-Free Encoder for Language Representation. Кроме игрушечных примеров и исторической ценности, символы как входы полезны в узких задачах, типа расстановки ударений или генерации названий и имён. И как альтернативный вариант там, где токены найти не удалось.
🔤 Текст / Слова
Разбиваем на слова. Обычно по пробелам и знакам препинания, но не во всех языках это так работает. Основная проблема в том, что существующих слов слишком много, и они регулярно создаются.
В истории такое было здесь, например. Опять же, сейчас нигде не используется, кроме специфичных случаев, типа автодополнения.
🔤 Текст / Токены
Мы можем соединять символы в n-граммы и нумеровать уже эти n-граммы. Теперь задача такая: минимизировать среднюю длину закодированных текстов при фиксированном размере словаря. Есть несколько основных алгоритмов, которые делают это для заданного набора текстов: BPE, Unigram, SentencePiece. Какой из них использовать — зависит от специфики языков.
Чуть подробнее почитать можно тут.
Этот тип входов для современных текстовых моделей является основным, потому что словарь получается компактным, как и закодированные тексты.
🖼️ Картинки / Пиксели
Если упрощенно, то картинка — это двумерный набор пикселей, чаще всего трёхканальных 8-битных чисел. Самое важное слово тут — “двумерный”, что и отличает картинки от текстов.
Напрямую трансформеры над пикселями использовать проблематично, потому что их много, для больших картинок сотни тысяч или миллионы.
🖼️ Картинки / Патчи
Нарезаем картинку на маленькие квадратные кусочки, каждый кусочек представляем в виде одномерной последовательности пикселей, после чего прогоняем её через обучаемый линейный слой. Добавляем позиционные эмбеддинги.
Это основной формат, которым оперируют энкодеры типа ViT.
🖼️ Картинки / Латенты
Учим отдельный автоэнкодер сжимать и восстанавливать картинки, причём с хитрыми лоссам и регуляризациями, которые учитывают глобальную и локальную схожесть предсказанной и оригинальной картинок. Сжатые картинки всё ещё двумерные.
Это основной формат, которым оперирует Stable Diffusion.
Про звук и видео напишу в следующем посте.