स्टेप 6 · ट्रेनिंग लूप जो कन्वर्ज होता है
मॉडल बनाना आसान हिस्सा है। यह मॉड्यूल तय करता है कि आपका रन काम करेगा या आपका एक हफ़्ता बर्बाद होगा।
60 सेकंड में
स्टेप 6 · ट्रेनिंग लूप जो कन्वर्ज होता है
मॉडल बनाना आसान हिस्सा है। यह मॉड्यूल तय करता है कि आपका रन काम करेगा या आपका एक हफ़्ता बर्बाद होगा।
import math, torch
model = TinyGPT(Config()).to(device)
model = torch.compile(model) # big speedup, one line
# weight decay on matrices, none on norms and biases
decay = [p for n, p in model.named_parameters() if p.dim() >= 2]
nodecay = [p for n, p in model.named_parameters() if p.dim() < 2]
opt = torch.optim.AdamW(
[{"params": decay, "weight_decay": 0.1},
{"params": nodecay, "weight_decay": 0.0}],
lr=6e-4, betas=(0.9, 0.95), eps=1e-8, fused=True)
max_steps, warmup, min_lr = 20000, 500, 6e-5
def lr_at(step):
if step < warmup: # linear warmup
return 6e-4 * (step + 1) / warmup
r = (step - warmup) / (max_steps - warmup) # cosine decay
return min_lr + 0.5 * (6e-4 - min_lr) * (1 + math.cos(math.pi * r))
scaler_dtype = torch.bfloat16
accum = 8 # gradient accumulation
for step in range(max_steps):
for g in opt.param_groups:
g["lr"] = lr_at(step)
opt.zero_grad(set_to_none=True)
for micro in range(accum): # simulate a big batch
x, y = get_batch("train")
with torch.autocast(device_type="cuda", dtype=scaler_dtype):
_, loss = model(x, y)
(loss / accum).backward()
norm = torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
opt.step()
if step % 100 == 0:
print(f"step {step} loss {loss.item():.3f} lr {lr_at(step):.2e} gnorm {norm:.2f}")हर ज़रूरी लाइन, और वह क्यों मायने रखती है
| विकल्प | आम वैल्यू | इसके बिना क्या गलत हो सकता है |
|---|---|---|
| AdamW, न कि Adam | सिर्फ मैट्रिसेस पर weight_decay 0.1 | norms और biases पर decay करने से नुकसान होता है; यह विभाजन स्टैंडर्ड है |
| beta2 = 0.95 | 0.999 डिफ़ॉल्ट नहीं | 0.999 बहुत धीमी गति से अडैप्ट होता है और बड़े मॉडलों को अस्थिर कर देता है |
| Warmup | 200–2000 स्टेप्स | रैंडम वेट्स पर शुरुआत में ही बड़े अपडेट्स पहले ही मिनट में रन को तबाह कर देते हैं |
| ~10% तक Cosine decay | पूरे रन के दौरान | लगातार एक जैसा LR मुमकिन loss से काफी ऊपर ही रुक जाता है |
| Gradient clipping | norm 1.0 | एक भी खराब बैच ऐसा स्पाइक पैदा कर देता है जो कभी ठीक नहीं होता |
| Gradient accumulation | प्रति स्टेप 0.5–4M टोकन तक पहुँचने के लिए | छोटे बैचों से noisy ग्रेडिएंट्स और खराब फ़ाइनल loss मिलता है |
| bfloat16 autocast | fp16 नहीं | fp16 को loss scaling की ज़रूरत होती है और फिर भी यह ओवरफ़्लो हो जाता है; bf16 में fp32 जितनी रेंज होती है |
सिर्फ loss ही नहीं, इन चार नंबरों पर नज़र रखें
- 1
ट्रेनिंग loss
शुरुआत में तेज़ी से गिरना चाहिए, फिर धीरे-धीरे। स्टेप ज़ीरो से ही सीधी सपाट लाइन दिखने का मतलब है डेटा में कोई बग है। अचानक स्पाइक आने का मतलब है खराब बैच या बहुत ज़्यादा learning rate। - 2
Validation loss
अलग रखा गया डेटा। जब ट्रेनिंग loss गिरता रहे लेकिन यह गिरना बंद हो जाए, तो इसका मतलब है कि मॉडल रट रहा है। नए डेटा पर बड़े प्रीट्रेनिंग रन में ऐसा शायद ही कभी होता है; लेकिन फाइन-ट्यूनिंग में यह कुछ ही मिनटों में हो जाता है। - 3
Gradient norm
यह स्थिर होना चाहिए, लगभग 0.1–1.0 की रेंज में। इसका लगातार बढ़ना अस्थिरता का संकेत है; बार-बार क्लिपिंग होने का मतलब है कि आपका learning rate बहुत ज़्यादा है। - 4
टोकन प्रति सेकंड
आपकी असली करेंसी। मॉड्यूल 46 की हर चीज़ इसी नंबर के बारे में है, और यही तय करता है कि रन में तीन दिन लगेंगे या तीन हफ़्ते।
ऐसे चेकपॉइंट बनाएं जैसे आपको क्रैश होने की पूरी उम्मीद हो
def save(step):
torch.save({
"step": step,
"model": model.state_dict(),
"opt": opt.state_dict(), # optimiser state is essential
"config": cfg.__dict__,
"rng": torch.get_rng_state(),
}, f"ckpt_{step}.pt")और देखें और पढ़ें
लैब
एक ट्रेनिंग रन जिसे आपने जानबूझकर चार तरीकों से खराब किया।
समस्या
print(f"step {step} loss {loss.item():.3f} gnorm {norm:.2f} lr {lr:.2e}")
# Learn to read these three numbers together — they diagnose almost everything.आपका काम तब पूरा होगा जब
कठिन सवाल
उत्तर देखने से पहले ख़ुद जवाब देने की कोशिश करें। अगर आप इनके जवाब दे सकते हैं, तो आप पाठ समझ गए हैं।
Q1स्टेप 8,000 पर आपका loss अचानक बढ़ जाता है और कभी ठीक नहीं होता। आपके पास हर 1,000 स्टेप्स पर चेकपॉइंट हैं। इसे ठीक करने की सटीक प्रक्रिया लिखें।दिखाएं
अक्सर पूछे जाने वाले सवाल
मैं learning rate कैसे चुनूँ?
अपने स्केल के लिए किसी परखे हुए अच्छे मान से शुरुआत करें — छोटे मॉडल के लिए लगभग 6e-4, 7B पर गिरकर लगभग 1.5e-4, और फ्रंटियर स्केल पर इससे भी कम। बड़े मॉडलों को छोटे learning rates की ज़रूरत होती है। अगर आपको सर्च करना ही पड़े, तो कई अलग-अलग वैल्यूज़ पर 200 स्टेप्स चलाएं और सबसे बड़ी वह वैल्यू चुनें जो स्थिर रहे।
बैच साइज़ कितना हो?
सीक्वेंस में नहीं, टोकन में गिनें। छोटे मॉडल लगभग 0.5M टोकन प्रति स्टेप पर अच्छा काम करते हैं; बड़े प्रीट्रेनिंग रन 4M से 16M का उपयोग करते हैं। अगर आपके GPU इसे एक बार में नहीं संभाल सकते, तो gradient accumulation के ज़रिए इस तक पहुँचें।
मेरा loss NaN हो गया। अब क्या करें?
Learning rate कम करें, पक्का करें कि warmup चालू है, जांचें कि gradient clipping चालू है, और पुष्टि करें कि आप fp16 के बजाय bf16 का उपयोग कर रहे हैं। अगर ऐसा फिर भी होता है, तो किसी करप्ट डेटा शार्ड की तलाश करें — कचरा बाइट्स वाली एक ही फ़ाइल यह सब बिगाड़ सकती है।
क्या मुझे torch.compile का इस्तेमाल करना चाहिए?
हाँ। यह आमतौर पर सिर्फ एक लाइन के कोड से 1.3–2x की स्पीड देता है, और कम्पाइल करने का समय सिर्फ एक बार लगता है। डीबगिंग करते समय इसे बंद कर दें, क्योंकि तब एरर मैसेज पढ़ना बहुत मुश्किल हो जाता है।
पाठ का टेस्ट
5 सवाल। पास होने और इस पाठ को पूरा करने के लिए 3 सही होने चाहिए (60%)।