एक LLM बनाएँमध्यमपाठ 427 मिनट का पाठ

स्टेप 6 · ट्रेनिंग लूप जो कन्वर्ज होता है

मॉडल बनाना आसान हिस्सा है। यह मॉड्यूल तय करता है कि आपका रन काम करेगा या आपका एक हफ़्ता बर्बाद होगा।

पाठ वीडियो में

60 सेकंड में

स्टेप 6 · ट्रेनिंग लूप जो कन्वर्ज होता है

मॉडल बनाना आसान हिस्सा है। यह मॉड्यूल तय करता है कि आपका रन काम करेगा या आपका एक हफ़्ता बर्बाद होगा।

1/6
आसान शब्दों में
ट्रेनिंग का मतलब है: अंदाज़ा लगाओ, देखो कि तुम कितने गलत थे, हर नंबर को सही दिशा में थोड़ा-सा खिसकाओ, और इसे दस लाख बार दोहराओ। सारा हुनर इसी बात में है कि वे खिसकाव कितने बड़े हैं।
A real training looppython
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.1norms और biases पर decay करने से नुकसान होता है; यह विभाजन स्टैंडर्ड है
beta2 = 0.950.999 डिफ़ॉल्ट नहीं0.999 बहुत धीमी गति से अडैप्ट होता है और बड़े मॉडलों को अस्थिर कर देता है
Warmup200–2000 स्टेप्सरैंडम वेट्स पर शुरुआत में ही बड़े अपडेट्स पहले ही मिनट में रन को तबाह कर देते हैं
~10% तक Cosine decayपूरे रन के दौरानलगातार एक जैसा LR मुमकिन loss से काफी ऊपर ही रुक जाता है
Gradient clippingnorm 1.0एक भी खराब बैच ऐसा स्पाइक पैदा कर देता है जो कभी ठीक नहीं होता
Gradient accumulationप्रति स्टेप 0.5–4M टोकन तक पहुँचने के लिएछोटे बैचों से noisy ग्रेडिएंट्स और खराब फ़ाइनल loss मिलता है
bfloat16 autocastfp16 नहींfp16 को loss scaling की ज़रूरत होती है और फिर भी यह ओवरफ़्लो हो जाता है; bf16 में fp32 जितनी रेंज होती है
सावधान रहें
शुरुआती लोगों की सबसे आम गलती है बिना किसी warmup के बहुत ज़्यादा learning rate रखना। पचास स्टेप्स तक loss ठीक दिखता है, फिर NaN हो जाता है। दूसरी सबसे आम गलती है बैच साइज़ का इतना छोटा होना कि ग्रेडिएंट ज़्यादातर शोर (noise) बनकर रह जाता है।

सिर्फ loss ही नहीं, इन चार नंबरों पर नज़र रखें

  1. 1

    ट्रेनिंग loss

    शुरुआत में तेज़ी से गिरना चाहिए, फिर धीरे-धीरे। स्टेप ज़ीरो से ही सीधी सपाट लाइन दिखने का मतलब है डेटा में कोई बग है। अचानक स्पाइक आने का मतलब है खराब बैच या बहुत ज़्यादा learning rate।
  2. 2

    Validation loss

    अलग रखा गया डेटा। जब ट्रेनिंग loss गिरता रहे लेकिन यह गिरना बंद हो जाए, तो इसका मतलब है कि मॉडल रट रहा है। नए डेटा पर बड़े प्रीट्रेनिंग रन में ऐसा शायद ही कभी होता है; लेकिन फाइन-ट्यूनिंग में यह कुछ ही मिनटों में हो जाता है।
  3. 3

    Gradient norm

    यह स्थिर होना चाहिए, लगभग 0.1–1.0 की रेंज में। इसका लगातार बढ़ना अस्थिरता का संकेत है; बार-बार क्लिपिंग होने का मतलब है कि आपका learning rate बहुत ज़्यादा है।
  4. 4

    टोकन प्रति सेकंड

    आपकी असली करेंसी। मॉड्यूल 46 की हर चीज़ इसी नंबर के बारे में है, और यही तय करता है कि रन में तीन दिन लगेंगे या तीन हफ़्ते।

ऐसे चेकपॉइंट बनाएं जैसे आपको क्रैश होने की पूरी उम्मीद हो

Resumable checkpointspython
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")
ख़तरा
सिर्फ weights ही नहीं, optimiser state भी सेव करें। AdamW हर पैरामीटर के लिए दो रनिंग ऐवरेज रखता है, और उनके बिना दोबारा शुरू करने से loss में साफ़ स्पाइक दिखता है और रन अस्थिर हो सकता है। इस गलती की वजह से लोगों का असली पैसा बर्बाद हुआ है।
यह करें
एक लंबा रन शुरू करने से पहले, एक छोटे पैमाने पर रिहर्सल करें: वही कोड, मॉडल का 1%, 500 स्टेप्स। यह लगभग हर उस बग को पकड़ लेता है जो वरना छह घंटे बाद सामने आता। पहले एक सिंगल बैच को लगभग शून्य loss तक ओवरफ़िट करें — अगर मॉडल दस उदाहरण याद नहीं रख सकता, तो वह दस अरब कभी नहीं सीख पाएगा।

और देखें और पढ़ें

Let's reproduce GPT-2 (124M)Andrej Karpathy · training section · video

लैब

एक ट्रेनिंग रन जिसे आपने जानबूझकर चार तरीकों से खराब किया।

~25 min

समस्या

एक सही चल रहे रन को लें और उसे खराब करें: (a) learning rate को 10 गुना करें, (b) warmup हटा दें, (c) gradient clipping हटा दें और एक करप्ट बैच डालें, (d) बिना loss scaling के bf16 से fp16 पर स्विच करें। हर खराबी के लक्षण को रिकॉर्ड करें।
शुरुआती कोडpython
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.
Google Colab खोलें ↗इस कोड के लिए आपके अपने सेटअप की ज़रूरत है (एक मॉडल, एक GPU या अतिरिक्त पैकेज)। इसे Google Colab में चलाएं: File → Upload notebook।

आपका काम तब पूरा होगा जब

कठिन सवाल

उत्तर देखने से पहले ख़ुद जवाब देने की कोशिश करें। अगर आप इनके जवाब दे सकते हैं, तो आप पाठ समझ गए हैं।

Q1स्टेप 8,000 पर आपका loss अचानक बढ़ जाता है और कभी ठीक नहीं होता। आपके पास हर 1,000 स्टेप्स पर चेकपॉइंट हैं। इसे ठीक करने की सटीक प्रक्रिया लिखें।दिखाएं
स्टेप 7,000 पर वापस जाएँ — 8,000 पर नहीं, जो शायद पहले ही खराब हो चुका है। Weights और optimiser state दोनों को रीस्टोर करें, नहीं तो दोबारा शुरू करने पर फिर से स्पाइक आ जाएगा। 7,000 और 8,000 के बीच इस्तेमाल हुए डेटा शार्ड की पहचान करें और उसे छोड़ दें या उसकी जांच करें; एक अकेला करप्ट शार्ड इसका सबसे आम कारण होता है। प्रभावित हिस्से के लिए थोड़े समय के लिए कम learning rate और सख्त clipping के साथ रन दोबारा शुरू करें, फिर सामान्य शेड्यूल बहाल करें। शार्ड आईडी के साथ इस घटना को लॉग करें — उसी डेटा पर दोबारा समस्या आना इस बात का संकेत है कि खराबी डेटा में है, महज़ किस्मत नहीं।

जारी रखने के लिए कृपया साइन इन करें।

अक्सर पूछे जाने वाले सवाल

मैं 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%)।

टेस्ट देने और अपनी प्रोग्रेस सेव करने के लिए साइन इन करें