

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Perluas Kontainer Pra-dibangun
<a name="prebuilt-containers-extend"></a>

Jika wadah SageMaker AI pra-bangun tidak memenuhi semua kebutuhan Anda, Anda dapat memperluas gambar yang ada untuk mengakomodasi kebutuhan Anda. Bahkan jika ada dukungan langsung untuk lingkungan atau kerangka kerja Anda, Anda mungkin ingin menambahkan fungsionalitas tambahan atau mengonfigurasi lingkungan penampung Anda secara berbeda. Dengan memperluas gambar yang sudah dibuat sebelumnya, Anda dapat memanfaatkan pustaka dan pengaturan pembelajaran mendalam yang disertakan tanpa harus membuat gambar dari awal. Anda dapat memperluas wadah untuk menambahkan pustaka, memodifikasi pengaturan, dan menginstal dependensi tambahan. 

Tutorial berikut menunjukkan cara memperluas SageMaker gambar pra-bangun dan mempublikasikannya ke Amazon ECR.

**Topics**
+ [Persyaratan untuk Memperpanjang Kontainer Pra-Built](#prebuilt-containers-extend-required)
+ [Perluas Kontainer SageMaker AI untuk Menjalankan Skrip Python](#prebuilt-containers-extend-tutorial)

## Persyaratan untuk Memperpanjang Kontainer Pra-Built
<a name="prebuilt-containers-extend-required"></a>

Untuk memperluas SageMaker gambar pra-bangun, Anda perlu mengatur variabel lingkungan berikut dalam Dockerfile Anda. Untuk informasi selengkapnya tentang variabel lingkungan dengan kontainer SageMaker AI, lihat [ GitHub repo SageMaker Training Toolkit](https://github.com/aws/sagemaker-training-toolkit/blob/master/ENVIRONMENT_VARIABLES.md).
+ `SAGEMAKER_SUBMIT_DIRECTORY`: Direktori dalam wadah tempat skrip Python untuk pelatihan berada.
+ `SAGEMAKER_PROGRAM`: Skrip Python yang harus dipanggil dan digunakan sebagai titik masuk untuk pelatihan.

Anda juga dapat menginstal pustaka tambahan dengan memasukkan yang berikut ini di Dockerfile Anda:

```
RUN pip install <library>
```

Tutorial berikut menunjukkan bagaimana menggunakan variabel lingkungan ini.

## Perluas Kontainer SageMaker AI untuk Menjalankan Skrip Python
<a name="prebuilt-containers-extend-tutorial"></a>

Dalam tutorial ini, Anda mempelajari cara memperluas PyTorch wadah SageMaker AI dengan file Python yang menggunakan dataset CIFAR-10. Dengan memperluas PyTorch wadah SageMaker AI, Anda memanfaatkan solusi pelatihan yang ada yang dibuat untuk bekerja dengan SageMaker AI. Tutorial ini memperluas gambar pelatihan, tetapi langkah yang sama dapat diambil untuk memperluas gambar inferensi. Untuk daftar lengkap gambar yang tersedia, lihat Gambar [Deep Learning Containers yang Tersedia](https://github.com/aws/deep-learning-containers/blob/master/available_images.md).

Untuk menjalankan model pelatihan Anda sendiri menggunakan kontainer SageMaker AI, buat wadah Docker melalui instance SageMaker Notebook. 

### Langkah 1: Buat Instance SageMaker Notebook
<a name="extend-step1"></a>

1. Buka [konsol SageMaker AI](https://console.aws.amazon.com/sagemaker/). 

1. Di panel navigasi kiri, pilih **Notebook**, pilih **instance Notebook**, lalu pilih **Buat instance notebook**. 

1. Pada halaman **Create notebook instance**, berikan informasi berikut: 

   1. Untuk **nama instance Notebook**, masukkan**RunScriptNotebookInstance**.

   1. Untuk **jenis Instance Notebook**, pilih**ml.t2.medium**.

   1. Di bagian **Izin dan enkripsi**, lakukan hal berikut:

      1. Untuk **Peran IAM**, pilih **Buat Peran Baru**.

      1. **Pada halaman **Buat peran IAM**, pilih bucket **S3 Spesifik, tentukan bucket** Amazon S3 bernama**sagemaker-run-script**, lalu pilih Buat peran.**

         SageMaker AI menciptakan peran IAM bernama`AmazonSageMaker-ExecutionRole-YYYYMMDDTHHmmSS`, seperti`AmazonSageMaker-ExecutionRole-20190429T110788`. Perhatikan bahwa konvensi penamaan peran eksekusi menggunakan tanggal dan waktu saat peran dibuat, dipisahkan oleh a`T`.

   1. Untuk **Akses Root**, pilih **Aktifkan**.

   1. Pilih **Buat instans notebook**. 

1. Pada halaman **Instance Notebook**, **Status** **Tertunda**. Amazon SageMaker AI dapat memakan waktu beberapa menit untuk meluncurkan instance komputasi pembelajaran mesin—dalam hal ini, ia meluncurkan instance notebook—dan melampirkan volume penyimpanan ML ke dalamnya. Instance notebook memiliki server notebook Jupyter yang telah dikonfigurasi sebelumnya dan satu set pustaka Anaconda. Untuk informasi lebih lanjut, lihat [ CreateNotebookInstance](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateNotebookInstance.html). 

   

1. Di bagian **Izin dan enkripsi**, salin **nomor ARN peran IAM**, dan tempel ke file notepad untuk menyimpannya sementara. Anda menggunakan nomor ARN peran IAM ini nanti untuk mengonfigurasi estimator pelatihan lokal di instance notebook. Nomor **ARN peran IAM** terlihat seperti berikut: `'arn:aws:iam::111122223333:role/service-role/AmazonSageMaker-ExecutionRole-20190429T110788'` 

1. Setelah status instance notebook berubah menjadi **InService**, pilih **Buka JupyterLab**.

### Langkah 2: Buat dan Unggah Skrip Pelatihan Dockerfile dan Python
<a name="extend-step2"></a>

1. Setelah JupyterLab terbuka, buat folder baru di direktori home Anda JupyterLab. Di sudut kiri atas, pilih ikon **Folder Baru**, lalu masukkan nama folder. `docker_test_folder` 

1.  Buat file `Dockerfile` teks di `docker_test_folder` direktori. 

   1. Pilih ikon **Peluncur Baru** (\$1) di sudut kiri atas. 

   1. Di panel kanan di bawah bagian **Lainnya**, pilih **File Teks**.

   1.  Tempelkan kode `Dockerfile` contoh berikut ke dalam file teks Anda. 

      ```
      # 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
      ```

      Skrip Dockerfile melakukan tugas-tugas berikut:
      + `FROM 763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-training:1.5.1-cpu-py36-ubuntu16.04`— Mengunduh gambar PyTorch dasar SageMaker AI. Anda dapat menggantinya dengan gambar dasar SageMaker AI apa pun yang ingin Anda bawa untuk membangun wadah.
      + `ENV SAGEMAKER_SUBMIT_DIRECTORY /opt/ml/code`— Set `/opt/ml/code` sebagai direktori skrip pelatihan.
      + `COPY cifar10.py /opt/ml/code/cifar10.py`— Menyalin skrip ke lokasi di dalam wadah yang diharapkan oleh SageMaker AI. Skrip harus berada di folder ini.
      + `ENV SAGEMAKER_PROGRAM cifar10.py`— Menetapkan skrip `cifar10.py` pelatihan Anda sebagai skrip entrypoint.

   1.  Di panel navigasi direktori kiri, nama file teks mungkin secara otomatis diberi `untitled.txt` nama. Untuk mengganti nama file, klik kanan file, pilih **Ganti nama**, ganti nama file `Dockerfile` tanpa `.txt` ekstensi, lalu tekan `Ctrl+s` atau `Command+s` untuk menyimpan file.

1. Buat atau unggah skrip pelatihan `cifar10.py` di`docker_test_folder`. Anda dapat menggunakan contoh skrip berikut untuk latihan ini. 

   ```
   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())
   ```

### Langkah 3: Bangun Kontainer
<a name="extend-step3"></a>

1. Di direktori JupyterLab home, buka notebook Jupyter. **Untuk membuka buku catatan baru, pilih ikon **New Launch** dan kemudian pilih **conda\$1pytorch\$1p39** di bagian Notebook.** 

1. Jalankan perintah berikut di sel notebook pertama untuk mengubah ke `docker_test_folder` direktori:

   ```
   % cd ~/SageMaker/docker_test_folder
   ```

   Ini mengembalikan direktori Anda saat ini sebagai berikut:

   ```
   ! pwd
   ```

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

1. Masuk ke Docker untuk mengakses wadah dasar:

   ```
   ! aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 763104351884.dkr.ecr.us-east-1.amazonaws.com
   ```

1. Untuk membangun kontainer Docker, jalankan perintah build Docker berikut, termasuk spasi yang diikuti oleh titik di akhir:

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

   Perintah Docker build harus dijalankan dari direktori Docker yang Anda buat, dalam hal ini. `docker_test_folder`
**catatan**  
Jika Anda mendapatkan pesan kesalahan berikut bahwa Docker tidak dapat menemukan Dockerfile, pastikan Dockerfile memiliki nama yang benar dan telah disimpan ke direktori.  

   ```
   unable to prepare context: unable to evaluate symlinks in Dockerfile path: 
   lstat /home/ec2-user/SageMaker/docker/Dockerfile: no such file or directory
   ```
Ingatlah bahwa `docker` mencari file yang secara khusus dipanggil `Dockerfile` tanpa ekstensi apa pun dalam direktori saat ini. Jika Anda menamakannya sesuatu yang lain, Anda dapat meneruskan nama file secara manual dengan `-f` bendera. Misalnya, jika Anda menamai Dockerfile Anda`Dockerfile-text.txt`, jalankan perintah berikut:  

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

### Langkah 4: Uji Wadah
<a name="extend-step4"></a>

1. Untuk menguji kontainer secara lokal di instance notebook, buka notebook Jupyter. Pilih **Peluncur Baru** dan pilih **Notebook** dalam **`conda_pytorch_p39`**kerangka kerja. Sisa cuplikan kode harus dijalankan dari instance notebook Jupyter.

1. Unduh dataset 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')
   ```

1. Setel `role` ke peran yang digunakan untuk membuat notebook Jupyter Anda. Ini digunakan untuk mengonfigurasi SageMaker AI Estimator Anda.

   ```
   from sagemaker import get_execution_role
   
   role=get_execution_role()
   ```

1. Tempelkan contoh skrip berikut ke sel kode notebook untuk mengonfigurasi SageMaker AI Estimator menggunakan penampung yang diperluas.

   ```
   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')
   ```

1. Jalankan sel kode. Tes ini menghasilkan konfigurasi lingkungan pelatihan, nilai yang digunakan untuk variabel lingkungan, sumber data, dan kehilangan dan akurasi yang diperoleh selama pelatihan.

### Langkah 5: Dorong Wadah ke Amazon Elastic Container Registry (Amazon ECR)
<a name="extend-step5"></a>

1. Setelah berhasil menjalankan pengujian mode lokal, Anda dapat mendorong wadah Docker ke [Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) dan menggunakannya untuk menjalankan pekerjaan pelatihan. 

   Jalankan baris perintah berikut di sel notebook.

   ```
   %%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}
   ```

1. Setelah Anda mendorong wadah, Anda dapat memanggil gambar Amazon ECR dari mana saja di lingkungan SageMaker AI. Jalankan contoh kode berikut di sel notebook berikutnya. 

   Jika Anda ingin menggunakan wadah pelatihan ini dengan SageMaker Studio untuk menggunakan fitur visualisasinya, Anda juga dapat menjalankan kode berikut di sel notebook Studio untuk memanggil gambar Amazon ECR dari wadah pelatihan Anda.

   ```
   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
   ```

1. Gunakan yang `ecr_image` diambil dari langkah sebelumnya untuk mengonfigurasi objek penaksir SageMaker AI. Contoh kode berikut mengonfigurasi PyTorch estimator SageMaker AI.

   ```
   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)
   ```

### Langkah 6: Bersihkan Sumber Daya
<a name="extend-step6"></a>

**Untuk membersihkan sumber daya saat selesai dengan contoh Memulai**

1. Buka [konsol SageMaker AI](https://console.aws.amazon.com/sagemaker/), pilih instance notebook **RunScriptNotebookInstance**, pilih **Actions**, dan pilih **Stop**. Hal ini dapat memerlukan waktu beberapa menit sampai instans berhenti. 

1. Setelah **Status** instance berubah menjadi **Berhenti**, pilih **Tindakan**, pilih **Hapus**, lalu pilih **Hapus** di kotak dialog. Diperlukan waktu beberapa menit untuk menghapus instance. Instance notebook menghilang dari tabel ketika telah dihapus. 

1. Buka [konsol Amazon S3](https://console.aws.amazon.com/s3/) dan hapus bucket yang Anda buat untuk menyimpan artefak model dan kumpulan data pelatihan. 

1. Buka [konsol IAM](https://console.aws.amazon.com/iam/) dan hapus peran IAM. Jika Anda membuat kebijakan izin, Anda juga dapat menghapusnya. 
**catatan**  
 Kontainer Docker dimatikan secara otomatis setelah dijalankan. Anda tidak perlu menghapusnya.