2025, Oct 31 17:31
इन्फरेंस में बैच साइज कैसे चुनें: PyTorch में गति, मेमोरी और शुद्धता
जानें कि PyTorch इन्फरेंस में बैच साइज आउटपुट को क्यों नहीं बदलता, कब फुल‑बैच तेज़ होता है, और मेमोरी/लेटेंसी लक्ष्यों के अनुसार सही साइज कैसे चुनें. कोड सहित
ट्रेनिंग के दौरान बैच साइज एक ऐसा पैरामीटर है जो बहुत मायने रखता है, इसलिए यह सवाल स्वाभाविक है कि क्या इन्फरेंस चलाते समय भी वह आपकी रणनीति सीमित करता है। यदि आपके पास पहले से प्रशिक्षित PyTorch मॉडल है और आप नए डेटा का स्कोर निकालना चाहते हैं, तो क्या छोटे-छोटे हिस्सों में घुमाने के बजाय पूरे डेटासेट को एक ही बैच में पास करना ठीक है? और क्या भविष्यवाणी के समय अलग बैच साइज चुनने से आउटपुट बदलेंगे?
इस प्रश्न में चर्चा किए गए इन्फरेंस पैटर्न का उदाहरण
नीचे दिया पैटर्न सभी सैंपल्स को एक बैच में लोड करता है और एक ही फॉरवर्ड पास चलाता है:
def infer_once(self, inputs):
ds_loader = DataLoader(
inputs,
batch_size=inputs.shape[0],
shuffle=False,
)
minibatch = next(iter(ds_loader))
with torch.no_grad():
outputs = self.net(minibatch)
return outputs
बैच साइज बदलने से वास्तव में क्या बदलता है
ट्रेनिंग और इन्फरेंस बैच का उपयोग अलग कारणों से करते हैं। ट्रेनिंग में बैच समूचे डेटा वितरण का लगभगन बनाते हैं ताकि बैकप्रॉप से निकाला गया ग्रेडिएंट असली ग्रेडिएंट के साथ अच्छी तरह मेल खाए। इसी कारण बैच साइज अन्य ऑप्टिमाइज़ेशन विकल्पों के साथ इंटरैक्ट करता है और अक्सर ट्यून किया जाता है। इन्फरेंस के समय उद्देश्य बस सीखे हुए पैरामीटर्स को नए सैंपल्स पर लागू करना होता है। तब बैचिंग का फोकस मुख्यतः पैरेललिज़्म और थ्रूपुट पर होता है: सैंपल्स को समूहित करने से एक्सेलेरेटर का उपयोग अधिक कुशल हो जाता है, पर इससे प्रति-आइटम मॉडल जो फ़ंक्शन गणना करता है, वह नहीं बदलता।
सामान्यत: एक प्रशिक्षित मॉडल किसी दिए गए इनपुट सैंपल के लिए वही परिणाम देगा, भले ही उसके साथ बैच में कौन‑कौन से अन्य सैंपल हों। इन्फरेंस के लिए चुना गया बैच साइज आमतौर पर ट्रेनिंग के दौरान इस्तेमाल हुए साइज से स्वतंत्र होता है। समान इनपुट्स पर आउटपुट किसी भी व्यवहारिक बैच साइज में मेल खाने चाहिए—फ्लोटिंग‑पॉइंट गणना से उत्पन्न बहुत सूक्ष्म संख्यात्मक अंतर को छोड़कर।
व्यावहारिक निष्कर्ष और इन्फरेंस को कैसे संरचित करें
यदि आपका हार्डवेयर संभाल सकता है, तो फुल‑बैच इन्फरेंस तेज़ हो सकता है क्योंकि बिना ग्रेडिएंट गणना के अधिकतम समानांतर कार्य मिलता है। वरना, मेमोरी या लेटेंसी सीमाओं के अनुसार छोटा बैच साइज चुनें। दोनों ही स्थितियों में, एक जैसे इनपुट्स के पूर्वानुमान इस बात पर निर्भर नहीं होने चाहिए कि एक साथ कितनी आइटम्स को समूहबद्ध किया गया है।
यहाँ एक संक्षिप्त इन्फरेंस पैटर्न है जो आपको कोई भी बैच साइज चुनने देता है, जबकि प्रति‑सैंपल परिणाम अपरिवर्तित रहते हैं। जब आप पूरा डेटासेट एक साथ नहीं भेजते, तो यह बैच दर बैच आउटपुट इकट्ठा करता है।
def infer_batched(self, inputs, bsz=None):
size = inputs.shape[0] if bsz is None else bsz
ds_loader = DataLoader(
inputs,
batch_size=size,
shuffle=False,
)
preds = []
with torch.no_grad():
for part in ds_loader:
preds.append(self.net(part))
return torch.cat(preds, dim=0)
क्या बैच साइज बदलने से परिणाम प्रभावित होते हैं?
नहीं होने चाहिए। एक सरल सैनीटी चेक यह है कि समान इनपुट्स को वही मॉडल पैरामीटर्स के साथ दो अलग‑अलग बैच साइज में चलाएँ और आउटपुट्स की तुलना फ्लोटिंग‑पॉइंट सहनशीलता के भीतर करें। समान इनपुट्स, बैचिंग से स्वतंत्र, आइटम‑वार वही भविष्यवाणी देंगे।
# उदाहरण: सैनीटी चेक
scores_1 = model.infer_batched(X, bsz=1)
scores_2 = model.infer_batched(X, bsz=X.shape[0])
ok = torch.allclose(scores_1, scores_2)
यह क्यों मायने रखता है
बैच साइज की भूमिकाएँ अलग‑अलग समझना आपको सही समय पर सही चीज़ को अनुकूलित करने में मदद करता है। ट्रेनिंग के दौरान, बैच साइज को इस तरह ट्यून करें कि वह लर्निंग रेट और ऑप्टिमाइज़ेशन के साथ अच्छी तरह काम करे। इन्फरेंस में, दक्षता और संसाधन सीमाओं के अनुसार बैच साइज चुनें—यह आश्वस्त रहते हुए कि हर सैंपल की भविष्यवाणी बैचिंग रणनीतियों के बीच समान रहती है।
निष्कर्ष
इन्फरेंस के समय आप कोई भी व्यावहारिक बैच साइज चुन सकते हैं। यदि मेमोरी में फिट बैठता हो और आपके थ्रूपुट या लेटेंसी लक्ष्यों को पूरा करता हो, तो पूरे डेटासेट को एक बैच के रूप में चलाना बिल्कुल ठीक है। चाहें तो डेटा को छोटे बैचों में प्रोसेस करें—पूर्वानुमानित आउटपुट बदलने की चिंता किए बिना। संदेह हो तो दो बैच साइज पर एक त्वरित समानता जाँच कर लें, ताकि पुष्टि हो सके कि मॉडल भविष्यवाणी के दौरान सैंपल्स को स्वतंत्र रूप से संभाल रहा है।