Посмотреть на TensorFlow.org | Запускаем в Google Colab | Посмотреть на GitHub | Скачать блокнот |
Обзор
В недавнем прошлом было проведено множество исследований в области генерации языков с использованием авторегрессивных моделей. В генерации языка авто-регрессивное, распределение вероятностей маркера на время шага K зависит от маркеров предсказаний модели до шага K-1. Для этих моделей декодирования стратегии , такие как поиск луча, жадный, Top-р и Top-к являются важнейшими компонентами модели и в значительной степени влияют на стиль / характер генерируемого выходного элемента в данный момент времени шага K.
Например, поиск луча уменьшает риск потери скрытых высокой вероятности лексем, храня наиболее вероятное num_beams гипотез на каждый шаг по времени и в конечном итоге выбрать гипотезу , которая имеет общие высокую вероятность. Мюррей и др. (2018) и Ян и др. (2018) показывают , что поиск луча хорошо работает в задачах машинного перевода. Оба поиск луча и Жадные стратегии имеет возможность генерировать повторяющиеся маркера.
Fan et. аль (2018) введен Топ-K выборка, в котором К наиболее вероятным маркерам фильтруют и вероятность массовый перераспределяются только среди тех K маркеров.
Ари Хольцман и др. аль (2019) введена Топ-р выборки, который выбирает из наименьшего возможного набора маркеров с кумулятивной вероятности того, что добавляет ДО вероятности р. Затем вероятностная масса перераспределяется среди этого множества. Таким образом, размер набора токенов может динамически увеличиваться и уменьшаться. Топ-р, Топ-K , как правило , используются в таких задачах, как история поколение.
API декодирования предоставляет интерфейс для экспериментов с различными стратегиями декодирования на авторегрессионных моделях.
Следующие стратегии выборки предоставляются в sampling_module.py, который наследуется от базового класса Decoding:
Поиск луча предоставляется в beam_search.py. github
Настраивать
pip install -q -U tensorflow-text
pip install -q tf-models-nightly
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from official import nlp
from official.nlp.modeling.ops import sampling_module
from official.nlp.modeling.ops import beam_search
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/pkg_resources/__init__.py:119: PkgResourcesDeprecationWarning: 0.18ubuntu0.18.04.1 is an invalid version and will not be supported in a future release PkgResourcesDeprecationWarning,
Инициализировать модуль выборки в TF-NLP.
- symbols_to_logits_fn: Используй это замыкание , чтобы вызвать модель для прогнозирования логита для
index+1
шага. Входы и выходы для этого закрытия следующие:
Args:
1] ids : Current decoded sequences. int tensor with shape (batch_size, index + 1 or 1 if padded_decode is True)],
2] index [scalar] : current decoded step,
3] cache [nested dictionary of tensors] : Only used for faster decoding to store pre-computed attention hidden states for keys and values. More explanation in the cell below.
Returns:
1] tensor for next-step logits [batch_size, vocab]
2] the updated_cache [nested dictionary of tensors].
Кэш используется для более быстрого декодирования. Вот ссылка осуществления для закрытия выше.
- length_normalization_fn: Используйте это замыкание для возвращения параметра длины нормализации.
Args:
1] length : scalar for decoded step index.
2] dtype : data-type of output tensor
Returns:
1] value of length normalization factor.
vocab_size: Выходной размер словаря.
max_decode_length: Скалярное для общего количества шагов декодирования.
eos_id: Декодирование остановится , если все выходные декодируются идентификаторы в пакете есть этот eos_id.
padded_decode: Установите это значение True , если работает на ТПУ. Тензоры дополняются до max_decoding_length, если это True.
top_k: top_k включена , если это значение> 1.
top_p: top_p включена , если это значение> 0 и <1,0
sampling_temperature: Используется для повторного оценить SoftMax выход. Температура искажает распределение в сторону жетонов с высокой вероятностью и снижает массу в распределении хвостов. Значение должно быть положительным. Низкая температура эквивалентна жадности и делает распределение более резким, а высокая температура делает его более плоским.
enable_greedy: По умолчанию, это правда , и жадное декодирование включено. Чтобы поэкспериментировать с другими стратегиями, установите значение False.
Инициализировать гиперпараметры модели
params = {}
params['num_heads'] = 2
params['num_layers'] = 2
params['batch_size'] = 2
params['n_dims'] = 256
params['max_decode_length'] = 4
В авто-регрессивный архитектур типа на основе трансформатора кодировщик-Decoder моделей, Cache используется для быстрого последовательного декодирования. Это вложенный словарь, хранящий предварительно вычисленные скрытые состояния (ключи и значения в блоках самовнимания и в блоках перекрестного внимания) для каждого уровня.
Инициализировать кеш.
cache = {
'layer_%d' % layer: {
'k': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], int(params['n_dims']/params['num_heads'])], dtype=tf.float32),
'v': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], int(params['n_dims']/params['num_heads'])], dtype=tf.float32)
} for layer in range(params['num_layers'])
}
print("cache key shape for layer 1 :", cache['layer_1']['k'].shape)
cache key shape for layer 1 : (2, 4, 2, 128)
При необходимости задайте замыкание для нормализации длины.
Это используется для нормализации окончательных оценок сгенерированных последовательностей и не является обязательным.
def length_norm(length, dtype):
"""Return length normalization factor."""
return tf.pow(((5. + tf.cast(length, dtype)) / 6.), 0.0)
Создать model_fn
На практике это будет заменено фактической реализацией модели , такие , как здесь
Args:
i : Step that is being decoded.
Returns:
logit probabilities of size [batch_size, 1, vocab_size]
probabilities = tf.constant([[[0.3, 0.4, 0.3], [0.3, 0.3, 0.4],
[0.1, 0.1, 0.8], [0.1, 0.1, 0.8]],
[[0.2, 0.5, 0.3], [0.2, 0.7, 0.1],
[0.1, 0.1, 0.8], [0.1, 0.1, 0.8]]])
def model_fn(i):
return probabilities[:, i, :]
Инициализировать symbols_to_logits_fn
def _symbols_to_logits_fn():
"""Calculates logits of the next tokens."""
def symbols_to_logits_fn(ids, i, temp_cache):
del ids
logits = tf.cast(tf.math.log(model_fn(i)), tf.float32)
return logits, temp_cache
return symbols_to_logits_fn
Жадный
Жадный декодирования выбирает идентификатор маркера с наибольшей вероятностью в качестве своего следующего ID: \(id_t = argmax_{w}P(id | id_{1:t-1})\) на каждом временном шаге \(t\). Следующий рисунок показывает жадное декодирование.
greedy_obj = sampling_module.SamplingModule(
length_normalization_fn=None,
dtype=tf.float32,
symbols_to_logits_fn=_symbols_to_logits_fn(),
vocab_size=3,
max_decode_length=params['max_decode_length'],
eos_id=10,
padded_decode=False)
ids, _ = greedy_obj.generate(
initial_ids=tf.constant([9, 1]), initial_cache=cache)
print("Greedy Decoded Ids:", ids)
Greedy Decoded Ids: tf.Tensor( [[9 1 2 2 2] [1 1 1 2 2]], shape=(2, 5), dtype=int32)
top_k выборка
В выборке Топ-К, К , скорее всего , в следующих лексемах идентификаторов фильтруют и вероятность массовый перераспределяются только среди тех K идентификаторов.
top_k_obj = sampling_module.SamplingModule(
length_normalization_fn=length_norm,
dtype=tf.float32,
symbols_to_logits_fn=_symbols_to_logits_fn(),
vocab_size=3,
max_decode_length=params['max_decode_length'],
eos_id=10,
sample_temperature=tf.constant(1.0),
top_k=tf.constant(3),
padded_decode=False,
enable_greedy=False)
ids, _ = top_k_obj.generate(
initial_ids=tf.constant([9, 1]), initial_cache=cache)
print("top-k sampled Ids:", ids)
top-k sampled Ids: tf.Tensor( [[9 1 0 2 2] [1 0 1 2 2]], shape=(2, 5), dtype=int32)
top_p выборка
Вместо того , чтобы отбор проб только из наиболее вероятный К маркер Идентификаторы, в Top-р выборки выбирает из наименьшего возможного набора идентификаторов которого интегральная вероятность превышает вероятность р.
top_p_obj = sampling_module.SamplingModule(
length_normalization_fn=length_norm,
dtype=tf.float32,
symbols_to_logits_fn=_symbols_to_logits_fn(),
vocab_size=3,
max_decode_length=params['max_decode_length'],
eos_id=10,
sample_temperature=tf.constant(1.0),
top_p=tf.constant(0.9),
padded_decode=False,
enable_greedy=False)
ids, _ = top_p_obj.generate(
initial_ids=tf.constant([9, 1]), initial_cache=cache)
print("top-p sampled Ids:", ids)
top-p sampled Ids: tf.Tensor( [[9 1 1 2 2] [1 1 1 0 2]], shape=(2, 5), dtype=int32)
Расшифровка поиска луча
Поиск луча снижает риск пропуска скрытых идентификаторов токенов высокой вероятности за счет сохранения наиболее вероятных num_beams гипотез на каждом временном шаге и, в конечном итоге, выбора гипотезы с наибольшей общей вероятностью.
beam_size = 2
params['batch_size'] = 1
beam_cache = {
'layer_%d' % layer: {
'k': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], params['n_dims']], dtype=tf.float32),
'v': tf.zeros([params['batch_size'], params['max_decode_length'], params['num_heads'], params['n_dims']], dtype=tf.float32)
} for layer in range(params['num_layers'])
}
print("cache key shape for layer 1 :", beam_cache['layer_1']['k'].shape)
ids, _ = beam_search.sequence_beam_search(
symbols_to_logits_fn=_symbols_to_logits_fn(),
initial_ids=tf.constant([9], tf.int32),
initial_cache=beam_cache,
vocab_size=3,
beam_size=beam_size,
alpha=0.6,
max_decode_length=params['max_decode_length'],
eos_id=10,
padded_decode=False,
dtype=tf.float32)
print("Beam search ids:", ids)
cache key shape for layer 1 : (1, 4, 2, 256) Beam search ids: tf.Tensor( [[[9 0 1 2 2] [9 1 2 2 2]]], shape=(1, 2, 5), dtype=int32)