All-gather operation: saare devices se {θl(0),θl(1),…,θl(N−1)} collect karo
Device memory mein temporarily poora θl reconstruct karo
Layer ka forward pass compute karo: hl+1=fl(hl,θl)
Borrowed shards discard karo, sirf θl(i) rakho
Yeh step kyun? Har layer ko apne saare parameters chahiye hote hain activations sahi se compute karne ke liye. Hum matrix multiply y=Wx split nahi kar sakte agar hamare paas sirf aadha W ho.
θl ko dobara all-gather karo (gradient computation ke liye zaroori)
Local gradients compute karo: ∂θl∂L
Gradients ko reduce-scatter karo: har device ko sirf ∇θl(i) milta hai (apne shard ka gradient)
Poora θl phir se discard karo
Reduce-scatter kyun? Poora gradient compute karne ke baad, hum devices ke contributions ko sum karte hain (reduce) aur chunks distribute karte hain (scatter), taaki har device sirf apna shard update kare.
FSDP, PyTorch ka implementation hai ZeRO (Zero Redundancy Optimizer) ka, jo Microsoft DeepSpeed se aaya hai:
ZeRO Stage 1: Sirf optimizer states shard karo → 4× memory reduction
ZeRO Stage 2: Optimizer states + gradients shard karo → 8× memory reduction
ZeRO Stage 3: Optimizer states + gradients + parameters shard karo → N× memory reduction (FSDP = ZeRO-3)
Teen stages kyun? Har stage zyada communication overhead introduce karta hai. ZeRO-1 moderate models ke liye faster hai; ZeRO-3 sirf tab zaroori hai jab models single-GPU memory se bade hon.
Wrapping granularity: FSDP individual layers, modules, ya poore model ko wrap kar sakta hai. Finer wrapping temporary memory kam karta hai (chhote all-gather buffers) lekin communication frequency badh jaati hai.
Typical strategy:
model = TransformerModel(...)for layer in model.transformer_layers: layer = FSDP(layer) # Wrap each transformer blockmodel = FSDP(model) # Outer wrap for top-level
Mixed precision: FSDP shards fp32 mein store karta hai (optimizer ke liye) lekin fp16 mein communicate karta hai (bandwidth ke liye). All-gather, send karne se pehle fp32 → fp16 convert karta hai.
CPU offloading: Kuch FSDP implementations inactive shards ko CPU RAM mein offload karne ki allow karte hain, GPU memory ke liye PCIe bandwidth trade karte hue. Severe latency penalties ki wajah se rarely use hota hai.
Recall Ek 12-Saal Ke Bachche Ko Samjhao
Socho tum aur 7 doston ek bada LEGO castle bana rahe ho (AI model). Castle itna bada hai ki ek insaan saare pieces ek saath nahi pakad sakta.
Normal tarika (data parallel): Aap mein se har ek ke paas saare pieces ki ek complete copy hai. Aap sabhi ek hi castle 8 baar banate ho. Yeh bahut zyada jagah waste karta hai!
FSDP tarika: Aap pieces ko 8 boxes mein divide karte ho. Tum box 1 rakho, tumhara dost box 2 rakhta hai, aur aage bhi aisa hi. Jab tumhe tower banana hota hai (jiske liye saari boxes ke pieces chahiye), sab log apni boxes circle mein jaldi se pass karte hain taaki tum zaroori pieces le sako. Tower banane ke baad, extra boxes waapas de do.
Yeh kyun help karta hai? Tumhe permanently sirf 1/8 pieces store karne ki zaroorat hai. Passing-around mein thoda time lagta hai, lekin yeh 8× shelf space khareedne se kaafi better hai. Bahut bade AI models ke liye (jaise ChatGPT ke bade bhai), yeh "pieces share karna" wala trick hi unhe banane ka ek maatra tarika hai, bina impossibly expensive computers khareed ke.