Applicare SageMaker Smart Sifting a uno script Hugging Face Transformers - Amazon SageMaker AI

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Applicare SageMaker Smart Sifting a uno script Hugging Face Transformers

Esistono due modi per implementare SageMaker Smart Sifting nella classe Transformers Trainer.

Nota

Se utilizzi uno dei Container DL per PyTorch con il pacchetto SageMaker Smart Sifting installato, tieni presente che è necessario installare la libreria transformers. Puoi installare pacchetti aggiuntivi estendendo i Container DL o passando requirements.txt alla classe del launcher del job di addestramento per PyTorch (sagemaker.pytorch.PyTorch) in SageMaker AI Python SDK.

Configurazione semplice

Il modo più semplice per implementare SageMaker Smart Sifting nella classe Trainer Transformers consiste nell’utilizzare la funzione enable_sifting. Questa funzione accetta un oggetto Trainer esistente ed esegue il wrapping dell’oggetto DataLoader esistente con SiftingDataloader. È possibile continuare a utilizzare lo stesso oggetto di addestramento. Guarda l’esempio di utilizzo seguente.

from smart_sifting.integrations.trainer import enable_sifting from smart_sifting.loss.abstract_sift_loss_module import Loss from smart_sifting.sift_config.sift_configs import ( RelativeProbabilisticSiftConfig LossConfig SiftingBaseConfig ) class SiftingImplementedLoss(Loss): def loss(self, model, transformed_batch, original_batch): loss_fct = MSELoss(reduction="none") # make sure to set reduction to "none" logits = model.bert(**original_batch) return loss_fct(logits, original_batch.get("labels")) sift_config = RelativeProbabilisticSiftConfig( beta_value=0.5, loss_history_length=500, loss_based_sift_config=LossConfig( sift_config=SiftingBaseConfig(sift_delay=0) ) ) trainer = Trainer(...) enable_sifting(trainer, sift_config, loss=SiftingImplementedLoss()) # updates the trainer with Sifting Loss and config trainer.train()

La classe SiftingDataloader è uno strumento di caricamento dei dati iterabile. La dimensione esatta del set di dati risultante non è nota in anticipo, a causa del campionamento casuale durante il sifting. Di conseguenza, Trainer di Hugging Face si aspetta l’argomento di addestramento max_steps. Questo argomento ha precedenza sul parametro di configurazione di epoch num_train_epochs. Se anche lo strumento di caricamento dei dati originale era iterabile, o se l’addestramento utilizza max_steps e una singola epoch, SiftingDataloader si comporta allo stesso modo dello strumento di caricamento dei dati esistente. Se lo strumento di caricamento dei dati originale non era iterabile o non è stato fornito max_steps, Trainer di Hugging Face potrebbe generare un messaggio di errore simile al seguente.

args.max_steps must be set to a positive value if dataloader does not have a length, was -1

Per risolvere questo problema, la funzione enable_sifting fornisce un parametro set_epochs opzionale. Ciò consente l’addestramento con epoch, utilizzando il numero di epoch fornito dall’argomento num_train_epochs della classe Trainer, e imposta max_steps sul numero intero massimo di sistema, permettendo all’addestramento di progredire fino al completamento delle epoch specificate.

Configurazione personalizzata

Per un’integrazione personalizzata dello strumento di caricamento dei dati della funzionalità di smart sifting di SageMaker, è possibile utilizzare una classe Trainer di Hugging Face personalizzata. All’interno di qualsiasi sottoclasse di Trainer, la funzione get_train_dataloader() può essere sostituita per restituire invece un oggetto della classe SiftingDataloader. Per i casi con trainer personalizzati esistenti, questo approccio potrebbe essere meno intrusivo, ma richiede modifiche al codice rispetto all’opzione di configurazione semplice. Di seguito è riportato un esempio di implementazione di SageMaker Smart Sifting in una classe Trainer di Hugging Face personalizzata.

from smart_sifting.sift_config.sift_configs import ( RelativeProbabilisticSiftConfig LossConfig SiftingBaseConfig ) from smart_sifting.dataloader.sift_dataloader import SiftingDataloader from smart_sifting.loss.abstract_sift_loss_module import Loss from smart_sifting.data_model.data_model_interface import SiftingBatch, SiftingBatchTransform from smart_sifting.data_model.list_batch import ListBatch class SiftingListBatchTransform(SiftingBatchTransform): def transform(self, batch: Any): inputs = batch[0].tolist() labels = batch[-1].tolist() # assume the last one is the list of labels return ListBatch(inputs, labels) def reverse_transform(self, list_batch: ListBatch): a_batch = [torch.tensor(list_batch.inputs), torch.tensor(list_batch.labels)] return a_batch class SiftingImplementedLoss(): # You should add the following initializaztion function # to calculate loss per sample, not per batch. def __init__(self): self.celoss = torch.nn.CrossEntropyLoss(reduction='none') def loss( self, model: torch.nn.Module, transformed_batch: SiftingBatch, original_batch: Any = None, ) -> torch.Tensor: device = next(model.parameters()).device batch = [t.to(device) for t in original_batch] # compute loss outputs = model(batch) return self.celoss(outputs.logits, batch[2]) class SiftingImplementedTrainer(Trainer): def get_train_dataloader(self): dl = super().get_train_dataloader() sift_config = RelativeProbabilisticSiftConfig( beta_value=0.5, loss_history_length=500, loss_based_sift_config=LossConfig( sift_config=SiftingBaseConfig(sift_delay=0) ) ) return SiftingDataloader( sift_config=sift_config, orig_dataloader=dl, batch_transforms=SiftingListBatchTransform(), loss_impl=SiftingImplementedLoss(), model=self.model )

Usando la classe Trainer con wrapping, creane un oggetto come segue.

trainer = SiftingImplementedTrainer( model=model, args=training_args, train_dataset=small_train_dataset, eval_dataset=small_eval_dataset ) trainer.train()