Ampliar una contenedor precompilado - Amazon SageMaker

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.

Ampliar una contenedor precompilado

Si un SageMaker contenedor prediseñado no cumple con todos sus requisitos, puede ampliar la imagen existente para adaptarla a sus necesidades. Incluso si hay soporte directo para su entorno o marco, es posible que desee añadir funciones adicionales o configurar el entorno de contenedores de forma diferente. Al ampliar una imagen precompilada, puede aprovechar las bibliotecas y configuraciones de aprendizaje profundo incluidas sin tener que crear una imagen desde cero. Puede ampliar el contenedor para añadir bibliotecas, modificar la configuración e instalar dependencias adicionales.

El siguiente tutorial muestra cómo ampliar una SageMaker imagen prediseñada y publicarla en Amazon ECR.

Requisitos para ampliar un contenedor precompilado

Para ampliar una SageMaker imagen prediseñada, debe configurar las siguientes variables de entorno en su Dockerfile. Para obtener más información sobre las variables de entorno con SageMaker contenedores, consulta el repositorio del SageMaker Training Toolkit. GitHub

  • SAGEMAKER_SUBMIT_DIRECTORY: el directorio dentro del contenedor en el que se encuentra el script de Python para el entrenamiento.

  • SAGEMAKER_PROGRAM: el script de Python que debe invocarse y usarse como punto de entrada para el entrenamiento.

También puede instalar bibliotecas adicionales si incluye lo siguiente en su Dockerfile:

RUN pip install <library>

En el siguiente tutorial se muestra cómo utilizar estas variables de entorno.

Amplíe SageMaker los contenedores para ejecutar un script de Python

En este tutorial, aprenderá a extender el SageMaker PyTorch contenedor con un archivo Python que usa el conjunto de datos CIFAR-10. Al ampliar el SageMaker PyTorch contenedor, se utiliza la solución de formación existente diseñada especialmente para funcionar. SageMaker En este tutorial se amplía una imagen de entrenamiento, pero se pueden seguir los mismos pasos para ampliar una imagen de inferencia. Para una lista completa de las Imágenes disponibles, consulte Imágenes de contenedores de aprendizaje profundo disponibles.

Para ejecutar su propio modelo de entrenamiento con los SageMaker contenedores, cree un contenedor de Docker a través de una instancia de SageMaker Notebook.

Paso 1: Crea una instancia de SageMaker Notebook

  1. Abra la consola de SageMaker .

  2. En el panel de navegación, elija Notebook Cuaderno), seleccione Notebook instances (Instancias de cuaderno) y, a continuación, seleccione Create notebook instance (Crear instancia de cuaderno).

  3. En la página Crear instancia de bloc de notas, proporcione la siguiente información:

    1. En Notebook instance name (Nombre de instancia del bloc de notas), escriba RunScriptNotebookInstance.

    2. En Tipo de instancia de bloc de notas, elija ml.t2.medium.

    3. En la sección Permissions and encryption (Permisos y cifrado), haga lo siguiente:

      1. En Rol de IAM, elija Crear un nuevo rol.

      2. En la página Create an IAM role (Crear un rol de IAM), elija Buckets de S3 específicos, especifique un bucket de Amazon S3 denominado sagemaker-run-script y, a continuación, elija Create role (Crear rol).

        SageMaker crea un rol de IAM denominadoAmazonSageMaker-ExecutionRole-YYYYMMDDTHHmmSS, por ejemplo. AmazonSageMaker-ExecutionRole-20190429T110788 Tenga en cuenta que la convención de nomenclatura de rol de ejecución utiliza la fecha y la hora en que se creó el rol, separadas por una T.

    4. En Root Access (Acceso raíz), elija Enable (Habilitar).

    5. Elija Crear instancia de bloc de notas.

  4. En la página Notebook instances (Instancias de cuaderno), Status (Estado) es Pemnding (Pendiente). Amazon CloudWatch Internet Monitor puede tardar unos minutos en lanzar una instancia de procesamiento de aprendizaje automático (en este caso, lanza una instancia de notebook) y adjuntarle un volumen de almacenamiento de aprendizaje automático. La instancia de cuaderno cuenta con un servidor de cuaderno de Jupyter configurado previamente y un conjunto de bibliotecas de Anaconda. Para obtener más información, consulte CreateNotebookInstance.

  5. En la sección Permissions and encryption (Permisos y cifrado), copie el número de ARN del rol de IAM y péguelo en un archivo de cuaderno para guardarlo temporalmente. Este número ARN del rol de IAM se utiliza más adelante para configurar un estimador de entrenamiento local en la instancia del cuaderno. El número de ARN de rol de IAM tiene el siguiente aspecto: 'arn:aws:iam::111122223333:role/service-role/AmazonSageMaker-ExecutionRole-20190429T110788'.

  6. Cuando el estado de la instancia del bloc de notas cambie a InService, seleccione Abrir JupyterLab.

Paso 2: Crear y cargar scripts de entrenamiento de Dockerfile y Python

  1. Cuando JupyterLab se abra, cree una nueva carpeta en el directorio principal de su JupyterLab. En la esquina superior izquierda, elija el icono de nueva carpeta y, a continuación, escriba el nombre de la carpeta docker_test_folder.

  2. Cree un archivo de texto Dockerfile en el directorio docker_test_folder.

    1. Seleccione el icono del nuevo lanzador (+) en la esquina superior izquierda.

    2. En el panel derecho, en la sección Other (Otro), seleccione Text file (Archivo de texto).

    3. Pegue el siguiente código de ejemplo Dockerfile en el archivo de texto.

      # SageMaker PyTorch image FROM 763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-training:1.5.1-cpu-py36-ubuntu16.04 ENV PATH="/opt/ml/code:${PATH}" # this environment variable is used by the SageMaker PyTorch container to determine our user code directory. ENV SAGEMAKER_SUBMIT_DIRECTORY /opt/ml/code # /opt/ml and all subdirectories are utilized by SageMaker, use the /code subdirectory to store your user code. COPY cifar10.py /opt/ml/code/cifar10.py # Defines cifar10.py as script entrypoint ENV SAGEMAKER_PROGRAM cifar10.py

      El script Dockerfile realiza las siguientes tareas:

      • FROM 763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-training:1.5.1-cpu-py36-ubuntu16.04— Descarga la imagen SageMaker PyTorch base. Puede sustituirla por cualquier imagen SageMaker base que desee utilizar para construir contenedores.

      • ENV SAGEMAKER_SUBMIT_DIRECTORY /opt/ml/code: establece /opt/ml/code como el directorio de scripts de entrenamiento.

      • COPY cifar10.py /opt/ml/code/cifar10.py— Copia el script en la ubicación prevista dentro del contenedor SageMaker. El script debe estar ubicado en esta carpeta.

      • ENV SAGEMAKER_PROGRAM cifar10.py: establece el script de entrenamiento cifar10.py como el script de punto de entrada.

    4. En la navegación del directorio izquierdo, el nombre del archivo de texto se establece automáticamente como untitled.txt. Para cambiar el nombre del archivo, haga clic con el botón derecho en el archivo, seleccione Rename (Cambiar nombre), cámbiele el nombre a Dockerfile sin la extensión .txt y, a continuación, pulse Ctrl+s o Command+s para guardar el archivo.

  3. Cree o cargue un script de entrenamiento cifar10.py en la docker_test_folder. Puede utilizar el siguiente script de ejemplo. para este ejercicio.

    import ast import argparse import logging import os import torch import torch.distributed as dist import torch.nn as nn import torch.nn.parallel import torch.optim import torch.utils.data import torch.utils.data.distributed import torchvision import torchvision.models import torchvision.transforms as transforms import torch.nn.functional as F logger=logging.getLogger(__name__) logger.setLevel(logging.DEBUG) classes=('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck') # https://github.com/pytorch/tutorials/blob/master/beginner_source/blitz/cifar10_tutorial.py#L118 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1=nn.Conv2d(3, 6, 5) self.pool=nn.MaxPool2d(2, 2) self.conv2=nn.Conv2d(6, 16, 5) self.fc1=nn.Linear(16 * 5 * 5, 120) self.fc2=nn.Linear(120, 84) self.fc3=nn.Linear(84, 10) def forward(self, x): x=self.pool(F.relu(self.conv1(x))) x=self.pool(F.relu(self.conv2(x))) x=x.view(-1, 16 * 5 * 5) x=F.relu(self.fc1(x)) x=F.relu(self.fc2(x)) x=self.fc3(x) return x def _train(args): is_distributed=len(args.hosts) > 1 and args.dist_backend is not None logger.debug("Distributed training - {}".format(is_distributed)) if is_distributed: # Initialize the distributed environment. world_size=len(args.hosts) os.environ['WORLD_SIZE']=str(world_size) host_rank=args.hosts.index(args.current_host) dist.init_process_group(backend=args.dist_backend, rank=host_rank, world_size=world_size) logger.info( 'Initialized the distributed environment: \'{}\' backend on {} nodes. '.format( args.dist_backend, dist.get_world_size()) + 'Current host rank is {}. Using cuda: {}. Number of gpus: {}'.format( dist.get_rank(), torch.cuda.is_available(), args.num_gpus)) device='cuda' if torch.cuda.is_available() else 'cpu' logger.info("Device Type: {}".format(device)) logger.info("Loading Cifar10 dataset") transform=transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) trainset=torchvision.datasets.CIFAR10(root=args.data_dir, train=True, download=False, transform=transform) train_loader=torch.utils.data.DataLoader(trainset, batch_size=args.batch_size, shuffle=True, num_workers=args.workers) testset=torchvision.datasets.CIFAR10(root=args.data_dir, train=False, download=False, transform=transform) test_loader=torch.utils.data.DataLoader(testset, batch_size=args.batch_size, shuffle=False, num_workers=args.workers) logger.info("Model loaded") model=Net() if torch.cuda.device_count() > 1: logger.info("Gpu count: {}".format(torch.cuda.device_count())) model=nn.DataParallel(model) model=model.to(device) criterion=nn.CrossEntropyLoss().to(device) optimizer=torch.optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum) for epoch in range(0, args.epochs): running_loss=0.0 for i, data in enumerate(train_loader): # get the inputs inputs, labels=data inputs, labels=inputs.to(device), labels.to(device) # zero the parameter gradients optimizer.zero_grad() # forward + backward + optimize outputs=model(inputs) loss=criterion(outputs, labels) loss.backward() optimizer.step() # print statistics running_loss += loss.item() if i % 2000 == 1999: # print every 2000 mini-batches print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000)) running_loss=0.0 print('Finished Training') return _save_model(model, args.model_dir) def _save_model(model, model_dir): logger.info("Saving the model.") path=os.path.join(model_dir, 'model.pth') # recommended way from http://pytorch.org/docs/master/notes/serialization.html torch.save(model.cpu().state_dict(), path) def model_fn(model_dir): logger.info('model_fn') device="cuda" if torch.cuda.is_available() else "cpu" model=Net() if torch.cuda.device_count() > 1: logger.info("Gpu count: {}".format(torch.cuda.device_count())) model=nn.DataParallel(model) with open(os.path.join(model_dir, 'model.pth'), 'rb') as f: model.load_state_dict(torch.load(f)) return model.to(device) if __name__ == '__main__': parser=argparse.ArgumentParser() parser.add_argument('--workers', type=int, default=2, metavar='W', help='number of data loading workers (default: 2)') parser.add_argument('--epochs', type=int, default=2, metavar='E', help='number of total epochs to run (default: 2)') parser.add_argument('--batch-size', type=int, default=4, metavar='BS', help='batch size (default: 4)') parser.add_argument('--lr', type=float, default=0.001, metavar='LR', help='initial learning rate (default: 0.001)') parser.add_argument('--momentum', type=float, default=0.9, metavar='M', help='momentum (default: 0.9)') parser.add_argument('--dist-backend', type=str, default='gloo', help='distributed backend (default: gloo)') # The parameters below retrieve their default values from SageMaker environment variables, which are # instantiated by the SageMaker containers framework. # https://github.com/aws/sagemaker-containers#how-a-script-is-executed-inside-the-container parser.add_argument('--hosts', type=str, default=ast.literal_eval(os.environ['SM_HOSTS'])) parser.add_argument('--current-host', type=str, default=os.environ['SM_CURRENT_HOST']) parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR']) parser.add_argument('--data-dir', type=str, default=os.environ['SM_CHANNEL_TRAINING']) parser.add_argument('--num-gpus', type=int, default=os.environ['SM_NUM_GPUS']) _train(parser.parse_args())

Paso 3: Compilar el contenedor

  1. En el directorio JupyterLab principal, abre un cuaderno de Jupyter. Para abrir un cuaderno nuevo, seleccionae el icono de nuevo lanzamiento y, a continuación, seleccione conda_pytorch_p39 en la sección Notebook (Cuaderno).

  2. Ejecute el siguiente comando en la primera celda del cuaderno para cambiar al directorio docker_test_folder:

    % cd ~/SageMaker/docker_test_folder

    Esto devuelve su directorio actual como se indica a continuación:

    ! pwd

    output: /home/ec2-user/SageMaker/docker_test_folder

  3. Inicie sesión en Docker para acceder al contenedor base:

    ! aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 763104351884.dkr.ecr.us-east-1.amazonaws.com
  4. Para crear el contenedor de Docker, ejecute el siguiente comando de compilación de Docker, incluyendo el espacio seguido del punto final:

    ! docker build -t pytorch-extended-container-test .

    El comando de compilación de Docker debe ejecutarse desde el directorio creado, en este caso docker_test_folder.

    nota

    Si aparece el siguiente mensaje de error que indica que Docker no puede encontrar el Dockerfile, asegúrese de que el Dockerfile tenga el nombre correcto y se haya guardado en el directorio.

    unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /home/ec2-user/SageMaker/docker/Dockerfile: no such file or directory

    Recuerde que docker busca un archivo llamado específicamente Dockerfile sin ninguna extensión en el directorio actual. Si lo nombró de otra manera, puede pasar el nombre de archivo manualmente con la marca -f. Por ejemplo, si asignó el nombre Dockerfile-text.txt a su Dockerfile, ejecute el siguiente comando:

    ! docker build -t tf-custom-container-test -f Dockerfile-text.txt .

Paso 4: Probar el contenedor

  1. Para probar el contenedor localmente en la instancia de cuaderno, abra un cuaderno de Jupyter. Elija New Launcher (Nuevo lanzador) y seleccione Notebook (Cuaderno) en el marco conda_pytorch_p39. El resto de los fragmentos de código deben ejecutarse desde la instancia del cuaderno de Jupyter.

  2. Descargue el conjunto de datos CIFAR-10.

    import torch import torchvision import torchvision.transforms as transforms def _get_transform(): return transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) def get_train_data_loader(data_dir='/tmp/pytorch/cifar-10-data'): transform=_get_transform() trainset=torchvision.datasets.CIFAR10(root=data_dir, train=True, download=True, transform=transform) return torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2) def get_test_data_loader(data_dir='/tmp/pytorch/cifar-10-data'): transform=_get_transform() testset=torchvision.datasets.CIFAR10(root=data_dir, train=False, download=True, transform=transform) return torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2) trainloader=get_train_data_loader('/tmp/pytorch-example/cifar-10-data') testloader=get_test_data_loader('/tmp/pytorch-example/cifar-10-data')
  3. Defina role en el rol utilizado para crear su cuaderno de Jupyter. Se usa para configurar su SageMaker estimador.

    from sagemaker import get_execution_role role=get_execution_role()
  4. Pegue el siguiente script de ejemplo en la celda de código del cuaderno para configurar un SageMaker estimador utilizando su contenedor extendido.

    from sagemaker.estimator import Estimator hyperparameters={'epochs': 1} estimator=Estimator( image_uri='pytorch-extended-container-test', role=role, instance_count=1, instance_type='local', hyperparameters=hyperparameters ) estimator.fit('file:///tmp/pytorch-example/cifar-10-data')
  5. Ejecute la celda de código. Esta prueba devuelve la configuración del entorno de capacitación, los valores utilizados en las variables de entorno, el origen de los datos y la pérdida y precisión obtenidas durante la capacitación.

Paso 5: Insertar el contenedor en Amazon Elastic Container Registry (Amazon ECR)

  1. Después de ejecutar correctamente la prueba de modo local, puede insertar el contenedor de Docker en Amazon ECR para utilizarlo para ejecutar trabajos de entrenamiento.

    Puede ejecutar manualmente comandos de Git como los siguientes en una celda del cuaderno.

    %%sh # Specify an algorithm name algorithm_name=pytorch-extended-container-test account=$(aws sts get-caller-identity --query Account --output text) # Get the region defined in the current configuration (default to us-west-2 if none defined) region=$(aws configure get region) fullname="${account}.dkr.ecr.${region}.amazonaws.com/${algorithm_name}:latest" # If the repository doesn't exist in ECR, create it. aws ecr describe-repositories --repository-names "${algorithm_name}" > /dev/null 2>&1 if [ $? -ne 0 ] then aws ecr create-repository --repository-name "${algorithm_name}" > /dev/null fi # Log into Docker aws ecr get-login-password --region ${region}|docker login --username AWS --password-stdin ${fullname} # Build the docker image locally with the image name and then push it to ECR # with the full name. docker build -t ${algorithm_name} . docker tag ${algorithm_name} ${fullname} docker push ${fullname}
  2. Después de empujar el contenedor, puede llamar a la imagen de Amazon ECR desde cualquier parte del SageMaker entorno. Ejecute el siguiente ejemplo de código en la siguiente celda del cuaderno.

    Si quieres usar este contenedor de entrenamiento con SageMaker Studio para usar sus funciones de visualización, también puedes ejecutar el siguiente código en una celda de un cuaderno de Studio para llamar a la imagen de Amazon ECR de tu contenedor de entrenamiento.

    import boto3 client=boto3.client('sts') account=client.get_caller_identity()['Account'] my_session=boto3.session.Session() region=my_session.region_name algorithm_name="pytorch-extended-container-test" ecr_image='{}.dkr.ecr.{}.amazonaws.com/{}:latest'.format(account, region, algorithm_name) ecr_image # This should return something like # 12-digits-of-your-account.dkr.ecr.us-east-2.amazonaws.com/tf-2.2-test:latest
  3. Usa lo ecr_image obtenido en el paso anterior para configurar un objeto SageMaker estimador. El siguiente ejemplo de código configura un estimador. SageMaker PyTorch

    import sagemaker from sagemaker import get_execution_role from sagemaker.estimator import Estimator estimator=Estimator( image_uri=ecr_image, role=get_execution_role(), base_job_name='pytorch-extended-container-test', instance_count=1, instance_type='ml.p2.xlarge' ) # start training estimator.fit() # deploy the trained model predictor=estimator.deploy(1, instance_type)

Paso 6: Eliminar recursos

Para eliminar recursos una vez que haya terminado con el ejemplo de inicio
  1. Abra la SageMaker consola, elija la instancia del bloc de notas RunScriptNotebookInstance, elija Acciones y elija Detener. Puede que transcurran unos minutos hasta que la instancia se detenga.

  2. Cuando State (Estado) de la instancia cambie a Stopped (Detenida), elija Actions (Acciones), elija Delete (Eliminar) y, a continuación, elija Delete (Eliminar) en el cuadro de diálogo. Puede que transcurran unos minutos hasta que la instancia se elimine. La instancia del cuaderno desaparece de la tabla cuando se elimina.

  3. Abra la consola de Amazon S3 y elimine el bucket que creó para almacenar los artefactos del modelo y los conjuntos de datos de entrenamiento.

  4. Abra la consola de IAM y elimine el rol de IAM. Si ha creado políticas de permisos, puede eliminarlas también.

    nota

    El contenedor de Docker se cierra automáticamente después de que se haya ejecutado. No es necesario eliminarlo.