mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/AI/AI-llm-architecture/0.-basic-llm-concepts.md', 'src/
This commit is contained in:
parent
ee5cb2a75c
commit
02f7d0cc20
@ -30,7 +30,7 @@ GPT_CONFIG_124M = {
|
||||
```
|
||||
## Tensors in PyTorch
|
||||
|
||||
In PyTorch, a **tensor** एक मौलिक डेटा संरचना है जो एक बहु-आयामी सरणी के रूप में कार्य करती है, जो स्केलर, वेक्टर और मैट्रिस जैसे अवधारणाओं को संभावित रूप से उच्च आयामों में सामान्यीकृत करती है। टेन्सर PyTorch में डेटा का प्रतिनिधित्व और हेरफेर करने का प्राथमिक तरीका है, विशेष रूप से गहरे शिक्षण और न्यूरल नेटवर्क के संदर्भ में।
|
||||
In PyTorch, एक **tensor** एक मौलिक डेटा संरचना है जो एक बहु-आयामी सरणी के रूप में कार्य करती है, जो स्केलर, वेक्टर और मैट्रिस जैसे अवधारणाओं को संभावित रूप से उच्च आयामों में सामान्यीकृत करती है। टेन्सर PyTorch में डेटा का प्रतिनिधित्व और हेरफेर करने का प्राथमिक तरीका हैं, विशेष रूप से गहरे शिक्षण और न्यूरल नेटवर्क के संदर्भ में।
|
||||
|
||||
### Mathematical Concept of Tensors
|
||||
|
||||
@ -41,18 +41,18 @@ In PyTorch, a **tensor** एक मौलिक डेटा संरचना
|
||||
|
||||
### Tensors as Data Containers
|
||||
|
||||
गणनात्मक दृष्टिकोण से, टेन्सर बहु-आयामी डेटा के लिए कंटेनर के रूप में कार्य करते हैं, जहाँ प्रत्येक आयाम डेटा की विभिन्न विशेषताओं या पहलुओं का प्रतिनिधित्व कर सकता है। यह टेन्सरों को मशीन लर्निंग कार्यों में जटिल डेटा सेट को संभालने के लिए अत्यधिक उपयुक्त बनाता है।
|
||||
सांख्यिकीय दृष्टिकोण से, टेन्सर बहु-आयामी डेटा के लिए कंटेनर के रूप में कार्य करते हैं, जहाँ प्रत्येक आयाम डेटा की विभिन्न विशेषताओं या पहलुओं का प्रतिनिधित्व कर सकता है। यह टेन्सरों को मशीन लर्निंग कार्यों में जटिल डेटा सेट को संभालने के लिए अत्यधिक उपयुक्त बनाता है।
|
||||
|
||||
### PyTorch Tensors vs. NumPy Arrays
|
||||
|
||||
हालांकि PyTorch टेन्सर अपने संख्यात्मक डेटा को स्टोर और हेरफेर करने की क्षमता में NumPy सरणियों के समान हैं, वे गहरे शिक्षण के लिए महत्वपूर्ण अतिरिक्त कार्यक्षमताएँ प्रदान करते हैं:
|
||||
हालांकि PyTorch टेन्सर संख्यात्मक डेटा को स्टोर और हेरफेर करने की अपनी क्षमता में NumPy सरणियों के समान हैं, वे गहरे शिक्षण के लिए महत्वपूर्ण अतिरिक्त कार्यक्षमताएँ प्रदान करते हैं:
|
||||
|
||||
- **Automatic Differentiation**: PyTorch टेन्सर स्वचालित रूप से ग्रेडिएंट्स (autograd) की गणना का समर्थन करते हैं, जो न्यूरल नेटवर्क को प्रशिक्षित करने के लिए आवश्यक व्युत्पत्तियों की गणना की प्रक्रिया को सरल बनाता है।
|
||||
- **GPU Acceleration**: PyTorch में टेन्सरों को GPUs पर स्थानांतरित और गणना की जा सकती है, जो बड़े पैमाने पर गणनाओं को काफी तेज़ी से करता है।
|
||||
|
||||
### Creating Tensors in PyTorch
|
||||
|
||||
You can create tensors using the `torch.tensor` function:
|
||||
आप `torch.tensor` फ़ंक्शन का उपयोग करके टेन्सर बना सकते हैं:
|
||||
```python
|
||||
pythonCopy codeimport torch
|
||||
|
||||
@ -201,16 +201,16 @@ Gradient w.r.t b: tensor([-0.0817])
|
||||
|
||||
बड़े न्यूरल नेटवर्क में, जिनमें कई परतें होती हैं, ग्रेडिएंट्स की गणना की प्रक्रिया अधिक जटिल हो जाती है क्योंकि पैरामीटर और ऑपरेशन्स की संख्या बढ़ जाती है। हालाँकि, मौलिक सिद्धांत वही रहते हैं:
|
||||
|
||||
- **Forward Pass:** प्रत्येक परत के माध्यम से इनपुट्स को पास करके नेटवर्क का आउटपुट निकालें।
|
||||
- **Forward Pass:** नेटवर्क का आउटपुट निकालें, इनपुट्स को प्रत्येक परत के माध्यम से पास करके।
|
||||
- **Compute Loss:** नेटवर्क के आउटपुट और लक्षित लेबल का उपयोग करके लॉस फंक्शन का मूल्यांकन करें।
|
||||
- **Backward Pass (Backpropagation):** आउटपुट लेयर से इनपुट लेयर तक चेन रूल को पुनरावृत्त करते हुए नेटवर्क में प्रत्येक पैरामीटर के सापेक्ष लॉस के ग्रेडिएंट्स की गणना करें।
|
||||
- **Backward Pass (Backpropagation):** आउटपुट परत से इनपुट परत तक चेन नियम को पुनरावृत्त करते हुए नेटवर्क में प्रत्येक पैरामीटर के सापेक्ष लॉस के ग्रेडिएंट्स की गणना करें।
|
||||
|
||||
### **2. Backpropagation Algorithm**
|
||||
|
||||
- **Step 1:** नेटवर्क के पैरामीटर (वेट्स और बायस) को प्रारंभ करें।
|
||||
- **Step 2:** प्रत्येक प्रशिक्षण उदाहरण के लिए, आउटपुट्स की गणना करने के लिए एक फॉरवर्ड पास करें।
|
||||
- **Step 3:** लॉस की गणना करें।
|
||||
- **Step 4:** चेन रूल का उपयोग करके प्रत्येक पैरामीटर के सापेक्ष लॉस के ग्रेडिएंट्स की गणना करें।
|
||||
- **Step 4:** चेन नियम का उपयोग करके प्रत्येक पैरामीटर के सापेक्ष लॉस के ग्रेडिएंट्स की गणना करें।
|
||||
- **Step 5:** एक ऑप्टिमाइजेशन एल्गोरिदम (जैसे, ग्रेडिएंट डिसेंट) का उपयोग करके पैरामीटर को अपडेट करें।
|
||||
|
||||
### **3. Mathematical Representation**
|
||||
|
@ -31,7 +31,7 @@ _(मानते हुए कि `[UNK]` का ID `987` है)_
|
||||
|
||||
### **Advanced Tokenizing Methods**
|
||||
|
||||
जबकि बेसिक टोकनाइज़र सरल टेक्स्ट के लिए अच्छी तरह से काम करता है, इसके कुछ सीमाएँ हैं, विशेष रूप से बड़े शब्दावली और नए या दुर्लभ शब्दों को संभालने में। उन्नत टोकनाइज़िंग विधियाँ इन समस्याओं को संबोधित करती हैं, टेक्स्ट को छोटे उप-इकाइयों में तोड़कर या टोकनाइज़ेशन प्रक्रिया को अनुकूलित करके।
|
||||
जबकि बेसिक टोकनाइज़र सरल टेक्स्ट के लिए अच्छी तरह से काम करता है, इसमें सीमाएँ हैं, विशेष रूप से बड़े शब्दावली और नए या दुर्लभ शब्दों को संभालने में। उन्नत टोकनाइज़िंग विधियाँ इन समस्याओं को संबोधित करती हैं, टेक्स्ट को छोटे उप-इकाइयों में तोड़कर या टोकनाइज़ेशन प्रक्रिया को अनुकूलित करके।
|
||||
|
||||
1. **Byte Pair Encoding (BPE):**
|
||||
- **Purpose:** शब्दावली के आकार को कम करता है और दुर्लभ या अज्ञात शब्दों को संभालता है, उन्हें अक्सर होने वाले बाइट जोड़ों में तोड़कर।
|
||||
|
233
src/AI/AI-llm-architecture/2.-data-sampling.md
Normal file
233
src/AI/AI-llm-architecture/2.-data-sampling.md
Normal file
@ -0,0 +1,233 @@
|
||||
# 2. Data Sampling
|
||||
|
||||
## **Data Sampling**
|
||||
|
||||
**Data Sampling** एक महत्वपूर्ण प्रक्रिया है जो बड़े भाषा मॉडल (LLMs) जैसे GPT के लिए डेटा तैयार करने में मदद करती है। इसमें टेक्स्ट डेटा को इनपुट और लक्ष्य अनुक्रमों में व्यवस्थित करना शामिल है, जिसका उपयोग मॉडल अगले शब्द (या टोकन) की भविष्यवाणी करने के लिए पिछले शब्दों के आधार पर करता है। उचित डेटा सैंपलिंग सुनिश्चित करती है कि मॉडल भाषा के पैटर्न और निर्भरताओं को प्रभावी ढंग से कैप्चर करे।
|
||||
|
||||
> [!TIP]
|
||||
> इस दूसरे चरण का लक्ष्य बहुत सरल है: **इनपुट डेटा का सैंपल लेना और इसे प्रशिक्षण चरण के लिए तैयार करना, आमतौर पर डेटासेट को एक विशिष्ट लंबाई के वाक्यों में विभाजित करके और अपेक्षित प्रतिक्रिया भी उत्पन्न करके।**
|
||||
|
||||
### **Why Data Sampling Matters**
|
||||
|
||||
LLMs जैसे GPT को टेक्स्ट उत्पन्न करने या भविष्यवाणी करने के लिए पिछले शब्दों द्वारा प्रदान किए गए संदर्भ को समझने के लिए प्रशिक्षित किया जाता है। इसे प्राप्त करने के लिए, प्रशिक्षण डेटा को इस तरह से संरचित किया जाना चाहिए कि मॉडल शब्दों के अनुक्रमों और उनके बाद के शब्दों के बीच संबंध सीख सके। यह संरचित दृष्टिकोण मॉडल को सामान्यीकृत करने और सुसंगत और संदर्भ में प्रासंगिक टेक्स्ट उत्पन्न करने की अनुमति देता है।
|
||||
|
||||
### **Key Concepts in Data Sampling**
|
||||
|
||||
1. **Tokenization:** टेक्स्ट को छोटे इकाइयों में तोड़ना जिन्हें टोकन कहा जाता है (जैसे, शब्द, उपशब्द, या अक्षर)।
|
||||
2. **Sequence Length (max_length):** प्रत्येक इनपुट अनुक्रम में टोकनों की संख्या।
|
||||
3. **Sliding Window:** एक विधि जो टोकनाइज्ड टेक्स्ट पर एक विंडो को आगे बढ़ाकर ओवरलैपिंग इनपुट अनुक्रम बनाने के लिए उपयोग की जाती है।
|
||||
4. **Stride:** अगला अनुक्रम बनाने के लिए स्लाइडिंग विंडो द्वारा आगे बढ़ाए गए टोकनों की संख्या।
|
||||
|
||||
### **Step-by-Step Example**
|
||||
|
||||
आइए डेटा सैंपलिंग को स्पष्ट करने के लिए एक उदाहरण के माध्यम से चलते हैं।
|
||||
|
||||
**Example Text**
|
||||
```arduino
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
||||
```
|
||||
**Tokenization**
|
||||
|
||||
मान लें कि हम एक **बुनियादी टोकनाइज़र** का उपयोग करते हैं जो पाठ को शब्दों और विराम चिह्नों में विभाजित करता है:
|
||||
```vbnet
|
||||
Tokens: ["Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit."]
|
||||
```
|
||||
**पैरामीटर**
|
||||
|
||||
- **अधिकतम अनुक्रम लंबाई (max_length):** 4 टोकन
|
||||
- **स्लाइडिंग विंडो स्ट्राइड:** 1 टोकन
|
||||
|
||||
**इनपुट और लक्ष्य अनुक्रम बनाना**
|
||||
|
||||
1. **स्लाइडिंग विंडो दृष्टिकोण:**
|
||||
- **इनपुट अनुक्रम:** प्रत्येक इनपुट अनुक्रम में `max_length` टोकन होते हैं।
|
||||
- **लक्ष्य अनुक्रम:** प्रत्येक लक्ष्य अनुक्रम में संबंधित इनपुट अनुक्रम के तुरंत बाद आने वाले टोकन होते हैं।
|
||||
2. **अनुक्रम उत्पन्न करना:**
|
||||
|
||||
<table><thead><tr><th width="177">विंडो स्थिति</th><th>इनपुट अनुक्रम</th><th>लक्ष्य अनुक्रम</th></tr></thead><tbody><tr><td>1</td><td>["Lorem", "ipsum", "dolor", "sit"]</td><td>["ipsum", "dolor", "sit", "amet,"]</td></tr><tr><td>2</td><td>["ipsum", "dolor", "sit", "amet,"]</td><td>["dolor", "sit", "amet,", "consectetur"]</td></tr><tr><td>3</td><td>["dolor", "sit", "amet,", "consectetur"]</td><td>["sit", "amet,", "consectetur", "adipiscing"]</td></tr><tr><td>4</td><td>["sit", "amet,", "consectetur", "adipiscing"]</td><td>["amet,", "consectetur", "adipiscing", "elit."]</td></tr></tbody></table>
|
||||
|
||||
3. **परिणामी इनपुट और लक्ष्य एरे:**
|
||||
|
||||
- **इनपुट:**
|
||||
|
||||
```python
|
||||
[
|
||||
["Lorem", "ipsum", "dolor", "sit"],
|
||||
["ipsum", "dolor", "sit", "amet,"],
|
||||
["dolor", "sit", "amet,", "consectetur"],
|
||||
["sit", "amet,", "consectetur", "adipiscing"],
|
||||
]
|
||||
```
|
||||
|
||||
- **लक्ष्य:**
|
||||
|
||||
```python
|
||||
[
|
||||
["ipsum", "dolor", "sit", "amet,"],
|
||||
["dolor", "sit", "amet,", "consectetur"],
|
||||
["sit", "amet,", "consectetur", "adipiscing"],
|
||||
["amet,", "consectetur", "adipiscing", "elit."],
|
||||
]
|
||||
```
|
||||
|
||||
**दृश्य प्रतिनिधित्व**
|
||||
|
||||
<table><thead><tr><th width="222">टोकन स्थिति</th><th>टोकन</th></tr></thead><tbody><tr><td>1</td><td>Lorem</td></tr><tr><td>2</td><td>ipsum</td></tr><tr><td>3</td><td>dolor</td></tr><tr><td>4</td><td>sit</td></tr><tr><td>5</td><td>amet,</td></tr><tr><td>6</td><td>consectetur</td></tr><tr><td>7</td><td>adipiscing</td></tr><tr><td>8</td><td>elit.</td></tr></tbody></table>
|
||||
|
||||
**स्लाइडिंग विंडो स्ट्राइड 1 के साथ:**
|
||||
|
||||
- **पहली विंडो (स्थिति 1-4):** \["Lorem", "ipsum", "dolor", "sit"] → **लक्ष्य:** \["ipsum", "dolor", "sit", "amet,"]
|
||||
- **दूसरी विंडो (स्थिति 2-5):** \["ipsum", "dolor", "sit", "amet,"] → **लक्ष्य:** \["dolor", "sit", "amet,", "consectetur"]
|
||||
- **तीसरी विंडो (स्थिति 3-6):** \["dolor", "sit", "amet,", "consectetur"] → **लक्ष्य:** \["sit", "amet,", "consectetur", "adipiscing"]
|
||||
- **चौथी विंडो (स्थिति 4-7):** \["sit", "amet,", "consectetur", "adipiscing"] → **लक्ष्य:** \["amet,", "consectetur", "adipiscing", "elit."]
|
||||
|
||||
**स्ट्राइड को समझना**
|
||||
|
||||
- **स्ट्राइड 1:** विंडो हर बार एक टोकन आगे बढ़ती है, जिससे अत्यधिक ओवरलैपिंग अनुक्रम बनते हैं। यह संदर्भ संबंधों के बेहतर अध्ययन की ओर ले जा सकता है लेकिन ओवरफिटिंग का जोखिम बढ़ा सकता है क्योंकि समान डेटा बिंदु दोहराए जाते हैं।
|
||||
- **स्ट्राइड 2:** विंडो हर बार दो टोकन आगे बढ़ती है, ओवरलैप को कम करती है। यह पुनरावृत्ति और गणनात्मक लोड को कम करता है लेकिन कुछ संदर्भ की बारीकियों को चूक सकता है।
|
||||
- **स्ट्राइड जो max_length के बराबर है:** विंडो पूरी विंडो आकार के द्वारा आगे बढ़ती है, जिससे गैर-ओवरलैपिंग अनुक्रम बनते हैं। यह डेटा पुनरावृत्ति को कम करता है लेकिन मॉडल की अनुक्रमों के बीच निर्भरताओं को सीखने की क्षमता को सीमित कर सकता है।
|
||||
|
||||
**स्ट्राइड 2 के साथ उदाहरण:**
|
||||
|
||||
उसी टोकनाइज्ड टेक्स्ट और `max_length` 4 का उपयोग करते हुए:
|
||||
|
||||
- **पहली विंडो (स्थिति 1-4):** \["Lorem", "ipsum", "dolor", "sit"] → **लक्ष्य:** \["ipsum", "dolor", "sit", "amet,"]
|
||||
- **दूसरी विंडो (स्थिति 3-6):** \["dolor", "sit", "amet,", "consectetur"] → **लक्ष्य:** \["sit", "amet,", "consectetur", "adipiscing"]
|
||||
- **तीसरी विंडो (स्थिति 5-8):** \["amet,", "consectetur", "adipiscing", "elit."] → **लक्ष्य:** \["consectetur", "adipiscing", "elit.", "sed"] _(जारी रहने की धारणा)_
|
||||
|
||||
## कोड उदाहरण
|
||||
|
||||
आइए इसे [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb) से कोड उदाहरण के माध्यम से बेहतर समझें:
|
||||
```python
|
||||
# Download the text to pre-train the LLM
|
||||
import urllib.request
|
||||
url = ("https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt")
|
||||
file_path = "the-verdict.txt"
|
||||
urllib.request.urlretrieve(url, file_path)
|
||||
|
||||
with open("the-verdict.txt", "r", encoding="utf-8") as f:
|
||||
raw_text = f.read()
|
||||
|
||||
"""
|
||||
Create a class that will receive some params lie tokenizer and text
|
||||
and will prepare the input chunks and the target chunks to prepare
|
||||
the LLM to learn which next token to generate
|
||||
"""
|
||||
import torch
|
||||
from torch.utils.data import Dataset, DataLoader
|
||||
|
||||
class GPTDatasetV1(Dataset):
|
||||
def __init__(self, txt, tokenizer, max_length, stride):
|
||||
self.input_ids = []
|
||||
self.target_ids = []
|
||||
|
||||
# Tokenize the entire text
|
||||
token_ids = tokenizer.encode(txt, allowed_special={"<|endoftext|>"})
|
||||
|
||||
# Use a sliding window to chunk the book into overlapping sequences of max_length
|
||||
for i in range(0, len(token_ids) - max_length, stride):
|
||||
input_chunk = token_ids[i:i + max_length]
|
||||
target_chunk = token_ids[i + 1: i + max_length + 1]
|
||||
self.input_ids.append(torch.tensor(input_chunk))
|
||||
self.target_ids.append(torch.tensor(target_chunk))
|
||||
|
||||
def __len__(self):
|
||||
return len(self.input_ids)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return self.input_ids[idx], self.target_ids[idx]
|
||||
|
||||
|
||||
"""
|
||||
Create a data loader which given the text and some params will
|
||||
prepare the inputs and targets with the previous class and
|
||||
then create a torch DataLoader with the info
|
||||
"""
|
||||
|
||||
import tiktoken
|
||||
|
||||
def create_dataloader_v1(txt, batch_size=4, max_length=256,
|
||||
stride=128, shuffle=True, drop_last=True,
|
||||
num_workers=0):
|
||||
|
||||
# Initialize the tokenizer
|
||||
tokenizer = tiktoken.get_encoding("gpt2")
|
||||
|
||||
# Create dataset
|
||||
dataset = GPTDatasetV1(txt, tokenizer, max_length, stride)
|
||||
|
||||
# Create dataloader
|
||||
dataloader = DataLoader(
|
||||
dataset,
|
||||
batch_size=batch_size,
|
||||
shuffle=shuffle,
|
||||
drop_last=drop_last,
|
||||
num_workers=num_workers
|
||||
)
|
||||
|
||||
return dataloader
|
||||
|
||||
|
||||
"""
|
||||
Finally, create the data loader with the params we want:
|
||||
- The used text for training
|
||||
- batch_size: The size of each batch
|
||||
- max_length: The size of each entry on each batch
|
||||
- stride: The sliding window (how many tokens should the next entry advance compared to the previous one). The smaller the more overfitting, usually this is equals to the max_length so the same tokens aren't repeated.
|
||||
- shuffle: Re-order randomly
|
||||
"""
|
||||
dataloader = create_dataloader_v1(
|
||||
raw_text, batch_size=8, max_length=4, stride=1, shuffle=False
|
||||
)
|
||||
|
||||
data_iter = iter(dataloader)
|
||||
first_batch = next(data_iter)
|
||||
print(first_batch)
|
||||
|
||||
# Note the batch_size of 8, the max_length of 4 and the stride of 1
|
||||
[
|
||||
# Input
|
||||
tensor([[ 40, 367, 2885, 1464],
|
||||
[ 367, 2885, 1464, 1807],
|
||||
[ 2885, 1464, 1807, 3619],
|
||||
[ 1464, 1807, 3619, 402],
|
||||
[ 1807, 3619, 402, 271],
|
||||
[ 3619, 402, 271, 10899],
|
||||
[ 402, 271, 10899, 2138],
|
||||
[ 271, 10899, 2138, 257]]),
|
||||
# Target
|
||||
tensor([[ 367, 2885, 1464, 1807],
|
||||
[ 2885, 1464, 1807, 3619],
|
||||
[ 1464, 1807, 3619, 402],
|
||||
[ 1807, 3619, 402, 271],
|
||||
[ 3619, 402, 271, 10899],
|
||||
[ 402, 271, 10899, 2138],
|
||||
[ 271, 10899, 2138, 257],
|
||||
[10899, 2138, 257, 7026]])
|
||||
]
|
||||
|
||||
# With stride=4 this will be the result:
|
||||
[
|
||||
# Input
|
||||
tensor([[ 40, 367, 2885, 1464],
|
||||
[ 1807, 3619, 402, 271],
|
||||
[10899, 2138, 257, 7026],
|
||||
[15632, 438, 2016, 257],
|
||||
[ 922, 5891, 1576, 438],
|
||||
[ 568, 340, 373, 645],
|
||||
[ 1049, 5975, 284, 502],
|
||||
[ 284, 3285, 326, 11]]),
|
||||
# Target
|
||||
tensor([[ 367, 2885, 1464, 1807],
|
||||
[ 3619, 402, 271, 10899],
|
||||
[ 2138, 257, 7026, 15632],
|
||||
[ 438, 2016, 257, 922],
|
||||
[ 5891, 1576, 438, 568],
|
||||
[ 340, 373, 645, 1049],
|
||||
[ 5975, 284, 502, 284],
|
||||
[ 3285, 326, 11, 287]])
|
||||
]
|
||||
```
|
||||
## संदर्भ
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
@ -12,7 +12,7 @@
|
||||
|
||||
### **What Are Token Embeddings?**
|
||||
|
||||
**Token Embeddings** निरंतर वेक्टर स्पेस में टोकनों के संख्यात्मक प्रतिनिधित्व हैं। शब्दकोश में प्रत्येक टोकन एक अद्वितीय निश्चित आयामों के वेक्टर से जुड़ा होता है। ये वेक्टर टोकनों के बारे में अर्थपूर्ण और व्याकरणिक जानकारी को कैप्चर करते हैं, जिससे मॉडल डेटा में संबंधों और पैटर्नों को समझने में सक्षम होता है।
|
||||
**Token Embeddings** निरंतर वेक्टर स्पेस में टोकनों के संख्यात्मक प्रतिनिधित्व हैं। शब्दकोश में प्रत्येक टोकन एक अद्वितीय निश्चित आयामों के वेक्टर से जुड़ा होता है। ये वेक्टर टोकनों के बारे में अर्थ और व्याकरणिक जानकारी को कैप्चर करते हैं, जिससे मॉडल डेटा में संबंधों और पैटर्नों को समझने में सक्षम होता है।
|
||||
|
||||
- **Vocabulary Size:** मॉडल के शब्दकोश में अद्वितीय टोकनों की कुल संख्या (जैसे, शब्द, उपशब्द)।
|
||||
- **Embedding Dimensions:** प्रत्येक टोकन के वेक्टर में संख्यात्मक मानों (आयामों) की संख्या। उच्च आयाम अधिक सूक्ष्म जानकारी कैप्चर कर सकते हैं लेकिन अधिक गणनात्मक संसाधनों की आवश्यकता होती है।
|
||||
@ -67,7 +67,7 @@ tensor([[-0.4015, 0.9666, -1.1481]], grad_fn=<EmbeddingBackward0>)
|
||||
```
|
||||
**व्याख्या:**
|
||||
|
||||
- अनुक्रमांक `3` पर स्थित टोकन को वेक्टर `[-0.4015, 0.9666, -1.1481]` द्वारा दर्शाया गया है।
|
||||
- अनुक्रमांक `3` पर टोकन को वेक्टर `[-0.4015, 0.9666, -1.1481]` द्वारा दर्शाया गया है।
|
||||
- ये मान प्रशिक्षनीय पैरामीटर हैं जिन्हें मॉडल प्रशिक्षण के दौरान टोकन के संदर्भ और अर्थ को बेहतर ढंग से दर्शाने के लिए समायोजित करेगा।
|
||||
|
||||
### **प्रशिक्षण के दौरान टोकन एम्बेडिंग कैसे काम करती हैं**
|
||||
@ -157,11 +157,11 @@ Combined Embedding = Token Embedding + Positional Embedding
|
||||
**स्थानिक एम्बेडिंग के लाभ:**
|
||||
|
||||
- **संदर्भ जागरूकता:** मॉडल अपने स्थानों के आधार पर टोकनों के बीच अंतर कर सकता है।
|
||||
- **अनुक्रम समझ:** मॉडल को व्याकरण, वाक्य रचना, और संदर्भ-निर्भर अर्थों को समझने में सक्षम बनाता है।
|
||||
- **अनुक्रम समझना:** मॉडल को व्याकरण, वाक्य रचना, और संदर्भ-निर्भर अर्थों को समझने में सक्षम बनाता है।
|
||||
|
||||
## कोड उदाहरण
|
||||
|
||||
[https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb) से कोड उदाहरण के साथ आगे बढ़ते हैं:
|
||||
Following with the code example from [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb):
|
||||
```python
|
||||
# Use previous code...
|
||||
|
||||
|
@ -14,11 +14,11 @@
|
||||
|
||||
#### उदाहरण: मशीन अनुवाद
|
||||
|
||||
जर्मन वाक्य "Kannst du mir helfen diesen Satz zu übersetzen" का अंग्रेजी में अनुवाद करने पर विचार करें। शब्द-दर-शब्द अनुवाद एक व्याकरणिक रूप से सही अंग्रेजी वाक्य उत्पन्न नहीं करेगा क्योंकि भाषाओं के बीच व्याकरणिक संरचनाओं में अंतर होता है। एक ध्यान तंत्र मॉडल को आउटपुट वाक्य के प्रत्येक शब्द को उत्पन्न करते समय इनपुट वाक्य के प्रासंगिक भागों पर ध्यान केंद्रित करने में सक्षम बनाता है, जिससे एक अधिक सटीक और सुसंगत अनुवाद होता है।
|
||||
जर्मन वाक्य "Kannst du mir helfen diesen Satz zu übersetzen" का अंग्रेजी में अनुवाद करने पर विचार करें। शब्द-द्वारा-शब्द अनुवाद एक व्याकरणिक रूप से सही अंग्रेजी वाक्य उत्पन्न नहीं करेगा क्योंकि भाषाओं के बीच व्याकरणिक संरचनाओं में भिन्नताएँ होती हैं। एक ध्यान तंत्र मॉडल को आउटपुट वाक्य के प्रत्येक शब्द को उत्पन्न करते समय इनपुट वाक्य के प्रासंगिक भागों पर ध्यान केंद्रित करने में सक्षम बनाता है, जिससे एक अधिक सटीक और सुसंगत अनुवाद होता है।
|
||||
|
||||
### आत्म-ध्यान का परिचय
|
||||
|
||||
आत्म-ध्यान, या अंतः-ध्यान, एक तंत्र है जहां ध्यान एकल अनुक्रम के भीतर लागू होता है ताकि उस अनुक्रम का प्रतिनिधित्व किया जा सके। यह अनुक्रम में प्रत्येक टोकन को सभी अन्य टोकनों पर ध्यान केंद्रित करने की अनुमति देता है, जिससे मॉडल को अनुक्रम में टोकनों के बीच निर्भरताओं को कैप्चर करने में मदद मिलती है, चाहे उनकी दूरी कितनी भी हो।
|
||||
आत्म-ध्यान, या अंतः-ध्यान, एक तंत्र है जहाँ ध्यान एकल अनुक्रम के भीतर लागू होता है ताकि उस अनुक्रम का प्रतिनिधित्व किया जा सके। यह अनुक्रम में प्रत्येक टोकन को सभी अन्य टोकनों पर ध्यान केंद्रित करने की अनुमति देता है, जिससे मॉडल को टोकनों के बीच की निर्भरताओं को कैप्चर करने में मदद मिलती है, चाहे वे अनुक्रम में कितनी भी दूर हों।
|
||||
|
||||
#### प्रमुख अवधारणाएँ
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
### ध्यान वजन की गणना: एक चरण-दर-चरण उदाहरण
|
||||
|
||||
आइए वाक्य **"Hello shiny sun!"** पर विचार करें और प्रत्येक शब्द का 3-आयामी एम्बेडिंग के साथ प्रतिनिधित्व करें:
|
||||
आइए वाक्य **"Hello shiny sun!"** पर विचार करें और प्रत्येक शब्द को 3-आयामी एम्बेडिंग के साथ प्रदर्शित करें:
|
||||
|
||||
- **Hello**: `[0.34, 0.22, 0.54]`
|
||||
- **shiny**: `[0.53, 0.34, 0.98]`
|
||||
@ -41,7 +41,7 @@
|
||||
> [!TIP]
|
||||
> बस प्रत्येक आयाम मान को क्वेरी के साथ संबंधित टोकन के एक के साथ गुणा करें और परिणामों को जोड़ें। आपको प्रत्येक टोकन के जोड़े के लिए 1 मान मिलता है।
|
||||
|
||||
वाक्य में प्रत्येक शब्द के लिए, "shiny" के संदर्भ में **ध्यान स्कोर** की गणना करें, उनके एम्बेडिंग का डॉट उत्पाद निकालकर।
|
||||
वाक्य में प्रत्येक शब्द के लिए, "shiny" के सापेक्ष **ध्यान स्कोर** की गणना करें, उनके एम्बेडिंग का डॉट उत्पाद निकालकर।
|
||||
|
||||
**"Hello" और "shiny" के बीच ध्यान स्कोर**
|
||||
|
||||
@ -58,10 +58,11 @@
|
||||
#### चरण 2: ध्यान स्कोर को सामान्य करें ताकि ध्यान वजन प्राप्त हो सके
|
||||
|
||||
> [!TIP]
|
||||
> गणितीय शर्तों में खो न जाएं, इस फ़ंक्शन का लक्ष्य सरल है, सभी वजन को सामान्य करें ताकि **वे कुल 1 में जोड़ें**।
|
||||
> इसके अलावा, **सॉफ्टमैक्स** फ़ंक्शन का उपयोग किया जाता है क्योंकि यह गुणनखंड के कारण भिन्नताओं को बढ़ाता है, उपयोगी मानों का पता लगाना आसान बनाता है।
|
||||
> गणितीय शर्तों में खो न जाएं, इस फ़ंक्शन का लक्ष्य सरल है, सभी वजन को सामान्य करें ताकि **वे कुल मिलाकर 1 हों**।
|
||||
>
|
||||
> इसके अलावा, **softmax** फ़ंक्शन का उपयोग किया जाता है क्योंकि यह गुणनात्मक भाग के कारण भिन्नताओं को बढ़ाता है, उपयोगी मानों का पता लगाना आसान बनाता है।
|
||||
|
||||
ध्यान स्कोर को ध्यान वजन में परिवर्तित करने के लिए **सॉफ्टमैक्स फ़ंक्शन** लागू करें जो 1 में जोड़ता है।
|
||||
ध्यान स्कोर को ध्यान वजन में परिवर्तित करने के लिए **softmax फ़ंक्शन** लागू करें जो 1 के बराबर होते हैं।
|
||||
|
||||
<figure><img src="../../images/image (3) (1) (1) (1) (1).png" alt="" width="293"><figcaption></figcaption></figure>
|
||||
|
||||
@ -109,7 +110,7 @@
|
||||
### प्रक्रिया का सारांश
|
||||
|
||||
1. **ध्यान स्कोर की गणना करें**: लक्षित शब्द के एम्बेडिंग और अनुक्रम में सभी शब्दों के एम्बेडिंग के बीच डॉट उत्पाद का उपयोग करें।
|
||||
2. **ध्यान वजन प्राप्त करने के लिए स्कोर को सामान्य करें**: ध्यान स्कोर को 1 में जोड़ने के लिए सॉफ्टमैक्स फ़ंक्शन लागू करें।
|
||||
2. **ध्यान वजन प्राप्त करने के लिए स्कोर को सामान्य करें**: ध्यान स्कोर को 1 के बराबर वजन प्राप्त करने के लिए softmax फ़ंक्शन लागू करें।
|
||||
3. **संदर्भ वेक्टर की गणना करें**: प्रत्येक शब्द के एम्बेडिंग को उसके ध्यान वजन से गुणा करें और परिणामों को जोड़ें।
|
||||
|
||||
## प्रशिक्षित वजन के साथ आत्म-ध्यान
|
||||
@ -118,7 +119,7 @@
|
||||
|
||||
<figure><img src="../../images/image (10) (1) (1).png" alt="" width="239"><figcaption></figcaption></figure>
|
||||
|
||||
क्वेरी वही डेटा है जिसका उपयोग पहले की तरह किया जाता है, जबकि कुंजी और मान मैट्रिक्स बस यादृच्छिक-प्रशिक्षण योग्य मैट्रिक्स हैं।
|
||||
क्वेरी वही डेटा है जिसका उपयोग पहले की तरह किया जाता है, जबकि कुंजी और मान मैट्रिक्स बस यादृच्छिक-प्रशिक्षित मैट्रिक्स हैं।
|
||||
|
||||
#### चरण 1: क्वेरी, कुंजी और मानों की गणना करें
|
||||
|
||||
@ -130,7 +131,7 @@
|
||||
|
||||
**उदाहरण**
|
||||
|
||||
मान लीजिए:
|
||||
मान लें:
|
||||
|
||||
- इनपुट आयाम `din=3` (एम्बेडिंग आकार)
|
||||
- आउटपुट आयाम `dout=2` (क्वेरी, कुंजी और मानों के लिए इच्छित आयाम)
|
||||
@ -225,7 +226,7 @@ print(sa_v2(inputs))
|
||||
|
||||
## कारणात्मक ध्यान: भविष्य के शब्दों को छिपाना
|
||||
|
||||
LLMs के लिए हम चाहते हैं कि मॉडल केवल उन टोकनों पर विचार करे जो वर्तमान स्थिति से पहले प्रकट होते हैं ताकि **अगले टोकन** की **भविष्यवाणी** की जा सके। **कारणात्मक ध्यान**, जिसे **मास्केड ध्यान** के रूप में भी जाना जाता है, भविष्य के टोकनों तक पहुंच को रोकने के लिए ध्यान तंत्र को संशोधित करके यह प्राप्त करता है।
|
||||
LLMs के लिए हम चाहते हैं कि मॉडल केवल उन टोकनों पर विचार करे जो वर्तमान स्थिति से पहले प्रकट होते हैं ताकि **अगले टोकन** की **भविष्यवाणी** की जा सके। **कारणात्मक ध्यान**, जिसे **मास्क किया गया ध्यान** भी कहा जाता है, भविष्य के टोकनों तक पहुंच को रोकने के लिए ध्यान तंत्र को संशोधित करके यह प्राप्त करता है।
|
||||
|
||||
### कारणात्मक ध्यान मास्क लागू करना
|
||||
|
||||
@ -249,7 +250,7 @@ attention_weights = torch.softmax(masked_scores, dim=-1)
|
||||
|
||||
### ड्रॉपआउट के साथ अतिरिक्त ध्यान वेट्स को मास्क करना
|
||||
|
||||
**ओवरफिटिंग** को **रोकने** के लिए, हम सॉफ्टमैक्स ऑपरेशन के बाद ध्यान वेट्स पर **ड्रॉपआउट** लागू कर सकते हैं। ड्रॉपआउट प्रशिक्षण के दौरान **ध्यान वेट्स में से कुछ को यादृच्छिक रूप से शून्य** कर देता है।
|
||||
**ओवरफिटिंग** को **रोकने** के लिए, हम सॉफ्टमैक्स ऑपरेशन के बाद ध्यान वेट्स पर **ड्रॉपआउट** लागू कर सकते हैं। ड्रॉपआउट प्रशिक्षण के दौरान **ध्यान वेट्स में से कुछ को यादृच्छिक रूप से शून्य कर देता है**।
|
||||
```python
|
||||
dropout = nn.Dropout(p=0.5)
|
||||
attention_weights = dropout(attention_weights)
|
||||
@ -326,7 +327,7 @@ print("context_vecs.shape:", context_vecs.shape)
|
||||
|
||||
### कोड उदाहरण
|
||||
|
||||
पिछले कोड का पुन: उपयोग करना और बस एक रैपर जोड़ना जो इसे कई बार लॉन्च करता है, संभव हो सकता है, लेकिन यह [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb) से एक अधिक अनुकूलित संस्करण है जो सभी सिरों को एक साथ संसाधित करता है (महंगे फॉर लूप की संख्या को कम करता है)। जैसा कि आप कोड में देख सकते हैं, प्रत्येक टोकन के आयामों को सिरों की संख्या के अनुसार विभिन्न आयामों में विभाजित किया गया है। इस तरह, यदि टोकन के 8 आयाम हैं और हम 3 सिरों का उपयोग करना चाहते हैं, तो आयामों को 4 आयामों के 2 ऐरे में विभाजित किया जाएगा और प्रत्येक सिर उनमें से एक का उपयोग करेगा:
|
||||
पिछले कोड का पुन: उपयोग करना और बस एक लपेटन जोड़ना जो इसे कई बार लॉन्च करता है संभव हो सकता है, लेकिन यह [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch03/01_main-chapter-code/ch03.ipynb) से एक अधिक अनुकूलित संस्करण है जो सभी सिरों को एक साथ संसाधित करता है (महंगे फॉर लूप की संख्या को कम करता है)। जैसा कि आप कोड में देख सकते हैं, प्रत्येक टोकन के आयामों को सिरों की संख्या के अनुसार विभिन्न आयामों में विभाजित किया गया है। इस तरह, यदि टोकन के 8 आयाम हैं और हम 3 सिरों का उपयोग करना चाहते हैं, तो आयामों को 4 आयामों के 2 ऐरे में विभाजित किया जाएगा और प्रत्येक सिर उनमें से एक का उपयोग करेगा:
|
||||
```python
|
||||
class MultiHeadAttention(nn.Module):
|
||||
def __init__(self, d_in, d_out, context_length, dropout, num_heads, qkv_bias=False):
|
||||
|
@ -245,12 +245,12 @@ return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
- **पोजीशन-वाइज फीडफॉरवर्ड नेटवर्क:** प्रत्येक पोजीशन पर अलग-अलग और समान रूप से दो-परतों वाला पूरी तरह से जुड़े नेटवर्क लागू करता है।
|
||||
- **परत विवरण:**
|
||||
- **पहली रैखिक परत:** `emb_dim` से `4 * emb_dim` तक के आयाम का विस्तार करता है।
|
||||
- **पहली रैखिक परत:** `emb_dim` से `4 * emb_dim` तक आयाम का विस्तार करता है।
|
||||
- **GELU सक्रियण:** गैर-रेखीयता लागू करता है।
|
||||
- **दूसरी रैखिक परत:** आयाम को फिर से `emb_dim` तक कम करता है।
|
||||
|
||||
> [!TIP]
|
||||
> जैसा कि आप देख सकते हैं, फीड फॉरवर्ड नेटवर्क 3 परतों का उपयोग करता है। पहली एक रैखिक परत है जो आयामों को 4 से गुणा करेगी, रैखिक वजन (मॉडल के अंदर प्रशिक्षित करने के लिए पैरामीटर) का उपयोग करके। फिर, सभी उन आयामों में GELU फ़ंक्शन का उपयोग किया जाता है ताकि समृद्ध प्रतिनिधित्व को पकड़ने के लिए गैर-रेखीय भिन्नताएँ लागू की जा सकें और अंततः एक और रैखिक परत का उपयोग किया जाता है ताकि आयामों के मूल आकार पर वापस लौट सकें।
|
||||
> जैसा कि आप देख सकते हैं, फीड फॉरवर्ड नेटवर्क 3 परतों का उपयोग करता है। पहली एक रैखिक परत है जो रैखिक वजन (मॉडल के अंदर प्रशिक्षित करने के लिए पैरामीटर) का उपयोग करके आयामों को 4 से गुणा करेगी। फिर, GELU फ़ंक्शन का उपयोग उन सभी आयामों में गैर-रेखीय भिन्नताओं को लागू करने के लिए किया जाता है ताकि समृद्ध प्रतिनिधित्व को कैप्चर किया जा सके और अंततः एक और रैखिक परत का उपयोग करके आयामों के मूल आकार पर वापस लाया जाता है।
|
||||
|
||||
### **मल्टी-हेड ध्यान तंत्र**
|
||||
|
||||
@ -258,10 +258,10 @@ return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
#### **उद्देश्य और कार्यक्षमता**
|
||||
|
||||
- **मल्टी-हेड सेल्फ-अटेंशन:** मॉडल को इनपुट अनुक्रम के भीतर विभिन्न पोजीशनों पर ध्यान केंद्रित करने की अनुमति देता है जब एक टोकन को एन्कोड किया जाता है।
|
||||
- **मल्टी-हेड सेल्फ-अटेंशन:** मॉडल को टोकन को एन्कोड करते समय इनपुट अनुक्रम के भीतर विभिन्न पोजीशनों पर ध्यान केंद्रित करने की अनुमति देता है।
|
||||
- **मुख्य घटक:**
|
||||
- **क्वेरी, कीज़, वैल्यूज़:** इनपुट के रैखिक प्रक्षिप्तियाँ, जो ध्यान स्कोर की गणना के लिए उपयोग की जाती हैं।
|
||||
- **हेड्स:** समानांतर में चलने वाले कई ध्यान तंत्र (`num_heads`), प्रत्येक के साथ एक कम आयाम (`head_dim`)।
|
||||
- **हेड्स:** समानांतर में चलने वाले कई ध्यान तंत्र (`num_heads`), प्रत्येक के पास एक कम आयाम (`head_dim`) होता है।
|
||||
- **ध्यान स्कोर:** क्वेरी और कीज़ के डॉट उत्पाद के रूप में गणना की जाती है, स्केल की जाती है और मास्क की जाती है।
|
||||
- **मास्किंग:** भविष्य के टोकनों पर ध्यान केंद्रित करने से रोकने के लिए एक कारणात्मक मास्क लागू किया जाता है (GPT जैसे ऑटोरिग्रेसिव मॉडलों के लिए महत्वपूर्ण)।
|
||||
- **ध्यान वजन:** मास्क किए गए और स्केल किए गए ध्यान स्कोर का सॉफ्टमैक्स।
|
||||
@ -269,9 +269,9 @@ return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
- **आउटपुट प्रक्षिप्ति:** सभी हेड्स के आउटपुट को संयोजित करने के लिए रैखिक परत।
|
||||
|
||||
> [!TIP]
|
||||
> इस नेटवर्क का लक्ष्य एक ही संदर्भ में टोकनों के बीच संबंधों को खोजना है। इसके अलावा, टोकनों को विभिन्न हेड्स में विभाजित किया जाता है ताकि ओवरफिटिंग से बचा जा सके, हालांकि प्रत्येक हेड में पाए गए अंतिम संबंधों को इस नेटवर्क के अंत में संयोजित किया जाता है।
|
||||
> इस नेटवर्क का लक्ष्य एक ही संदर्भ में टोकनों के बीच संबंधों को खोजना है। इसके अलावा, टोकनों को विभिन्न हेड्स में विभाजित किया जाता है ताकि ओवरफिटिंग को रोका जा सके, हालांकि प्रत्येक हेड में पाए गए अंतिम संबंधों को इस नेटवर्क के अंत में संयोजित किया जाता है।
|
||||
>
|
||||
> इसके अलावा, प्रशिक्षण के दौरान एक **कारणात्मक मास्क** लागू किया जाता है ताकि बाद के टोकनों को एक टोकन के लिए विशिष्ट संबंधों को देखते समय ध्यान में नहीं लिया जाए और कुछ **ड्रॉपआउट** भी लागू किया जाता है ताकि **ओवरफिटिंग से बचा जा सके**।
|
||||
> इसके अलावा, प्रशिक्षण के दौरान एक **कारणात्मक मास्क** लागू किया जाता है ताकि बाद के टोकनों को एक टोकन के लिए विशिष्ट संबंधों को देखते समय ध्यान में न लिया जाए और कुछ **ड्रॉपआउट** भी लागू किया जाता है ताकि **ओवरफिटिंग को रोका जा सके**।
|
||||
|
||||
### **परत** सामान्यीकरण
|
||||
```python
|
||||
@ -297,16 +297,16 @@ return self.scale * norm_x + self.shift
|
||||
- **`scale` और `shift`:** सीखने योग्य पैरामीटर (`nn.Parameter`) जो मॉडल को सामान्यीकृत आउटपुट को स्केल और शिफ्ट करने की अनुमति देते हैं। इन्हें क्रमशः एक और शून्य पर प्रारंभ किया जाता है।
|
||||
- **सामान्यीकरण प्रक्रिया:**
|
||||
- **मीन की गणना (`mean`):** एम्बेडिंग आयाम (`dim=-1`) के बीच इनपुट `x` का औसत निकालता है, प्रसार के लिए आयाम को बनाए रखते हुए (`keepdim=True`)।
|
||||
- **वैरिएंस की गणना (`var`):** एम्बेडिंग आयाम के बीच `x` का वैरिएंस निकालता है, आयाम को बनाए रखते हुए। `unbiased=False` पैरामीटर यह सुनिश्चित करता है कि वैरिएंस पूर्वाग्रहित अनुमानक का उपयोग करके निकाला जाता है (जिसे `N` से विभाजित किया जाता है न कि `N-1` से), जो विशेषताओं के बजाय नमूनों पर सामान्यीकृत करते समय उपयुक्त है।
|
||||
- **नॉर्मलाइज (`norm_x`):** `x` से औसत घटाता है और वैरिएंस के वर्गमूल के साथ `eps` को जोड़कर विभाजित करता है।
|
||||
- **वैरिएंस की गणना (`var`):** एम्बेडिंग आयाम के बीच `x` का वैरिएंस निकालता है, आयाम को भी बनाए रखते हुए। `unbiased=False` पैरामीटर यह सुनिश्चित करता है कि वैरिएंस पूर्वाग्रहित अनुमानक का उपयोग करके निकाला जाता है (जिसमें `N` के बजाय `N-1` से विभाजित किया जाता है), जो विशेषताओं के बजाय नमूनों पर सामान्यीकृत करते समय उपयुक्त है।
|
||||
- **नॉर्मलाइज (`norm_x`):** `x` से औसत घटाता है और वैरिएंस के वर्गमूल के साथ `eps` से विभाजित करता है।
|
||||
- **स्केल और शिफ्ट:** सामान्यीकृत आउटपुट पर सीखने योग्य `scale` और `shift` पैरामीटर लागू करता है।
|
||||
|
||||
> [!TIP]
|
||||
> लक्ष्य यह सुनिश्चित करना है कि एक ही टोकन के सभी आयामों में 0 का औसत और 1 का वैरिएंस हो। इसका लक्ष्य **गहरे न्यूरल नेटवर्क के प्रशिक्षण को स्थिर करना** है, जो आंतरिक सह-परिवर्तन को कम करने के द्वारा होता है, जो नेटवर्क सक्रियण के वितरण में परिवर्तन को संदर्भित करता है जो प्रशिक्षण के दौरान पैरामीटर के अद्यतन के कारण होता है।
|
||||
> लक्ष्य यह सुनिश्चित करना है कि एक ही टोकन के सभी आयामों में 0 का औसत और 1 का वैरिएंस हो। इसका लक्ष्य **गहरे न्यूरल नेटवर्क के प्रशिक्षण को स्थिर करना** है, जो आंतरिक सह-परिवर्तन शिफ्ट को कम करने के द्वारा होता है, जो नेटवर्क सक्रियण के वितरण में परिवर्तन को संदर्भित करता है जो प्रशिक्षण के दौरान पैरामीटर के अद्यतन के कारण होता है।
|
||||
|
||||
### **ट्रांसफार्मर ब्लॉक**
|
||||
|
||||
_आकृतियों को मैट्रिस के आकार को बेहतर समझने के लिए टिप्पणियों के रूप में जोड़ा गया है:_
|
||||
_आकृतियों को मैट्रिसेस के आकार को बेहतर समझने के लिए टिप्पणियों के रूप में जोड़ा गया है:_
|
||||
```python
|
||||
# From https://github.com/rasbt/LLMs-from-scratch/tree/main/ch04
|
||||
|
||||
@ -348,7 +348,7 @@ return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
```
|
||||
#### **उद्देश्य और कार्यक्षमता**
|
||||
|
||||
- **परतों की संरचना:** मल्टी-हेड ध्यान, फीडफॉरवर्ड नेटवर्क, परत सामान्यीकरण, और अवशिष्ट कनेक्शन को जोड़ता है।
|
||||
- **परतों की संरचना:** मल्टी-हेड ध्यान, फीडफॉरवर्ड नेटवर्क, परत सामान्यीकरण, और अवशिष्ट कनेक्शन को मिलाता है।
|
||||
- **परत सामान्यीकरण:** स्थिर प्रशिक्षण के लिए ध्यान और फीडफॉरवर्ड परतों से पहले लागू किया जाता है।
|
||||
- **अवशिष्ट कनेक्शन (शॉर्टकट):** ग्रेडिएंट प्रवाह में सुधार करने और गहरे नेटवर्क के प्रशिक्षण को सक्षम करने के लिए एक परत के इनपुट को इसके आउटपुट में जोड़ता है।
|
||||
- **ड्रॉपआउट:** नियमितीकरण के लिए ध्यान और फीडफॉरवर्ड परतों के बाद लागू किया जाता है।
|
||||
@ -357,22 +357,22 @@ return x # Output shape: (batch_size, seq_len, emb_dim)
|
||||
|
||||
1. **पहला अवशिष्ट पथ (स्वयं-ध्यान):**
|
||||
- **इनपुट (`shortcut`):** अवशिष्ट कनेक्शन के लिए मूल इनपुट को सहेजें।
|
||||
- **परत मान (`norm1`):** इनपुट को सामान्यीकृत करें।
|
||||
- **परत मानक (`norm1`):** इनपुट को सामान्यीकृत करें।
|
||||
- **मल्टी-हेड ध्यान (`att`):** स्वयं-ध्यान लागू करें।
|
||||
- **ड्रॉपआउट (`drop_shortcut`):** नियमितीकरण के लिए ड्रॉपआउट लागू करें।
|
||||
- **अवशिष्ट जोड़ें (`x + shortcut`):** मूल इनपुट के साथ मिलाएं।
|
||||
2. **दूसरा अवशिष्ट पथ (फीडफॉरवर्ड):**
|
||||
- **इनपुट (`shortcut`):** अगले अवशिष्ट कनेक्शन के लिए अपडेटेड इनपुट को सहेजें।
|
||||
- **परत मान (`norm2`):** इनपुट को सामान्यीकृत करें।
|
||||
- **परत मानक (`norm2`):** इनपुट को सामान्यीकृत करें।
|
||||
- **फीडफॉरवर्ड नेटवर्क (`ff`):** फीडफॉरवर्ड परिवर्तन लागू करें।
|
||||
- **ड्रॉपआउट (`drop_shortcut`):** ड्रॉपआउट लागू करें।
|
||||
- **अवशिष्ट जोड़ें (`x + shortcut`):** पहले अवशिष्ट पथ से इनपुट के साथ मिलाएं।
|
||||
|
||||
> [!TIP]
|
||||
> ट्रांसफार्मर ब्लॉक सभी नेटवर्क को एक साथ समूहित करता है और प्रशिक्षण स्थिरता और परिणामों में सुधार के लिए कुछ **सामान्यीकरण** और **ड्रॉपआउट** लागू करता है।\
|
||||
> ट्रांसफार्मर ब्लॉक सभी नेटवर्क को एक साथ समूहित करता है और प्रशिक्षण की स्थिरता और परिणामों में सुधार के लिए कुछ **सामान्यीकरण** और **ड्रॉपआउट** लागू करता है।\
|
||||
> ध्यान दें कि ड्रॉपआउट प्रत्येक नेटवर्क के उपयोग के बाद किया जाता है जबकि सामान्यीकरण पहले लागू किया जाता है।
|
||||
>
|
||||
> इसके अलावा, यह शॉर्टकट का भी उपयोग करता है जिसमें **एक नेटवर्क के आउटपुट को इसके इनपुट के साथ जोड़ना** शामिल है। यह सुनिश्चित करके वैनिशिंग ग्रेडिएंट समस्या को रोकने में मदद करता है कि प्रारंभिक परतें "जितना संभव" योगदान करती हैं जैसे कि अंतिम परतें।
|
||||
> इसके अलावा, यह शॉर्टकट का भी उपयोग करता है जिसमें **एक नेटवर्क के आउटपुट को इसके इनपुट के साथ जोड़ना** शामिल है। यह सुनिश्चित करके वैनिशिंग ग्रेडिएंट समस्या को रोकने में मदद करता है कि प्रारंभिक परतें "जितना संभव हो" अंतिम परतों में योगदान करती हैं।
|
||||
|
||||
### **GPTModel**
|
||||
|
||||
@ -608,7 +608,7 @@ total_params = 163,009,536
|
||||
```
|
||||
## Generate Text
|
||||
|
||||
एक ऐसा मॉडल होना जो अगले टोकन की भविष्यवाणी करता है जैसे कि पहले वाला, बस अंतिम टोकन मानों को आउटपुट से लेना आवश्यक है (क्योंकि वे भविष्यवाणी किए गए टोकन के होंगे), जो कि **शब्दावली में प्रत्येक प्रविष्टि के लिए एक मान** होगा और फिर `softmax` फ़ंक्शन का उपयोग करके आयामों को उन संभावनाओं में सामान्यीकृत करना होगा जो 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):
|
||||
```python
|
||||
@ -661,6 +661,6 @@ context_size=GPT_CONFIG_124M["context_length"]
|
||||
print("Output:", out)
|
||||
print("Output length:", len(out[0]))
|
||||
```
|
||||
## References
|
||||
## संदर्भ
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
||||
|
943
src/AI/AI-llm-architecture/6.-pre-training-and-loading-models.md
Normal file
943
src/AI/AI-llm-architecture/6.-pre-training-and-loading-models.md
Normal file
@ -0,0 +1,943 @@
|
||||
# 6. प्री-ट्रेनिंग और मॉडल लोड करना
|
||||
|
||||
## टेक्स्ट जनरेशन
|
||||
|
||||
एक मॉडल को प्रशिक्षित करने के लिए हमें उस मॉडल को नए टोकन उत्पन्न करने में सक्षम होना चाहिए। फिर हम उत्पन्न किए गए टोकनों की तुलना अपेक्षित टोकनों से करेंगे ताकि मॉडल को **उन टोकनों को सीखने के लिए प्रशिक्षित किया जा सके जिन्हें उसे उत्पन्न करना है**।
|
||||
|
||||
जैसे कि पिछले उदाहरणों में हमने कुछ टोकनों की भविष्यवाणी की है, इसे इस उद्देश्य के लिए पुन: उपयोग करना संभव है।
|
||||
|
||||
> [!TIP]
|
||||
> इस छठे चरण का लक्ष्य बहुत सरल है: **मॉडल को शून्य से प्रशिक्षित करना**। इसके लिए पिछले LLM आर्किटेक्चर का उपयोग किया जाएगा जिसमें डेटा सेट पर परिभाषित हानि कार्यों और ऑप्टिमाइज़र का उपयोग करते हुए कुछ लूप होंगे ताकि मॉडल के सभी पैरामीटर को प्रशिक्षित किया जा सके।
|
||||
|
||||
## टेक्स्ट मूल्यांकन
|
||||
|
||||
सही प्रशिक्षण करने के लिए अपेक्षित टोकन के लिए प्राप्त भविष्यवाणियों को मापना आवश्यक है। प्रशिक्षण का लक्ष्य सही टोकन की संभावना को अधिकतम करना है, जिसमें अन्य टोकनों की तुलना में इसकी संभावना बढ़ाना शामिल है।
|
||||
|
||||
सही टोकन की संभावना को अधिकतम करने के लिए, मॉडल के वेट्स को इस प्रकार संशोधित किया जाना चाहिए कि संभावना अधिकतम हो। वेट्स के अपडेट **बैकप्रोपेगेशन** के माध्यम से किए जाते हैं। इसके लिए एक **हानि कार्य की आवश्यकता होती है जिसे अधिकतम करना है**। इस मामले में, कार्य होगा **किए गए पूर्वानुमान और इच्छित पूर्वानुमान के बीच का अंतर**।
|
||||
|
||||
हालांकि, कच्चे पूर्वानुमानों के साथ काम करने के बजाय, यह आधार n के साथ एक लॉगरिदम के साथ काम करेगा। इसलिए यदि अपेक्षित टोकन का वर्तमान पूर्वानुमान 7.4541e-05 था, तो **7.4541e-05** का प्राकृतिक लॉगरिदम (आधार *e*) लगभग **-9.5042** है।\
|
||||
फिर, उदाहरण के लिए, 5 टोकनों की संदर्भ लंबाई के साथ प्रत्येक प्रविष्टि के लिए, मॉडल को 5 टोकनों की भविष्यवाणी करने की आवश्यकता होगी, पहले 4 टोकन इनपुट के अंतिम होंगे और पांचवां पूर्वानुमानित होगा। इसलिए, प्रत्येक प्रविष्टि के लिए हमारे पास उस मामले में 5 भविष्यवाणियाँ होंगी (हालांकि पहले 4 इनपुट में थे, मॉडल इसे नहीं जानता) जिसमें 5 अपेक्षित टोकन और इसलिए 5 संभावनाएँ अधिकतम करने के लिए होंगी।
|
||||
|
||||
इसलिए, प्रत्येक भविष्यवाणी के लिए प्राकृतिक लॉगरिदम करने के बाद, **औसत** की गणना की जाती है, **माइनस प्रतीक हटा दिया जाता है** (इसे _क्रॉस एंट्रॉपी लॉस_ कहा जाता है) और यही **संख्या है जिसे 0 के करीब लाना है** क्योंकि 1 का प्राकृतिक लॉगरिदम 0 है:
|
||||
|
||||
<figure><img src="../../images/image (10) (1).png" alt="" width="563"><figcaption><p><a href="https://camo.githubusercontent.com/3c0ab9c55cefa10b667f1014b6c42df901fa330bb2bc9cea88885e784daec8ba/68747470733a2f2f73656261737469616e72617363686b612e636f6d2f696d616765732f4c4c4d732d66726f6d2d736372617463682d696d616765732f636830355f636f6d707265737365642f63726f73732d656e74726f70792e776562703f313233">https://camo.githubusercontent.com/3c0ab9c55cefa10b667f1014b6c42df901fa330bb2bc9cea88885e784daec8ba/68747470733a2f2f73656261737469616e72617363686b612e636f6d2f696d616765732f4c4c4d732d66726f6d2d736372617463682d696d616765732f636830355f636f6d707265737365642f63726f73732d656e74726f70792e776562703f313233</a></p></figcaption></figure>
|
||||
|
||||
मॉडल की गुणवत्ता को मापने का एक और तरीका **परप्लेक्सिटी** कहा जाता है। **परप्लेक्सिटी** एक मीट्रिक है जिसका उपयोग यह मूल्यांकन करने के लिए किया जाता है कि एक संभाव्यता मॉडल एक नमूने की भविष्यवाणी कितनी अच्छी तरह करता है। भाषा मॉडलिंग में, यह अनुक्रम में अगले टोकन की भविष्यवाणी करते समय **मॉडल की अनिश्चितता** का प्रतिनिधित्व करता है।\
|
||||
उदाहरण के लिए, 48725 का परप्लेक्सिटी मान, इसका मतलब है कि जब एक टोकन की भविष्यवाणी करने की आवश्यकता होती है, तो यह यह सुनिश्चित नहीं है कि शब्दकोश में 48,725 टोकनों में से कौन सा सही है।
|
||||
|
||||
## प्री-ट्रेन उदाहरण
|
||||
|
||||
यह प्रारंभिक कोड है जो [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch05/01_main-chapter-code/ch05.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch05/01_main-chapter-code/ch05.ipynb) में प्रस्तावित किया गया है, कभी-कभी थोड़ा संशोधित
|
||||
|
||||
<details>
|
||||
|
||||
<summary>यहां उपयोग किया गया पूर्व का कोड लेकिन पहले के अनुभागों में पहले ही समझाया गया है</summary>
|
||||
```python
|
||||
"""
|
||||
This is code explained before so it won't be exaplained
|
||||
"""
|
||||
|
||||
import tiktoken
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from torch.utils.data import Dataset, DataLoader
|
||||
|
||||
|
||||
class GPTDatasetV1(Dataset):
|
||||
def __init__(self, txt, tokenizer, max_length, stride):
|
||||
self.input_ids = []
|
||||
self.target_ids = []
|
||||
|
||||
# Tokenize the entire text
|
||||
token_ids = tokenizer.encode(txt, allowed_special={"<|endoftext|>"})
|
||||
|
||||
# Use a sliding window to chunk the book into overlapping sequences of max_length
|
||||
for i in range(0, len(token_ids) - max_length, stride):
|
||||
input_chunk = token_ids[i:i + max_length]
|
||||
target_chunk = token_ids[i + 1: i + max_length + 1]
|
||||
self.input_ids.append(torch.tensor(input_chunk))
|
||||
self.target_ids.append(torch.tensor(target_chunk))
|
||||
|
||||
def __len__(self):
|
||||
return len(self.input_ids)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return self.input_ids[idx], self.target_ids[idx]
|
||||
|
||||
|
||||
def create_dataloader_v1(txt, batch_size=4, max_length=256,
|
||||
stride=128, shuffle=True, drop_last=True, num_workers=0):
|
||||
# Initialize the tokenizer
|
||||
tokenizer = tiktoken.get_encoding("gpt2")
|
||||
|
||||
# Create dataset
|
||||
dataset = GPTDatasetV1(txt, tokenizer, max_length, stride)
|
||||
|
||||
# Create dataloader
|
||||
dataloader = DataLoader(
|
||||
dataset, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last, num_workers=num_workers)
|
||||
|
||||
return dataloader
|
||||
|
||||
|
||||
class MultiHeadAttention(nn.Module):
|
||||
def __init__(self, d_in, d_out, context_length, dropout, num_heads, qkv_bias=False):
|
||||
super().__init__()
|
||||
assert d_out % num_heads == 0, "d_out must be divisible by n_heads"
|
||||
|
||||
self.d_out = d_out
|
||||
self.num_heads = num_heads
|
||||
self.head_dim = d_out // num_heads # Reduce the projection dim to match desired output dim
|
||||
|
||||
self.W_query = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_key = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.W_value = nn.Linear(d_in, d_out, bias=qkv_bias)
|
||||
self.out_proj = nn.Linear(d_out, d_out) # Linear layer to combine head outputs
|
||||
self.dropout = nn.Dropout(dropout)
|
||||
self.register_buffer('mask', torch.triu(torch.ones(context_length, context_length), diagonal=1))
|
||||
|
||||
def forward(self, x):
|
||||
b, num_tokens, d_in = x.shape
|
||||
|
||||
keys = self.W_key(x) # Shape: (b, num_tokens, d_out)
|
||||
queries = self.W_query(x)
|
||||
values = self.W_value(x)
|
||||
|
||||
# We implicitly split the matrix by adding a `num_heads` dimension
|
||||
# Unroll last dim: (b, num_tokens, d_out) -> (b, num_tokens, num_heads, head_dim)
|
||||
keys = keys.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
values = values.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
queries = queries.view(b, num_tokens, self.num_heads, self.head_dim)
|
||||
|
||||
# Transpose: (b, num_tokens, num_heads, head_dim) -> (b, num_heads, num_tokens, head_dim)
|
||||
keys = keys.transpose(1, 2)
|
||||
queries = queries.transpose(1, 2)
|
||||
values = values.transpose(1, 2)
|
||||
|
||||
# Compute scaled dot-product attention (aka self-attention) with a causal mask
|
||||
attn_scores = queries @ keys.transpose(2, 3) # Dot product for each head
|
||||
|
||||
# Original mask truncated to the number of tokens and converted to boolean
|
||||
mask_bool = self.mask.bool()[:num_tokens, :num_tokens]
|
||||
|
||||
# Use the mask to fill attention scores
|
||||
attn_scores.masked_fill_(mask_bool, -torch.inf)
|
||||
|
||||
attn_weights = torch.softmax(attn_scores / keys.shape[-1]**0.5, dim=-1)
|
||||
attn_weights = self.dropout(attn_weights)
|
||||
|
||||
# Shape: (b, num_tokens, num_heads, head_dim)
|
||||
context_vec = (attn_weights @ values).transpose(1, 2)
|
||||
|
||||
# Combine heads, where self.d_out = self.num_heads * self.head_dim
|
||||
context_vec = context_vec.reshape(b, num_tokens, self.d_out)
|
||||
context_vec = self.out_proj(context_vec) # optional projection
|
||||
|
||||
return context_vec
|
||||
|
||||
|
||||
class LayerNorm(nn.Module):
|
||||
def __init__(self, emb_dim):
|
||||
super().__init__()
|
||||
self.eps = 1e-5
|
||||
self.scale = nn.Parameter(torch.ones(emb_dim))
|
||||
self.shift = nn.Parameter(torch.zeros(emb_dim))
|
||||
|
||||
def forward(self, x):
|
||||
mean = x.mean(dim=-1, keepdim=True)
|
||||
var = x.var(dim=-1, keepdim=True, unbiased=False)
|
||||
norm_x = (x - mean) / torch.sqrt(var + self.eps)
|
||||
return self.scale * norm_x + self.shift
|
||||
|
||||
|
||||
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))
|
||||
))
|
||||
|
||||
|
||||
class FeedForward(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.layers = nn.Sequential(
|
||||
nn.Linear(cfg["emb_dim"], 4 * cfg["emb_dim"]),
|
||||
GELU(),
|
||||
nn.Linear(4 * cfg["emb_dim"], cfg["emb_dim"]),
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.layers(x)
|
||||
|
||||
|
||||
class TransformerBlock(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.att = MultiHeadAttention(
|
||||
d_in=cfg["emb_dim"],
|
||||
d_out=cfg["emb_dim"],
|
||||
context_length=cfg["context_length"],
|
||||
num_heads=cfg["n_heads"],
|
||||
dropout=cfg["drop_rate"],
|
||||
qkv_bias=cfg["qkv_bias"])
|
||||
self.ff = FeedForward(cfg)
|
||||
self.norm1 = LayerNorm(cfg["emb_dim"])
|
||||
self.norm2 = LayerNorm(cfg["emb_dim"])
|
||||
self.drop_shortcut = nn.Dropout(cfg["drop_rate"])
|
||||
|
||||
def forward(self, x):
|
||||
# Shortcut connection for attention block
|
||||
shortcut = x
|
||||
x = self.norm1(x)
|
||||
x = self.att(x) # Shape [batch_size, num_tokens, emb_size]
|
||||
x = self.drop_shortcut(x)
|
||||
x = x + shortcut # Add the original input back
|
||||
|
||||
# Shortcut connection for feed-forward block
|
||||
shortcut = x
|
||||
x = self.norm2(x)
|
||||
x = self.ff(x)
|
||||
x = self.drop_shortcut(x)
|
||||
x = x + shortcut # Add the original input back
|
||||
|
||||
return x
|
||||
|
||||
|
||||
class GPTModel(nn.Module):
|
||||
def __init__(self, cfg):
|
||||
super().__init__()
|
||||
self.tok_emb = nn.Embedding(cfg["vocab_size"], cfg["emb_dim"])
|
||||
self.pos_emb = nn.Embedding(cfg["context_length"], cfg["emb_dim"])
|
||||
self.drop_emb = nn.Dropout(cfg["drop_rate"])
|
||||
|
||||
self.trf_blocks = nn.Sequential(
|
||||
*[TransformerBlock(cfg) for _ in range(cfg["n_layers"])])
|
||||
|
||||
self.final_norm = LayerNorm(cfg["emb_dim"])
|
||||
self.out_head = nn.Linear(cfg["emb_dim"], cfg["vocab_size"], bias=False)
|
||||
|
||||
def forward(self, in_idx):
|
||||
batch_size, seq_len = in_idx.shape
|
||||
tok_embeds = self.tok_emb(in_idx)
|
||||
pos_embeds = self.pos_emb(torch.arange(seq_len, device=in_idx.device))
|
||||
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
|
||||
```
|
||||
</details>
|
||||
```python
|
||||
# Download contents to train the data with
|
||||
import os
|
||||
import urllib.request
|
||||
|
||||
file_path = "the-verdict.txt"
|
||||
url = "https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt"
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
with urllib.request.urlopen(url) as response:
|
||||
text_data = response.read().decode('utf-8')
|
||||
with open(file_path, "w", encoding="utf-8") as file:
|
||||
file.write(text_data)
|
||||
else:
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
text_data = file.read()
|
||||
|
||||
total_characters = len(text_data)
|
||||
tokenizer = tiktoken.get_encoding("gpt2")
|
||||
total_tokens = len(tokenizer.encode(text_data))
|
||||
|
||||
print("Data downloaded")
|
||||
print("Characters:", total_characters)
|
||||
print("Tokens:", total_tokens)
|
||||
|
||||
# Model initialization
|
||||
GPT_CONFIG_124M = {
|
||||
"vocab_size": 50257, # Vocabulary size
|
||||
"context_length": 256, # Shortened context length (orig: 1024)
|
||||
"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)
|
||||
model.eval()
|
||||
print ("Model initialized")
|
||||
|
||||
|
||||
# Functions to transform from tokens to ids and from to ids to tokens
|
||||
def text_to_token_ids(text, tokenizer):
|
||||
encoded = tokenizer.encode(text, allowed_special={'<|endoftext|>'})
|
||||
encoded_tensor = torch.tensor(encoded).unsqueeze(0) # add batch dimension
|
||||
return encoded_tensor
|
||||
|
||||
def token_ids_to_text(token_ids, tokenizer):
|
||||
flat = token_ids.squeeze(0) # remove batch dimension
|
||||
return tokenizer.decode(flat.tolist())
|
||||
|
||||
|
||||
|
||||
# Define loss functions
|
||||
def calc_loss_batch(input_batch, target_batch, model, device):
|
||||
input_batch, target_batch = input_batch.to(device), target_batch.to(device)
|
||||
logits = model(input_batch)
|
||||
loss = torch.nn.functional.cross_entropy(logits.flatten(0, 1), target_batch.flatten())
|
||||
return loss
|
||||
|
||||
|
||||
def calc_loss_loader(data_loader, model, device, num_batches=None):
|
||||
total_loss = 0.
|
||||
if len(data_loader) == 0:
|
||||
return float("nan")
|
||||
elif num_batches is None:
|
||||
num_batches = len(data_loader)
|
||||
else:
|
||||
# Reduce the number of batches to match the total number of batches in the data loader
|
||||
# if num_batches exceeds the number of batches in the data loader
|
||||
num_batches = min(num_batches, len(data_loader))
|
||||
for i, (input_batch, target_batch) in enumerate(data_loader):
|
||||
if i < num_batches:
|
||||
loss = calc_loss_batch(input_batch, target_batch, model, device)
|
||||
total_loss += loss.item()
|
||||
else:
|
||||
break
|
||||
return total_loss / num_batches
|
||||
|
||||
|
||||
# Apply Train/validation ratio and create dataloaders
|
||||
train_ratio = 0.90
|
||||
split_idx = int(train_ratio * len(text_data))
|
||||
train_data = text_data[:split_idx]
|
||||
val_data = text_data[split_idx:]
|
||||
|
||||
torch.manual_seed(123)
|
||||
|
||||
train_loader = create_dataloader_v1(
|
||||
train_data,
|
||||
batch_size=2,
|
||||
max_length=GPT_CONFIG_124M["context_length"],
|
||||
stride=GPT_CONFIG_124M["context_length"],
|
||||
drop_last=True,
|
||||
shuffle=True,
|
||||
num_workers=0
|
||||
)
|
||||
|
||||
val_loader = create_dataloader_v1(
|
||||
val_data,
|
||||
batch_size=2,
|
||||
max_length=GPT_CONFIG_124M["context_length"],
|
||||
stride=GPT_CONFIG_124M["context_length"],
|
||||
drop_last=False,
|
||||
shuffle=False,
|
||||
num_workers=0
|
||||
)
|
||||
|
||||
|
||||
# Sanity checks
|
||||
if total_tokens * (train_ratio) < GPT_CONFIG_124M["context_length"]:
|
||||
print("Not enough tokens for the training loader. "
|
||||
"Try to lower the `GPT_CONFIG_124M['context_length']` or "
|
||||
"increase the `training_ratio`")
|
||||
|
||||
if total_tokens * (1-train_ratio) < GPT_CONFIG_124M["context_length"]:
|
||||
print("Not enough tokens for the validation loader. "
|
||||
"Try to lower the `GPT_CONFIG_124M['context_length']` or "
|
||||
"decrease the `training_ratio`")
|
||||
|
||||
print("Train loader:")
|
||||
for x, y in train_loader:
|
||||
print(x.shape, y.shape)
|
||||
|
||||
print("\nValidation loader:")
|
||||
for x, y in val_loader:
|
||||
print(x.shape, y.shape)
|
||||
|
||||
train_tokens = 0
|
||||
for input_batch, target_batch in train_loader:
|
||||
train_tokens += input_batch.numel()
|
||||
|
||||
val_tokens = 0
|
||||
for input_batch, target_batch in val_loader:
|
||||
val_tokens += input_batch.numel()
|
||||
|
||||
print("Training tokens:", train_tokens)
|
||||
print("Validation tokens:", val_tokens)
|
||||
print("All tokens:", train_tokens + val_tokens)
|
||||
|
||||
|
||||
# Indicate the device to use
|
||||
if torch.cuda.is_available():
|
||||
device = torch.device("cuda")
|
||||
elif torch.backends.mps.is_available():
|
||||
device = torch.device("mps")
|
||||
else:
|
||||
device = torch.device("cpu")
|
||||
|
||||
print(f"Using {device} device.")
|
||||
|
||||
model.to(device) # no assignment model = model.to(device) necessary for nn.Module classes
|
||||
|
||||
|
||||
|
||||
# Pre-calculate losses without starting yet
|
||||
torch.manual_seed(123) # For reproducibility due to the shuffling in the data loader
|
||||
|
||||
with torch.no_grad(): # Disable gradient tracking for efficiency because we are not training, yet
|
||||
train_loss = calc_loss_loader(train_loader, model, device)
|
||||
val_loss = calc_loss_loader(val_loader, model, device)
|
||||
|
||||
print("Training loss:", train_loss)
|
||||
print("Validation loss:", val_loss)
|
||||
|
||||
|
||||
# Functions to train the data
|
||||
def train_model_simple(model, train_loader, val_loader, optimizer, device, num_epochs,
|
||||
eval_freq, eval_iter, start_context, tokenizer):
|
||||
# Initialize lists to track losses and tokens seen
|
||||
train_losses, val_losses, track_tokens_seen = [], [], []
|
||||
tokens_seen, global_step = 0, -1
|
||||
|
||||
# Main training loop
|
||||
for epoch in range(num_epochs):
|
||||
model.train() # Set model to training mode
|
||||
|
||||
for input_batch, target_batch in train_loader:
|
||||
optimizer.zero_grad() # Reset loss gradients from previous batch iteration
|
||||
loss = calc_loss_batch(input_batch, target_batch, model, device)
|
||||
loss.backward() # Calculate loss gradients
|
||||
optimizer.step() # Update model weights using loss gradients
|
||||
tokens_seen += input_batch.numel()
|
||||
global_step += 1
|
||||
|
||||
# Optional evaluation step
|
||||
if global_step % eval_freq == 0:
|
||||
train_loss, val_loss = evaluate_model(
|
||||
model, train_loader, val_loader, device, eval_iter)
|
||||
train_losses.append(train_loss)
|
||||
val_losses.append(val_loss)
|
||||
track_tokens_seen.append(tokens_seen)
|
||||
print(f"Ep {epoch+1} (Step {global_step:06d}): "
|
||||
f"Train loss {train_loss:.3f}, Val loss {val_loss:.3f}")
|
||||
|
||||
# Print a sample text after each epoch
|
||||
generate_and_print_sample(
|
||||
model, tokenizer, device, start_context
|
||||
)
|
||||
|
||||
return train_losses, val_losses, track_tokens_seen
|
||||
|
||||
|
||||
def evaluate_model(model, train_loader, val_loader, device, eval_iter):
|
||||
model.eval()
|
||||
with torch.no_grad():
|
||||
train_loss = calc_loss_loader(train_loader, model, device, num_batches=eval_iter)
|
||||
val_loss = calc_loss_loader(val_loader, model, device, num_batches=eval_iter)
|
||||
model.train()
|
||||
return train_loss, val_loss
|
||||
|
||||
|
||||
def generate_and_print_sample(model, tokenizer, device, start_context):
|
||||
model.eval()
|
||||
context_size = model.pos_emb.weight.shape[0]
|
||||
encoded = text_to_token_ids(start_context, tokenizer).to(device)
|
||||
with torch.no_grad():
|
||||
token_ids = generate_text(
|
||||
model=model, idx=encoded,
|
||||
max_new_tokens=50, context_size=context_size
|
||||
)
|
||||
decoded_text = token_ids_to_text(token_ids, tokenizer)
|
||||
print(decoded_text.replace("\n", " ")) # Compact print format
|
||||
model.train()
|
||||
|
||||
|
||||
# Start training!
|
||||
import time
|
||||
start_time = time.time()
|
||||
|
||||
torch.manual_seed(123)
|
||||
model = GPTModel(GPT_CONFIG_124M)
|
||||
model.to(device)
|
||||
optimizer = torch.optim.AdamW(model.parameters(), lr=0.0004, weight_decay=0.1)
|
||||
|
||||
num_epochs = 10
|
||||
train_losses, val_losses, tokens_seen = train_model_simple(
|
||||
model, train_loader, val_loader, optimizer, device,
|
||||
num_epochs=num_epochs, eval_freq=5, eval_iter=5,
|
||||
start_context="Every effort moves you", tokenizer=tokenizer
|
||||
)
|
||||
|
||||
end_time = time.time()
|
||||
execution_time_minutes = (end_time - start_time) / 60
|
||||
print(f"Training completed in {execution_time_minutes:.2f} minutes.")
|
||||
|
||||
|
||||
|
||||
# Show graphics with the training process
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.ticker import MaxNLocator
|
||||
import math
|
||||
def plot_losses(epochs_seen, tokens_seen, train_losses, val_losses):
|
||||
fig, ax1 = plt.subplots(figsize=(5, 3))
|
||||
ax1.plot(epochs_seen, train_losses, label="Training loss")
|
||||
ax1.plot(
|
||||
epochs_seen, val_losses, linestyle="-.", label="Validation loss"
|
||||
)
|
||||
ax1.set_xlabel("Epochs")
|
||||
ax1.set_ylabel("Loss")
|
||||
ax1.legend(loc="upper right")
|
||||
ax1.xaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
ax2 = ax1.twiny()
|
||||
ax2.plot(tokens_seen, train_losses, alpha=0)
|
||||
ax2.set_xlabel("Tokens seen")
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
|
||||
# Compute perplexity from the loss values
|
||||
train_ppls = [math.exp(loss) for loss in train_losses]
|
||||
val_ppls = [math.exp(loss) for loss in val_losses]
|
||||
# Plot perplexity over tokens seen
|
||||
plt.figure()
|
||||
plt.plot(tokens_seen, train_ppls, label='Training Perplexity')
|
||||
plt.plot(tokens_seen, val_ppls, label='Validation Perplexity')
|
||||
plt.xlabel('Tokens Seen')
|
||||
plt.ylabel('Perplexity')
|
||||
plt.title('Perplexity over Training')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
epochs_tensor = torch.linspace(0, num_epochs, len(train_losses))
|
||||
plot_losses(epochs_tensor, tokens_seen, train_losses, val_losses)
|
||||
|
||||
|
||||
torch.save({
|
||||
"model_state_dict": model.state_dict(),
|
||||
"optimizer_state_dict": optimizer.state_dict(),
|
||||
},
|
||||
"/tmp/model_and_optimizer.pth"
|
||||
)
|
||||
```
|
||||
चलिए एक कदम दर कदम व्याख्या देखते हैं
|
||||
|
||||
### Functions to transform text <--> ids
|
||||
|
||||
ये कुछ सरल फ़ंक्शन हैं जो शब्दावली से टेक्स्ट को आईडी में और इसके विपरीत परिवर्तित करने के लिए उपयोग किए जा सकते हैं। यह टेक्स्ट के हैंडलिंग की शुरुआत में और भविष्यवाणियों के अंत में आवश्यक है:
|
||||
```python
|
||||
# Functions to transform from tokens to ids and from to ids to tokens
|
||||
def text_to_token_ids(text, tokenizer):
|
||||
encoded = tokenizer.encode(text, allowed_special={'<|endoftext|>'})
|
||||
encoded_tensor = torch.tensor(encoded).unsqueeze(0) # add batch dimension
|
||||
return encoded_tensor
|
||||
|
||||
def token_ids_to_text(token_ids, tokenizer):
|
||||
flat = token_ids.squeeze(0) # remove batch dimension
|
||||
return tokenizer.decode(flat.tolist())
|
||||
```
|
||||
### Generate text functions
|
||||
|
||||
एक पिछले अनुभाग में एक फ़ंक्शन था जो **सबसे संभावित टोकन** को लॉजिट प्राप्त करने के बाद प्राप्त करता था। हालाँकि, इसका मतलब यह होगा कि प्रत्येक प्रविष्टि के लिए हमेशा एक ही आउटपुट उत्पन्न होगा, जो इसे बहुत निर्धारक बनाता है।
|
||||
|
||||
निम्नलिखित `generate_text` फ़ंक्शन, `top-k`, `temperature` और `multinomial` अवधारणाओं को लागू करेगा।
|
||||
|
||||
- **`top-k`** का अर्थ है कि हम शीर्ष k टोकनों को छोड़कर सभी टोकनों की संभावनाओं को `-inf` तक कम करना शुरू करेंगे। इसलिए, यदि k=3 है, तो निर्णय लेने से पहले केवल 3 सबसे संभावित टोकनों की संभावना `-inf` से अलग होगी।
|
||||
- **`temperature`** का अर्थ है कि प्रत्येक संभावना को तापमान मान से विभाजित किया जाएगा। 0.1 का मान उच्चतम संभावना को सबसे कम संभावना की तुलना में बेहतर बनाएगा, जबकि 5 का तापमान उदाहरण के लिए इसे अधिक समतल बना देगा। यह LLM के उत्तरों में विविधता को सुधारने में मदद करता है।
|
||||
- तापमान लागू करने के बाद, एक **`softmax`** फ़ंक्शन फिर से लागू किया जाता है ताकि सभी शेष टोकनों की कुल संभावना 1 हो सके।
|
||||
- अंत में, सबसे बड़ी संभावना वाले टोकन को चुनने के बजाय, फ़ंक्शन **`multinomial`** को **अंतिम संभावनाओं के अनुसार अगले टोकन की भविष्यवाणी करने के लिए** लागू किया जाता है। इसलिए यदि टोकन 1 की संभावनाएँ 70% थीं, टोकन 2 की 20% और टोकन 3 की 10%, तो 70% समय टोकन 1 का चयन किया जाएगा, 20% समय यह टोकन 2 होगा और 10% समय यह 10% होगा।
|
||||
```python
|
||||
# Generate text function
|
||||
def generate_text(model, idx, max_new_tokens, context_size, temperature=0.0, top_k=None, eos_id=None):
|
||||
|
||||
# For-loop is the same as before: Get logits, and only focus on last time step
|
||||
for _ in range(max_new_tokens):
|
||||
idx_cond = idx[:, -context_size:]
|
||||
with torch.no_grad():
|
||||
logits = model(idx_cond)
|
||||
logits = logits[:, -1, :]
|
||||
|
||||
# New: Filter logits with top_k sampling
|
||||
if top_k is not None:
|
||||
# Keep only top_k values
|
||||
top_logits, _ = torch.topk(logits, top_k)
|
||||
min_val = top_logits[:, -1]
|
||||
logits = torch.where(logits < min_val, torch.tensor(float("-inf")).to(logits.device), logits)
|
||||
|
||||
# New: Apply temperature scaling
|
||||
if temperature > 0.0:
|
||||
logits = logits / temperature
|
||||
|
||||
# Apply softmax to get probabilities
|
||||
probs = torch.softmax(logits, dim=-1) # (batch_size, context_len)
|
||||
|
||||
# Sample from the distribution
|
||||
idx_next = torch.multinomial(probs, num_samples=1) # (batch_size, 1)
|
||||
|
||||
# Otherwise same as before: get idx of the vocab entry with the highest logits value
|
||||
else:
|
||||
idx_next = torch.argmax(logits, dim=-1, keepdim=True) # (batch_size, 1)
|
||||
|
||||
if idx_next == eos_id: # Stop generating early if end-of-sequence token is encountered and eos_id is specified
|
||||
break
|
||||
|
||||
# Same as before: append sampled index to the running sequence
|
||||
idx = torch.cat((idx, idx_next), dim=1) # (batch_size, num_tokens+1)
|
||||
|
||||
return idx
|
||||
```
|
||||
> [!TIP]
|
||||
> एक सामान्य विकल्प है `top-k` जिसे [**`top-p`**](https://en.wikipedia.org/wiki/Top-p_sampling) कहा जाता है, जिसे नाभिक नमूना भी कहा जाता है, जो सबसे अधिक संभावना वाले k नमूनों को प्राप्त करने के बजाय, सभी परिणामस्वरूप **शब्दावली** को संभावनाओं के अनुसार **व्यवस्थित** करता है और सबसे उच्च संभावना से सबसे कम तक **योग** करता है जब तक कि एक **थ्रेशोल्ड तक नहीं पहुँचता**।
|
||||
>
|
||||
> फिर, **केवल उन शब्दों** को शब्दावली में उनके सापेक्ष संभावनाओं के अनुसार माना जाएगा।
|
||||
>
|
||||
> यह `k` नमूनों की संख्या का चयन करने की आवश्यकता को समाप्त करता है, क्योंकि प्रत्येक मामले में आदर्श k भिन्न हो सकता है, बल्कि **केवल एक थ्रेशोल्ड**।
|
||||
>
|
||||
> _ध्यान दें कि यह सुधार पिछले कोड में शामिल नहीं है।_
|
||||
|
||||
> [!TIP]
|
||||
> उत्पन्न पाठ को सुधारने का एक और तरीका है **Beam search** का उपयोग करना, बजाय इस उदाहरण में उपयोग किए गए लालची खोज के।\
|
||||
> लालची खोज के विपरीत, जो प्रत्येक चरण में सबसे संभावित अगले शब्द का चयन करता है और एकल अनुक्रम बनाता है, **बीम खोज प्रत्येक चरण में शीर्ष 𝑘 k उच्चतम-स्कोर वाले आंशिक अनुक्रमों** (जिसे "बीम" कहा जाता है) का ट्रैक रखता है। एक साथ कई संभावनाओं का अन्वेषण करके, यह दक्षता और गुणवत्ता के बीच संतुलन बनाता है, **एक बेहतर समग्र** अनुक्रम खोजने के अवसरों को बढ़ाता है जो लालची दृष्टिकोण द्वारा जल्दी, उप-आदर्श विकल्पों के कारण छूट सकता है।
|
||||
>
|
||||
> _ध्यान दें कि यह सुधार पिछले कोड में शामिल नहीं है।_
|
||||
|
||||
### हानि कार्य
|
||||
|
||||
**`calc_loss_batch`** फ़ंक्शन एक एकल बैच की भविष्यवाणी की क्रॉस एंट्रोपी की गणना करता है।\
|
||||
**`calc_loss_loader`** सभी बैचों की क्रॉस एंट्रोपी प्राप्त करता है और **औसत क्रॉस एंट्रोपी** की गणना करता है।
|
||||
```python
|
||||
# Define loss functions
|
||||
def calc_loss_batch(input_batch, target_batch, model, device):
|
||||
input_batch, target_batch = input_batch.to(device), target_batch.to(device)
|
||||
logits = model(input_batch)
|
||||
loss = torch.nn.functional.cross_entropy(logits.flatten(0, 1), target_batch.flatten())
|
||||
return loss
|
||||
|
||||
def calc_loss_loader(data_loader, model, device, num_batches=None):
|
||||
total_loss = 0.
|
||||
if len(data_loader) == 0:
|
||||
return float("nan")
|
||||
elif num_batches is None:
|
||||
num_batches = len(data_loader)
|
||||
else:
|
||||
# Reduce the number of batches to match the total number of batches in the data loader
|
||||
# if num_batches exceeds the number of batches in the data loader
|
||||
num_batches = min(num_batches, len(data_loader))
|
||||
for i, (input_batch, target_batch) in enumerate(data_loader):
|
||||
if i < num_batches:
|
||||
loss = calc_loss_batch(input_batch, target_batch, model, device)
|
||||
total_loss += loss.item()
|
||||
else:
|
||||
break
|
||||
return total_loss / num_batches
|
||||
```
|
||||
> [!TIP]
|
||||
> **ग्रेडिएंट क्लिपिंग** एक तकनीक है जिसका उपयोग बड़े न्यूरल नेटवर्क में **प्रशिक्षण स्थिरता** को बढ़ाने के लिए किया जाता है, जिसमें ग्रेडिएंट के परिमाण के लिए एक **अधिकतम सीमा** निर्धारित की जाती है। जब ग्रेडिएंट इस पूर्वनिर्धारित `max_norm` को पार कर जाते हैं, तो उन्हें अनुपात में कम किया जाता है ताकि मॉडल के पैरामीटर में अपडेट एक प्रबंधनीय सीमा के भीतर रहें, जिससे विस्फोटक ग्रेडिएंट जैसी समस्याओं से बचा जा सके और अधिक नियंत्रित और स्थिर प्रशिक्षण सुनिश्चित हो सके।
|
||||
>
|
||||
> _ध्यान दें कि यह सुधार पिछले कोड में शामिल नहीं है।_
|
||||
>
|
||||
> निम्नलिखित उदाहरण देखें:
|
||||
|
||||
<figure><img src="../../images/image (6) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### डेटा लोड करना
|
||||
|
||||
फंक्शंस `create_dataloader_v1` और `create_dataloader_v1` पहले के अनुभाग में पहले ही चर्चा की जा चुकी हैं।
|
||||
|
||||
यहां से ध्यान दें कि यह परिभाषित किया गया है कि 90% टेक्स्ट का उपयोग प्रशिक्षण के लिए किया जाएगा जबकि 10% का उपयोग मान्यता के लिए किया जाएगा और दोनों सेट 2 अलग-अलग डेटा लोडर्स में संग्रहीत हैं।\
|
||||
ध्यान दें कि कभी-कभी डेटा सेट का एक भाग परीक्षण सेट के लिए भी छोड़ा जाता है ताकि मॉडल के प्रदर्शन का बेहतर मूल्यांकन किया जा सके।
|
||||
|
||||
दोनों डेटा लोडर्स समान बैच आकार, अधिकतम लंबाई और स्ट्राइड और कार्यकर्ताओं की संख्या (इस मामले में 0) का उपयोग कर रहे हैं।\
|
||||
मुख्य अंतर यह है कि प्रत्येक द्वारा उपयोग किया जाने वाला डेटा और मान्यकर्ता अंतिम को नहीं छोड़ रहा है और डेटा को शफल नहीं कर रहा है क्योंकि यह मान्यता के उद्देश्यों के लिए आवश्यक नहीं है।
|
||||
|
||||
इसके अलावा, तथ्य यह है कि **स्ट्राइड संदर्भ लंबाई के समान बड़ा है**, इसका मतलब है कि डेटा को प्रशिक्षित करने के लिए उपयोग किए जाने वाले संदर्भों के बीच ओवरलैप नहीं होगा (ओवरफिटिंग को कम करता है लेकिन प्रशिक्षण डेटा सेट को भी)।
|
||||
|
||||
इसके अलावा, ध्यान दें कि इस मामले में बैच आकार 2 है ताकि डेटा को 2 बैच में विभाजित किया जा सके, इसका मुख्य लक्ष्य समानांतर प्रसंस्करण की अनुमति देना और प्रति बैच खपत को कम करना है।
|
||||
```python
|
||||
train_ratio = 0.90
|
||||
split_idx = int(train_ratio * len(text_data))
|
||||
train_data = text_data[:split_idx]
|
||||
val_data = text_data[split_idx:]
|
||||
|
||||
torch.manual_seed(123)
|
||||
|
||||
train_loader = create_dataloader_v1(
|
||||
train_data,
|
||||
batch_size=2,
|
||||
max_length=GPT_CONFIG_124M["context_length"],
|
||||
stride=GPT_CONFIG_124M["context_length"],
|
||||
drop_last=True,
|
||||
shuffle=True,
|
||||
num_workers=0
|
||||
)
|
||||
|
||||
val_loader = create_dataloader_v1(
|
||||
val_data,
|
||||
batch_size=2,
|
||||
max_length=GPT_CONFIG_124M["context_length"],
|
||||
stride=GPT_CONFIG_124M["context_length"],
|
||||
drop_last=False,
|
||||
shuffle=False,
|
||||
num_workers=0
|
||||
)
|
||||
```
|
||||
## Sanity Checks
|
||||
|
||||
उद्देश्य यह है कि यह जांचा जाए कि प्रशिक्षण के लिए पर्याप्त टोकन हैं, आकार अपेक्षित हैं और प्रशिक्षण और मान्यता के लिए उपयोग किए गए टोकनों की संख्या के बारे में कुछ जानकारी प्राप्त की जाए:
|
||||
```python
|
||||
# Sanity checks
|
||||
if total_tokens * (train_ratio) < GPT_CONFIG_124M["context_length"]:
|
||||
print("Not enough tokens for the training loader. "
|
||||
"Try to lower the `GPT_CONFIG_124M['context_length']` or "
|
||||
"increase the `training_ratio`")
|
||||
|
||||
if total_tokens * (1-train_ratio) < GPT_CONFIG_124M["context_length"]:
|
||||
print("Not enough tokens for the validation loader. "
|
||||
"Try to lower the `GPT_CONFIG_124M['context_length']` or "
|
||||
"decrease the `training_ratio`")
|
||||
|
||||
print("Train loader:")
|
||||
for x, y in train_loader:
|
||||
print(x.shape, y.shape)
|
||||
|
||||
print("\nValidation loader:")
|
||||
for x, y in val_loader:
|
||||
print(x.shape, y.shape)
|
||||
|
||||
train_tokens = 0
|
||||
for input_batch, target_batch in train_loader:
|
||||
train_tokens += input_batch.numel()
|
||||
|
||||
val_tokens = 0
|
||||
for input_batch, target_batch in val_loader:
|
||||
val_tokens += input_batch.numel()
|
||||
|
||||
print("Training tokens:", train_tokens)
|
||||
print("Validation tokens:", val_tokens)
|
||||
print("All tokens:", train_tokens + val_tokens)
|
||||
```
|
||||
### प्रशिक्षण और पूर्व गणनाओं के लिए डिवाइस का चयन करें
|
||||
|
||||
निम्नलिखित कोड केवल उपयोग करने के लिए डिवाइस का चयन करता है और एक प्रारंभिक बिंदु के रूप में प्रशिक्षण हानि और मान्यता हानि की गणना करता है (बिना कुछ प्रशिक्षित किए)।
|
||||
```python
|
||||
# Indicate the device to use
|
||||
|
||||
if torch.cuda.is_available():
|
||||
device = torch.device("cuda")
|
||||
elif torch.backends.mps.is_available():
|
||||
device = torch.device("mps")
|
||||
else:
|
||||
device = torch.device("cpu")
|
||||
|
||||
print(f"Using {device} device.")
|
||||
|
||||
model.to(device) # no assignment model = model.to(device) necessary for nn.Module classes
|
||||
|
||||
# Pre-calculate losses without starting yet
|
||||
torch.manual_seed(123) # For reproducibility due to the shuffling in the data loader
|
||||
|
||||
with torch.no_grad(): # Disable gradient tracking for efficiency because we are not training, yet
|
||||
train_loss = calc_loss_loader(train_loader, model, device)
|
||||
val_loss = calc_loss_loader(val_loader, model, device)
|
||||
|
||||
print("Training loss:", train_loss)
|
||||
print("Validation loss:", val_loss)
|
||||
```
|
||||
### प्रशिक्षण कार्य
|
||||
|
||||
कार्य `generate_and_print_sample` केवल एक संदर्भ प्राप्त करेगा और कुछ टोकन उत्पन्न करेगा ताकि यह महसूस किया जा सके कि उस समय मॉडल कितना अच्छा है। इसे `train_model_simple` द्वारा प्रत्येक चरण पर कॉल किया जाता है।
|
||||
|
||||
कार्य `evaluate_model` को प्रशिक्षण कार्य के अनुसार बार-बार कॉल किया जाता है और इसका उपयोग उस समय मॉडल प्रशिक्षण में ट्रेन लॉस और वैलिडेशन लॉस को मापने के लिए किया जाता है।
|
||||
|
||||
फिर बड़ा कार्य `train_model_simple` है जो वास्तव में मॉडल को प्रशिक्षित करता है। यह अपेक्षाएँ करता है:
|
||||
|
||||
- ट्रेन डेटा लोडर (जिसमें डेटा पहले से अलग और प्रशिक्षण के लिए तैयार किया गया है)
|
||||
- वैलिडेटर लोडर
|
||||
- प्रशिक्षण के दौरान उपयोग करने के लिए **ऑप्टिमाइज़र**: यह वह कार्य है जो ग्रेडिएंट्स का उपयोग करेगा और लॉस को कम करने के लिए पैरामीटर को अपडेट करेगा। इस मामले में, जैसा कि आप देखेंगे, `AdamW` का उपयोग किया गया है, लेकिन और भी कई हैं।
|
||||
- `optimizer.zero_grad()` को प्रत्येक राउंड में ग्रेडिएंट्स को रीसेट करने के लिए कॉल किया जाता है ताकि उन्हें जमा न किया जा सके।
|
||||
- **`lr`** पैरामीटर **लर्निंग रेट** है जो ऑप्टिमाइजेशन प्रक्रिया के दौरान मॉडल के पैरामीटर को अपडेट करते समय **चरणों के आकार** को निर्धारित करता है। एक **छोटा** लर्निंग रेट का मतलब है कि ऑप्टिमाइज़र **वेट्स में छोटे अपडेट** करता है, जो अधिक **सटीक** समागम की ओर ले जा सकता है लेकिन प्रशिक्षण को **धीमा** कर सकता है। एक **बड़ा** लर्निंग रेट प्रशिक्षण को तेज कर सकता है लेकिन लॉस फ़ंक्शन के न्यूनतम को **ओवरशूट** करने का **जोखिम** उठाता है (**उस बिंदु पर कूदना** जहां लॉस फ़ंक्शन न्यूनतम होता है)।
|
||||
- **वेट डिके** लॉस कैलकुलेशन चरण को संशोधित करता है एक अतिरिक्त टर्म जोड़कर जो बड़े वेट्स को दंडित करता है। यह ऑप्टिमाइज़र को छोटे वेट्स के साथ समाधान खोजने के लिए प्रोत्साहित करता है, डेटा को अच्छी तरह से फिट करने और मॉडल को सरल रखने के बीच संतुलन बनाते हुए मशीन लर्निंग मॉडलों में ओवरफिटिंग को रोकने के लिए किसी एक विशेषता को अधिक महत्व देने से हतोत्साहित करता है।
|
||||
- पारंपरिक ऑप्टिमाइज़र जैसे SGD के साथ L2 नियमितीकरण वेट डिके को लॉस फ़ंक्शन के ग्रेडिएंट के साथ जोड़ते हैं। हालाँकि, **AdamW** (एडम ऑप्टिमाइज़र का एक रूप) वेट डिके को ग्रेडिएंट अपडेट से अलग करता है, जिससे अधिक प्रभावी नियमितीकरण होता है।
|
||||
- प्रशिक्षण के लिए उपयोग करने के लिए डिवाइस
|
||||
- एपॉक्स की संख्या: प्रशिक्षण डेटा पर जाने की次数
|
||||
- मूल्यांकन आवृत्ति: `evaluate_model` को कॉल करने की आवृत्ति
|
||||
- मूल्यांकन पुनरावृत्ति: `generate_and_print_sample` को कॉल करते समय मॉडल की वर्तमान स्थिति का मूल्यांकन करने के लिए उपयोग करने के लिए बैचों की संख्या
|
||||
- प्रारंभ संदर्भ: `generate_and_print_sample` को कॉल करते समय उपयोग करने के लिए प्रारंभिक वाक्य
|
||||
- टोकनाइज़र
|
||||
```python
|
||||
# Functions to train the data
|
||||
def train_model_simple(model, train_loader, val_loader, optimizer, device, num_epochs,
|
||||
eval_freq, eval_iter, start_context, tokenizer):
|
||||
# Initialize lists to track losses and tokens seen
|
||||
train_losses, val_losses, track_tokens_seen = [], [], []
|
||||
tokens_seen, global_step = 0, -1
|
||||
|
||||
# Main training loop
|
||||
for epoch in range(num_epochs):
|
||||
model.train() # Set model to training mode
|
||||
|
||||
for input_batch, target_batch in train_loader:
|
||||
optimizer.zero_grad() # Reset loss gradients from previous batch iteration
|
||||
loss = calc_loss_batch(input_batch, target_batch, model, device)
|
||||
loss.backward() # Calculate loss gradients
|
||||
optimizer.step() # Update model weights using loss gradients
|
||||
tokens_seen += input_batch.numel()
|
||||
global_step += 1
|
||||
|
||||
# Optional evaluation step
|
||||
if global_step % eval_freq == 0:
|
||||
train_loss, val_loss = evaluate_model(
|
||||
model, train_loader, val_loader, device, eval_iter)
|
||||
train_losses.append(train_loss)
|
||||
val_losses.append(val_loss)
|
||||
track_tokens_seen.append(tokens_seen)
|
||||
print(f"Ep {epoch+1} (Step {global_step:06d}): "
|
||||
f"Train loss {train_loss:.3f}, Val loss {val_loss:.3f}")
|
||||
|
||||
# Print a sample text after each epoch
|
||||
generate_and_print_sample(
|
||||
model, tokenizer, device, start_context
|
||||
)
|
||||
|
||||
return train_losses, val_losses, track_tokens_seen
|
||||
|
||||
|
||||
def evaluate_model(model, train_loader, val_loader, device, eval_iter):
|
||||
model.eval() # Set in eval mode to avoid dropout
|
||||
with torch.no_grad():
|
||||
train_loss = calc_loss_loader(train_loader, model, device, num_batches=eval_iter)
|
||||
val_loss = calc_loss_loader(val_loader, model, device, num_batches=eval_iter)
|
||||
model.train() # Back to training model applying all the configurations
|
||||
return train_loss, val_loss
|
||||
|
||||
|
||||
def generate_and_print_sample(model, tokenizer, device, start_context):
|
||||
model.eval() # Set in eval mode to avoid dropout
|
||||
context_size = model.pos_emb.weight.shape[0]
|
||||
encoded = text_to_token_ids(start_context, tokenizer).to(device)
|
||||
with torch.no_grad():
|
||||
token_ids = generate_text(
|
||||
model=model, idx=encoded,
|
||||
max_new_tokens=50, context_size=context_size
|
||||
)
|
||||
decoded_text = token_ids_to_text(token_ids, tokenizer)
|
||||
print(decoded_text.replace("\n", " ")) # Compact print format
|
||||
model.train() # Back to training model applying all the configurations
|
||||
```
|
||||
> [!TIP]
|
||||
> सीखने की दर में सुधार करने के लिए कुछ प्रासंगिक तकनीकें हैं जिन्हें **linear warmup** और **cosine decay** कहा जाता है।
|
||||
>
|
||||
> **Linear warmup** में एक प्रारंभिक सीखने की दर और एक अधिकतम दर को परिभाषित करना शामिल है और प्रत्येक युग के बाद इसे लगातार अपडेट करना शामिल है। इसका कारण यह है कि छोटे वजन अपडेट के साथ प्रशिक्षण शुरू करने से मॉडल के बड़े, अस्थिर अपडेट का सामना करने का जोखिम कम हो जाता है।\
|
||||
> **Cosine decay** एक तकनीक है जो **warmup** चरण के बाद **आधा-कोसाइन वक्र** का पालन करते हुए **सीखने की दर को धीरे-धीरे कम करती है**, वजन अपडेट को धीमा करके **हानि के न्यूनतम स्तर को ओवरशूट करने के जोखिम को कम करने** और बाद के चरणों में प्रशिक्षण स्थिरता सुनिश्चित करने के लिए।
|
||||
>
|
||||
> _ध्यान दें कि ये सुधार पिछले कोड में शामिल नहीं हैं।_
|
||||
|
||||
### Start training
|
||||
```python
|
||||
import time
|
||||
start_time = time.time()
|
||||
|
||||
torch.manual_seed(123)
|
||||
model = GPTModel(GPT_CONFIG_124M)
|
||||
model.to(device)
|
||||
optimizer = torch.optim.AdamW(model.parameters(), lr=0.0004, weight_decay=0.1)
|
||||
|
||||
num_epochs = 10
|
||||
train_losses, val_losses, tokens_seen = train_model_simple(
|
||||
model, train_loader, val_loader, optimizer, device,
|
||||
num_epochs=num_epochs, eval_freq=5, eval_iter=5,
|
||||
start_context="Every effort moves you", tokenizer=tokenizer
|
||||
)
|
||||
|
||||
end_time = time.time()
|
||||
execution_time_minutes = (end_time - start_time) / 60
|
||||
print(f"Training completed in {execution_time_minutes:.2f} minutes.")
|
||||
```
|
||||
### प्रिंट प्रशिक्षण विकास
|
||||
|
||||
इस फ़ंक्शन के साथ, यह संभव है कि मॉडल के प्रशिक्षण के दौरान विकास को प्रिंट किया जा सके।
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.ticker import MaxNLocator
|
||||
import math
|
||||
def plot_losses(epochs_seen, tokens_seen, train_losses, val_losses):
|
||||
fig, ax1 = plt.subplots(figsize=(5, 3))
|
||||
ax1.plot(epochs_seen, train_losses, label="Training loss")
|
||||
ax1.plot(
|
||||
epochs_seen, val_losses, linestyle="-.", label="Validation loss"
|
||||
)
|
||||
ax1.set_xlabel("Epochs")
|
||||
ax1.set_ylabel("Loss")
|
||||
ax1.legend(loc="upper right")
|
||||
ax1.xaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
ax2 = ax1.twiny()
|
||||
ax2.plot(tokens_seen, train_losses, alpha=0)
|
||||
ax2.set_xlabel("Tokens seen")
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
|
||||
# Compute perplexity from the loss values
|
||||
train_ppls = [math.exp(loss) for loss in train_losses]
|
||||
val_ppls = [math.exp(loss) for loss in val_losses]
|
||||
# Plot perplexity over tokens seen
|
||||
plt.figure()
|
||||
plt.plot(tokens_seen, train_ppls, label='Training Perplexity')
|
||||
plt.plot(tokens_seen, val_ppls, label='Validation Perplexity')
|
||||
plt.xlabel('Tokens Seen')
|
||||
plt.ylabel('Perplexity')
|
||||
plt.title('Perplexity over Training')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
epochs_tensor = torch.linspace(0, num_epochs, len(train_losses))
|
||||
plot_losses(epochs_tensor, tokens_seen, train_losses, val_losses)
|
||||
```
|
||||
### मॉडल को सहेजें
|
||||
|
||||
यदि आप बाद में प्रशिक्षण जारी रखना चाहते हैं तो मॉडल + ऑप्टिमाइज़र को सहेजना संभव है:
|
||||
```python
|
||||
# Save the model and the optimizer for later training
|
||||
torch.save({
|
||||
"model_state_dict": model.state_dict(),
|
||||
"optimizer_state_dict": optimizer.state_dict(),
|
||||
},
|
||||
"/tmp/model_and_optimizer.pth"
|
||||
)
|
||||
# Note that this model with the optimizer occupied close to 2GB
|
||||
|
||||
# Restore model and optimizer for training
|
||||
checkpoint = torch.load("/tmp/model_and_optimizer.pth", map_location=device)
|
||||
|
||||
model = GPTModel(GPT_CONFIG_124M)
|
||||
model.load_state_dict(checkpoint["model_state_dict"])
|
||||
optimizer = torch.optim.AdamW(model.parameters(), lr=5e-4, weight_decay=0.1)
|
||||
optimizer.load_state_dict(checkpoint["optimizer_state_dict"])
|
||||
model.train(); # Put in training mode
|
||||
```
|
||||
या केवल मॉडल यदि आप केवल इसका उपयोग करने की योजना बना रहे हैं:
|
||||
```python
|
||||
# Save the model
|
||||
torch.save(model.state_dict(), "model.pth")
|
||||
|
||||
# Load it
|
||||
model = GPTModel(GPT_CONFIG_124M)
|
||||
|
||||
model.load_state_dict(torch.load("model.pth", map_location=device))
|
||||
|
||||
model.eval() # Put in eval mode
|
||||
```
|
||||
## GPT2 वेट्स लोड करना
|
||||
|
||||
GPT2 वेट्स को स्थानीय रूप से लोड करने के लिए 2 त्वरित स्क्रिप्ट हैं। दोनों के लिए आप स्थानीय रूप से रिपॉजिटरी को क्लोन कर सकते हैं [https://github.com/rasbt/LLMs-from-scratch](https://github.com/rasbt/LLMs-from-scratch), फिर:
|
||||
|
||||
- स्क्रिप्ट [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch05/01_main-chapter-code/gpt_generate.py](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch05/01_main-chapter-code/gpt_generate.py) सभी वेट्स को डाउनलोड करेगी और OpenAI से हमारे LLM द्वारा अपेक्षित प्रारूपों में परिवर्तित करेगी। स्क्रिप्ट आवश्यक कॉन्फ़िगरेशन और प्रॉम्प्ट के साथ भी तैयार है: "Every effort moves you"
|
||||
- स्क्रिप्ट [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch05/02_alternative_weight_loading/weight-loading-hf-transformers.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch05/02_alternative_weight_loading/weight-loading-hf-transformers.ipynb) आपको स्थानीय रूप से किसी भी GPT2 वेट्स को लोड करने की अनुमति देती है (बस `CHOOSE_MODEL` वेरिएबल को बदलें) और कुछ प्रॉम्प्ट्स से टेक्स्ट की भविष्यवाणी करें।
|
||||
|
||||
## संदर्भ
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
@ -7,9 +7,9 @@
|
||||
|
||||
LoRA बड़े मॉडलों को प्रभावी ढंग से फाइन-ट्यून करने की अनुमति देता है, केवल मॉडल के **छोटे हिस्से** को बदलकर। यह उन पैरामीटर की संख्या को कम करता है जिन्हें आपको प्रशिक्षित करने की आवश्यकता होती है, **मेमोरी** और **गणनात्मक संसाधनों** की बचत करता है। इसका कारण है:
|
||||
|
||||
1. **प्रशिक्षण योग्य पैरामीटर की संख्या को कम करता है**: मॉडल में पूरे वजन मैट्रिक्स को अपडेट करने के बजाय, LoRA वजन मैट्रिक्स को दो छोटे मैट्रिक्स (जिन्हें **A** और **B** कहा जाता है) में **विभाजित** करता है। इससे प्रशिक्षण **तेज़** हो जाता है और **कम मेमोरी** की आवश्यकता होती है क्योंकि कम पैरामीटर को अपडेट करने की आवश्यकता होती है।
|
||||
1. **प्रशिक्षण योग्य पैरामीटर की संख्या को कम करता है**: मॉडल में पूरे वजन मैट्रिक्स को अपडेट करने के बजाय, LoRA वजन मैट्रिक्स को दो छोटे मैट्रिक्स (जिसे **A** और **B** कहा जाता है) में **विभाजित** करता है। इससे प्रशिक्षण **तेज़** हो जाता है और **कम मेमोरी** की आवश्यकता होती है क्योंकि कम पैरामीटर को अपडेट करने की आवश्यकता होती है।
|
||||
|
||||
1. इसका कारण यह है कि एक परत (मैट्रिक्स) के पूर्ण वजन अपडेट की गणना करने के बजाय, यह इसे 2 छोटे मैट्रिक्स के उत्पाद के रूप में अनुमानित करता है, अपडेट को गणना करने के लिए कम करता है:\
|
||||
1. इसका कारण यह है कि एक परत (मैट्रिक्स) के पूर्ण वजन अपडेट की गणना करने के बजाय, यह इसे 2 छोटे मैट्रिक्स के उत्पाद के रूप में अनुमानित करता है, अपडेट की गणना को कम करता है:\
|
||||
|
||||
<figure><img src="../../images/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
|
@ -0,0 +1,110 @@
|
||||
# 7.1. Fine-Tuning for Classification
|
||||
|
||||
## What is
|
||||
|
||||
फाइन-ट्यूनिंग एक **पूर्व-प्रशिक्षित मॉडल** को लेने की प्रक्रिया है जिसने विशाल मात्रा में डेटा से **सामान्य भाषा पैटर्न** सीखे हैं और इसे एक **विशिष्ट कार्य** करने या डोमेन-विशिष्ट भाषा को समझने के लिए **अनुकूलित** किया जाता है। यह एक छोटे, कार्य-विशिष्ट डेटा सेट पर मॉडल के प्रशिक्षण को जारी रखकर प्राप्त किया जाता है, जिससे इसे नए डेटा की बारीकियों के अनुसार अपने पैरामीटर को समायोजित करने की अनुमति मिलती है जबकि यह पहले से अधिग्रहित व्यापक ज्ञान का लाभ उठाता है। फाइन-ट्यूनिंग मॉडल को विशेष अनुप्रयोगों में अधिक सटीक और प्रासंगिक परिणाम देने में सक्षम बनाता है बिना नए मॉडल को शून्य से प्रशिक्षित करने की आवश्यकता के।
|
||||
|
||||
> [!TIP]
|
||||
> चूंकि एक LLM को "समझने" के लिए पूर्व-प्रशिक्षण करना काफी महंगा है, इसलिए आमतौर पर इसे एक विशिष्ट कार्य करने के लिए ओपन-सोर्स पूर्व-प्रशिक्षित मॉडलों को फाइन-ट्यून करना आसान और सस्ता होता है।
|
||||
|
||||
> [!TIP]
|
||||
> इस अनुभाग का लक्ष्य यह दिखाना है कि पहले से पूर्व-प्रशिक्षित मॉडल को कैसे फाइन-ट्यून किया जाए ताकि LLM नए पाठ उत्पन्न करने के बजाय **प्रत्येक दिए गए श्रेणी में वर्गीकृत होने के लिए दिए गए पाठ की संभावनाएँ** प्रदान करे (जैसे कि यदि कोई पाठ स्पैम है या नहीं)।
|
||||
|
||||
## Preparing the data set
|
||||
|
||||
### Data set size
|
||||
|
||||
बेशक, एक मॉडल को फाइन-ट्यून करने के लिए आपको अपने LLM को विशेषीकृत करने के लिए कुछ संरचित डेटा की आवश्यकता होती है। [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb) में प्रस्तावित उदाहरण में, GPT2 को यह पहचानने के लिए फाइन ट्यून किया गया है कि क्या एक ईमेल स्पैम है या नहीं, [https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip](https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip) से डेटा का उपयोग करके।
|
||||
|
||||
इस डेटा सेट में "स्पैम" की तुलना में "स्पैम नहीं" के बहुत अधिक उदाहरण हैं, इसलिए पुस्तक सुझाव देती है कि **"स्पैम नहीं" के उतने ही उदाहरणों का उपयोग करें जितने "स्पैम" के** (इसलिए, प्रशिक्षण डेटा से सभी अतिरिक्त उदाहरणों को हटा दें)। इस मामले में, यह प्रत्येक के 747 उदाहरण थे।
|
||||
|
||||
फिर, **70%** डेटा सेट का उपयोग **प्रशिक्षण** के लिए, **10%** **मान्यता** के लिए और **20%** **परीक्षण** के लिए किया जाता है।
|
||||
|
||||
- **मान्यता सेट** का उपयोग प्रशिक्षण चरण के दौरान मॉडल के **हाइपरपैरामीटर** को फाइन-ट्यून करने और मॉडल आर्किटेक्चर के बारे में निर्णय लेने के लिए किया जाता है, प्रभावी रूप से अज्ञात डेटा पर मॉडल के प्रदर्शन पर फीडबैक प्रदान करके ओवरफिटिंग को रोकने में मदद करता है। यह अंतिम मूल्यांकन को पूर्वाग्रहित किए बिना क्रमिक सुधार की अनुमति देता है।
|
||||
- इसका मतलब है कि हालांकि इस डेटा सेट में शामिल डेटा का उपयोग सीधे प्रशिक्षण के लिए नहीं किया जाता है, इसका उपयोग सबसे अच्छे **हाइपरपैरामीटर** को ट्यून करने के लिए किया जाता है, इसलिए इस सेट का उपयोग परीक्षण सेट की तरह मॉडल के प्रदर्शन का मूल्यांकन करने के लिए नहीं किया जा सकता है।
|
||||
- इसके विपरीत, **परीक्षण सेट** का उपयोग **केवल तब** किया जाता है जब मॉडल को पूरी तरह से प्रशिक्षित किया गया हो और सभी समायोजन पूर्ण हो चुके हों; यह नए, अज्ञात डेटा पर सामान्यीकरण की क्षमता का पूर्वाग्रह-मुक्त आकलन प्रदान करता है। परीक्षण सेट पर यह अंतिम मूल्यांकन यह दर्शाता है कि मॉडल वास्तविक दुनिया के अनुप्रयोगों में कैसे प्रदर्शन करने की उम्मीद है।
|
||||
|
||||
### Entries length
|
||||
|
||||
चूंकि प्रशिक्षण उदाहरण समान लंबाई के प्रविष्टियों (इस मामले में ईमेल पाठ) की अपेक्षा करता है, इसलिए यह तय किया गया कि प्रत्येक प्रविष्टि को सबसे बड़ी प्रविष्टि के आकार का बनाया जाए, जिसमें `<|endoftext|>` के आईडी को पैडिंग के रूप में जोड़ा जाए।
|
||||
|
||||
### Initialize the model
|
||||
|
||||
ओपन-सोर्स पूर्व-प्रशिक्षित वेट्स का उपयोग करके मॉडल को प्रशिक्षित करने के लिए प्रारंभ करें। हमने पहले ही यह किया है और [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb) के निर्देशों का पालन करके आप इसे आसानी से कर सकते हैं।
|
||||
|
||||
## Classification head
|
||||
|
||||
इस विशेष उदाहरण (यह भविष्यवाणी करना कि क्या एक पाठ स्पैम है या नहीं) में, हम GPT2 के पूर्ण शब्दावली के अनुसार फाइन ट्यून करने में रुचि नहीं रखते हैं, बल्कि हम केवल नए मॉडल से यह कहना चाहते हैं कि ईमेल स्पैम है (1) या नहीं (0)। इसलिए, हम **अंतिम परत को संशोधित करने जा रहे हैं** जो शब्दावली के प्रत्येक टोकन के लिए संभावनाएँ देती है, एक ऐसी परत में जो केवल स्पैम होने या न होने की संभावनाएँ देती है (तो जैसे 2 शब्दों की शब्दावली)।
|
||||
```python
|
||||
# This code modified the final layer with a Linear one with 2 outs
|
||||
num_classes = 2
|
||||
model.out_head = torch.nn.Linear(
|
||||
|
||||
in_features=BASE_CONFIG["emb_dim"],
|
||||
|
||||
out_features=num_classes
|
||||
)
|
||||
```
|
||||
## Parameters to tune
|
||||
|
||||
तेज़ी से फाइन ट्यून करने के लिए सभी पैरामीटर को फाइन ट्यून करना आसान नहीं है, बल्कि केवल कुछ अंतिम पैरामीटर को फाइन ट्यून करना बेहतर है। इसका कारण यह है कि यह ज्ञात है कि निचले स्तर आमतौर पर बुनियादी भाषा संरचनाओं और प्रासंगिक अर्थों को कैप्चर करते हैं। इसलिए, केवल **अंतिम स्तरों को फाइन ट्यून करना आमतौर पर पर्याप्त और तेज़ होता है**।
|
||||
```python
|
||||
# This code makes all the parameters of the model unrtainable
|
||||
for param in model.parameters():
|
||||
param.requires_grad = False
|
||||
|
||||
# Allow to fine tune the last layer in the transformer block
|
||||
for param in model.trf_blocks[-1].parameters():
|
||||
param.requires_grad = True
|
||||
|
||||
# Allow to fine tune the final layer norm
|
||||
for param in model.final_norm.parameters():
|
||||
|
||||
param.requires_grad = True
|
||||
```
|
||||
## Entries to use for training
|
||||
|
||||
पिछले अनुभागों में LLM को हर पूर्वानुमानित टोकन के नुकसान को कम करके प्रशिक्षित किया गया था, हालांकि लगभग सभी पूर्वानुमानित टोकन इनपुट वाक्य में थे (केवल अंत में 1 वास्तव में पूर्वानुमानित था) ताकि मॉडल भाषा को बेहतर तरीके से समझ सके।
|
||||
|
||||
इस मामले में, हम केवल इस बात की परवाह करते हैं कि मॉडल यह पूर्वानुमानित कर सके कि मॉडल स्पैम है या नहीं, इसलिए हम केवल अंतिम पूर्वानुमानित टोकन की परवाह करते हैं। इसलिए, हमें अपने पिछले प्रशिक्षण हानि कार्यों को संशोधित करने की आवश्यकता है ताकि केवल उस टोकन को ध्यान में रखा जा सके।
|
||||
|
||||
यह [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb) में इस प्रकार लागू किया गया है:
|
||||
```python
|
||||
def calc_accuracy_loader(data_loader, model, device, num_batches=None):
|
||||
model.eval()
|
||||
correct_predictions, num_examples = 0, 0
|
||||
|
||||
if num_batches is None:
|
||||
num_batches = len(data_loader)
|
||||
else:
|
||||
num_batches = min(num_batches, len(data_loader))
|
||||
for i, (input_batch, target_batch) in enumerate(data_loader):
|
||||
if i < num_batches:
|
||||
input_batch, target_batch = input_batch.to(device), target_batch.to(device)
|
||||
|
||||
with torch.no_grad():
|
||||
logits = model(input_batch)[:, -1, :] # Logits of last output token
|
||||
predicted_labels = torch.argmax(logits, dim=-1)
|
||||
|
||||
num_examples += predicted_labels.shape[0]
|
||||
correct_predictions += (predicted_labels == target_batch).sum().item()
|
||||
else:
|
||||
break
|
||||
return correct_predictions / num_examples
|
||||
|
||||
|
||||
def calc_loss_batch(input_batch, target_batch, model, device):
|
||||
input_batch, target_batch = input_batch.to(device), target_batch.to(device)
|
||||
logits = model(input_batch)[:, -1, :] # Logits of last output token
|
||||
loss = torch.nn.functional.cross_entropy(logits, target_batch)
|
||||
return loss
|
||||
```
|
||||
ध्यान दें कि प्रत्येक बैच के लिए हम केवल **अंतिम टोकन की भविष्यवाणी किए गए लॉजिट्स** में रुचि रखते हैं।
|
||||
|
||||
## पूर्ण GPT2 फाइन-ट्यून वर्गीकरण कोड
|
||||
|
||||
आप [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/load-finetuned-model.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/load-finetuned-model.ipynb) में स्पैम वर्गीकरणकर्ता के रूप में GPT2 को फाइन-ट्यून करने के लिए सभी कोड पा सकते हैं।
|
||||
|
||||
## संदर्भ
|
||||
|
||||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|
@ -1,7 +1,7 @@
|
||||
# 7.2. निर्देशों का पालन करने के लिए फाइन-ट्यूनिंग
|
||||
|
||||
> [!TIP]
|
||||
> इस अनुभाग का लक्ष्य यह दिखाना है कि **कैसे पहले से प्रशिक्षित मॉडल को निर्देशों का पालन करने के लिए फाइन-ट्यून किया जाए** न कि केवल पाठ उत्पन्न करने के लिए, उदाहरण के लिए, एक चैट बॉट के रूप में कार्यों का उत्तर देना।
|
||||
> इस अनुभाग का लक्ष्य यह दिखाना है कि **कैसे पहले से प्रशिक्षित मॉडल को निर्देशों का पालन करने के लिए फाइन-ट्यून किया जाए** न कि केवल टेक्स्ट उत्पन्न करने के लिए, उदाहरण के लिए, एक चैट बॉट के रूप में कार्यों का उत्तर देना।
|
||||
|
||||
## डेटासेट
|
||||
|
||||
@ -19,7 +19,7 @@ The area of a circle is calculated using the formula \( A = \pi r^2 \). Plugging
|
||||
|
||||
\( A = \pi (5)^2 = \pi \times 25 = 25\pi \) square units.
|
||||
```
|
||||
- Phi-3 प्रॉम्प्ट स्टाइल उदाहरण:
|
||||
- Phi-3 प्रॉम्प्ट शैली उदाहरण:
|
||||
```vbnet
|
||||
<|User|>
|
||||
Can you explain what gravity is in simple terms?
|
||||
@ -65,31 +65,31 @@ print(model_input + desired_response)
|
||||
|
||||
## पूर्व-प्रशिक्षित LLM लोड करें और फाइन ट्यून करें और हानि की जांच करें
|
||||
|
||||
इसे फाइन ट्यून करने के लिए एक पूर्व-प्रशिक्षित LLM लोड करना आवश्यक है। यह पहले ही अन्य पृष्ठों पर चर्चा की जा चुकी है। फिर, LLM को फाइन ट्यून करने के लिए पहले से उपयोग किए गए प्रशिक्षण फ़ंक्शन का उपयोग करना संभव है।
|
||||
इसे फाइन ट्यून करने के लिए एक पूर्व-प्रशिक्षित LLM लोड करना आवश्यक है। यह पहले अन्य पृष्ठों पर चर्चा की गई थी। फिर, LLM को फाइन ट्यून करने के लिए पहले से उपयोग की गई प्रशिक्षण फ़ंक्शन का उपयोग करना संभव है।
|
||||
|
||||
प्रशिक्षण के दौरान यह भी देखना संभव है कि प्रशिक्षण हानि और मान्यता हानि कैसे युगों के दौरान भिन्न होती है ताकि यह देखा जा सके कि हानि कम हो रही है या ओवरफिटिंग हो रही है।\
|
||||
याद रखें कि ओवरफिटिंग तब होती है जब प्रशिक्षण हानि कम हो रही होती है लेकिन मान्यता हानि कम नहीं हो रही है या यहां तक कि बढ़ रही है। इसे रोकने के लिए, सबसे सरल बात यह है कि उस युग में प्रशिक्षण को रोक दें जहां यह व्यवहार शुरू होता है।
|
||||
प्रशिक्षण के दौरान यह भी देखना संभव है कि प्रशिक्षण हानि और मान्यता हानि कैसे युगों के दौरान भिन्न होती है यह देखने के लिए कि क्या हानि कम हो रही है और क्या ओवरफिटिंग हो रही है।\
|
||||
याद रखें कि ओवरफिटिंग तब होती है जब प्रशिक्षण हानि कम हो रही है लेकिन मान्यता हानि कम नहीं हो रही है या यहां तक कि बढ़ रही है। इसे रोकने के लिए, सबसे सरल बात यह है कि उस युग में प्रशिक्षण को रोक दें जहां यह व्यवहार शुरू होता है।
|
||||
|
||||
## प्रतिक्रिया गुणवत्ता
|
||||
|
||||
चूंकि यह एक वर्गीकरण फाइन-ट्यून नहीं है जहां हानि परिवर्तनों पर अधिक भरोसा किया जा सकता है, इसलिए परीक्षण सेट में प्रतिक्रियाओं की गुणवत्ता की जांच करना भी महत्वपूर्ण है। इसलिए, सभी परीक्षण सेट से उत्पन्न प्रतिक्रियाओं को इकट्ठा करना और **उनकी गुणवत्ता को मैन्युअल रूप से जांचना** अनुशंसित है ताकि यह देखा जा सके कि क्या गलत उत्तर हैं (ध्यान दें कि LLM प्रतिक्रिया वाक्य के प्रारूप और वाक्यविन्यास को सही ढंग से बना सकता है लेकिन पूरी तरह से गलत उत्तर दे सकता है। हानि परिवर्तन इस व्यवहार को नहीं दर्शाएंगे)।\
|
||||
चूंकि यह एक वर्गीकरण फाइन-ट्यून नहीं है जहां हानि परिवर्तनों पर अधिक भरोसा किया जा सकता है, इसलिए परीक्षण सेट में प्रतिक्रियाओं की गुणवत्ता की जांच करना भी महत्वपूर्ण है। इसलिए, सभी परीक्षण सेट से उत्पन्न प्रतिक्रियाओं को इकट्ठा करना और **उनकी गुणवत्ता को मैन्युअल रूप से जांचना** अनुशंसित है यह देखने के लिए कि क्या गलत उत्तर हैं (ध्यान दें कि LLM प्रतिक्रिया वाक्य के प्रारूप और वाक्यविन्यास को सही ढंग से बना सकता है लेकिन पूरी तरह से गलत उत्तर दे सकता है। हानि परिवर्तन इस व्यवहार को नहीं दर्शाएंगे)।\
|
||||
ध्यान दें कि यह समीक्षा उत्पन्न प्रतिक्रियाओं और अपेक्षित प्रतिक्रियाओं को **अन्य LLMs को पास करके और उनसे प्रतिक्रियाओं का मूल्यांकन करने के लिए कहकर** भी की जा सकती है।
|
||||
|
||||
प्रतिक्रियाओं की गुणवत्ता की पुष्टि करने के लिए चलाने के लिए अन्य परीक्षण:
|
||||
|
||||
1. **मासिव मल्टीटास्क लैंग्वेज अंडरस्टैंडिंग (**[**MMLU**](https://arxiv.org/abs/2009.03300)**):** MMLU एक मॉडल के ज्ञान और समस्या-समाधान क्षमताओं का मूल्यांकन करता है, जिसमें 57 विषय शामिल हैं, जैसे मानविकी, विज्ञान, और अधिक। यह विभिन्न कठिनाई स्तरों पर समझ का आकलन करने के लिए बहुविकल्पीय प्रश्नों का उपयोग करता है, प्रारंभिक से लेकर उन्नत पेशेवर तक।
|
||||
1. **मासिव मल्टीटास्क लैंग्वेज अंडरस्टैंडिंग (**[**MMLU**](https://arxiv.org/abs/2009.03300)**):** MMLU एक मॉडल के ज्ञान और समस्या-समाधान क्षमताओं का मूल्यांकन करता है जिसमें 57 विषय शामिल हैं, जिसमें मानविकी, विज्ञान और अधिक शामिल हैं। यह विभिन्न कठिनाई स्तरों पर समझ का आकलन करने के लिए बहुविकल्पीय प्रश्नों का उपयोग करता है, प्रारंभिक से लेकर उन्नत पेशेवर तक।
|
||||
2. [**LMSYS चैटबॉट एरिना**](https://arena.lmsys.org): यह प्लेटफ़ॉर्म उपयोगकर्ताओं को विभिन्न चैटबॉट्स की प्रतिक्रियाओं की तुलना एक साथ करने की अनुमति देता है। उपयोगकर्ता एक प्रॉम्प्ट इनपुट करते हैं, और कई चैटबॉट्स प्रतिक्रियाएँ उत्पन्न करते हैं जिन्हें सीधे तुलना की जा सकती है।
|
||||
3. [**AlpacaEval**](https://github.com/tatsu-lab/alpaca_eval)**:** AlpacaEval एक स्वचालित मूल्यांकन ढांचा है जहां एक उन्नत LLM जैसे GPT-4 अन्य मॉडलों की प्रतिक्रियाओं का विभिन्न प्रॉम्प्ट्स पर मूल्यांकन करता है।
|
||||
4. **जनरल लैंग्वेज अंडरस्टैंडिंग मूल्यांकन (**[**GLUE**](https://gluebenchmark.com/)**):** GLUE नौ प्राकृतिक भाषा समझ कार्यों का एक संग्रह है, जिसमें भावना विश्लेषण, पाठ संबंध, और प्रश्न उत्तर शामिल हैं।
|
||||
4. **जनरल लैंग्वेज अंडरस्टैंडिंग मूल्यांकन (**[**GLUE**](https://gluebenchmark.com/)**):** GLUE नौ प्राकृतिक भाषा समझ कार्यों का एक संग्रह है, जिसमें भावना विश्लेषण, पाठ संबंध और प्रश्न उत्तर शामिल हैं।
|
||||
5. [**SuperGLUE**](https://super.gluebenchmark.com/)**:** GLUE पर आधारित, SuperGLUE में अधिक चुनौतीपूर्ण कार्य शामिल हैं जो वर्तमान मॉडलों के लिए कठिन होने के लिए डिज़ाइन किए गए हैं।
|
||||
6. **इमिटेशन गेम बेंचमार्क के परे (**[**BIG-bench**](https://github.com/google/BIG-bench)**):** BIG-bench एक बड़े पैमाने पर बेंचमार्क है जिसमें 200 से अधिक कार्य हैं जो एक मॉडल की क्षमताओं का परीक्षण करते हैं जैसे तर्क, अनुवाद, और प्रश्न उत्तर।
|
||||
7. **भाषा मॉडलों का समग्र मूल्यांकन (**[**HELM**](https://crfm.stanford.edu/helm/lite/latest/)**):** HELM विभिन्न मेट्रिक्स जैसे सटीकता, robustness, और निष्पक्षता के माध्यम से एक व्यापक मूल्यांकन प्रदान करता है।
|
||||
7. **भाषा मॉडलों का समग्र मूल्यांकन (**[**HELM**](https://crfm.stanford.edu/helm/lite/latest/)**):** HELM विभिन्न मैट्रिक्स जैसे सटीकता, robustness, और निष्पक्षता के माध्यम से एक व्यापक मूल्यांकन प्रदान करता है।
|
||||
8. [**OpenAI Evals**](https://github.com/openai/evals)**:** OpenAI द्वारा एक ओपन-सोर्स मूल्यांकन ढांचा जो कस्टम और मानकीकृत कार्यों पर AI मॉडलों का परीक्षण करने की अनुमति देता है।
|
||||
9. [**HumanEval**](https://github.com/openai/human-eval)**:** प्रोग्रामिंग समस्याओं का एक संग्रह जिसका उपयोग भाषा मॉडलों की कोड जनरेशन क्षमताओं का मूल्यांकन करने के लिए किया जाता है।
|
||||
10. **स्टैनफोर्ड प्रश्न उत्तरिंग डेटासेट (**[**SQuAD**](https://rajpurkar.github.io/SQuAD-explorer/)**):** SQuAD में विकिपीडिया लेखों के बारे में प्रश्न होते हैं, जहां मॉडलों को सटीक उत्तर देने के लिए पाठ को समझना होता है।
|
||||
10. **स्टैनफोर्ड प्रश्न उत्तरिंग डेटासेट (**[**SQuAD**](https://rajpurkar.github.io/SQuAD-explorer/)**):** SQuAD में विकिपीडिया लेखों के बारे में प्रश्न होते हैं, जहां मॉडलों को सटीक उत्तर देने के लिए पाठ को समझना आवश्यक है।
|
||||
11. [**TriviaQA**](https://nlp.cs.washington.edu/triviaqa/)**:** ट्रिविया प्रश्नों और उत्तरों का एक बड़े पैमाने पर डेटासेट, साथ ही साक्ष्य दस्तावेज़।
|
||||
|
||||
और कई और
|
||||
और कई और बहुत कुछ
|
||||
|
||||
## निर्देशों का पालन करने के लिए फाइन-ट्यूनिंग कोड
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# LLM Training - Data Preparation
|
||||
|
||||
**ये मेरी नोट्स हैं बहुत ही अनुशंसित किताब से** [**https://www.manning.com/books/build-a-large-language-model-from-scratch**](https://www.manning.com/books/build-a-large-language-model-from-scratch) **कुछ अतिरिक्त जानकारी के साथ।**
|
||||
**ये मेरे नोट्स हैं बहुत ही अनुशंसित पुस्तक से** [**https://www.manning.com/books/build-a-large-language-model-from-scratch**](https://www.manning.com/books/build-a-large-language-model-from-scratch) **कुछ अतिरिक्त जानकारी के साथ।**
|
||||
|
||||
## Basic Information
|
||||
|
||||
@ -32,9 +32,9 @@
|
||||
|
||||
> [!TIP]
|
||||
> इस तीसरे चरण का लक्ष्य बहुत सरल है: **शब्दकोश में पिछले टोकनों में से प्रत्येक को मॉडल को प्रशिक्षित करने के लिए इच्छित आयामों का एक वेक्टर सौंपें।** शब्दकोश में प्रत्येक शब्द X आयामों के एक स्थान में एक बिंदु होगा।\
|
||||
> ध्यान दें कि प्रारंभ में प्रत्येक शब्द का स्थान "यादृच्छिक" रूप से प्रारंभ किया जाता है और ये स्थान प्रशिक्षित करने योग्य पैरामीटर होते हैं (जो प्रशिक्षण के दौरान सुधरेंगे)।
|
||||
> ध्यान दें कि प्रारंभ में प्रत्येक शब्द का स्थान "यादृच्छिक" रूप से प्रारंभ किया गया है और ये स्थान प्रशिक्षित करने योग्य पैरामीटर हैं (प्रशिक्षण के दौरान सुधारित होंगे)।
|
||||
>
|
||||
> इसके अलावा, टोकन एम्बेडिंग के दौरान **एक और एम्बेडिंग परत बनाई जाती है** जो (इस मामले में) **शब्द के प्रशिक्षण वाक्य में सापेक्ष स्थिति** का प्रतिनिधित्व करती है। इस तरह वाक्य में विभिन्न स्थानों पर एक शब्द का अलग प्रतिनिधित्व (अर्थ) होगा।
|
||||
> इसके अलावा, टोकन एम्बेडिंग के दौरान **एक और एम्बेडिंग परत बनाई जाती है** जो (इस मामले में) **प्रशिक्षण वाक्य में शब्द की पूर्ण स्थिति का प्रतिनिधित्व करती है।** इस तरह वाक्य में विभिन्न स्थानों पर एक शब्द का अलग प्रतिनिधित्व (अर्थ) होगा।
|
||||
|
||||
{{#ref}}
|
||||
3.-token-embeddings.md
|
||||
@ -53,9 +53,9 @@
|
||||
## 5. LLM Architecture
|
||||
|
||||
> [!TIP]
|
||||
> इस पांचवे चरण का लक्ष्य बहुत सरल है: **पूर्ण LLM की आर्किटेक्चर विकसित करें।** सब कुछ एक साथ रखें, सभी परतें लागू करें और पाठ उत्पन्न करने या पाठ को IDs में और इसके विपरीत परिवर्तित करने के लिए सभी कार्यों को बनाएं।
|
||||
> इस पांचवे चरण का लक्ष्य बहुत सरल है: **पूर्ण LLM की वास्तुकला विकसित करें।** सब कुछ एक साथ रखें, सभी परतें लागू करें और पाठ उत्पन्न करने या पाठ को IDs में और इसके विपरीत परिवर्तित करने के लिए सभी कार्यों को बनाएं।
|
||||
>
|
||||
> यह आर्किटेक्चर दोनों, प्रशिक्षण और भविष्यवाणी के लिए उपयोग किया जाएगा जब इसे प्रशिक्षित किया गया हो।
|
||||
> यह वास्तुकला दोनों के लिए उपयोग की जाएगी, प्रशिक्षण और भविष्यवाणी पाठ के लिए जब इसे प्रशिक्षित किया गया हो।
|
||||
|
||||
{{#ref}}
|
||||
5.-llm-architecture.md
|
||||
@ -64,7 +64,7 @@
|
||||
## 6. Pre-training & Loading models
|
||||
|
||||
> [!TIP]
|
||||
> इस छठे चरण का लक्ष्य बहुत सरल है: **मॉडल को शून्य से प्रशिक्षित करें।** इसके लिए पिछले LLM आर्किटेक्चर का उपयोग किया जाएगा जिसमें डेटा सेट पर परिभाषित हानि कार्यों और ऑप्टिमाइज़र का उपयोग करते हुए लूप होंगे ताकि मॉडल के सभी पैरामीटर को प्रशिक्षित किया जा सके।
|
||||
> इस छठे चरण का लक्ष्य बहुत सरल है: **मॉडल को शून्य से प्रशिक्षित करें।** इसके लिए पिछले LLM वास्तुकला का उपयोग किया जाएगा जिसमें डेटा सेट पर परिभाषित हानि कार्यों और ऑप्टिमाइज़र का उपयोग करते हुए लूप होंगे ताकि मॉडल के सभी पैरामीटर को प्रशिक्षित किया जा सके।
|
||||
|
||||
{{#ref}}
|
||||
6.-pre-training-and-loading-models.md
|
||||
@ -73,7 +73,7 @@
|
||||
## 7.0. LoRA Improvements in fine-tuning
|
||||
|
||||
> [!TIP]
|
||||
> **LoRA का उपयोग पहले से प्रशिक्षित मॉडलों को ठीक करने के लिए आवश्यक गणना को बहुत कम करता है।**
|
||||
> **LoRA का उपयोग पहले से प्रशिक्षित मॉडलों को ठीक करने के लिए आवश्यक गणना को बहुत कम कर देता है।**
|
||||
|
||||
{{#ref}}
|
||||
7.0.-lora-improvements-in-fine-tuning.md
|
||||
@ -82,7 +82,7 @@
|
||||
## 7.1. Fine-Tuning for Classification
|
||||
|
||||
> [!TIP]
|
||||
> इस अनुभाग का लक्ष्य यह दिखाना है कि पहले से प्रशिक्षित मॉडल को कैसे ठीक किया जाए ताकि नए पाठ उत्पन्न करने के बजाय LLM **प्रत्येक दिए गए श्रेणी में वर्गीकृत होने के लिए दिए गए पाठ की संभावनाएं** प्रदान करे (जैसे कि कोई पाठ स्पैम है या नहीं)।
|
||||
> इस अनुभाग का लक्ष्य यह दिखाना है कि पहले से प्रशिक्षित मॉडल को कैसे ठीक किया जाए ताकि नए पाठ उत्पन्न करने के बजाय LLM **प्रत्येक दिए गए श्रेणी में वर्गीकृत किए जाने की संभावनाएं** प्रदान करे (जैसे कि कोई पाठ स्पैम है या नहीं)।
|
||||
|
||||
{{#ref}}
|
||||
7.1.-fine-tuning-for-classification.md
|
||||
|
Loading…
x
Reference in New Issue
Block a user