Aplicación de la selección inteligente de SageMaker al script de transformadores de Hugging Face - Amazon SageMaker AI

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Aplicación de la selección inteligente de SageMaker al script de transformadores de Hugging Face

Hay dos maneras de implementar la selección inteligente de SageMaker en la clase Trainer de transformadores.

nota

Si utiliza uno de los DLC de PyTorch con el paquete de selección inteligente SageMaker instalado, tenga en cuenta que debe instalar la biblioteca transformers. Puede instalar paquetes adicionales ampliando los DLC o pasando requirements.txt a la clase de iniciador de trabajos de entrenamiento para PyTorch (sagemaker.pytorch.PyTorch) en el SageMaker AI Python SDK.

Configuración sencilla

La manera más sencilla de implementar la selección inteligente de SageMaker en la clase Trainer de transformadores es usar la función enable_sifting. Esta función acepta un objeto Trainer existente y encapsula el objetoDataLoader existente con SiftingDataloader. Puede seguir utilizando el mismo objeto de entrenamiento. Consulte el siguiente uso de ejemplo.

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 clase SiftingDataloader es un cargador de datos iterable. El tamaño exacto del conjunto de datos resultante no se conoce de antemano debido al muestreo aleatorio que se realiza durante la selección. Como resultado, Trainer de Hugging Face espera el argumento de entrenamiento de max_steps. Tenga en cuenta que este argumento anula el parámetro de configuración epoch num_train_epochs. Si el cargador de datos original también era iterable, o si su entrenamiento utiliza max_steps y un solo epoch, SiftingDataloader funciona igual que el cargador de datos existente. Si el cargador de datos original no era iterable o no se proporcionó max_steps, el entrenador de Hugging Face podría generar un mensaje de error similar al siguiente.

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

Para solucionar este problema, la función enable_sifting proporciona un parámetro set_epochs opcional. Esto permite el entrenamiento con epochs, utilizando el número de épocas proporcionado por el argumento num_train_epochs de la clase Trainer, y establece max_steps en el número entero máximo del sistema, lo que permite que el entrenamiento avance hasta completar los epochs especificados.

Configuración personalizada

Para una integración personalizada del cargador de datos de selección inteligente de SageMaker, puede utilizar una clase Trainer de Hugging Face personalizada. Dentro de cualquier subclase de Trainer, la función get_train_dataloader() se puede anular para devolver un objeto de la clase SiftingDataloader en su lugar. En el caso de los entrenadores personalizados existentes, este enfoque puede ser menos intrusivo, pero requiere cambios de código, en comparación con la opción de configuración sencilla. A continuación se muestra una implementación de ejemplo de la selección inteligente de SageMaker en una clase Trainer personalizada de Hugging Face.

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 )

Con la clase Trainer encapsulada, cree un objeto de la misma de la siguiente manera.

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