Идеи улучшения точности, удобства и скорости языковых моделей

1b8dbff9f6725c274f8c0ef45d55e632

Я не специалист, и это список моих идей для улучшения работы языковых моделей. К сожалению хорошо проверить это не имею возможности. Нигде не встречал таких идей. Интересно узнать мнения о них.

1. Новая функция потерь для минимизации переобучения на пре-тренировке. Предполагается что достаточно контролировать только «нужные» токены. Остальные выровняться косвенно.

def true_loss(y_true, y_pred, weight):
  vals = tf.gather(y_pred, y_true, batch_dims=-1)
  return tf.reduce_mean(tf.square(vals) * weight)

def true_acc(y_true, y_pred):
  y_pred = tf.argmin(tf.abs(y_pred), axis=-1)
  y_pred = tf.cast(y_pred, tf.float32)
  return tf.equal(y_true, y_pred)

def find_nearest_zero(x):
  return tf.argmin(tf.abs(x), axis=-1)

Тюнинг и интерактивный тюнинг:

2. Правка весов токенов в конкретных позициях ответа. Можно использовать для быстрого исправления конкретных косяков. Пример:
Есть: 12345 → Надо: 12045 → Обучающий пример: 12 → Веса в словарях ответа принимаем за истину кроме веса интересующих токенов. Для вероятности 0 или 3 используем нужные значения. не используется.

3. Модификация потерь для токенов подстрок в ответе. Позволяет сосредоточиться на фрагментах которые важно исправить.

4. Поскольку вставка/удаление хотя бы одного токена приводит к смещению всех последующих. Взвешивать только разницу в ответе и примере (как diff в git) для минимизации побочных эффектов. + к пункту 3.

5. Считать ошибку только для не совпавших токенов (наиболее вероятного и целевого).

6. Не обновлять весы с градиентами меньше порога. Установив минимальный порог для градиентов, можно предотвратить незначительные обновления. Поможет вносить в веса модели только значимые изменения и бороться с общим дрейфом модели.

Генерация (inference):

7. Сжатие предложения в один вектор встраивания позволяет освободить место в контексте. Также его можно хранить в векторной базе данных вместе с текстом.

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

9. topT (Threshold) — Отбрасывание всех токенов с весом ниже порога.

def topT(values, threshold):
  norm = values / tf.reduce_max(values)
  return norm >= threshold

topK, topP ненадёжны потому что в выборку могут попадать мусорные токены.

10. Исправление ответа на лету если сэмплер внесёт серьёзную ошибку. Есть подозрение что уверенность ИИ в последующих токенах заметно уменьшится. Это можно отследить по уменьшению разброса вероятностей и откатить плохой токен.

Хорошо бы всё это появилось в API всяких сервисов.

11. Мои наблюдения показывают что количество нейронов важней количества параметров. Поскольку Dense слои жрут квадратично от размера, то придумал такой заменитель. Жор должен быть линейным от размера. С этим ширина слоя может быть в сотни раз больше. gather тут плохо подходит. Но как реализовать быстрей на фреймворках не придумал. Только если Cuda ядро делать. Да и вообще добавили бы Vulkan уже во фреймворки. Хватит поддерживать монополию Nvidia.

class Local1D(Layer):
  def __init__(self, kernel, units=0, **kwargs):
    super().__init__(**kwargs)
    self.kernel = kernel
    self.units = units

  def build(self, input_shape):
    if self.units < 1:
      self.units = input_shape[-1]
    self.filters = self.add_weight(
      shape=(self.units, self.kernel),
      initializer='glorot_uniform',
      dtype=self.compute_dtype)
    stride = (input_shape[-1] - self.kernel + 1) / self.units
    indices = tf.cast(tf.range(0, self.units, dtype=tf.float32) * stride, tf.int32)
    self.indices = tf.range(self.kernel) + tf.expand_dims(indices, -1)
    super().build(input_shape)

  def call(self, inputs):
    slices = tf.gather(inputs, self.indices, axis=-1)
    return tf.reduce_sum(self.filters * slices, axis=-1)

PS: Пока ждал модерации, скомпилировал свои идеи обучения:

При обучении оценивается только первое несовпадение токенов. Предсказанный токен понижается, а ожидаемый повышается. Это исключает переобучение, совместимо с пре-тренировкой и настройкой, максимально дёшево, быстро обучается, и даёт наилучшую производительность.

© Habrahabr.ru