इस पांचवे चरण का लक्ष्य बहुत सरल है: **पूर्ण LLM की आर्किटेक्चर विकसित करना**। सब कुछ एक साथ रखें, सभी परतों को लागू करें और पाठ उत्पन्न करने या पाठ को आईडी में और इसके विपरीत परिवर्तित करने के लिए सभी कार्यों को बनाएं।
LLM आर्किटेक्चर का उदाहरण [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01\_main-chapter-code/ch04.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb):
1.**Input (Tokenized Text)**: प्रक्रिया टोकनयुक्त पाठ के साथ शुरू होती है, जिसे संख्यात्मक प्रतिनिधित्व में परिवर्तित किया जाता है।
2.**Token Embedding and Positional Embedding Layer**: टोकनयुक्त पाठ को **टोकन एम्बेडिंग** परत और **पोजिशनल एम्बेडिंग परत** के माध्यम से भेजा जाता है, जो अनुक्रम में टोकनों की स्थिति को कैप्चर करता है, जो शब्द क्रम को समझने के लिए महत्वपूर्ण है।
3.**Transformer Blocks**: मॉडल में **12 ट्रांसफार्मर ब्लॉक्स** होते हैं, प्रत्येक में कई परतें होती हैं। ये ब्लॉक्स निम्नलिखित अनुक्रम को दोहराते हैं:
* **Masked Multi-Head Attention**: मॉडल को एक बार में इनपुट पाठ के विभिन्न भागों पर ध्यान केंद्रित करने की अनुमति देता है।
* **Layer Normalization**: प्रशिक्षण को स्थिर और सुधारने के लिए एक सामान्यीकरण कदम।
* **Feed Forward Layer**: ध्यान परत से जानकारी को संसाधित करने और अगले टोकन के बारे में भविष्यवाणी करने के लिए जिम्मेदार।
* **Dropout Layers**: ये परतें प्रशिक्षण के दौरान यादृच्छिक रूप से इकाइयों को छोड़कर ओवरफिटिंग को रोकती हैं।
4.**Final Output Layer**: मॉडल एक **4x50,257-आयामी टेन्सर** आउटपुट करता है, जहाँ **50,257** शब्दावली के आकार का प्रतिनिधित्व करता है। इस टेन्सर में प्रत्येक पंक्ति एक वेक्टर के अनुरूप होती है जिसका उपयोग मॉडल अनुक्रम में अगले शब्द की भविष्यवाणी करने के लिए करता है।
5.**Goal**: उद्देश्य इन एम्बेडिंग को लेना और उन्हें फिर से पाठ में परिवर्तित करना है। विशेष रूप से, आउटपुट की अंतिम पंक्ति का उपयोग अगले शब्द को उत्पन्न करने के लिए किया जाता है, जिसे इस आरेख में "आगे" के रूप में दर्शाया गया है।
x = tok_embeds + pos_embeds # Shape [batch_size, num_tokens, emb_size]
x = self.drop_emb(x)
x = self.trf_blocks(x)
x = self.final_norm(x)
logits = self.out_head(x)
return logits
GPT_CONFIG_124M = {
"vocab_size": 50257, # Vocabulary size
"context_length": 1024, # Context length
"emb_dim": 768, # Embedding dimension
"n_heads": 12, # Number of attention heads
"n_layers": 12, # Number of layers
"drop_rate": 0.1, # Dropout rate
"qkv_bias": False # Query-Key-Value bias
}
torch.manual_seed(123)
model = GPTModel(GPT_CONFIG_124M)
out = model(batch)
print("Input batch:\n", batch)
print("\nOutput shape:", out.shape)
print(out)
```
### **GELU सक्रियण फ़ंक्शन**
```python
# From https://github.com/rasbt/LLMs-from-scratch/tree/main/ch04
class GELU(nn.Module):
def __init__(self):
super().__init__()
def forward(self, x):
return 0.5 * x * (1 + torch.tanh(
torch.sqrt(torch.tensor(2.0 / torch.pi)) *
(x + 0.044715 * torch.pow(x, 3))
))
```
#### **उद्देश्य और कार्यक्षमता**
* **GELU (Gaussian Error Linear Unit):** एक सक्रियण फ़ंक्शन जो मॉडल में गैर-रेखीयता को पेश करता है।
* **स्मूद सक्रियण:** ReLU के विपरीत, जो नकारात्मक इनपुट को शून्य कर देता है, GELU इनपुट को आउटपुट में स्मूद तरीके से मैप करता है, जिससे नकारात्मक इनपुट के लिए छोटे, गैर-शून्य मानों की अनुमति मिलती है।
इस फ़ंक्शन का उपयोग FeedForward लेयर के अंदर रेखीय परतों के बाद करने का लक्ष्य रेखीय डेटा को गैर-रेखीय में बदलना है ताकि मॉडल जटिल, गैर-रेखीय संबंधों को सीख सके।
जैसा कि आप देख सकते हैं, फीड फॉरवर्ड नेटवर्क 3 परतों का उपयोग करता है। पहली एक रैखिक परत है जो रैखिक वजन (मॉडल के अंदर प्रशिक्षित करने के लिए पैरामीटर) का उपयोग करके आयामों को 4 से गुणा करेगी। फिर, सभी उन आयामों में GELU फ़ंक्शन का उपयोग किया जाता है ताकि समृद्ध प्रतिनिधित्व को पकड़ने के लिए गैर-रेखीय भिन्नताएँ लागू की जा सकें और अंततः एक और रैखिक परत का उपयोग करके आयामों के मूल आकार पर वापस जाने के लिए किया जाता है।
* **हेड्स:** समानांतर में चलने वाले कई ध्यान तंत्र (`num_heads`), प्रत्येक के साथ एक कम आयाम (`head_dim`)।
* **ध्यान स्कोर:** क्वेरी और कीज़ के डॉट उत्पाद के रूप में गणना की जाती है, स्केल और मास्क की जाती है।
* **मास्किंग:** भविष्य के टोकनों पर ध्यान केंद्रित करने से रोकने के लिए एक कारणात्मक मास्क लागू किया जाता है (GPT जैसे ऑटोरिग्रेसिव मॉडलों के लिए महत्वपूर्ण)।
* **ध्यान वजन:** मास्क किए गए और स्केल किए गए ध्यान स्कोर का सॉफ्टमैक्स।
* **संदर्भ वेक्टर:** ध्यान वजन के अनुसार मानों का भारित योग।
* **आउटपुट प्रक्षिप्ति:** सभी हेड्स के आउटपुट को संयोजित करने के लिए रैखिक परत।
इस नेटवर्क का लक्ष्य एक ही संदर्भ में टोकनों के बीच संबंधों को खोजना है। इसके अलावा, टोकनों को विभिन्न हेड्स में विभाजित किया जाता है ताकि ओवरफिटिंग को रोका जा सके, हालांकि प्रत्येक हेड में पाए गए अंतिम संबंधों को इस नेटवर्क के अंत में संयोजित किया जाता है।
इसके अलावा, प्रशिक्षण के दौरान एक **कारणात्मक मास्क** लागू किया जाता है ताकि बाद के टोकनों को एक टोकन के लिए विशिष्ट संबंधों को देखते समय ध्यान में न लिया जाए और कुछ **ड्रॉपआउट** भी लागू किया जाता है ताकि **ओवरफिटिंग को रोका जा सके**।
* **लेयर नॉर्मलाइजेशन:** एक तकनीक जो बैच में प्रत्येक व्यक्तिगत उदाहरण के लिए विशेषताओं (एम्बेडिंग आयामों) के बीच इनपुट को सामान्य करने के लिए उपयोग की जाती है।
* **`scale` और `shift`:** सीखने योग्य पैरामीटर (`nn.Parameter`) जो मॉडल को सामान्यीकृत आउटपुट को स्केल और शिफ्ट करने की अनुमति देते हैं। इन्हें क्रमशः एक और शून्य पर प्रारंभ किया जाता है।
* **मीन की गणना (`mean`):** इनपुट `x` का मीन एम्बेडिंग आयाम (`dim=-1`) के पार गणना करता है, प्रसार के लिए आयाम को बनाए रखते हुए (`keepdim=True`)।
* **वैरिएंस की गणना (`var`):** एम्बेडिंग आयाम के पार `x` का वैरिएंस गणना करता है, आयाम को भी बनाए रखते हुए। `unbiased=False` पैरामीटर यह सुनिश्चित करता है कि वैरिएंस पूर्वाग्रहित अनुमानक का उपयोग करके गणना की जाती है (N के बजाय N-1 से विभाजित करना), जो विशेषताओं के बजाय नमूनों के ऊपर सामान्यीकृत करते समय उपयुक्त है।
* **नॉर्मलाइज करें (`norm_x`):** `x` से मीन घटाता है और वैरिएंस के वर्गमूल के साथ `eps` को जोड़कर विभाजित करता है।
लक्ष्य यह सुनिश्चित करना है कि समान टोकन के सभी आयामों में 0 का मीन और 1 का वैरिएंस हो। इसका लक्ष्य **गहरे न्यूरल नेटवर्क के प्रशिक्षण को स्थिर करना** है, जो प्रशिक्षण के दौरान पैरामीटर के अद्यतन के कारण नेटवर्क सक्रियण के वितरण में परिवर्तन को आंतरिक सह-परिवर्तन शिफ्ट के रूप में संदर्भित करता है।
* **परत सामान्यीकरण:** स्थिर प्रशिक्षण के लिए ध्यान और फीडफॉरवर्ड परतों से पहले लागू किया जाता है।
* **अवशिष्ट कनेक्शन (शॉर्टकट):** ग्रेडिएंट प्रवाह में सुधार करने और गहरे नेटवर्क के प्रशिक्षण को सक्षम करने के लिए एक परत के इनपुट को इसके आउटपुट में जोड़ता है।
* **ड्रॉपआउट:** नियमितीकरण के लिए ध्यान और फीडफॉरवर्ड परतों के बाद लागू किया जाता है।
* **फीडफॉरवर्ड नेटवर्क (`ff`):** फीडफॉरवर्ड परिवर्तन लागू करें।
* **ड्रॉपआउट (`drop_shortcut`):** ड्रॉपआउट लागू करें।
* **अवशिष्ट जोड़ें (`x + shortcut`):** पहले अवशिष्ट पथ से इनपुट के साथ मिलाएं।
{% hint style="info" %}
ट्रांसफार्मर ब्लॉक सभी नेटवर्क को एक साथ समूहित करता है और प्रशिक्षण स्थिरता और परिणामों में सुधार के लिए कुछ **सामान्यीकरण** और **ड्रॉपआउट** लागू करता है।\
इसके अलावा, यह शॉर्टकट का भी उपयोग करता है जिसमें **एक नेटवर्क के आउटपुट को इसके इनपुट के साथ जोड़ना** शामिल है। यह सुनिश्चित करके वैनिशिंग ग्रेडिएंट समस्या को रोकने में मदद करता है कि प्रारंभिक परतें "जितना" योगदान करती हैं जितना कि अंतिम परतें।
* **Token Embeddings (`tok_emb`):** टोकन अनुक्रमांक को एम्बेडिंग में परिवर्तित करता है। याद दिलाने के लिए, ये शब्दावली में प्रत्येक टोकन के प्रत्येक आयाम को दिए गए वजन हैं।
* **Positional Embeddings (`pos_emb`):** एम्बेडिंग में स्थिति संबंधी जानकारी जोड़ता है ताकि टोकनों के क्रम को कैप्चर किया जा सके। याद दिलाने के लिए, ये टेक्स्ट में स्थिति के अनुसार टोकन को दिए गए वजन हैं।
इस वर्ग का लक्ष्य **अनुक्रम में अगले टोकन की भविष्यवाणी करने** के लिए सभी अन्य उल्लेखित नेटवर्क का उपयोग करना है, जो टेक्स्ट जनरेशन जैसे कार्यों के लिए मौलिक है।
ध्यान दें कि यह **जितने ट्रांसफार्मर ब्लॉकों की संख्या बताई गई है, उतने का उपयोग करेगा** और प्रत्येक ट्रांसफार्मर ब्लॉक एक मल्टी-हेड अटेंशन नेट, एक फीड फॉरवर्ड नेट और कई नॉर्मलाइजेशन का उपयोग कर रहा है। इसलिए यदि 12 ट्रांसफार्मर ब्लॉक्स का उपयोग किया जाता है, तो इसे 12 से गुणा करें।
इसके अलावा, एक **नॉर्मलाइजेशन** लेयर **आउटपुट** से **पहले** जोड़ी जाती है और अंत में परिणामों को उचित आयामों के साथ प्राप्त करने के लिए एक अंतिम रैखिक लेयर लागू की जाती है। ध्यान दें कि प्रत्येक अंतिम वेक्टर का आकार उपयोग की गई शब्दावली के आकार के बराबर है। इसका कारण यह है कि यह शब्दावली के भीतर संभावित टोकन के लिए एक संभावना प्राप्त करने की कोशिश कर रहा है।
{% endhint %}
## प्रशिक्षित करने के लिए पैरामीटर की संख्या
GPT संरचना को परिभाषित करने के बाद, प्रशिक्षित करने के लिए पैरामीटर की संख्या पता लगाना संभव है:
```python
GPT_CONFIG_124M = {
"vocab_size": 50257, # Vocabulary size
"context_length": 1024, # Context length
"emb_dim": 768, # Embedding dimension
"n_heads": 12, # Number of attention heads
"n_layers": 12, # Number of layers
"drop_rate": 0.1, # Dropout rate
"qkv_bias": False # Query-Key-Value bias
}
model = GPTModel(GPT_CONFIG_124M)
total_params = sum(p.numel() for p in model.parameters())
print(f"Total number of parameters: {total_params:,}")
# Total number of parameters: 163,009,536
```
### **चरण-दर-चरण गणना**
#### **1. एम्बेडिंग परतें: टोकन एम्बेडिंग और स्थिति एम्बेडिंग**
एक ऐसा मॉडल होना जो अगले टोकन की भविष्यवाणी करता है जैसे कि पहले वाला, बस अंतिम टोकन मानों को आउटपुट से लेना आवश्यक है (क्योंकि वे भविष्यवाणी किए गए टोकन के होंगे), जो कि **शब्दावली में प्रत्येक प्रविष्टि के लिए एक मान** होगा और फिर `softmax` फ़ंक्शन का उपयोग करके आयामों को उन संभावनाओं में सामान्यीकृत करना होगा जो 1 के बराबर होती हैं और फिर सबसे बड़े प्रविष्टि का अनुक्रमांक प्राप्त करना होगा, जो कि शब्दावली के भीतर शब्द का अनुक्रमांक होगा।
Code from [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01\_main-chapter-code/ch04.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch04/01_main-chapter-code/ch04.ipynb):