Всё про LLM

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

Что такое языковые модели и их история

Языковые модели (Large Language Models, LLM) представляют собой искусственные нейронные сети, обученные на огромных объемах текстовых данных для распознавания сложных паттернов, контекстных отношений и лингвистических нюансов в человеческом языке. Эти модели способны предсказывать вероятность следующего токена (слова или его части) в последовательности на основе предыдущего контекста.

История языковых моделей началась задолго до современных LLM. Еще в 1977 году был впервые применен алгоритм beam search для распознавания речи, который до сих пор используется как окончательный слой принятия решений в NLP-системах. Первоначально языковые модели были относительно простыми n-граммными моделями, где вероятность каждого слова зависела только от n-1 предыдущих слов. Однако с развитием технологий и увеличением вычислительных мощностей появились более сложные архитектуры.

Современные LLM, такие как GPT, Llama, Mistral и другие, представляют собой гигантские нейронные сети с миллиардами параметров. Обучение LLM требует колоссальных вычислительных ресурсов. Для обучения крупномасштабных моделей, таких как Llama или GPT, часто необходимо использовать десятки тысяч процессорных единиц. Большинство LLM обучаются на интернет-данных, включая Википедию, книги и другие текстовые источники, преобразованные в формат простого текста.

Архитектура Transformer

Современные LLM, как правило, используют decoder-only Transformer архитектуру и механизмы self-attention. Transformer, представленный в 2017 году в статье "Attention is All You Need", кардинально изменил подход к обработке естественного языка, заменив рекуррентные и сверточные нейронные сети на механизмы внимания.

Статья Attention Is All You Need

Статья "Attention Is All You Need"

Процесс работы LLM можно описать следующим образом:

  1. Токенизация: Входной текст разбивается на токены с помощью токенизатора. Токены могут представлять собой целые слова, части слов или даже отдельные символы, в зависимости от используемого алгоритма токенизации.
  2. Эмбеддинги: Каждому токену присваивается числовой вектор, который кодирует его семантическое значение. Этот вектор является отправной точкой для понимания модели. В некоторых архитектурах векторы также содержат информацию о позиции токена в последовательности, в других — эта информация добавляется позже.
  3. Decoder Layers: Токены проходят через серию идентичных декодерных слоев (количество может варьироваться от 24 до 80+ в зависимости от размера модели).
  4. Output Generation: После прохождения всех слоев модель использует функцию softmax для преобразования оценок, указывающих, насколько модель считает каждый токен вероятным, в вероятности. Эти вероятности показывают, насколько вероятен каждый токен как следующее слово в выходной последовательности.

Параметры моделей

Параметры языковой модели - это численные значения, определяющие поведение нейронной сети. Чем больше параметров имеет модель, тем сложнее зависимости она может улавливать, однако для её запуска потребуется больше ресурсов. Размер модели обычно выражается в миллиардах параметров (7B, 13B, 70B и т.д.). Для оценки требований к памяти можно использовать простое правило: модель в формате FP16 занимает примерно 2 гигабайта памяти на каждый миллиард параметров. Например:

  • Модель 7B в FP16 занимает около 14 ГБ
  • Модель 13B в FP16 занимает около 26 ГБ
  • Модель 70B в FP16 занимает около 140 ГБ

Однако для фактического запуска модели требуется немного больше памяти, чем размер самой модели, поскольку необходимо хранить данные текущих вычислений и обработанный контекст. Например, теоретический запуск модели 7B потребует минимум 16 ГБ видеопамяти (в реальности почти 20 ГБ). Это очень много для такого количества параметров, и мы можем оптимизировать вес модели благодаря такой технологии как квантование.

Квантование

Квантование - это процесс сжатия языковой модели, который позволяет снизить точность представления весов модели с 16 бит до 8, 4, 3 или даже 2 бит, сохраняя при этом основной функционал и качество генерации. Это критически важно для запуска моделей на обычных домашних компьютерах с ограниченными ресурсами видеопамяти.

  • Результаты при генерации токенов моделью, квантованной в 8 бит, практически не имеют отличий от 16-битной версии
  • Большие модели (70B) лучше переносят квантование даже в малые битности (~3 бита), тогда как на малых моделях (7B) заметная деградация может проявиться уже при 4 битах
  • Квантованные (особенно в малую битность) модели малопригодны для обучения
  • Сильное ужатие (ниже 3 бит) приведет к поломке и деградации модели, вы это сразу почувствуете.

Для понимания квантования необходимо знать структуру языковой модели. Каждый слой модели состоит из двух основных типов тензоров:

  1. Тензоры внимания (attn) - отвечают за механизм self-attention, определяющий, насколько качественной будет квантованная модель
  2. Тензоры полносвязной сети (ffn) - отвечают за непосредственную обработку информации после механизма внимания

В формате GGUF квантование обозначается как Qx_K_S/M/L, где:

  • Qx - основной уровень квантования для тензоров ffn (полносвязной сети), где x — число от 1 до 8
  • K - указывает на версию формата квантования
  • S/M/L - определяет, насколько выше будут квантованы важные тензоры внимания (attn)
  • S (Small) - важные тензоры внимания квантуются на 1 шаг выше (Qx+1)
  • M (Medium) - важные тензоры внимания квантуются на 2 шага выше (Qx+2)
  • L (Large) - важные тензоры внимания квантуются на 3 шага выше (Qx+3)

К примеру, в Q4_K_M:

  • Основной уровень квантования — 4 бита (Q4)
  • Важные тензоры внимания квантуются на 2 шага выше — до 6 бит (Q6)

Типы квантования и их особенности:

Статическое квантование (Qx_K_S/M/L)

Это наиболее распространенный тип квантования. Важно понимать, что разные создатели квантов могут иметь разные интерпретации "важных тензоров". Например, некоторые квантуют ffn_up и ffn_gate на 1 шаг ниже, чем основной уровень, считая это оптимальным. Это приводит к ситуации, когда кванты с одинаковым названием (например, Q4_K_M) от разных создателей могут вести себя по-разному.

IQ кванты

IQ кванты используют матрицу важности (imatrix), которая создается на основе типичного использования модели. Процесс создания imatrix включает сбор типичных примеров использования модели (тексты, программирование, факты и т.д.) и анализ, какие части модели активируются при их обработке.

Преимущество IQ квантования:

  • Уменьшение размера модели при сохранении качества
  • Более эффективное распределение битности между тензорами

Динамическое квантование

UD (Unsloth Dynamic 2.0)

Это передовая технология квантования, которая динамически определяет, какие части модели требуют более высокой точности. Например, UD-Q2_K_XL (2-битное квантование) может давать качество, близкое к оригиналу, теряя всего несколько процентов на примере DeepSeek R1, будучи в 3.3 раза меньше по размеру (212 ГБ против 700 ГБ).

R4

R4 - это state-of-the-art квантование от ikawrakow, позволяющее создать самый маленький квант для крупных моделей. Например, R4 позволяет создать квант DeepSeek R1 размером всего 130 ГБ, который может работать на домашних ПК с 128 ГБ RAM и одной GPU.

iqN_rt (Trellis квантование)

Это новейший тип квантования, аналогичный QTIP, используемому в exl3. Trellis квантование находит оптимальные параметры для каждого блока, позволяет лучше сохранить свойства оригинальной модели при минимальном количестве бит на вес (bpw).

Токенизация

Токенизация - это фундаментальный процесс, который включает разделение заданного текста на отдельные единицы, называемые токенами. Токены могут представлять собой целые слова, части слов или даже отдельные символы, в зависимости от уровня детализации, необходимого для конкретной задачи. Причина необходимости токенизации достаточно проста: машины не понимают слов в их естественной форме, поэтому необходимо преобразовать слова в численные представления. Однако разделение текста по алфавитным буквам слишком неэффективно (потребуется в среднем 4 токена на одно слово), а разделение по словам тоже неоптимально (потребуется словарь размером около 171 476 слов только для английского языка). Поэтому создается небольшая модель токенизатора, обученная на большом объеме текста, чтобы обеспечить наиболее эффективную токенизацию с минимальным размером словаря. Например, токенизатор BPE (Byte Pair Encoding) или его варианты, используемые в современных моделях, создают словарь фиксированного размера (обычно 32 000-50 000 токенов), который может эффективно кодировать как целые слова, так и их части.

Важно отметить, что разные языки имеют разную эффективность токенизации. Английский язык (и латиница в целом) потребляет наименьшее количество токенов (в среднем 1-2 на слово), тогда как кириллица может потребовать вдвое больше токенов на тот же объем символов. Эмодзи и специальные символы могут потребовать нескольких токенов на один символ.

Контекст

Контекст - это объем текста, который модель обрабатывает за один раз. Он включает в себя историю чата, системный промт, карточки персонажей, авторские заметки, лорбуки и другие элементы, которые формируют основу для генерации ответа. Модель "помнит" и учитывает только то, что находится в пределах контекста. Базовый контекст в новых моделях составляет 4096 и более токенов, в более ранних моделях было 2048 или меньше. Это означает, что если ваши сообщения в чате, упоминание важного события или определение какого-то термина выходит за пределы этого контекста, модель перестанет помнить об этом и будет интерпретировать запрос на основе своих общих знаний.

Проблема ограниченного контекста решается несколькими способами:

  • Суммаризацией (созданием краткого содержания предыдущего контекста)
  • Использованием лорбуков (специальных хранилищ знаний с информацией о мире и персонажах)
  • Векторными базами данных для поиска релевантной информации
  • Простым увеличением контекста

Контекст можно увеличить через настройки LLM в Soul of Waifu, однако не забудьте перезагрузить локальную языковую модель, если на момент изменения значения контекстного окна она была запущена.

Сильное увеличение контекста (более чем в 2-3 раза относительно исходного для модели) может привести к ухудшению качества ответов. Некоторые модели изначально обучаются с использованием подобных параметров, что позволяет увеличивать контекст до огромных величин (32K, 64K, 100K и более) без существенного ухудшения качества.

Flash Attention

Flash Attention - это оптимизация, разработанная для ускорения и снижения потребления памяти механизмов внимания в трансформерах. Эта технология особенно важна при работе с длинными контекстами, так как вычислительная сложность стандартного механизма внимания растет квадратично с увеличением длины последовательности. Стандартный механизм внимания требует O(n²) памяти и вычислений для последовательности длиной n, что становится узким местом при работе с длинными контекстами (8K, 32K, 128K токенов). Flash Attention решает эту проблему, оптимизируя вычисления и уменьшая потребление памяти. Включение Flash Attention экономит 20-30% VRAM для длинных контекстов и особенно эффективно при использовании llama.cpp, которая как раз и используется в нашей программе. Эта оптимизация уменьшает влияние контекстного окна на память, причем эффект более заметен при большем количестве контекста. В сочетании с квантованием контекста до 4-бит можно дополнительно снизить нагрузку на память. Flash Attention работает за счет более эффективной организации вычислений и использования специализированных ядер для GPU, что позволяет уменьшить количество обращений к памяти и оптимизировать использование вычислительных ресурсов.

Формат GGUF

GGUF (GPT-Generated Unified Format) - это формат файлов для хранения квантованных языковых моделей, разработанный специально для использования с llama.cpp. Этот формат заменяет более старый формат GGML и предоставляет ряд улучшений и дополнительных возможностей:

  • Все данные хранятся в одном файле (в отличие от других форматов, где модель распространяется папкой с множеством файлов)
  • Поддерживает различные уровни квантования (от 2.5 до 8 бит)
  • Включает метаданные, такие как архитектура модели, токенизатор
  • Позволяет запускать модели на CPU, GPU или гибридно
  • Поддерживает матрицу важности (Imatrix) для более эффективного квантования

Имена файлов GGUF следуют определенному шаблону: "имя_модели-битность_формат.расширение". Например, "gemma-3-9b-q4_K_M.gguf".

Llama.CPP

llama.cpp - это один из самых популярных программ для запуска языковых моделей, разработанный Georgi Gerganov. Этот проект представляет собой высокопроизводительную реализацию языковых моделей на языке C/C++, оптимизированную для запуска на различных устройствах, включая CPU, GPU и даже мобильные платформы.

Основные особенности llama.cpp:

  1. Кроссплатформенность: Работает на Windows, Linux, macOS, включая поддержку Apple Silicon через Metal.
  2. Гибкость в использовании ресурсов: Позволяет запускать модели как на CPU, так и на GPU, а также в гибридном режиме, где часть слоев обрабатывается на GPU, а часть — на CPU.
  3. Поддержка GGUF: Является основным движком для работы с моделями в формате GGUF.
  4. Offloading слоев: Одна из ключевых функций - возможность выбора количества слоев, которые будут загружены в видеопамять (VRAM). Это реализуется через настройку GPU-слоев в программе. Например, выставленное значение в 30 слоёв загрузит первые 30 слоев модели в VRAM, остальные будут обрабатываться вашим процессором.
  5. Поддержка различных оптимизаций: Например, Flash Attention для уменьшения потребления памяти при длинных контекстах.
  6. Производительность: Даже при запуске на CPU llama.cpp демонстрирует впечатляющую производительность благодаря оптимизации для современных архитектур (AVX2, AVX-512).

И как раз Soul of Waifu использует llama.cpp для запуска локальных языковых моделей внутри себя. Надеюсь, вы узнали много нового о языковых моделях, а в следующем разделе мы поговорим о персонах - инструменте, которые позволят вам представить себя персонажу.