Pytorch
TensorFlow

#
मॉडल कि Trainer API के साथ

🤗 ट्रान्सफ़ॉर्मर एक `ट्रेनर` क्लास प्रदान करता है जिससे आपको उपलब्ध कराए गए किसी भी पूर्व-प्रशिक्षित मॉडल को अपने डेटासेट पर फाइन-ट्यून करने में मदद मिलती है। एक बार जब आप अंतिम खंड में सभी डेटा पूर्व प्रसंस्करण कार्य कर लेते हैं, तो आपके पास `ट्रेनर` को परिभाषित करने के लिए बस कुछ ही चरण शेष हैं। सबसे कठिन हिस्सा `Trainer.train()` को चलाने के लिए वातावरण को तैयार करने की संभावना है, क्योंकि यह CPU पर बहुत धीमी गति से चलेगा। यदि आपके पास GPU सेट अप नहीं है, तो आप Google Colab पर निःशुल्क GPUs या TPUs का एक्सेस प्राप्त कर सकते हैं।

नीचे दिए गए कोड उदाहरण मानते हैं कि आपने पिछले खंड में उदाहरणों को पहले ही निष्पादित कर दिया है। यहां एक संक्षिप्त सारांश दिया गया है जिसकी आपको आवश्यकता है:

    from datasets import load_dataset
    from transformers import AutoTokenizer, DataCollatorWithPadding

    raw_datasets = load_dataset("glue", "mrpc")
    checkpoint = "bert-base-uncased"
    tokenizer = AutoTokenizer.from_pretrained(checkpoint)

    def tokenize_function(example):
        return tokenizer(example["sentence1"], example["sentence2"], truncation=True)

    tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)
    data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

###
प्रशिक्षण

हमारे `ट्रेनर` को परिभाषित करने से पहले पहला कदम है एक `TrainingArguments` क्लास को परिभाषित करना जिसमें प्रशिक्षण और मूल्यांकन के लिए `ट्रेनर` द्वारा उपयोग किए जाने वाले सभी हाइपरपैरामीटर शामिल होंगे। एकमात्र आर्गूमेन्ट जो आपको प्रदान करना है वह है एक निर्देशिका जहां प्रशिक्षित मॉडल सहेजा जाएगा, साथ ही साथ चौकियों को भी। बाकी सभी के लिए, आप डिफ़ॉल्ट रूप में छोड़ सकते हैं, जो एक बुनियादी फ़ाइन-ट्यूनिंग के लिए बहुत अच्छी तरह से काम करना चाहिए।

    from transformers import TrainingArguments

    training_args = TrainingArguments("test-trainer")

💡 यदि आप प्रशिक्षण के दौरान अपने मॉडल को हब पर स्वचालित रूप से अपलोड करना चाहते हैं, तो आप `TrainingArguments` में `push_to_hub=True` के साथ पास कर सकते हैं। हम इसके बारे में अध्याय 4 में और जानेंगे

दूसरा कदम हमारे मॉडल को परिभाषित करना है। पिछले अध्याय की तरह, हम `AutoModelForSequenceClassification` वर्ग का उपयोग करेंगे, दो लेबल के साथ :

    from transformers import AutoModelForSequenceClassification

    model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

आप देखेंगे कि अध्याय 2 के विपरीत, आपको इस पूर्व-प्रशिक्षित मॉडल को इन्स्टैन्शीऐट करने के बाद एक चेतावनी मिलती है। ऐसा इसलिए है क्योंकि BERT को वाक्यों के जोड़े का वर्गीकरण करने के लिए पूर्व प्रशिक्षित नहीं किया गया है, इसलिए पूर्व-प्रशिक्षित मॉडल के प्रमुख को त्याग दिया गया है और इसके बजाये अनुक्रम वर्गीकरण के लिए उपयुक्त एक नया प्रमुख डाला गया है। इन चेतावनियों से संकेत मिलता है कि कुछ वज़न का उपयोग नहीं किया गया था (त्यागे गए पूर्व-प्रशिक्षण के प्रमुख के अनुरूप) और कुछ अन्य क्रमरहित रूप से प्रारंभ किए गए थे (नए प्रमुख के लिए वाले)। यह समापन आपको मॉडल को प्रशिक्षित करने के लिए प्रोत्साहित करने के साथ होगा, जो कि अब हम करने जा रहे हैं।

एक बार जब हमारे पास हमारा मॉडल होगा, तो हम एक `Trainer` को परिभाषित अब तक की निर्मित सभी वस्तुओं को पास करके कर सकते है — `model`, `training_args`, प्रशिक्षण और सत्यापन डेटासेट, हमारे `data_collator`, और हमारे `tokenizer`:

    from transformers import Trainer

    trainer = Trainer(
        model,
        training_args,
        train_dataset=tokenized_datasets["train"],
        eval_dataset=tokenized_datasets["validation"],
        data_collator=data_collator,
        tokenizer=tokenizer,
    )

ध्यान दें कि जब आप `tokenizer` पास करते हैं जैसा कि हमने यहां किया था, तो `Trainer` द्वारा उपयोग किया जाने वाला डिफ़ॉल्ट `data_colllator` एक `DataCollatorWithPadding` होगा जैसा कि पहले परिभाषित किया गया था, इसलिए आप इस कॉल में `data_collator=data_collator` लाइन को छोड़ सकते हैं। आपको प्रोसेसिंग के इस भाग को खंड 2 में दिखाना फिर भी महत्वपूर्ण था!

मॉडल को हमारे डेटासेट पर फाइन-ट्यून करने के लिए, हमें बस अपने `Trainer` के `train()` विधि को कॉल करना होगा:

    trainer.train()

यह फाइन-ट्यूनिंग को शुरू करेगा (जिसमें GPU पर कुछ मिनट लगने चाहिए) और हर 500 कदम पर प्रशिक्षण लॉस की रिपोर्ट करेगा । हालांकि, यह आपको यह नहीं बताएगा कि आपका मॉडल कितना अच्छा (या खराब) प्रदर्शन कर रहा है। यह है क्योंकि:

1. हमने `Trainer` को नहीं बताया की प्रशिक्षण के दौरान मूल्यांकन करने के लिए `evaluation_strategy` को या तो `"steps"`(हर `eval_steps` का मूल्यांकन करें) या `"epoch"` (प्रत्येक एपॉक के अंत में मूल्यांकन) को सेट करे।
2. हमने `Trainer` को `compute_metrics()` फ़ंक्शन के साथ प्रदान नहीं किया जो मूल्यांकन के दौरान मीट्रिक की गणना करता है (अन्यथा मूल्यांकन ने केवल लॉस को मुद्रित किया होगा, जो बहुत सहज संख्या नहीं है)

###
मूल्यांकन

आइए देखें कि हम एक उपयोगी `compute_metrics()` फ़ंक्शन कैसे बना सकते हैं और अगली बार जब हम प्रशिक्षण करेंगे तो इसका उपयोग कैसे कर सकते हैं। फ़ंक्शन को एक `EvalPrediction` ऑब्जेक्ट लेना होगा (जो एक `predictions` फ़ील्ड और एक `label_ids` फ़ील्ड के साथ एक नामित टपल है) और लौटाएगा एक डिक्शनरी जो मैप करेगा स्ट्रिंग्स को फ़्लोट में (स्ट्रिंग्स लौटाए गए मेट्रिक्स के नाम हैं, और फ़्लोट उनकी वैल्यूज)। हमारे मॉडल से कुछ प्रिडिक्शन्स प्राप्त करने के लिए, हम `Trainer.predict()` कमांड का उपयोग कर सकते हैं:

    predictions = trainer.predict(tokenized_datasets["validation"])
    print(predictions.predictions.shape, predictions.label_ids.shape)

    (408, 2) (408,)

`predict()` विधि का आउटपुट नामित टपल है तीन क्षेत्रों के साथ : `predictions`, `label_ids`, और `metrics`। `metrics` फ़ील्ड में केवल पास किए गए डेटासेट पर होने वाला लॉस होगा, साथ ही साथ कुछ समय मीट्रिक (कुल और औसत रूप से प्रिडिक्ट करने में कितना समय लगा) शामिल होंगे। एक बार जब हम अपना `compute_metrics()` फ़ंक्शन पूरा कर लेते हैं और इसे `ट्रेनर` को पास कर देते हैं, तो उस फ़ील्ड में `compute_metrics()` द्वारा लौटाए गए मीट्रिक भी शामिल होंगे।

जैसा कि आप देख सकते हैं, `predictions` एक 2-डिमेन्शनल सरणी है जिसका आकार 408 x 2 (408 हमारे द्वारा उपयोग किए गए डेटासेट में तत्वों की संख्या है)। वे डेटासेट के प्रत्येक तत्व के लिए लॉगिट हैं जिन्हें हमने `predict()` में पास किया है (जैसा कि आपने पिछले अध्याय में देखा था, सभी ट्रांसफॉर्मर मॉडल लॉगिट लौटाते हैं)। उन्हें भविष्यवाणियों यानि प्रिडिक्शन्स में बदलने के लिए जिन्हें हम अपने लेबल से तुलना कर सकते हैं, हमें दूसरी एक्सिस पर अधिकतम मूल्य के साथ इन्डेक्स लेने की आवश्यकता है:

    import numpy as np

    preds = np.argmax(predictions.predictions, axis=-1)

अब हम उन `preds` की तुलना लेबल से कर सकते हैं। हमारे `compute_metric()` फ़ंक्शन को बनाने के लिए, हम 🤗 मूल्यांकन करना लाइब्रेरी के मेट्रिक्स पर निर्भर है। हम MRPC डेटासेट से जुड़े मेट्रिक्स को उतनी ही आसानी से लोड कर सकते हैं, जितनी आसानी से हमने डेटासेट लोड किया, इस बार `evaluate.load()` फ़ंक्शन के साथ। इसने एक वस्तु लौटाया जिसमे एक `compute()` विधि है जिसका उपयोग हम मीट्रिक गणना करने के लिए कर सकते हैं:

    import evaluate

    metric = evaluate.load("glue", "mrpc")
    metric.compute(predictions=preds, references=predictions.label_ids)

    {'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}

आपको मिलने वाले सटीक परिणाम अलग-अलग हो सकते हैं, क्योंकि मॉडल हेड के क्रमरहित इनिशियलाइज़ेशन से प्राप्त मेट्रिक्स में बदलाव हो सकता है। यहां, हम देख सकते हैं कि हमारे मॉडल का सत्यापन सेट पर 85.78% की सटीकता है और 89.97 का F1 स्कोर है। वे दो मेट्रिक्स हैं जिनका उपयोग GLUE बेंचमार्क के लिए MRPC डेटासेट पर परिणामों का मूल्यांकन करने के लिए किया जाता है। BERT पेपर में टेबल ने बेस मॉडल के लिए F1 स्कोर 88.9 बताया। वह एक `uncased` मॉडल था जबकि हम वर्तमान में `cased` मॉडल का उपयोग कर रहे हैं, जो बेहतर परिणाम की व्याख्या करता है।

सब कुछ एक साथ लपेटकर, हमें अपना `compute_metrics()` फ़ंक्शन मिलता है:

    def compute_metrics(eval_preds):
        metric = evaluate.load("glue", "mrpc")
        logits, labels = eval_preds
        predictions = np.argmax(logits, axis=-1)
        return metric.compute(predictions=predictions, references=labels)

और इसे प्रत्येक एपॉक के अंत में मेट्रिक्स की रिपोर्ट करने के लिए इसके उपयोग की क्रिया को देखने के लिए, यहां बताया गया है कि हम इस `compute_metrics()` फ़ंक्शन के साथ एक नया `Trainer` कैसे परिभाषित करते हैं:

    training_args = TrainingArguments("test-trainer", evaluation_strategy="epoch")
    model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

    trainer = Trainer(
        model,
        training_args,
        train_dataset=tokenized_datasets["train"],
        eval_dataset=tokenized_datasets["validation"],
        data_collator=data_collator,
        tokenizer=tokenizer,
        compute_metrics=compute_metrics,
    )

ध्यान दें कि हम एक नया `TrainingArguments` उसके `evaluation_strategy` जिसे सेट किया है `"epoch"` और एक नए मॉडल के साथ बनाते है — अन्यथा, हम केवल उस मॉडल का प्रशिक्षण जारी रख रहे होते जिसे हमने पहले ही प्रशिक्षित किया है। एक नया प्रशिक्षण रन शुरू करने के लिए, हम निष्पादित यानि एक्सक्यूट करते हैं:

    trainer.train()

इस बार, यह सत्यापन लॉस और मेट्रिक्स की रिपोर्ट हर एपॉक के अंत में प्रशिक्षण लॉस के ऊपर करेगा। फिर से, एक सटीक एक्यूरेसी/F1 स्कोर जिसपे हम पहुंचे थोड़ा अलग हो सकता है उससे जो हमने पाया, क्योंकि मॉडल के रैंडम हेड इनिशियलाइज़ेशन के कारण, लेकिन यह उसी बॉलपार्क में होना चाहिए।

`Trainer` कई GPUs या TPUs पर बिलकुल हटकर काम करेगा और बहुत सारे विकल्प प्रदान करता है, जैसे मिश्रित-सटीक प्रशिक्षण (अपने प्रशिक्षण आर्गूमेन्ट में `fp16 = True` का उपयोग करें)। हम अध्याय 10 में इसके द्वारा समर्थित हर चीज पर अध्ययन करेंगे।

यह `Trainer` API का उपयोग करके फाइन-ट्यूनिंग के परिचय को समाप्त करता है। अधिकांश सामान्य NLP कार्यों के लिए ऐसा करने का एक उदाहरण अध्याय 7 में दिया जाएगा, लेकिन अभी के लिए आइए देखें कि शुद्ध PyTorch में वही काम कैसे करें।

✏️ कोशिश करके देखे! GLUE SST-2 डेटासेट पर एक मॉडल को फाइन-ट्यून करें, डेटा प्रसंस्करण यानि डेटा प्रोसेसिंग का उपयोग करके जिसे आपने सेक्शन 2 में किया था