TensorFlow/Keras সহ পাইথনে 5-লাইন GPT-স্টাইল টেক্সট জেনারেশন

2017 সালে প্রকাশিত হলেও ট্রান্সফরমারগুলি গত কয়েক বছরে উল্লেখযোগ্য আকর্ষণ অর্জন করতে শুরু করেছে। HuggingFace, NLP এবং এর মত প্ল্যাটফর্মের মাধ্যমে প্রযুক্তির বিস্তারের সাথে বড় ভাষার মডেল (LLMs) আগের চেয়ে আরও অ্যাক্সেসযোগ্য হয়ে উঠেছে।

তবুও – এমনকি তাদের চারপাশে এবং সঙ্গে সব হাইপ সঙ্গে অনেক তত্ত্ব-ভিত্তিক নির্দেশিকা, অনলাইনে অনেকগুলি কাস্টম বাস্তবায়ন নেই, এবং সংস্থানগুলি কিছু অন্যান্য নেটওয়ার্ক প্রকারের মতো সহজলভ্য নয়, যা দীর্ঘকাল ধরে রয়েছে। আপনি HuggingFace (অন্য গাইডের বিষয়) থেকে একটি প্রাক-নির্মিত ট্রান্সফরমার ব্যবহার করে আপনার কর্মচক্রকে সহজ করতে পারেন - আপনি পেতে পারেন মনে একটি লাইব্রেরির মাধ্যমে এটিকে বিমূর্ত করার আগে এটি নিজেই একটি তৈরি করে কীভাবে কাজ করে। আমরা এখানে তত্ত্ব এবং অপ্টিমাইজেশানের পরিবর্তে বিল্ডিংয়ের উপর ফোকাস করব।

এই নির্দেশিকা, আমরা একটি নির্মাণ করা হবে অটোরিগ্রেসিভ ল্যাঙ্গুয়েজ মডেল থেকে টেক্সট তৈরি করুন. আমরা ডেটা লোড করার ব্যবহারিক এবং সংক্ষিপ্ত/সংক্ষিপ্ত দিকগুলিতে ফোকাস করব, এটিকে বিভক্ত করা, এটিকে ভেক্টরাইজ করা, একটি মডেল তৈরি করা, একটি কাস্টম কলব্যাক লেখা এবং প্রশিক্ষণ/অনুমান করা। এই কাজগুলির প্রত্যেকটি আরও বিস্তারিত নির্দেশিকাগুলিতে তৈরি করা যেতে পারে, তাই আমরা বাস্তবায়নটিকে একটি সাধারণ হিসাবে রাখব, আপনার নিজস্ব ডেটাসেটের উপর নির্ভর করে কাস্টমাইজেশন এবং অপ্টিমাইজেশনের জন্য জায়গা রেখে দেব।

LLM এবং GPT-Fyodor এর প্রকারভেদ

যদিও শ্রেণীকরণ অনেক বেশি জটিল হতে পারে - আপনি করতে পারেন বিস্তৃতভাবে ট্রান্সফরমার-ভিত্তিক ভাষা মডেলকে তিনটি বিভাগে শ্রেণীবদ্ধ করুন:

  • এনকোডার-ভিত্তিক মডেল - আলবার্ট, বার্ট, ডিস্টিলবার্ট, রবার্টা
  • ডিকোডার-ভিত্তিক - GPT, GPT-2, GPT-3, TransformerXL
  • Seq2Seq মডেল - BART, mBART, T5

এনকোডার ভিত্তিক মডেলগুলি শুধুমাত্র তাদের আর্কিটেকচারে একটি ট্রান্সফরমার এনকোডার ব্যবহার করে (সাধারণত, স্ট্যাক করা) এবং বাক্য বোঝার জন্য দুর্দান্ত (শ্রেণীবিভাগ, নামযুক্ত সত্তা স্বীকৃতি, প্রশ্নের উত্তর)।

ডিকোডার ভিত্তিক মডেলগুলি শুধুমাত্র তাদের আর্কিটেকচারে একটি ট্রান্সফরমার ডিকোডার ব্যবহার করে (এছাড়াও সাধারণত স্ট্যাক করা) এবং ভবিষ্যতের ভবিষ্যদ্বাণীর জন্য দুর্দান্ত, যা তাদের পাঠ্য তৈরির জন্য উপযুক্ত করে তোলে।

সিক 2 সেক মডেলগুলি এনকোডার এবং ডিকোডার উভয়ই একত্রিত করে এবং পাঠ্য তৈরি, সংক্ষিপ্তকরণ এবং সবচেয়ে গুরুত্বপূর্ণ - অনুবাদে দুর্দান্ত।

মডেলের GPT পরিবার, যা গত কয়েক বছরে প্রচুর ট্র্যাকশন অর্জন করেছে, এটি ডিকোডার-ভিত্তিক ট্রান্সফরমার মডেল, এবং মানুষের মতো পাঠ্য তৈরিতে দুর্দান্ত, ডেটার বড় কর্পোরার উপর প্রশিক্ষিত, এবং একটি নতুন হিসাবে প্রম্পট দেওয়া হয়েছে প্রজন্মের জন্য শুরু বীজ। এই ক্ষেত্রে:

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 অনুকরণ করে। যেহেতু আমরা ফিডর দস্তয়েভস্কির উপন্যাসে মডেলটিকে প্রশিক্ষণ দেব (যা আপনি উইকিপিডিয়া থেকে রেডডিট মন্তব্য পর্যন্ত অন্য কিছু দিয়ে প্রতিস্থাপন করতে পারেন) - আমরা অস্থায়ীভাবে মডেলটিকে কল করব GPT-Fyodor.

কেরাসএনএলপি

একটি 5-লাইন GPT-Fyodor-এর কৌশলটি রয়েছে৷ কেরাসএনএলপি, যা কেরাসের একটি অনুভূমিক এক্সটেনশন হিসাবে অফিসিয়াল কেরাস টিম দ্বারা তৈরি করা হয়েছে, যা সত্যিকারের কেরাস ফ্যাশনে, নতুন স্তরগুলির (এনকোডার, ডিকোডার, টোকেন এম্বেডিং, অবস্থান এমবেডিং, মেট্রিক্স, টোকেনাইজার, ইত্যাদি)।

কেরাসএনএলপি একটি মডেল চিড়িয়াখানা নয়. এটি কেরাসের একটি অংশ (একটি পৃথক প্যাকেজ হিসাবে), যা এনএলপি মডেল বিকাশের জন্য প্রবেশের বাধাকে কম করে, ঠিক যেমন এটি মূল প্যাকেজের সাথে সাধারণ গভীর শিক্ষার বিকাশের জন্য প্রবেশের বাধাকে কম করে।

বিঃদ্রঃ: কেরাসএনএলপি লেখার সময় এখনও উত্পাদিত হচ্ছে এবং প্রাথমিক পর্যায়ে। সূক্ষ্ম পার্থক্য ভবিষ্যতে সংস্করণ উপস্থিত হতে পারে. লেখার সংস্করণ ব্যবহার করা হয় 0.3.0.

KerasNLP ব্যবহার করতে সক্ষম হতে, আপনাকে এটি এর মাধ্যমে ইনস্টল করতে হবে pip:

$ pip install keras_nlp

এবং আপনি এর সাথে সংস্করণটি যাচাই করতে পারেন:

keras_nlp.__version__

কেরাসের সাথে একটি GPT-স্টাইল মডেল বাস্তবায়ন করা

আসুন আমরা যে লাইব্রেরিগুলি ব্যবহার করব তা আমদানি করে শুরু করি - TensorFlow, Keras, KerasNLP এবং NumPy:

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

তথ্য প্রস্তুত হচ্ছে

চলুন দস্তয়েভস্কির কয়েকটি উপন্যাসে লোড করা যাক - একটি মডেলের জন্য উপযুক্ত হওয়ার জন্য খুব ছোট হবে, প্রাথমিক পর্যায় থেকে মোটামুটি ওভারফিটিং ছাড়াই। আমরা gracefully থেকে কাঁচা টেক্সট ফাইল ব্যবহার করা হবে প্রকল্প গুটেনবার্গ, এই ধরনের ডেটার সাথে কাজ করার সরলতার কারণে:

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) 

আমরা 69k বাক্য পেয়েছি. আপনি প্রতিস্থাপন যখন 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-শব্দ (টোকেন) দীর্ঘ। সেই ক্ষেত্রে, ওয়াল-ই বাক্য দুটি শূন্য দ্বারা প্যাড করা হবে যাতে আমরা একই ইনপুট আকৃতি নিশ্চিত করি:

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

ঐতিহ্যগতভাবে, এটি একটি টেনসরফ্লো ব্যবহার করে করা হয়েছিল Tokenizer এবং কেরাস' pad_sequences() পদ্ধতি - যাইহোক, একটি অনেক সহজ স্তর, TextVectorization, ব্যবহার করা যেতে পারে, যা টোকেনাইজ করে এবং আপনার ইনপুট প্যাড করে, আপনাকে ভোকাবুলারি এবং এর আকার বের করতে দেয়, ভোকাব আগে না জেনেই!

সেরা-অভ্যাস, শিল্প-স্বীকৃত মান এবং অন্তর্ভুক্ত চিট শীট সহ গিট শেখার জন্য আমাদের হ্যান্ডস-অন, ব্যবহারিক গাইড দেখুন। গুগলিং গিট কমান্ড এবং আসলে বন্ধ করুন শেখা এটা!

এর মানিয়ে নেওয়া যাক এবং একটি ফিট করা যাক 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, আমরা একটি মাধ্যমে ইনপুট এনকোড করব 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 প্যারাম) রয়েছে, যখন GPT-2 অতিরিক্ত বড়-এ 48টি স্তুপীকৃত ডিকোডার (1.5B প্যারাম) রয়েছে। একটি নম্র 13M প্যারামিটার সহ আমাদের একক-ডিকোডার মডেলটি শিক্ষাগত উদ্দেশ্যে যথেষ্ট ভাল কাজ করবে৷ এলএলএম-এর সাথে - স্কেলিং আপ একটি অত্যন্ত ভাল কৌশল হিসাবে প্রমাণিত হয়েছে, এবং ট্রান্সফরমারগুলি ভাল স্কেলিং করার অনুমতি দেয়, এটি অত্যন্ত বড় মডেলগুলিকে প্রশিক্ষণ দেওয়া সম্ভবপর করে তোলে।

GPT-3 আছে a "অল্প" 175B প্যারামিটার। Google ব্রেইনের দল একটি 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 স্তরগুলি

ডিকোডারের বিভিন্ন গভীরতা ব্যবহার করে দেখুন - 1 থেকে আপনার মেশিন যেভাবে পরিচালনা করতে পারে এবং ফলাফলগুলি নোট করতে পারে। যাই হোক না কেন - আমরা মডেলকে প্রশিক্ষণ দিতে প্রায় প্রস্তুত! আসুন একটি কাস্টম কলব্যাক তৈরি করি যা প্রতিটি যুগে পাঠ্যের একটি নমুনা তৈরি করবে, যাতে আমরা দেখতে পারি কিভাবে মডেলটি প্রশিক্ষণের মাধ্যমে বাক্য গঠন করতে শেখে।

কাস্টম কলব্যাক

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 – একটি পদ্ধতি যা একটি বীজ এবং একটি গ্রহণ করে 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 লাইন প্রয়োজন!

জেনেরিক সিকোয়েন্স মডেলিংয়ের জন্য ট্রান্সফরমার জনপ্রিয় এবং ব্যাপকভাবে প্রযোজ্য (এবং অনেক কিছুকে সিকোয়েন্স হিসেবে প্রকাশ করা যেতে পারে)। এখন পর্যন্ত, প্রবেশের প্রধান বাধা ছিল একটি জটিল বাস্তবায়ন, কিন্তু কেরাসএনএলপি-র সাথে গভীর শিক্ষার অনুশীলনকারীরা দ্রুত এবং সহজে মডেল তৈরি করতে বাস্তবায়নের সুবিধা নিতে পারে।

সময় স্ট্যাম্প:

থেকে আরো Stackabuse