एक LLM बनाएँएडवांस्डपाठ 456 मिनट का पाठ

स्टेप 9 · कई GPUs पर ट्रेनिंग

एक मॉडल अब एक कार्ड पर फिट नहीं होता। इसे बांटने के चार तरीके, और उनके बीच चुनने का नियम।

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

60 सेकंड में

स्टेप 9 · कई GPUs पर ट्रेनिंग

एक मॉडल अब एक कार्ड पर फिट नहीं होता। इसे बांटने के चार तरीके, और उनके बीच चुनने का नियम।

1/5
आसान शब्दों में
एक व्यक्ति पियानो नहीं उठा सकता। तो या तो आप हर किसी को उसका अपना छोटा पियानो दे दें, या फिर आप एक पियानो के टुकड़े कर दें और हर व्यक्ति एक टुकड़ा उठाए। दोनों काम करते हैं; बस दोनों में चिल्लाने-बताने की मेहनत अलग-अलग लगती है।
रणनीति (Strategy)क्या बांटा जाता हैकम्युनिकेशन की लागतकब इस्तेमाल करें
डेटा पैरेलल (DDP)बैच (The batch)हर स्टेप पर ग्रेडिएंट ऑल-रिड्यूस (Gradient all-reduce)जब मॉडल एक GPU पर फिट हो जाए
FSDP / ZeRO-3वेट्स, ग्रेडिएंट्स, ऑप्टिमाइज़र स्टेटहर लेयर को गैदर (gather) और स्कैटर (scatter) करनाजब मॉडल फिट न हो — आज की तारीख में डिफ़ॉल्ट पसंद
टेंसर पैरेलल (Tensor parallel)एक लेयर के अंदर के अलग-अलग मैट्रिसेस (matrices)हर लेयर पर दो बार — तेज़ इंटरकनेक्ट की ज़रूरत होती हैNVLink वाले एक ही नोड के अंदर
पाइपलाइन पैरेलल (Pipeline parallel)अलग-अलग डिवाइसेज़ पर लेयर्ससिर्फ़ स्टेज की सीमाओं (boundaries) परधीमे लिंक्स वाले नोड्स के बीच

यहाँ से शुरुआत करें: FSDP

Fully Sharded Data Parallel व्यावहारिक रूप से डिफ़ॉल्ट विकल्प है। हर GPU वेट्स, ग्रेडिएंट्स और ऑप्टिमाइज़र स्टेट का एक हिस्सा (slice) रखता है। किसी लेयर की गणना करने से पहले, यह उस लेयर के पूरे वेट्स इकट्ठा करता है, उनका उपयोग करता है, और फिर उस कॉपी को हटा देता है। प्रति GPU मेमोरी डिवाइसेज़ की संख्या के साथ लगभग लीनियर रूप से घटती है।
FSDP in practicepython
import torch, functools
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
from torch.distributed.fsdp import MixedPrecision, ShardingStrategy
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy

torch.distributed.init_process_group("nccl")
torch.cuda.set_device(local_rank)

policy = functools.partial(
    transformer_auto_wrap_policy,
    transformer_layer_cls={Block},          # shard at block granularity
)

model = FSDP(
    model,
    auto_wrap_policy=policy,
    sharding_strategy=ShardingStrategy.FULL_SHARD,     # ZeRO-3
    mixed_precision=MixedPrecision(
        param_dtype=torch.bfloat16,
        reduce_dtype=torch.float32,          # reduce gradients in fp32
    ),
    device_id=torch.cuda.current_device(),
    limit_all_gathers=True,
)
# the training loop is otherwise unchanged

इन्हें आपस में जोड़ने का नियम

  1. 1

    एक नोड के अंदर टेंसर पैरेलल

    मैट्रिक्स को बांटने का मतलब है हर लेयर पर दो बार बात करना। यह सिर्फ़ NVLink जैसी हाई-बैंडविड्थ पर ही मुमकिन है। आम तौर पर 2–8 गुना (way)।
  2. 2

    नोड्स के बीच पाइपलाइन पैरेलल

    यह सिर्फ़ स्टेज की सीमाओं पर कम्युनिकेट करता है, इसलिए यह धीमे लिंक्स को भी झेल लेता है। इसमें आपको पाइपलाइन "बबल" (bubble) का नुकसान होता है — वह खाली समय जब स्टेजेस भर रही होती हैं और खाली हो रही होती हैं।
  3. 3

    सबके ऊपर डेटा पैरेलल

    पूरे टेंसर-और-पाइपलाइन सेटअप की नकल (replicate) करें, और इन प्रतियों के बीच ग्रेडिएंट्स को ऑल-रिड्यूस करें।
  4. 4

    3D पैरेललिज़्म

    तीनों का मेल। इसी तरह सबसे बड़े और नए (frontier) रन आयोजित किए जाते हैं, और इसका सही कॉन्फ़िगरेशन खोजना अपने आप में इंजीनियरिंग का एक बड़ा काम है।

बड़े पैमाने पर असल में क्या गड़बड़ी होती है

  • पीछे छूटने वाले (Stragglers)। हर GPU सबसे धीमे वाले का इंतज़ार करता है। एक भी धीमा (throttling) कार्ड पूरे क्लस्टर की रफ़्तार कम कर देता है।
  • हार्डवेयर फ़ेलियर। हफ़्तों तक चलने वाले हज़ारों GPUs में ख़राबियाँ आना आम बात है। बार-बार चेकपॉइंट बनाना और अपने आप रीस्टार्ट होना अनिवार्य है, कोई ऐच्छिक सुविधा नहीं।
  • लॉस स्पाइक्स (Loss spikes)। बड़े रनों में अचानक अस्थिरता आ जाती है। मानक समाधान: आखिरी अच्छे चेकपॉइंट पर वापस लौटें, गड़बड़ करने वाले डेटा शार्ड को छोड़ें, और फिर से शुरू करें।
  • धीमा न्यूमेरिकल ड्रिफ्ट (Silent numerical drift)। अलग-अलग रनों में रिडक्शन का क्रम बदलने से नतीजों में थोड़ा फ़र्क आ जाता है। अलग-अलग क्लस्टर साइज़ में बिल्कुल हूबहू नतीजों के पीछे न भागें; स्थिर आँकड़ों (stable statistics) पर ध्यान दें।
  • डेटा लोडर की कमी (Data loader starvation)। अक्सर रुकावट GPUs की वजह से बिल्कुल नहीं होती। डेटा को पहले से टोकनाइज़ करें, शार्ड करें, और मेमोरी-मैप्ड रीड्स का इस्तेमाल करें।
यह करें
Model FLOPs Utilisation (MFU) मापें — सैद्धांतिक पीक FLOPs का वह हिस्सा जो आप असल में हासिल करते हैं। 30% से कम का मतलब है कि कुछ बहुत गलत है। 40–55% एक अच्छी तरह से ट्यून किया गया रन है। यह अकेला नंबर आपको आपके सेटअप के बारे में किसी भी अन्य चीज़ से ज़्यादा बताता है।
सावधान रहें
अपने पहले प्रोजेक्ट के लिए इसे खुद न बनाएं। किसी परखे हुए फ़्रेमवर्क का उपयोग करें और अपनी मेहनत डेटा और मूल्यांकन पर लगाएं — असल क्वालिटी वहीं से आती है।

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

लैब

मापे गए MFU के साथ एक मल्टी-GPU रन।

~20 min

समस्या

वही मॉडल 1 GPU पर चलाएं, फिर 2+ GPUs पर FSDP के साथ चलाएं। दोनों के लिए टोकन/सेकंड और MFU मापें। रुकावट (bottleneck) ढूंढें — अगर MFU 30% से कम है, तो पता लगाएं कि क्या यह डेटा लोडर, कम्युनिकेशन या मॉडल की वजह से है।
शुरुआती कोडpython
mfu = (6 * n_params * tokens_per_sec) / (peak_flops * n_gpus)
print(f"{tokens_per_sec:,.0f} tok/s  MFU {mfu:.1%}")
# Under 30%: time the data loader in isolation first. It is usually the loader.
Google Colab खोलें ↗इस कोड के लिए आपके अपने सेटअप की ज़रूरत है (एक मॉडल, एक GPU या अतिरिक्त पैकेज)। इसे Google Colab में चलाएं: File → Upload notebook।

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

कठिन सवाल

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

Q1दो GPUs 2x के बजाय 1.4x थ्रूपुट देते हैं। उन कारणों की सूची बनाएं जिस क्रम में आप उनकी जांच करेंगे।दिखाएं
पहला: डेटा लोडर का सैचुरेशन — एक लोडर अब दो डिवाइसेज़ को डेटा दे रहा है; पहले इसे अकेले चलाकर समय मापें क्योंकि यह सबसे आम समस्या है और इसे ठीक करना सबसे सस्ता है। दूसरा: धीमे इंटरकनेक्ट पर ग्रेडिएंट ऑल-रिड्यूस — जांचें कि क्या कम्युनिकेशन बैकवर्ड कंप्यूट के साथ ओवरलैप हो रहा है या नहीं। तीसरा: प्रति डिवाइस बैच साइज़ बहुत छोटा है, जिससे कर्नेल्स कंप्यूट-बाउंड होने के बजाय लॉन्च-बाउंड हो जाते हैं। चौथा: किसी एक कार्ड का पीछे छूटना (stragglers) या बहुत गर्म होना (thermal throttling)। इसी क्रम में जांच करें; अधिकतर मामलों में पहले दो ही कारण होते हैं।

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

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

FSDP या DeepSpeed?

दोनों एक ही तरह के शार्डिंग आइडिया पर काम करते हैं। FSDP, PyTorch का अपना (native) हिस्सा है और अब डिफ़ॉल्ट बनता जा रहा है; DeepSpeed में ज़्यादा फ़ीचर्स हैं और यह CPU-ऑफलोडिंग को बेहतर सपोर्ट करता है। कोई भी चुन लें — जो आपकी टीम को पहले से आता हो उसे चुनें।

7B मॉडल के लिए मुझे कितने GPUs की ज़रूरत होगी?

पूरी ट्रेनिंग के लिए लगभग 100 GB स्टेट की ज़रूरत होती है, इसलिए FSDP के साथ कम से कम दो 80 GB कार्ड, और सही समय में पूरा करने के लिए व्यावहारिक रूप से 8–64 कार्ड चाहिए। इसी मॉडल का LoRA फ़ाइन-ट्यून एक 24 GB कार्ड पर फिट हो जाता है।

पाइपलाइन बबल क्या है?

वह खाली समय जब पहला माइक्रो-बैच सभी स्टेजेस से होकर गुज़र रहा होता है और आखिरी वाला बाहर निकल रहा होता है। ज़्यादा माइक्रो-बैच इसे छोटा कर देते हैं। इंटरलीव्ड शेड्यूल्स इसे और छोटा कर देते हैं, लेकिन इससे जटिलता बढ़ जाती है।

क्या ग्रेडिएंट चेकपॉइंटिंग से मदद मिलती है?

हाँ — बैकवर्ड पास के दौरान एक्टिवेशन्स को स्टोर करने के बजाय उन्हें फिर से कैलकुलेट करें। यह आमतौर पर लगभग 30% अतिरिक्त कंप्यूट के बदले बहुत सारी मेमोरी बचाता है, जिससे अक्सर आप बैच साइज़ को इतना बढ़ा पाते हैं कि फ़ायदे में रहें।

पाठ का टेस्ट

5 सवाल। पास होने और इस पाठ को पूरा करने के लिए 3 सही होने चाहिए (60%)।

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