TensorFlow/Keras کے ساتھ Python میں 5-لائن GPT-اسٹائل ٹیکسٹ جنریشن

ٹرانسفارمرز، اگرچہ 2017 میں ریلیز ہوئے، صرف پچھلے دو سالوں میں ہی نمایاں کرشن حاصل کرنا شروع ہوئے ہیں۔ HuggingFace، NLP اور جیسے پلیٹ فارمز کے ذریعے ٹیکنالوجی کے پھیلاؤ کے ساتھ بڑی زبان کے ماڈلز (LLMs) پہلے سے کہیں زیادہ قابل رسائی ہو گئے ہیں۔

پھر بھی – یہاں تک کہ ان کے آس پاس کی تمام ہائپ کے ساتھ اور ساتھ بہت سے تھیوری پر مبنی گائیڈز، آن لائن بہت سے حسب ضرورت نفاذ نہیں ہیں، اور وسائل اتنے آسانی سے دستیاب نہیں ہیں جتنے کہ نیٹ ورک کی کچھ دوسری اقسام کے ساتھ، جو کہ طویل عرصے سے موجود ہیں۔ جب کہ آپ HuggingFace (دوسرے گائیڈ کا موضوع) سے پہلے سے بنایا ہوا ٹرانسفارمر استعمال کر کے اپنے ورک سائیکل کو آسان بنا سکتے ہیں - آپ حاصل کر سکتے ہیں محسوس لائبریری کے ذریعے اس کا خلاصہ کرنے سے پہلے یہ خود اسے بنا کر کیسے کام کرتا ہے۔ ہم یہاں تھیوری اور اصلاح کے بجائے تعمیر پر توجہ مرکوز کریں گے۔

اس گائیڈ میں، ہم ایک کی تعمیر کریں گے۔ خود مختار زبان کا ماڈل کرنے کے لئے متن پیدا کریں. ہم ڈیٹا کو لوڈ کرنے، اس کو تقسیم کرنے، اسے ویکٹرائز کرنے، ماڈل بنانے، حسب ضرورت کال بیک لکھنے اور تربیت/انفرنس کے عملی اور کم سے کم/مختصر پہلوؤں پر توجہ مرکوز کریں گے۔ ان میں سے ہر ایک کام کو مزید تفصیلی گائیڈز میں تبدیل کیا جا سکتا ہے، لہذا ہم آپ کے اپنے ڈیٹاسیٹ کے لحاظ سے تخصیص اور اصلاح کی گنجائش چھوڑتے ہوئے عمل درآمد کو ایک عام کے طور پر رکھیں گے۔

LLMs اور GPT-Fyodor کی اقسام

جبکہ درجہ بندی بہت زیادہ پیچیدہ ہو سکتی ہے – آپ کر سکتے ہیں۔ موٹے طور پر ٹرانسفارمر پر مبنی لینگویج ماڈلز کو تین زمروں میں درجہ بندی کریں:

  • انکوڈر پر مبنی ماڈلز - البرٹ، برٹ، ڈسٹل برٹ، روبرٹا
  • ڈیکوڈر پر مبنی - GPT, GPT-2, GPT-3, TransformerXL
  • Seq2Seq ماڈلز - BART، mBART، T5

انکوڈر پر مبنی ماڈلز اپنے فن تعمیر میں صرف ایک ٹرانسفارمر انکوڈر کا استعمال کرتے ہیں (عام طور پر، اسٹیکڈ) اور جملوں کو سمجھنے کے لیے بہترین ہیں (درجہ بندی، نام کی ہستی کی شناخت، سوال کا جواب دینا)۔

ڈیکوڈر پر مبنی ماڈلز اپنے فن تعمیر میں صرف ٹرانسفارمر ڈیکوڈر کا استعمال کرتے ہیں (عام طور پر اسٹیکڈ بھی) اور مستقبل کی پیشین گوئی کے لیے بہترین ہیں، جو انہیں متن کی تیاری کے لیے موزوں بناتا ہے۔

Seq2Seq ماڈلز انکوڈرز اور ڈیکوڈرز دونوں کو یکجا کرتے ہیں اور ٹیکسٹ جنریشن، خلاصہ اور سب سے اہم - ترجمہ میں بہترین ہیں۔

ماڈلز کا جی پی ٹی خاندان، جس نے پچھلے کچھ سالوں میں بہت زیادہ توجہ حاصل کی ہے، ڈیکوڈر پر مبنی ٹرانسفارمر ماڈلز ہیں، اور انسان کی طرح متن تیار کرنے میں بہت اچھے ہیں، ڈیٹا کے بڑے کارپورا پر تربیت یافتہ ہیں، اور ایک نئے کے طور پر فوری طور پر دیا گیا ہے۔ نسل کے لیے ابتدائی بیج۔ مثال کے طور پر:

generate_text('the truth ultimately is')

جو ہڈ کے نیچے اس پرامپٹ کو GPT نما ماڈل میں فیڈ کرتا ہے، اور پیدا کرتا ہے:

'the truth ultimately is really a joy in history, this state of life through which is almost invisible, superfluous  teleological...'

یہ درحقیقت گائیڈ کے اختتام سے ایک چھوٹا سا بگاڑنے والا ہے! ایک اور چھوٹا بگاڑنے والا فن تعمیر ہے جس نے اس متن کو تیار کیا:

inputs = layers.Input(shape=(maxlen,))
embedding_layer = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
transformer_block = keras_nlp.layers.TransformerDecoder(embed_dim, num_heads)(embedding_layer)
outputs = layers.Dense(vocab_size, activation='softmax')(transformer_block)
    
model = keras.Model(inputs=inputs, outputs=outputs)

صرف ایک ڈیکوڈر ٹرانسفارمر ماڈل بنانے کے لیے صرف 5 لائنیں لگتی ہیں - ایک چھوٹے GPT کی نقل کرتے ہوئے۔ چونکہ ہم ماڈل کو فیوڈور دوستوفسکی کے ناولوں پر تربیت دیں گے (جسے آپ وکی پیڈیا سے لے کر Reddit تبصروں تک کسی اور چیز سے بدل سکتے ہیں) - ہم عارضی طور پر ماڈل کو کال کریں گے۔ جی پی ٹی فیوڈور.

KerasNLP

5 لائن والے GPT-Fyodor کی چال اس میں مضمر ہے۔ KerasNLP، جسے آفیشل Keras ٹیم نے Keras میں افقی توسیع کے طور پر تیار کیا ہے، جس کا اصل Keras فیشن میں، نئی پرتوں (انکوڈرز، ڈیکوڈرز، ٹوکن ایمبیڈنگز، پوزیشن ایمبیڈنگز، میٹرکس،) کے ساتھ صنعت کی طاقت NLP کو آپ کی انگلیوں تک پہنچانا ہے۔ ٹوکنائزرز وغیرہ)۔

KerasNLP ایک ماڈل چڑیا گھر نہیں ہے۔. یہ Keras کا ایک حصہ ہے (ایک علیحدہ پیکج کے طور پر)، جو NLP ماڈل کی ترقی کے لیے داخلے کی رکاوٹ کو کم کرتا ہے، بالکل اسی طرح جیسے یہ مرکزی پیکج کے ساتھ عمومی گہری سیکھنے کی ترقی کے لیے داخلے کی رکاوٹ کو کم کرتا ہے۔

نوٹ: لکھنے کے مطابق KerasNLP ابھی بھی تیار کیا جا رہا ہے، اور ابتدائی مراحل میں۔ ٹھیک ٹھیک اختلافات مستقبل کے ورژن میں موجود ہو سکتے ہیں۔ رائٹ اپ ورژن کا استعمال کر رہا ہے۔ 0.3.0.

KerasNLP استعمال کرنے کے قابل ہونے کے لیے، آپ کو اسے اس کے ذریعے انسٹال کرنا ہوگا۔ pip:

$ pip install keras_nlp

اور آپ اس کے ساتھ ورژن کی تصدیق کر سکتے ہیں:

keras_nlp.__version__

کیراس کے ساتھ جی پی ٹی اسٹائل ماڈل کو نافذ کرنا

آئیے ان لائبریریوں کو درآمد کرکے شروع کریں جو ہم استعمال کریں گے - TensorFlow، Keras، KerasNLP اور NumPy:

import tensorflow as tf
from tensorflow import keras
import keras_nlp
import numpy as np

ڈیٹا لوڈ ہو رہا ہے

آئیے دوستوفسکی کے چند ناولوں کو لوڈ کرتے ہیں – ایک ماڈل کے فٹ ہونے کے لیے بہت چھوٹا ہو گا، ابتدائی مراحل سے لے کر اب تک کسی حد تک اوور فٹنگ کے بغیر۔ ہم اس کی خام ٹیکسٹ فائلوں کو احسن طریقے سے استعمال کریں گے۔ پروجیکٹ گٹینبرگاس طرح کے ڈیٹا کے ساتھ کام کرنے کی سادگی کی وجہ سے:

crime_and_punishment_url = 'https://www.gutenberg.org/files/2554/2554-0.txt'
brothers_of_karamazov_url = 'https://www.gutenberg.org/files/28054/28054-0.txt'
the_idiot_url = 'https://www.gutenberg.org/files/2638/2638-0.txt'
the_possessed_url = 'https://www.gutenberg.org/files/8117/8117-0.txt'

paths = [crime_and_punishment_url, brothers_of_karamazov_url, the_idiot_url, the_possessed_url]
names = ['Crime and Punishment', 'Brothers of Karamazov', 'The Idiot', 'The Possessed']
texts = ''
for index, path in enumerate(paths):
    filepath = keras.utils.get_file(f'{names[index]}.txt', origin=path)
    text = ''
    with open(filepath, encoding='utf-8') as f:
        text = f.read()
        
        
        
        texts += text[10000:]

ہم نے آسانی سے تمام فائلوں کو ڈاؤن لوڈ کیا ہے، ان میں سے گزرے ہیں اور ان کو ایک دوسرے کے اوپر جوڑ دیا ہے۔ اس میں استعمال کی جانے والی زبان میں کچھ تنوع بھی شامل ہے، جبکہ اسے اب بھی واضح طور پر رکھتے ہوئے Fyodor! ہر فائل کے لیے، ہم نے پہلے 10k حروف کو چھوڑ دیا ہے، جو کہ دیباچہ اور گٹنبرگ تعارف کی اوسط لمبائی کے قریب ہے، اس لیے ہمارے پاس ہر تکرار کے لیے کتاب کا ایک بڑا حصہ باقی رہ گیا ہے۔ آئیے میں کچھ بے ترتیب 500 حروف پر ایک نظر ڈالیں۔ texts ابھی تار:


texts[25000:25500]
'nd that was whynI addressed you at once. For in unfolding to you the story of my life, Indo not wish to make myself a laughing-stock before these idle listeners,nwho indeed know all about it already, but I am looking for a mannof feeling and education. Know then that my wife was educated in anhigh-class school for the daughters of noblemen, and on leaving shendanced the shawl dance before the governor and other personages fornwhich she was presented with a gold medal and a certificate of merit.n'

آئیے کوئی اور پروسیسنگ کرنے سے پہلے سٹرنگ کو جملوں میں الگ کریں:

text_list = texts.split('.')
len(text_list) 

ہمارے پاس 69 ہزار جملے ہیں۔ جب آپ کو تبدیل کریں۔ n وائٹ اسپیس والے حروف اور الفاظ گنیں:

len(texts.replace('n', ' ').split(' ')) 

نوٹ: آپ عام طور پر ڈیٹا سیٹ میں کم از کم دس لاکھ الفاظ رکھنا چاہیں گے، اور مثالی طور پر، اس سے کہیں زیادہ۔ ہم چند میگا بائٹس ڈیٹا (~5MB) کے ساتھ کام کر رہے ہیں جبکہ لینگویج ماڈلز کو عام طور پر دسیوں گیگا بائٹس ٹیکسٹ پر تربیت دی جاتی ہے۔ اس سے، قدرتی طور پر، ٹیکسٹ ان پٹ کو اوور فٹ کرنا واقعی آسان ہو جائے گا اور عام کرنا مشکل ہو جائے گا (اوور فٹنگ کے بغیر زیادہ پریشانی، یا بہت زیادہ فٹنگ کے ساتھ کم پریشانی)۔ نمک کے ایک دانے کے ساتھ نتائج لیں۔

بہر حال، آئیے ان کو ایک میں تقسیم کرتے ہیں۔ تربیت, ٹیسٹ اور توثیق سیٹ سب سے پہلے، آئیے خالی تاروں کو ہٹاتے ہیں اور جملوں کو شفل کرتے ہیں:


text_list = list(filter(None, text_list))

import random
random.shuffle(text_list)

پھر، ہم ایک 70/15/15 تقسیم کریں گے:

length = len(text_list)
text_train = text_list[:int(0.7*length)]
text_test = text_list[int(0.7*length):int(0.85*length)]
text_valid = text_list[int(0.85*length):]

یہ ٹرین ٹیسٹ کی توثیق کی تقسیم کو انجام دینے کا ایک آسان، لیکن مؤثر طریقہ ہے۔ آئیے ایک جھانکتے ہیں۔ text_train:

[' It was a dull morning, but the snow had ceased',
 'nn"Pierre, you who know so much of what goes on here, can you really havenknown nothing of this business and have heard nothing about it?"nn"What? What a set! So it's not enough to be a child in your old age,nyou must be a spiteful child too! Varvara Petrovna, did you hear what hensaid?"nnThere was a general outcry; but then suddenly an incident took placenwhich no one could have anticipated', ...

معیاری کاری اور ویکٹرائزیشن کا وقت!

ٹیکسٹ ویکٹرائزیشن

نیٹ ورک الفاظ کو نہیں سمجھتے – وہ نمبر سمجھتے ہیں۔ ہم الفاظ کو نشان زد کرنا چاہیں گے:

...
sequence = ['I', 'am', 'Wall-E']
sequence = tokenize(sequence)
print(sequence) # [4, 26, 472]
...

اس کے علاوہ، چونکہ جملے لمبائی میں مختلف ہوتے ہیں - پیڈنگ کو عام طور پر بائیں یا دائیں شامل کیا جاتا ہے تاکہ اس بات کو یقینی بنایا جا سکے کہ تمام جملوں میں ایک ہی شکل کو شامل کیا جا رہا ہے۔ کہہ دیں کہ ہمارا سب سے طویل جملہ 5-الفاظ (ٹوکن) لمبا ہے۔ اس صورت میں، Wall-E جملے کو دو زیرو سے پیڈ کیا جائے گا لہذا ہم ایک ہی ان پٹ شکل کو یقینی بناتے ہیں:

sequence = pad_sequence(sequence)
print(sequence) # [4, 26, 472, 0, 0]

روایتی طور پر، یہ TensorFlow کا استعمال کرتے ہوئے کیا جاتا تھا۔ Tokenizer اور کیراس pad_sequences() طریقوں - تاہم، ایک بہت زیادہ آسان پرت، TextVectorization، استعمال کیا جا سکتا ہے، جو ٹوکنائز کرتا ہے۔ اور آپ کے ان پٹ کو پیڈ کرتا ہے، جس سے آپ کو الفاظ اور اس کے سائز کو نکالنے کی اجازت ملتی ہے، بغیر پہلے کے الفاظ کو جانے!

بہترین طرز عمل، صنعت کے لیے منظور شدہ معیارات، اور چیٹ شیٹ کے ساتھ Git سیکھنے کے لیے ہمارے ہینڈ آن، عملی گائیڈ کو دیکھیں۔ گوگلنگ گٹ کمانڈز کو روکیں اور اصل میں سیکھ یہ!

آئیے ہم آہنگ کریں اور فٹ کریں a TextVectorization پرت:

from tensorflow.keras.layers import TextVectorization

def custom_standardization(input_string):
    sentence = tf.strings.lower(input_string)
    sentence = tf.strings.regex_replace(sentence, "n", " ")
    return sentence

maxlen = 50



vectorize_layer = TextVectorization(
    standardize = custom_standardization,
    output_mode="int",
    output_sequence_length=maxlen + 1,
)

vectorize_layer.adapt(text_list)
vocab = vectorize_layer.get_vocabulary()

۔ custom_standardization() طریقہ اس سے بہت لمبا ہو سکتا ہے۔ ہم نے بس تمام ان پٹ کو چھوٹا کر کے بدل دیا ہے۔ n ساتھ " ". یہ وہ جگہ ہے جہاں آپ متن کے لیے اپنی زیادہ تر پری پروسیسنگ میں ڈال سکتے ہیں – اور اسے اختیاری کے ذریعے ویکٹرائزیشن پرت میں فراہم کر سکتے ہیں۔ standardize دلیل. ایک بار آپ adapt() متن کی پرت (NumPy سرنی یا متن کی فہرست) - آپ وہاں سے الفاظ کے ساتھ ساتھ اس کا سائز بھی حاصل کر سکتے ہیں:

vocab_size = len(vocab)
vocab_size 

آخر میں، الفاظ کو ڈی ٹوکنائز کرنے کے لیے، ہم ایک بنائیں گے۔ index_lookup لغت:

index_lookup = dict(zip(range(len(vocab)), vocab))    
index_lookup[5] 

یہ تمام ٹوکنز کا نقشہ بناتا ہے ([1, 2, 3, 4, ...]الفاظ میں الفاظ تک (['a', 'the', 'i', ...])۔ ایک کلید (ٹوکن انڈیکس) میں گزرنے سے، ہم آسانی سے لفظ واپس حاصل کر سکتے ہیں۔ اب آپ چلا سکتے ہیں۔ vectorize_layer() کسی بھی ان پٹ پر اور ویکٹرائزڈ جملوں کا مشاہدہ کریں:

vectorize_layer(['hello world!'])

جس کے نتیجے میں:

<tf.Tensor: shape=(1, 51), dtype=int64, numpy=
array([[   1, 7509,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0]], dtype=int64)>

ہیلو کا انڈیکس ہے۔ 1 جبکہ دنیا کا انڈیکس ہے۔ 7509! باقی کی پیڈنگ ہے۔ maxlen ہم نے حساب لگایا ہے.

ہمارے پاس ٹیکسٹ کو ویکٹرائز کرنے کے ذرائع ہیں - اب، آئیے اس سے ڈیٹا سیٹ بنائیں text_train, text_test اور text_valid، ہماری ویکٹرائزیشن پرت کو الفاظ اور ویکٹرز کے درمیان تبادلوں کے ذریعہ کے طور پر استعمال کرتے ہوئے جنہیں GPT-Fyodor میں فیڈ کیا جا سکتا ہے۔

ڈیٹا سیٹ کی تخلیق

ہم ایک تخلیق کریں گے۔ tf.data.Dataset ہمارے ہر سیٹ کے لیے، استعمال کرتے ہوئے from_tensor_slices() اور اچھی طرح سے ٹینسر سلائسز (جملوں) کی فہرست فراہم کرنا:

batch_size = 64

train_dataset = tf.data.Dataset.from_tensor_slices(text_train)
train_dataset = train_dataset.shuffle(buffer_size=256)
train_dataset = train_dataset.batch(batch_size)

test_dataset = tf.data.Dataset.from_tensor_slices(text_test)
test_dataset = test_dataset.shuffle(buffer_size=256)
test_dataset = test_dataset.batch(batch_size)

valid_dataset = tf.data.Dataset.from_tensor_slices(text_valid)
valid_dataset = valid_dataset.shuffle(buffer_size=256)
valid_dataset = valid_dataset.batch(batch_size)

ایک بار تخلیق اور شفل ہو جانے کے بعد (دوبارہ، اچھی پیمائش کے لیے) - ہم پری پروسیسنگ (ویکٹرائزیشن اور سیکوئنس اسپلٹنگ) فنکشن کا اطلاق کر سکتے ہیں:

def preprocess_text(text):
    text = tf.expand_dims(text, -1)
    tokenized_sentences = vectorize_layer(text)
    x = tokenized_sentences[:, :-1]
    y = tokenized_sentences[:, 1:]
    return x, y


train_dataset = train_dataset.map(preprocess_text)
train_dataset = train_dataset.prefetch(tf.data.AUTOTUNE)

test_dataset = test_dataset.map(preprocess_text)
test_dataset = test_dataset.prefetch(tf.data.AUTOTUNE)

valid_dataset = valid_dataset.map(preprocess_text)
valid_dataset = valid_dataset.prefetch(tf.data.AUTOTUNE)

۔ preprocess_text() فنکشن صرف آخری جہت سے پھیلتا ہے، ہمارے استعمال کرکے متن کو ویکٹرائز کرتا ہے۔ vectorize_layer اور ان پٹ اور اہداف تخلیق کرتا ہے، ایک ہی ٹوکن کے ذریعے آفسیٹ کرتا ہے۔ ماڈل استعمال کرے گا۔ [0..n] نتیجہ نکالنا n+1, ہر لفظ کے لیے پیشین گوئی پیدا کرنا، اس سے پہلے کے تمام الفاظ کا حساب لگانا۔ آئیے کسی بھی ڈیٹاسیٹ میں ایک اندراج پر ایک نظر ڈالیں:

for entry in train_dataset.take(1):
    print(entry)

64 کے بیچوں (ہر ایک کی لمبائی 30 کے ساتھ) میں واپس کیے گئے ان پٹس اور اہداف کی چھان بین کرتے ہوئے، ہم واضح طور پر دیکھ سکتے ہیں کہ وہ کس طرح ایک سے آفسیٹ ہوتے ہیں:

(<tf.Tensor: shape=(64, 50), dtype=int64, numpy=
array([[17018,   851,     2, ...,     0,     0,     0],
       [  330,    74,     4, ...,     0,     0,     0],
       [   68,   752, 30273, ...,     0,     0,     0],
       ...,
       [    7,    73,  2004, ...,     0,     0,     0],
       [   44,    42,    67, ...,     0,     0,     0],
       [  195,   252,   102, ...,     0,     0,     0]], dtype=int64)>, <tf.Tensor: shape=(64, 50), dtype=int64, numpy=
array([[  851,     2,  8289, ...,     0,     0,     0],
       [   74,     4,    34, ...,     0,     0,     0],
       [  752, 30273,  7514, ...,     0,     0,     0],
       ...,
       [   73,  2004,    31, ...,     0,     0,     0],
       [   42,    67,    76, ...,     0,     0,     0],
       [  252,   102,  8596, ...,     0,     0,     0]], dtype=int64)>)

آخر میں - یہ ماڈل بنانے کا وقت ہے!

ماڈل کی تعریف

ہم یہاں KerasNLP تہوں کا استعمال کریں گے۔ ایک کے بعد Input، ہم ان پٹ کو a کے ذریعے انکوڈ کریں گے۔ TokenAndPositionEmbedding پرت، ہمارے میں گزر رہا ہے vocab_size, maxlen اور embed_dim. ایسا ہی embed_dim کہ یہ پرت آؤٹ پٹ اور ان پٹ میں داخل ہوتی ہے۔ TransformerDecoder ہو جائے گا ڈیکوڈر میں برقرار ہے۔. تحریری طور پر، ڈیکوڈر خود بخود ان پٹ کی جہت کو برقرار رکھتا ہے، اور آپ کو اسے مختلف آؤٹ پٹ میں پیش کرنے کی اجازت نہیں دیتا ہے، لیکن یہ آپ کو خفیہ جہتوں کی وضاحت کرنے دیتا ہے intermediate_dim دلیل.

ہم اویکت نمائیندگی کے لیے سرایت کرنے والے طول و عرض کو دو سے ضرب دیں گے، لیکن آپ اسے ایک جیسا رکھ سکتے ہیں یا ایمبیڈنگ ڈیمز سے علیحدہ نمبر استعمال کر سکتے ہیں:

embed_dim = 128
num_heads = 4

def create_model():
    inputs = keras.layers.Input(shape=(maxlen,), dtype=tf.int32)
    embedding_layer = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
    decoder = keras_nlp.layers.TransformerDecoder(intermediate_dim=embed_dim, 
                                                            num_heads=num_heads, 
                                                            dropout=0.5)(embedding_layer)
    
    outputs = keras.layers.Dense(vocab_size, activation='softmax')(decoder)
    
    model = keras.Model(inputs=inputs, outputs=outputs)
    
    model.compile(
        optimizer="adam", 
        loss='sparse_categorical_crossentropy',
        metrics=[keras_nlp.metrics.Perplexity(), 'accuracy']
    )
    return model

model = create_model()
model.summary()

ڈیکوڈر کے اوپر، ہمارے پاس ایک ہے۔ Dense ترتیب میں اگلا لفظ منتخب کرنے کے لیے پرت، a کے ساتھ softmax ایکٹیویشن (جو ہر اگلے ٹوکن کے لیے امکانی تقسیم پیدا کرتا ہے)۔ آئیے ماڈل کے خلاصے پر ایک نظر ڈالیں:

Model: "model_5"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_6 (InputLayer)        [(None, 30)]              0         
                                                                 
 token_and_position_embeddin  (None, 30, 128)          6365824   
 g_5 (TokenAndPositionEmbedd                                     
 ing)                                                            
                                                                 
 transformer_decoder_5 (Tran  (None, 30, 128)          132480    
 sformerDecoder)                                                 
                                                                 
 dense_5 (Dense)             (None, 30, 49703)         6411687   
                                                                 
=================================================================
Total params: 13,234,315
Trainable params: 13,234,315
Non-trainable params: 0
_________________________________________________________________

GPT-2 بہت سے ڈیکوڈرز کو اسٹیک کرتا ہے - GPT-2 Small میں 12 اسٹیکڈ ڈیکوڈرز (117M params) ہیں، جب کہ GPT-2 Extra Lar میں 48 اسٹیکڈ ڈیکوڈرز (1.5B پیرامز) ہیں۔ ہمارے سنگل ڈیکوڈر ماڈل کو ایک شائستہ 13M پیرامیٹرز کے ساتھ تعلیمی مقاصد کے لیے کافی اچھا کام کرنا چاہیے۔ LLMs کے ساتھ - اسکیلنگ اپ ایک بہت اچھی حکمت عملی ثابت ہوئی ہے، اور ٹرانسفارمرز اچھی اسکیلنگ کی اجازت دیتے ہیں، جس سے یہ انتہائی بڑے ماڈلز کو تربیت دینا ممکن بناتا ہے۔

GPT-3 میں ایک ہے۔ "معمولی" 175B پیرامیٹرز۔ گوگل برین کی ٹیم نے ایک 1.6T پیرامیٹر ماڈل کو تربیت دی ہے تاکہ اسپرسٹی تحقیق کو انجام دیا جا سکے اور حساب کو اسی سطح پر رکھا جائے جیسا کہ چھوٹے ماڈلز۔

درحقیقت، اگر ہم ڈیکوڈرز کی تعداد 1 سے بڑھا کر 3 کر دیں:

def create_model():
    inputs = keras.layers.Input(shape=(maxlen,), dtype=tf.int32)
    x = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
    for i in range(4):
        x = keras_nlp.layers.TransformerDecoder(intermediate_dim=embed_dim*2, num_heads=num_heads,                                                             dropout=0.5)(x)
    do = keras.layers.Dropout(0.4)(x)
    outputs = keras.layers.Dense(vocab_size, activation='softmax')(do)
    
    model = keras.Model(inputs=inputs, outputs=outputs)

ہمارے پیرامیٹر کی تعداد 400k تک بڑھ جائے گی:

Total params: 13,631,755
Trainable params: 13,631,755
Non-trainable params: 0

ہمارے نیٹ ورک میں زیادہ تر پیرامیٹرز سے آتے ہیں۔ TokenAndPositionEmbedding اور Dense تہوں!

ڈیکوڈر کی مختلف گہرائیوں کو آزمائیں۔ کسی بھی صورت میں – ہم ماڈل کو تربیت دینے کے لیے تقریباً تیار ہیں! آئیے ایک حسب ضرورت کال بیک بنائیں جو ہر دور پر متن کا نمونہ تیار کرے گا، تاکہ ہم دیکھ سکیں کہ ماڈل تربیت کے ذریعے جملے کیسے بنانا سیکھتا ہے۔

حسب ضرورت کال بیک

class TextSampler(keras.callbacks.Callback):
    def __init__(self, start_prompt, max_tokens):
        self.start_prompt = start_prompt
        self.max_tokens = max_tokens
        
    
    
    def sample_token(self, logits):
        logits, indices = tf.math.top_k(logits, k=5, sorted=True)
        indices = np.asarray(indices).astype("int32")
        preds = keras.activations.softmax(tf.expand_dims(logits, 0))[0]
        preds = np.asarray(preds).astype("float32")
        return np.random.choice(indices, p=preds)

    def on_epoch_end(self, epoch, logs=None):
        decoded_sample = self.start_prompt
        
        for i in range(self.max_tokens-1):
            tokenized_prompt = vectorize_layer([decoded_sample])[:, :-1]
            predictions = self.model.predict([tokenized_prompt], verbose=0)
            
            
            
            
            sample_index = len(decoded_sample.strip().split())-1
            
            sampled_token = self.sample_token(predictions[0][sample_index])
            sampled_token = index_lookup[sampled_token]
            decoded_sample += " " + sampled_token
            
        print(f"nSample text:n{decoded_sample}...n")


random_sentence = ' '.join(random.choice(text_valid).replace('n', ' ').split(' ')[:4])
sampler = TextSampler(random_sentence, 30)
reducelr = keras.callbacks.ReduceLROnPlateau(patience=10, monitor='val_loss')

ماڈل کی تربیت

آخر میں، تربیت کا وقت! چلو ہمارے میں چک train_dataset اور validation_dataset کال بیکس کے ساتھ:

model = create_model()
history = model.fit(train_dataset, 
                    validation_data=valid_dataset,
                    epochs=10, 
                    callbacks=[sampler, reducelr])

نمونے لینے والے نے ایک بدقسمت جملے کا انتخاب کیا جو اختتامی اقتباس اور آغاز کے اقتباس سے شروع ہوتا ہے، لیکن تربیت کے دوران یہ اب بھی دلچسپ نتائج پیدا کرتا ہے:

# Epoch training
Epoch 1/10
658/658 [==============================] - ETA: 0s - loss: 2.7480 - perplexity: 15.6119 - accuracy: 0.6711
# on_epoch_end() sample generation
Sample text:
”  “What do you had not been i had been the same man was not be the same eyes to been a whole man and he did a whole man to the own...
# Validation
658/658 [==============================] - 158s 236ms/step - loss: 2.7480 - perplexity: 15.6119 - accuracy: 0.6711 - val_loss: 2.2130 - val_perplexity: 9.1434 - val_accuracy: 0.6864 - lr: 0.0010
...
Sample text:
”  “What do you know it is it all this very much as i should not have a great impression  in the room to be  able of it in my heart...

658/658 [==============================] - 149s 227ms/step - loss: 1.7753 - perplexity: 5.9019 - accuracy: 0.7183 - val_loss: 2.0039 - val_perplexity: 7.4178 - val_accuracy: 0.7057 - lr: 0.0010

یہ اس سے شروع ہوتا ہے:

"تم کیا نہیں تھے میں ویسا تھا"...

جو واقعی زیادہ معنی نہیں رکھتا۔ دس مختصر ادوار کے اختتام تک، یہ ان خطوط پر کچھ پیدا کرتا ہے:

’’تمہارا کیا مطلب ہے کہ وہ انسان کا سب سے عام آدمی ہے‘‘…

جب کہ دوسرا جملہ اب بھی زیادہ معنی نہیں رکھتا ہے – یہ پہلے سے کہیں زیادہ حساس ہے۔ مزید ڈیٹا پر طویل تربیت (زیادہ پیچیدہ پری پروسیسنگ اقدامات کے ساتھ) بہتر نتائج برآمد کرے گی۔ چھوٹے ڈیٹا سیٹ کے سائز کا مقابلہ کرنے کے لیے ہم نے اسے صرف 10 عہدوں پر تربیت دی ہے جس میں زیادہ ڈراپ آؤٹ ہے۔ اگر اس کی تربیت زیادہ دیر تک چھوڑ دی جاتی تو یہ بہت فیوڈور جیسا متن تیار کرے گا، کیونکہ اس نے اس کے بڑے ٹکڑوں کو حفظ کرلیا ہوگا۔

نوٹ: چونکہ آؤٹ پٹ کافی لفظی ہے، آپ اسے موافقت دے سکتے ہیں۔ verbose اسکرین پر متن کی مقدار کو کم کرنے کے لیے ماڈل کو فٹ کرتے وقت دلیل۔

ماڈل کا اندازہ

اندازہ لگانے کے لیے، ہم انٹرفیس کو نقل کرنا چاہیں گے۔ TextSampler – ایک طریقہ جو بیج کو قبول کرتا ہے اور a response_length (max_tokens)۔ ہم وہی طریقے استعمال کریں گے جیسے نمونے کے اندر:

def sample_token(logits):
        logits, indices = tf.math.top_k(logits, k=5, sorted=True)
        indices = np.asarray(indices).astype("int32")
        preds = keras.activations.softmax(tf.expand_dims(logits, 0))[0]
        preds = np.asarray(preds).astype("float32")
        return np.random.choice(indices, p=preds)

def generate_text(prompt, response_length=20):
    decoded_sample = prompt
    for i in range(response_length-1):
        tokenized_prompt = vectorize_layer([decoded_sample])[:, :-1]
        predictions = model.predict([tokenized_prompt], verbose=0)
        sample_index = len(decoded_sample.strip().split())-1

        sampled_token = sample_token(predictions[0][sample_index])
        sampled_token = index_lookup[sampled_token]
        decoded_sample += " " + sampled_token
    return decoded_sample

اب، آپ نئے نمونوں پر طریقہ چلا سکتے ہیں:

generate_text('the truth ultimately is')


generate_text('the truth ultimately is')

نتائج کو بہتر بنانا؟

تو، آپ نتائج کو کیسے بہتر بنا سکتے ہیں؟ کچھ خوبصورت قابل عمل چیزیں ہیں جو آپ کر سکتے ہیں:

  • ڈیٹا کی صفائی (ان پٹ ڈیٹا کو زیادہ احتیاط سے صاف کریں، ہم نے شروع سے ہی ایک تخمینی تعداد کو تراش لیا اور نئے حروف کو ہٹا دیا)
  • مزید ڈیٹا حاصل کریں (ہم نے صرف چند میگا بائٹس ٹیکسٹ ڈیٹا کے ساتھ کام کیا)
  • ڈیٹا کے ساتھ ساتھ ماڈل کو اسکیل کریں (ڈیکوڈرز کو اسٹیک کرنا مشکل نہیں ہے!)

نتیجہ

جبکہ پری پروسیسنگ پائپ لائن کم سے کم ہے اور اسے بہتر بنایا جا سکتا ہے – اس گائیڈ میں بیان کردہ پائپ لائن نے ایک مہذب GPT طرز کا ماڈل تیار کیا ہے، جس میں صرف 5 لائنوں کوڈ کی ضرورت ہے جو کیراس کا استعمال کرتے ہوئے، صرف اپنی مرضی کے مطابق ڈیکوڈر ٹرانسفارمر بنانے کے لیے ضروری ہے!

ٹرانسفارمرز عام ترتیب ماڈلنگ کے لیے مقبول اور وسیع پیمانے پر لاگو ہوتے ہیں (اور بہت سی چیزوں کو ترتیب کے طور پر ظاہر کیا جا سکتا ہے)۔ ابھی تک، داخلے میں بنیادی رکاوٹ ایک بوجھل عمل درآمد تھا، لیکن KerasNLP کے ساتھ - گہری سیکھنے کے مشق کرنے والے ماڈلز کو تیزی سے اور آسانی سے بنانے کے لیے نفاذ کا فائدہ اٹھا سکتے ہیں۔

ٹائم اسٹیمپ:

سے زیادہ Stackabuse