فك تشفير API

عرض على TensorFlow.org تشغيل في Google Colab عرض على جيثب تحميل دفتر

ملخص

في الماضي القريب ، كان هناك الكثير من الأبحاث في مجال توليد اللغة باستخدام نماذج الانحدار التلقائي. في توليد لغة السيارات الرجعية، وتوزيع احتمال رمز في وقت خطوة K يعتمد على التوقعات رمزية للنموذج حتى خطوة K-1. لهذه النماذج والاستراتيجيات فك مثل شعاع البحث، طماع، الأعلى ف، وأعلى ك هي مكونات أساسية للنموذج وتؤثر إلى حد كبير على غرار / طبيعة الإخراج التي تم إنشاؤها رمزية في وقت خطوة K معين.

على سبيل المثال، البحث شعاع يقلل من خطر المفقودين الرموز ارتفاع احتمال مخفي عن طريق الحفاظ على معظم num_beams الأرجح من الفرضيات في كل خطوة الوقت وفي نهاية المطاف اختيار الفرضية القائلة بأن لديه عموما أعلى احتمال. موراي وآخرون. (2018) و يانغ وآخرون. (2018) تبين أن البحث شعاع يعمل بشكل جيد في مهام الترجمة الآلية. كلا شعاع البحث واستراتيجيات الجشع لديهم إمكانية توليد الرموز تكرار.

فان وآخرون. آخرون (2018) قدم أعلى-K أخذ العينات، التي يتم فيها إعادة توزيع K يتم تصفيتها الرموز الأكثر احتمالا وكتلة احتمال بين تلك الرموز فقط K.

آري هولتزمان وآخرون. آخرون (2019) قدم أخذ العينات الأعلى ف، الذي يختار من أصغر مجموعة ممكنة من الرموز مع الاحتمال التراكمي الذي يضيف تصل احتمال ص. ثم يتم إعادة توزيع كتلة الاحتمال بين هذه المجموعة. بهذه الطريقة ، يمكن أن يزيد حجم مجموعة الرموز ويقلص ديناميكيًا. وتستخدم كبار ف، ك أعلى عموما في مهام مثل الجيل طوابق.

يوفر Decoding API واجهة لتجربة استراتيجيات فك التشفير المختلفة على نماذج الانحدار التلقائي.

  1. يتم توفير استراتيجيات أخذ العينات التالية في sampling_module.py ، والتي ترث من فئة فك التشفير الأساسية:

  2. يتم توفير بحث الشعاع في beam_search.py. جيثب

يثبت

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: استخدام هذا الإغلاق لاستدعاء نموذج للتنبؤ logits لل 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: تعيين هذا صحيح إذا يعمل على TPU. تكون الموترات مبطنة إلى max_decoding_length إذا كان هذا صحيحًا.

  • top_k: يتم تمكين top_k إذا هذه القيمة> 1.

  • يتم تمكين top_p إذا هذه القيمة> 0 و <1.0: top_p

  • sampling_temperature: هذا وتستخدم لإعادة تقدير-إخراج softmax. تميل درجة الحرارة التوزيع نحو الرموز المميزة ذات الاحتمالية العالية وتخفض الكتلة في توزيع الذيل. يجب أن تكون القيمة موجبة. درجة الحرارة المنخفضة تعادل الجشع وتجعل التوزيع أكثر حدة ، في حين أن درجة الحرارة المرتفعة تجعله أكثر ثباتًا.

  • enable_greedy: افتراضيا، وهذا هو صحيح ويتم تمكين فك الجشع. لتجربة استراتيجيات أخرى ، يرجى ضبط هذا على خطأ.

تهيئة النموذج التشعبي

params = {}
params['num_heads'] = 2
params['num_layers'] = 2
params['batch_size'] = 2
params['n_dims'] = 256
params['max_decode_length'] = 4

في أبنية السيارات الرجعية مثل المحولات القائمة على التشفير، فك النماذج، ويستخدم ذاكرة التخزين المؤقت من أجل فك رموز متسلسل سريع. إنه قاموس متداخل يخزن الحالات المخفية المحسوبة مسبقًا (المفتاح والقيم في كتل الانتباه الذاتي وفي كتل الانتباه المتبادل) لكل طبقة.

تهيئة ذاكرة التخزين المؤقت.

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, :]

قم بتهيئة الرموز_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_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، و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

بدلا من أخذ عينات فقط من الأرجح K رمز هويات، في الأعلى ف أخذ العينات يختار من أصغر مجموعة ممكنة من هويات الذين يتجاوز احتمال p الاحتمال التراكمي.

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)

بحث شعاع فك

يقلل البحث في الحزمة من مخاطر فقدان معرّفات الرموز المميزة المخفية ذات الاحتمالية العالية عن طريق الاحتفاظ بعدد الحزم الأكثر احتمالاً من الفرضيات في كل خطوة زمنية وفي النهاية اختيار الفرضية ذات الاحتمال الأكبر بشكل عام.

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)