Языковые модели на символьном уровне

TensorFlow.js представляет собой библиотеку для машинного обучения на JavaScript, позволяющую создавать и обучать модели как в браузере, так и на сервере с использованием Node.js. Основным объектом для работы является tf.Tensor — многомерный массив данных, аналогичный ndarray в Python. Тензоры могут иметь различные формы (shape) и типы данных (float32, int32, bool).

Создание тензоров осуществляется через методы:

const t1 = tf.tensor([1, 2, 3, 4]); // одномерный тензор
const t2 = tf.tensor2d([[1, 2], [3, 4]]); // двумерный

Для выполнения операций над тензорами используются встроенные функции: add, mul, matMul, reshape и многие другие. Все операции оптимизированы под WebGL, что позволяет ускорять вычисления в браузере.

Архитектура языковой модели на символьном уровне

Модели на символьном уровне обрабатывают текст не по словам, а по отдельным символам. Такой подход полезен для генерации текста, работы с нестандартными словарями, автоматического исправления ошибок и кодирования нестандартных последовательностей. В основе лежит рекуррентная нейронная сеть (RNN) или её современный аналог — LSTM/GRU, способный хранить долгосрочные зависимости между символами.

Представление текста

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

const chars = Array.from(new Set(text));
const char2idx = {};
chars.forEach((c, i) => char2idx[c] = i);
const idx2char = chars;

После этого текст переводится в последовательность индексов:

const sequence = text.split('').map(c => char2idx[c]);

Создание обучающих выборок

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

const seq_length = 100;
const examples = [];
for (let i = 0; i < sequence.length - seq_length; i++) {
  const inputSeq = sequence.slice(i, i + seq_length);
  const targetChar = sequence[i + seq_length];
  examples.push({input: inputSeq, target: targetChar});
}

Эти последовательности преобразуются в тензоры:

const xs = tf.tensor2d(examples.map(e => e.input.map(i => oneHot(i, chars.length))));
const ys = tf.tensor2d(examples.map(e => oneHot(e.target, chars.length)));

Функция oneHot создаёт вектор, где 1 стоит на позиции символа, а остальные элементы равны 0.

Построение модели

Модель на символьном уровне обычно состоит из:

  • Embedding layer — уменьшает размерность входного символа;
  • RNN/LSTM/GRU layer — хранит контекст;
  • Dense layer с функцией активации softmax для предсказания следующего символа.

Пример модели на TensorFlow.js:

const model = tf.sequential();
model.add(tf.layers.embedding({inputDim: chars.length, outputDim: 64, inputLength: seq_length}));
model.add(tf.layers.lstm({units: 128, returnSequences: false}));
model.add(tf.layers.dense({units: chars.length, activation: 'softmax'}));

model.compile({
  optimizer: tf.train.adam(),
  loss: 'categoricalCrossentropy'
});

Обучение модели

Обучение происходит с использованием метода model.fit, передавая входные и целевые тензоры:

await model.fit(xs, ys, {
  batchSize: 64,
  epochs: 50
});

Для символьных моделей важна регуляризация, чтобы предотвратить переобучение, и shuffle последовательностей.

Генерация текста

После обучения модель может предсказывать следующий символ по текущей последовательности. Начальная последовательность (seed) преобразуется в тензор, передаётся в модель, и на основе вероятностей выбирается следующий символ:

let input = seed.split('').map(c => char2idx[c]);
for (let i = 0; i < 200; i++) {
  const inputTensor = tf.tensor2d([input], [1, input.length]);
  const prediction = model.predict(inputTensor);
  const nextIdx = tf.multinomial(prediction, 1).dataSync()[0];
  input.push(nextIdx);
  input.shift();
}

Полученные индексы переводятся обратно в символы через idx2char и объединяются в текстовую строку.

Оптимизация и ускорение

TensorFlow.js поддерживает вычисления на GPU через WebGL. Для улучшения производительности:

  • Минимизировать частое создание тензоров в цикле, использовать tf.tidy для автоматической очистки памяти.
  • Использовать статические входы для предсказаний при генерации текста.
  • Настраивать параметры обучения: размер батча, скорость обучения, регуляризацию.

Важные аспекты символьных моделей

  • Гибкость словаря — легко добавлять новые символы.
  • Длинные зависимости — LSTM/GRU лучше RNN для удержания контекста.
  • Случайность генерации — выбор следующего символа через температурный параметр позволяет варьировать креативность текста:
const temperature = 0.5;
const logits = tf.div(tf.log(prediction), temperature);
const nextIdx = tf.multinomial(logits, 1).dataSync()[0];
  • Память и производительность — обучение больших моделей на клиенте ограничено, поэтому часто используют Node.js с GPU или делят данные на чанки.

Интеграция с веб-приложениями

TensorFlow.js позволяет интегрировать символьные модели напрямую в браузер:

  • Обученные модели сохраняются через model.save('localstorage://model-name') или model.save('downloads://model-name').
  • Предсказания выполняются в реальном времени, позволяя создавать автодополнение, генерацию кода, чат-ботов и интерактивные инструменты на основе текста.

Такой подход делает возможным создание полноценных языковых моделей на JavaScript без необходимости серверной обработки, что особенно важно для веб-приложений с ограничениями приватности данных.