вторник, 17 февраля 2026 г.

Как работают нейросети

Недавно один разработчик нейросетей написал код на python содержащий всего 200 строк (+коменнтарии, то есть кода даже меньше) кода нейросети, которая как и все остальные нейросети - сначала обучается, а потом генерирует.  Вот статья откуда я про это узнал. Это хоть и маленькая нейросеть, но все же нейросеть, и она действительно генерирует то на чем обучилась. Разработчик предложил понять ее работу на основе генерации имен: он создал датасет (информация для обучения нейросети) -который является словарем имен состоящий из 32000 строк - каждая строка это отдельное имя. Нейросеть в процессе обучения генерирует случайное имя, и сверяет его со словарем, в процессе сверки обновляя свои параметры, чтобы понимать как лучше генерировать имена в дальнейшем. Пройдя 1000 циклов обучения, она имеет готовый массив чисел (об этом позже), на основании которого может сгенерировать 20 имен. Все это можно прогнать в онлайн на этой странице (просто нажмите генерировать), а выглядит все это примерно вот так:


обращаю внимание что страница сгенерирована нейросетью, я просто попросил ее создать такое для онлайн обучения. Можно обучить эту нейронку на своем словаре (датасете) и получить другие генерации близкие к тому что у вас есть в вашем датасете. например вот список городов РФ: https://boolkin.github.io/html/Vibe/microgpt/cities.txt Скачайте, скормите, посмотрите, поиграйтесь с настройками. Поидее кол-во циклов обучения улучшает нейросеть, но тут это работает не совсем понятно, но об этом ниже. Сейчас о том как это работает.

В общем-то с нейронками никаких чудес не бывает — это обычная математика. По-большому счету все что делают нейросети (привычные нам LLM или генераторы звуков и картинок) — это генерируют токены: слова, буквы, пиксели.
Все это они делают на основе обучения. Они научились тому, что если есть какая-то последовательность букв, то следующей с высокой вероятностью должна идти такая-то. Поэтому выдают текст, который в целом вполне осмысленный, хотя сама нейронка его почти не понимает. Она просто обучена на миллиардах текстов и вычисляет (предсказывает) следующие токены, которые встречались в похожих контекстах во время обучения.
И хотя мы видим при общении с нейросетью процесс генерации — текст создается на наших глазах, — ничего принципиально нового не создается. Пользователю выдают то, что уже было «известно» модели в виде закономерностей, просто сгруппированное в конкретной последовательности на основании математического ожидания. Сейчас мы все пользуемся уже обученными нейросетями — теми, что уже знают много зависимостей. Разработчики заранее провели обучение: скормили нейронке миллиарды текстов, чтобы та построила зависимости (веса) и в процессе генерации ответа обращалась к ним, выдавая осмысленные слова.
Чтобы понять этот процесс глубже, изучим программу MicroGPT. Она обучается на заданном списке имен и на основании выученного сможет сгенерировать новые имена. Тут возникает вопрос: как же так, ведь я говорил, что нового ничего не создается, а тут нейросеть придумывает новые имена? Секрет в том, что нейросеть выучила не сами имена наизусть, а правила их построения. Поэтому она может собрать новое сочетание букв, которого не было в списке, но которое выглядит как имя, потому что следует выученным принципам. В случае с MicroGPT модель маленькая и видит только имена, поэтому она генерирует похожие на имена последовательности, комбинируя изученные паттерны.
В общем, давайте чуть подробнее, как это работает внутри.
1. Токены В начале MicroGPT создает словарь токенов. Токены — это минимальная информация, которой оперирует нейросеть. Она выдает не текст, она выдает токены. В контексте MicroGPT токен — это одна буква. Конкретно как оно работает: есть датасет (словарь имен), состоящий из 32 000 слов-имен на английском языке. Там буквы английского алфавита — 26 штук. И есть еще переносы строк, символ окончания последовательности. Итого 27 токенов. Алгоритм MicroGPT проходится по словарю имен и добавляет в базу токенов все уникальные символы. Вот и получается, что добавляется все 26 букв + конец строки. Если брать русские слова — например, список городов России, то токенизатор добавит в массив 33 буквы + конец строки. (Нюанс: другие современные нейросети используют в качестве токенов целые слова или их части, и их словарь токенов может достигать 100+ тысяч единиц).
2. Параметры Дальше алгоритм наполняет нейросеть параметрами, потому что сами токены ничего не решают без «знаний». Знания хранятся именно в числах. Из статьи автора:
«Параметры — это знания модели. Это большой набор чисел с плавающей точкой, которые изначально случайны и постепенно оптимизируются в процессе обучения... В нашей крошечной модели — 4192 параметра. У GPT-2 — 1,6 миллиарда, у современных LLM — сотни миллиардов... Каждый параметр инициализируется малым случайным числом из гауссового распределения».
Именно эти параметры (веса) мы и видим в итоговом JSON-файле. Давайте разберем их структуру...


1. Входные слои (Embeddings)

wte (Word Token Embeddings): [ 27 items ] - 27 букв 27 токенов - Внутри каждого из 27 элементов лежит вектор из 16 чисел. (16 числе потому что размерность эмбеддинга (n_embd) =16 ). Вектор в математике задается координатами 2 числами на плоскости. Здесь 16 цифр - 16 мерное пространство. 

wpe (Word Position Embeddings): [ 16 items ] Позиционные кодировки. максимальная длина слова в нашем случае. Как работает: Трансформеры не знают порядка слов сами по себе. Этот слой добавляет информацию о том, где стоит буква (первая, вторая, пятая...).Размер: У вас задана максимальная длина фразы 16 символов. Значит, здесь 16 векторов (для позиции 0, позиции 1... до позиции 15). Внутри каждого тоже 16 чисел (n_embd помним)

Далее описание от нейронки: 

2. Выходной слой 

 lm_head (Language Model Head): [ 27 items ]

  • Что это: "Голова" модели, которая делает предсказание.
  • Как работает: Это обратная операция к wte. В конце работы сеть выдает вектор из 16 чисел. Этот слой умножает его на матрицу весов, чтобы получить 27 чисел (логитов).
  • Смысл: Эти 27 чисел превращаются в вероятности. Какое число самое большое — ту букву сеть и предсказывает как следующую. 

3. Слой трансформера (layer0)

У вас всего один слой (layer0), поэтому модель очень маленькая и быстрая, но не очень умная. Внутри слоя есть два основных механизма: Внимание (Attention) и MLP (Feed Forward).

Механизм Внимания (Attention)

Он позволяет сети смотреть на предыдущие буквы, чтобы понять контекст.
  • layer0.attn_wq (Query Weights): [ 16 items ]
    • Матрица весов для создания Запросов (Query). Превращает входной вектор (16 чисел) в вектор запроса (тоже 16 чисел).
  • layer0.attn_wk (Key Weights): [ 16 items ]
    • Матрица весов для создания Ключей (Key). Превращает входной вектор в вектор ключа.
  • layer0.attn_wv (Value Weights): [ 16 items ]
    • Матрица весов для создания Значений (Value). Превращает входной вектор в вектор значения (сама информация).
  • layer0.attn_wo (Output Weights): [ 16 items ]
    • Матрица весов для выхода из блока внимания. После того как механизм внимания собрал информацию от нужных букв, этот слой проецирует результат обратно в размерность 16, чтобы передать дальше.

Механизм MLP (Feed Forward Network)

Это "мышление" сети внутри слоя. Она обрабатывает информацию, полученную от механизма внимания. Обычно в трансформерах этот блок сначала расширяет данные, а потом сжимает.
  • layer0.mlp_fc1 (Fully Connected 1): [ 64 items ]
    • Это первый линейный слой. Он расширяет пространство признаков.
    • Обратите внимание: на входе было 16 чисел, а здесь 64 элемента. Это стандартный прием (обычно расширение в 4 раза: 16×4=64). Сеть ищет более сложные закономерности в этом увеличенном пространстве.
  • layer0.mlp_fc2 (Fully Connected 2): [ 16 items ]
    • Это второй линейный слой. Он сжимает данные обратно.
    • Из 64 чисел он снова делает 16 чисел, чтобы передать их либо в следующий слой трансформера (если бы он был), либо на выход (lm_head).

 то есть это базовая структура именно этой нейросети, которая в первом этапе наполняется случайными числами, а уже потом запускается «Цикл обучения» (Training Loop) - это по сути исправление весов и состоит он из из таких этапов:

  1. Выбор документа. Случайное слово с которым будем сравнивать предсказание.
  2. Прямой проход модели по токенам. Forward: Прогон данных через сеть (получение предсказаний).
  3. Вычисление величины потери. Loss: Расчет ошибки (сравнение предсказаний с правильными ответами из датасета).
  4. Обратное распространение (через градиенты). Backward: Расчет градиентов (понимание, как исправить веса).
  5.  Обновление параметров.Update: Обновление параметров (весов/векторов) 
Снова из статьи на хабре:

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

Каждый экземпляр мы начинаем с токена BOS, который говорит модели: "начни новое имя". Модель выдает 27 логитов, мы преобразуем их в вероятности и случайным образом выбираем один токен в соответствии с этими вероятностями. Этот токен снова подается на вход как следующий, и мы повторяем процесс до тех пор, пока модель не сгенерирует токен BOS (означающий "я закончила") или пока не будет достигнута максимальная длина последовательности.

Параметр температура (temperature) контролирует степень случайности. Перед применением softmax мы делим логиты на значение температуры. Температура, равная 1,0, означает сэмплирование непосредственно из распределения, которое выучила модель. Более низкие значения температуры (например, 0,5 , как в данном случае) делают распределение более "острым" (вероятности сконцентрированы на наиболее вероятных вариантах), что приводит к более консервативному поведению модели, когда она с большей вероятностью выбирает свои лучшие варианты. При температуре, стремящейся к нулю, модель всегда будет выбирать самый вероятный токен (это называется жадным декодированием). Более высокие значения температуры, наоборот, сглаживают распределение, делая вывод более разнообразным, но потенциально менее связным.

 Вот так и происходит генерация ответа - случайный выбор токенов внутри нейросети. Хотя нет, не случайный - поддающийся правилам которым она научилась. Короче как-то так.

Ах да. 


 График loss при 1000 циклах обучения и при 10 000 - видно что потерь меньше, но все еще вроде как довольно мало. при 32000 вот такой список:

step 32000 / 32000 | loss 2.0509

--- инференс ---
Образец 1: aneyl
Образец 2: amalee
Образец 3: amilee
Образец 4: kaylann
Образец 5: samarie
Образец 6: shari
Образец 7: aruha
Образец 8: sharia
Образец 9: kana
Образец 10: aylia
Образец 11: jariyah
Образец 12: kari
Образец 13: ashalia
Образец 14: phamer
Образец 15: hastan
Образец 16: mami
Образец 17: dasten
Образец 18: aharan
Образец 19: mala
Образец 20: arisa 

PS. что я еще хотел добавить. Все оперируют терминами, токены, веса, векторы - голова кругом. Как это понять на примере не очень понятно, и вот тут можно заглянуть внутрь. Эта microgpt обучается, и имеет свою память грубо говоря - то что она знает, какие последовательности выучила она хранит в виде векторов (весов) и выглядеть они могут вот так, как в этом JSON файле. То есть четко видно что один вектор это массив чисел с плавающей точкой - 16 чисел, 16 измерений. Но опять же не все параметры, некоторые имеют размерность 64. Но смысл в том что это веса обученной модели - и если брать их за основу, то не нужно каждый раз проходить обучение. Поэтому современные нейросети работают быстро - запрос ответ - они уже знают на что ориентироваться, есть база параметров.

Комментариев нет:

Отправить комментарий