

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 자습서
<a name="tutorials"></a>

다음은 Conda를 사용하는 DLAMI 소프트웨어 사용 방법에 대한 자습서입니다.

**Topics**
+ [

# 프레임워크 활성화
](activating.md)
+ [

# Elastic Fabric Adapter를 사용한 분산 훈련
](tutorial-efa.md)
+ [

# GPU 모니터링 및 최적화
](tutorial-gpu.md)
+ [

# DLAMI를 사용하는 AWS Inferentia 칩
](tutorial-inferentia.md)
+ [

# ARM64 DLAMI
](tutorial-arm64.md)
+ [

# Inference
](tutorial-inference.md)
+ [

# 모델 제공
](model-serving.md)

# 프레임워크 활성화
<a name="activating"></a>

다음은 Conda를 사용하는 DLAMI에 설치된 딥 러닝 프레임워크입니다. 프레임워크를 클릭하면 활성화하는 방법을 자세히 알아볼 수 있습니다.

**Topics**
+ [

# PyTorch
](tutorial-pytorch.md)
+ [

# TensorFlow 2
](tutorial-tensorflow-2.md)

# PyTorch
<a name="tutorial-pytorch"></a>

## PyTorch 활성화
<a name="tutorial-pytorch-overview"></a>

프레임워크의 안정적인 Conda 패키지가 출시되면 테스트 후 DLAMI에 사전 설치됩니다. 테스트되지 않은 최신 야간 구축을 실행하려는 경우 수동으로 [PyTorch의 야간 구축 설치(실험)](#tutorial-pytorch-install)를 수행할 수 있습니다.

현재 설치된 프레임워크를 활성화하려면 Conda를 사용하는 DLAMI에서 다음 지침을 따릅니다.

CUDA 및 MKL-DNN이 있는 Python 3의 PyTorch인 경우 다음 명령을 실행하세요.

```
$ source activate pytorch_p310
```

iPython 터미널을 시작합니다.

```
(pytorch_p310)$ ipython
```

빠른 PyTorch 프로그램을 실행합니다.

```
import torch
x = torch.rand(5, 3)
print(x)
print(x.size())
y = torch.rand(5, 3)
print(torch.add(x, y))
```

출력된 최초 임의 어레이와 그 키기, 그리고 또 다른 임의 어레이가 추가된 것을 볼 수 있습니다.

## PyTorch의 야간 구축 설치(실험)
<a name="tutorial-pytorch-install"></a>

**야간 구축에서 PyTorch를 설치하는 방법**

Conda를 사용하는 DLAMI의 두 가지 PyTorch Conda 환경 중 하나 또는 모두에 최신 PyTorch 빌드를 설치할 수 있습니다.

1. 
   + (Python 3에 대한 옵션) - Python 3 PyTorch 환경을 활성화합니다.

     ```
     $ source activate pytorch_p310
     ```

1. 나머지 단계에서는 `pytorch_p310` 환경을 사용하고 있다고 가정합니다. 현재 설치된 PyTorch를 제거합니다.

   ```
   (pytorch_p310)$ pip uninstall torch
   ```

1. 
   + (GPU 인스턴스에 대한 옵션) - CUDA.0이 포함된 PyTorch의 최신 야간 빌드를 설치합니다.

     ```
     (pytorch_p310)$ pip install torch_nightly -f https://download.pytorch.org/whl/nightly/cu100/torch_nightly.html
     ```
   + (CPU 인스턴스에 대한 옵션) - GPU가 없는 인스턴스에 대한 PyTorch의 최신 야간 구축을 설치합니다.

     ```
     (pytorch_p310)$ pip install torch_nightly -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
     ```

1. 최신 야간 구축을 성공적으로 설치했는지 확인하려면 IPython 터미널을 시작하고 PyTorch의 버전을 점검합니다.

   ```
   (pytorch_p310)$ ipython
   ```

   ```
   import torch
   print (torch.__version__)
   ```

   출력은 `1.0.0.dev20180922`와 비슷하게 인쇄됩니다.

1. PyTorch 야간 구축이 MNIST 예제에 효과적으로 작동하는지 확인하려면 PyTorch의 예제 리포지토리에서 테스트 스크립트를 실행할 수 있습니다.

   ```
   (pytorch_p310)$ cd ~
   (pytorch_p310)$ git clone https://github.com/pytorch/examples.git pytorch_examples
   (pytorch_p310)$ cd pytorch_examples/mnist
   (pytorch_p310)$ python main.py || exit 1
   ```

## 추가 자습서
<a name="tutorial-pytorch-more"></a>

추가 자습서와 예제는 프레임워크의 공식 설명서, [PyTorch 설명서](http://pytorch.org/docs/master/), 그리고 [PyTorch](http://pytorch.org) 웹 사이트를 참조하세요.

# TensorFlow 2
<a name="tutorial-tensorflow-2"></a>

이 자습서는 Conda를 사용하는 DLAMI를 실행 중인 인스턴스에서 TensorFlow 2를 활성화하고 TensorFlow 2 프로그램을 실행하는 방법을 보여줍니다.

프레임워크의 안정적인 Conda 패키지가 출시되면 테스트 후 DLAMI에 사전 설치됩니다.

## TensorFlow 2 활성화
<a name="tutorial-tensorflow-2-overview"></a>

**Conda를 사용하는 DLAMI 에서 TensorFlow 실행**

1. TensorFlow 2를 활성화하려면 Conda를 사용하는 DLAMI의 Amazon Elastic Compute Cloud (Amazon EC2) 인스턴스를 엽니다.

1. CUDA 10.1 및 MKL-DNN이 있는 Python 3의 TensorFlow 2 및 Keras 2의 경우 다음 명령을 실행하세요.

   ```
   $ source activate tensorflow2_p310
   ```

1. iPython 터미널을 시작합니다:

   ```
   (tensorflow2_p310)$ ipython
   ```

1. TensorFlow 2 프로그램을 실행하여 제대로 작동하는지 확인합니다.

   ```
   import tensorflow as tf
   hello = tf.constant('Hello, TensorFlow!')
   tf.print(hello)
   ```

   화면에 `Hello, TensorFlow!`가 표시되어야 합니다.

## 추가 자습서
<a name="tutorial-tensorflow-2-more"></a>

더 많은 자습서와 예제는 [TensorFlow Python API](https://www.tensorflow.org/api_docs/python/)에 대한 TensorFlow 설명서 또는 [TensorFlow](https://www.tensorflow.org) 웹 사이트를 참조하세요.

# Elastic Fabric Adapter를 사용한 분산 훈련
<a name="tutorial-efa"></a>

[Elastic Fabric Adapter](https://aws.amazon.com/hpc/efa/)(EFA)는 DLAMI 인스턴스에 연결하여 고성능 컴퓨팅(HPC) 및 기계 학습 애플리케이션의 속도를 높일 수 있는 네트워크 디바이스입니다. EFA를 사용하면 AWS 클라우드에서 제공하는 확장성, 유연성 및 탄력성을 통해 온프레미스 HPC 클러스터의 애플리케이션 성능을 달성할 수 있습니다.

다음 섹션에서는 DLAMI에서 EFA 사용을 시작하는 방법을 보여 줍니다.

**참고**  
이 [기본 GPU DLAMI 목록](appendix-ami-release-notes.md#appendix-ami-release-notes-base)에서 원하는 DLAMI를 선택하세요.

**Topics**
+ [

# EFA를 사용하여 AWS Deep Learning AMIs 인스턴스 시작
](tutorial-efa-launching.md)
+ [

# DLAMI에서 EFA 사용
](tutorial-efa-using.md)

# EFA를 사용하여 AWS Deep Learning AMIs 인스턴스 시작
<a name="tutorial-efa-launching"></a>

최신 버전 Base DLAMI는 EFA와 사용 가능하며, 필수 드라이버, 커널 모듈, libfabric, openmpi 및 GPU 인스턴스용 [NCCL OFI 플러그인](https://github.com/aws/aws-ofi-nccl/tree/aws)이 함께 제공됩니다.

지원되는 Base DLAMI CUDA 버전은 [릴리스 노트](appendix-ami-release-notes.md#appendix-ami-release-notes-base)에서 확인할 수 있습니다.

참고:
+ EFA에서 `mpirun`을 사용하여 NCCL 애플리케이션을 실행할 때 EFA 지원 설치의 전체 경로를 다음과 같이 지정해야 합니다.

  ```
  /opt/amazon/openmpi/bin/mpirun <command>  
  ```
+ 애플리케이션에서 EFA를 사용할 수 있도록 하려면 [DLAMI에서 EFA 사용](tutorial-efa-using.md)에서와 같이 `mpirun` 명령에 `FI_PROVIDER="efa"`를 추가합니다.

**Topics**
+ [

## EFA 보안 그룹 준비
](#tutorial-efa-security-group)
+ [

## 인스턴스 시작
](#tutorial-efa-launch)
+ [

## EFA 연결 확인
](#tutorial-efa-verify-attachment)

## EFA 보안 그룹 준비
<a name="tutorial-efa-security-group"></a>

EFA에는 보안 그룹 자체 내의 모든 인바운드 및 아웃바운드 트래픽을 허용하는 보안 그룹이 필요합니다. 자세한 내용은 [EFA 설명서](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-security)를 참조하세요.

1. [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)에서 Amazon EC2 콘솔을 엽니다.

1. 탐색 창에서 **보안 그룹**을 선택한 다음, **보안 그룹 생성**을 선택합니다.

1. **보안 그룹 생성** 창에서 다음을 수행하세요.
   + **보안 그룹 이름**의 경우 `EFA-enabled security group`과 같은 보안 그룹의 고유한 이름을 입력합니다.
   + (선택 사항) **설명**에 보안 그룹에 대한 간략한 설명을 입력합니다.
   + **VPC**에서는 EFA 사용 인스턴스를 시작하려는 VPC를 선택합니다.
   + **생성(Create)**을 선택합니다.

1. 생성한 보안 그룹을 선택하고 **설명** 탭에서 **그룹 ID**를 복사합니다.

1. **인바운드** 및 **아웃바운드** 탭에서 다음을 수행합니다.
   + **편집**을 선택합니다.
   + **유형(Type)**에서 **모든 트래픽(All traffic)**을 선택합니다.
   + **소스(Source)**에서 **사용자 지정(Custom)**을 선택합니다.
   + 복사한 보안 그룹 ID를 필드에 붙여넣습니다.
   + **저장**을 선택합니다.

1. [Linux 인스턴스에 대한 인바운드 트래픽 권한 부여](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html)를 참조하여 인바운드 트래픽을 활성화합니다. 이 단계를 건너뛰면 DLAMI 인스턴스와 통신할 수 없습니다.

## 인스턴스 시작
<a name="tutorial-efa-launch"></a>

의 EFA AWS Deep Learning AMIs 는 현재 다음 인스턴스 유형 및 운영 체제에서 지원됩니다.
+  P3dn: Amazon Linux 2, Ubuntu 20.04
+  P4d, P4de: Amazon Linux 2, Amazon Linux 2023, Ubuntu 20.04, Ubuntu 22.04
+  P5, P5e, P5en: Amazon Linux 2, Amazon Linux 2023, Ubuntu 20.04, Ubuntu 22.04

다음 섹션에서는 EFA 활성화 DLAMI 인스턴스를 시작하는 방법을 설명합니다. EFA 활성화 인스턴스 실행에 대한 자세한 내용은 [클러스터 배치 그룹으로 EFA 활성화 인스턴스 실행](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-instances)을 참조하세요.

1. [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)에서 Amazon EC2 콘솔을 엽니다.

1. **인스턴스 시작**을 선택합니다.

1. **AMI 선택** 페이지에서 [DLAMI 릴리스 노트 페이지](https://docs.aws.amazon.com/dlami/latest/devguide/appendix-ami-release-notes)에 있는 지원되는 DLAMI를 선택합니다.

1. **인스턴스 유형 선택** 페이지에서 다음과 같이 지원되는 인스턴스 유형 중 하나를 선택하고 **다음: 인스턴스 세부 정보 구성**을 선택합니다. 지원되는 인스턴스 목록은 [EFA 및 MPI 시작](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html) 링크를 참조하세요.

1. [**Configure Instance Details**] 페이지에서 다음을 수행합니다.
   + **인스턴스 수**에 시작할 EFA를 사용한 인스턴스 수를 입력합니다.
   + **네트워크** 및 **서브넷**에서 인스턴스를 시작할 VPC와 서브넷을 선택합니다.
   + [선택 사항] **배치 그룹**에서 **배치 그룹에 인스턴스 추가**를 선택합니다. 최상의 성능을 위해 배치 그룹 내에서 인스턴스를 시작합니다.
   + [선택 사항] **배치 그룹 이름**에서 **새 배치 그룹 추가**를 선택하고 배치 그룹을 설명하는 이름을 입력한 뒤 **배치 그룹 전략**에서 **클러스터**를 선택합니다.
   + 이 페이지에서 **“Elastic Fabric Adapter”**를 활성화해야 합니다. 이 옵션이 비활성화된 경우 선택한 인스턴스 유형을 지원하는 서브넷으로 서브넷을 변경합니다.
   + **네트워크 인터페이스** 항목의 디바이스 **eth0**에서 **새 네트워크 인터페이스**를 선택합니다. 하나의 기본 IPv4 주소와 하나 이상의 보조 IPv4 주소를 입력할 수도 있습니다. 연결된 IPv6 CIDR 블록이 있는 서브넷에서 인스턴스를 시작하는 경우 기본 IPv6 주소 및 하나 이상의 보조 IPv6 주소를 입력할 수도 있습니다.
   + **다음: 스토리지 추가**를 선택합니다.

1. **스토리지 추가** 페이지에서 인스턴스를 연결할 볼륨과 AMI로 지정한 볼륨(루트 디바이스 볼륨 등)을 지정하고 **다음: 태그 추가**를 선택합니다.

1. **태그 추가** 페이지에서 사용자에게 친숙한 이름 등의 인스턴스 태그를 지정한 후 **다음: 보안 그룹 구성(Next: Configure Security Group)**을 선택합니다.

1. **보안 그룹 구성** 페이지의 **보안 그룹 할당**에서 **기존 보안 그룹 선택**을 선택하고 이전에 생성한 보안 그룹을 선택합니다**.**

1. [**검토 및 시작(Review and Launch)**]를 선택합니다.

1. **인스턴스 시작 검토** 페이지에서 설정을 검토한 후 **시작**을 선택하여 키 페어를 선택하고 인스턴스를 시작합니다.

## EFA 연결 확인
<a name="tutorial-efa-verify-attachment"></a>

### 콘솔에서
<a name="tutorial-efa-verify-attachment-console"></a>

인스턴스를 시작한 후 AWS 콘솔에서 인스턴스 세부 정보를 확인합니다. 이렇게 하려면 EC2 콘솔에서 인스턴스를 선택하고 페이지의 아래쪽 창에 있는 설명 탭을 확인합니다. ‘Network Interfaces: eth0’ 매개 변수를 찾아 eth0을 클릭하면 팝업이 열립니다. 'Elastic Fabric Adapter'가 활성화되어 있는지 확인합니다.

EFA가 활성화되지 않은 경우 다음 중 하나를 사용하여 이 문제를 해결할 수 있습니다.
+ EC2 인스턴스를 종료하고 동일한 단계로 새 인스턴스를 시작합니다. EFA가 연결되어 있는지 확인합니다.
+ 기존 인스턴스에 EFA를 연결합니다.

  1. EC2 콘솔에서 네트워크 인터페이스로 이동합니다.

  1. Create a Network Interface(네트워크 인터페이스 생성)를 클릭합니다.

  1. 인스턴스가 있는 서브넷과 동일한 서브넷을 선택합니다.

  1. ‘Elastic Fabric Adapter’를 활성화하고 생성을 클릭합니다.

  1. EC2 인스턴스 탭으로 돌아가서 인스턴스를 선택합니다.

  1. 작업: 인스턴스 상태로 이동하여 EFA를 연결하기 전에 인스턴스를 중지합니다.

  1. 작업에서 네트워킹: Networking: Attach Network Interface(네트워크 인터페이스 연결)를 선택합니다.

  1. 방금 생성한 인터페이스를 선택하고 연결을 클릭합니다.

  1. 인스턴스를 재시작합니다.

### 인스턴스에서
<a name="tutorial-efa-verify-attachment-instance"></a>

다음 테스트 스크립트가 DLAMI에 이미 표시됩니다. 이를 실행하여 커널 모듈이 올바르게 로드되었는지 확인합니다.

```
$ fi_info -p efa
```

출력은 다음과 비슷한 형태가 됩니다.

```
provider: efa
    fabric: EFA-fe80::e5:56ff:fe34:56a8
    domain: efa_0-rdm
    version: 2.0
    type: FI_EP_RDM
    protocol: FI_PROTO_EFA
provider: efa
    fabric: EFA-fe80::e5:56ff:fe34:56a8
    domain: efa_0-dgrm
    version: 2.0
    type: FI_EP_DGRAM
    protocol: FI_PROTO_EFA
provider: efa;ofi_rxd
    fabric: EFA-fe80::e5:56ff:fe34:56a8
    domain: efa_0-dgrm
    version: 1.0
    type: FI_EP_RDM
    protocol: FI_PROTO_RXD
```

### 보안 그룹 구성 확인
<a name="tutorial-efa-verify-attachment-security"></a>

다음 테스트 스크립트가 DLAMI에 이미 표시됩니다. 이를 실행하여 생성한 보안 그룹이 올바르게 구성되었는지 확인합니다.

```
$ cd /opt/amazon/efa/test/ 
$ ./efa_test.sh
```

출력은 다음과 비슷한 형태가 됩니다.

```
Starting server...
Starting client...
bytes   #sent   #ack     total       time     MB/sec    usec/xfer   Mxfers/sec
64      10      =10      1.2k        0.02s      0.06    1123.55       0.00
256     10      =10      5k          0.00s     17.66      14.50       0.07
1k      10      =10      20k         0.00s     67.81      15.10       0.07
4k      10      =10      80k         0.00s    237.45      17.25       0.06
64k     10      =10      1.2m        0.00s    921.10      71.15       0.01
1m      10      =10      20m         0.01s   2122.41     494.05       0.00
```

응답이 중단되거나 작업이 완료되지 않으면 보안 그룹에 올바른 인바운드/아웃바운드 규칙이 있는지 확인합니다.

# DLAMI에서 EFA 사용
<a name="tutorial-efa-using"></a>

다음 섹션에서는 EFA를 사용하여 AWS Deep Learning AMIs에서 다중 노드 애플리케이션을 실행하는 방법에 대해 설명합니다.

## EFA를 사용하여 다중 노드 애플리케이션 실행
<a name="tutorial-efa-using-multi-node"></a>

노드 클러스터에서 애플리케이션을 실행하려면 다음 구성이 필요합니다.

**Topics**
+ [

### 암호 없는 SSH 사용
](#tutorial-efa-using-multi-node-ssh)
+ [

### 호스트 파일 생성
](#tutorial-efa-using-multi-node-hosts)
+ [

### NCCL 테스트
](#tutorial-efa-using-2node)

### 암호 없는 SSH 사용
<a name="tutorial-efa-using-multi-node-ssh"></a>

클러스터의 노드 하나를 리더 노드로 선택합니다. 나머지 노드들을 멤버 노드라고 합니다.

1. 리더 노드에서 RSA 키 페어를 생성합니다.

   ```
   ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
   ```

1. 리더 노드에서 프라이빗 키의 사용 권한을 변경합니다.

   ```
   chmod 600 ~/.ssh/id_rsa
   ```

1. 퍼블릭 키를 `~/.ssh/id_rsa.pub`에 복사하고 클러스터 멤버 노드의 `~/.ssh/authorized_keys`에 추가합니다.

1. 이제 프라이빗 IP를 사용하여 리더 노드에서 멤버 노드에 직접 로그인 할 수 있습니다.

   ```
   ssh <member private ip>
   ```

1. 리더 노드에서 \$1 /.ssh/config 파일을 추가하여 strictHostKeyChecking을 비활성화하고 리더 노드에서 에이전트 전달을 활성화합니다.

   ```
   Host *
       ForwardAgent yes
   Host *
       StrictHostKeyChecking no
   ```

1. Amazon Linux 2 인스턴스의 리더 노드에서 다음 명령을 실행하여 구성 파일에 올바른 권한을 제공합니다.

   ```
   chmod 600 ~/.ssh/config
   ```

### 호스트 파일 생성
<a name="tutorial-efa-using-multi-node-hosts"></a>

리더 노드에서 클러스터의 노드를 식별하기 위한 호스트 파일을 생성합니다. 호스트 파일에는 클러스터의 각 노드에 대한 항목이 있어야 합니다. 파일 \$1/hosts를 생성하고 다음과 같이 프라이빗 IP를 사용하여 각 노드를 추가합니다.

```
localhost slots=8
<private ip of node 1> slots=8
<private ip of node 2> slots=8
```

### NCCL 테스트
<a name="tutorial-efa-using-2node"></a>

**참고**  
이러한 테스트는 EFA 버전 1.38.0 및 OFI NCCL 플러그인 1.13.2를 사용하여 실행되었습니다.

 다음은 여러 컴퓨팅 노드의 기능과 성능을 모두 테스트하도록 Nvidia에서 제공하는 NCCL 테스트의 하위 집합입니다.

 **지원되는 인스턴스: P3dn, P4, P5, P5e, P5en** 

#### 성능 테스트
<a name="tutorial-efa-using-multinode"></a>

##### P4d.24xlarge에 대한 다중 노드 NCCL 성능 테스트
<a name="tutorial-efa-using-multi-node-performance"></a>

EFA에서 NCCL 성능을 확인하려면 공식 [NCCL-Tests Repo](https://github.com/NVIDIA/nccl-tests.git)에서 사용할 수 있는 표준 NCCL 성능 테스트를 실행합니다. DLAMI는 CUDA XX.X용으로 이미 구축된 이 테스트와 함께 제공됩니다. 마찬가지로 EFA를 사용하여 자체 스크립트를 실행할 수 있습니다.

자체 스크립트를 작성할 때 다음 지침을 참조하세요.
+ EFA에서 NCCL 애플리케이션을 실행하는 동안 예제에서와 같이 mpirun으로의 전체 경로를 사용합니다.
+ 클러스터의 인스턴스 및 GPU 개수에 따라 매개 변수 np와 N을 변경합니다.
+ NCCL\$1DEBUG=INFO 플래그를 추가하고 로그에 EFA 사용법이 "Selected Provider is "EFA로 표시되어 있는지 확인합니다.
+  검증을 위해 구문 분석할 훈련 로그 위치 설정 

  ```
  TRAINING_LOG="testEFA_$(date +"%N").log"
  ```

멤버 노드에서 명령 `watch nvidia-smi`을 사용하여 GPU 사용을 모니터링합니다. 다음 `watch nvidia-smi` 명령은 일반 CUDA xx.x 버전에서만 사용할 수 있으며 인스턴스의 운영 체제에 따라 달라질 수 있습니다. 스크립트에서 CUDA 버전을 교체하여 Amazon EC2 인스턴스에서 사용 가능한 모든 CUDA 버전에 대해 명령을 실행할 수 있습니다.
+ Amazon Linux 2, Amazon Linux 2023:

  ```
   $ /opt/amazon/openmpi/bin/mpirun -n 16 -N 8 \
  -x NCCL_DEBUG=INFO --mca pml ^cm \
  -x LD_LIBRARY_PATH=/usr/local/cuda-xx.x/efa/lib:/usr/local/cuda-xx.x/lib:/usr/local/cuda-xx.x/lib64:/usr/local/cuda-xx.x:/opt/amazon/efa/lib64:/opt/amazon/openmpi/lib64:$LD_LIBRARY_PATH \
  --hostfile hosts --mca btl tcp,self --mca btl_tcp_if_exclude lo,docker0 --bind-to none \
  /usr/local/cuda-xx.x/efa/test-cuda-xx.x/all_reduce_perf -b 8 -e 1G -f 2 -g 1 -c 1 -n 100 | tee ${TRAINING_LOG}
  ```
+ Ubuntu 20.04, Ubuntu 20.04:

  ```
  $ /opt/amazon/openmpi/bin/mpirun -n 16 -N 8 \
  -x NCCL_DEBUG=INFO --mca pml ^cm \
  -x LD_LIBRARY_PATH=/usr/local/cuda-xx.x/efa/lib:/usr/local/cuda-xx.x/lib:/usr/local/cuda-xx.x/lib64:/usr/local/cuda-xx.x:/opt/amazon/efa/lib:/opt/amazon/openmpi/lib:$LD_LIBRARY_PATH \
  --hostfile hosts --mca btl tcp,self --mca btl_tcp_if_exclude lo,docker0 --bind-to none \
  /usr/local/cuda-xx.x/efa/test-cuda-xx.x/all_reduce_perf -b 8 -e 1G -f 2 -g 1 -c 1 -n 100 | tee ${TRAINING_LOG}
  ```

출력은 다음과 같아야 합니다.

```
# nThread 1 nGpus 1 minBytes 8 maxBytes 1073741824 step: 2(factor) warmup iters: 5 iters: 100 agg iters: 1 validation: 1 graph: 0
#
# Using devices
#  Rank  0 Group  0 Pid  33378 on ip-172-31-42-25 device  0 [0x10] NVIDIA A100-SXM4-40GB
#  Rank  1 Group  0 Pid  33379 on ip-172-31-42-25 device  1 [0x10] NVIDIA A100-SXM4-40GB
#  Rank  2 Group  0 Pid  33380 on ip-172-31-42-25 device  2 [0x20] NVIDIA A100-SXM4-40GB
#  Rank  3 Group  0 Pid  33381 on ip-172-31-42-25 device  3 [0x20] NVIDIA A100-SXM4-40GB
#  Rank  4 Group  0 Pid  33382 on ip-172-31-42-25 device  4 [0x90] NVIDIA A100-SXM4-40GB
#  Rank  5 Group  0 Pid  33383 on ip-172-31-42-25 device  5 [0x90] NVIDIA A100-SXM4-40GB
#  Rank  6 Group  0 Pid  33384 on ip-172-31-42-25 device  6 [0xa0] NVIDIA A100-SXM4-40GB
#  Rank  7 Group  0 Pid  33385 on ip-172-31-42-25 device  7 [0xa0] NVIDIA A100-SXM4-40GB
#  Rank  8 Group  0 Pid  30378 on ip-172-31-43-8 device  0 [0x10] NVIDIA A100-SXM4-40GB
#  Rank  9 Group  0 Pid  30379 on ip-172-31-43-8 device  1 [0x10] NVIDIA A100-SXM4-40GB
#  Rank 10 Group  0 Pid  30380 on ip-172-31-43-8 device  2 [0x20] NVIDIA A100-SXM4-40GB
#  Rank 11 Group  0 Pid  30381 on ip-172-31-43-8 device  3 [0x20] NVIDIA A100-SXM4-40GB
#  Rank 12 Group  0 Pid  30382 on ip-172-31-43-8 device  4 [0x90] NVIDIA A100-SXM4-40GB
#  Rank 13 Group  0 Pid  30383 on ip-172-31-43-8 device  5 [0x90] NVIDIA A100-SXM4-40GB
#  Rank 14 Group  0 Pid  30384 on ip-172-31-43-8 device  6 [0xa0] NVIDIA A100-SXM4-40GB
#  Rank 15 Group  0 Pid  30385 on ip-172-31-43-8 device  7 [0xa0] NVIDIA A100-SXM4-40GB
ip-172-31-42-25:33385:33385 [7] NCCL INFO cudaDriverVersion 12060
ip-172-31-43-8:30383:30383 [5] NCCL INFO Bootstrap : Using ens32:172.31.43.8
ip-172-31-43-8:30383:30383 [5] NCCL INFO NCCL version 2.23.4+cuda12.5
...
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Initializing aws-ofi-nccl 1.13.2-aws
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Using Libfabric version 1.22
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Using CUDA driver version 12060 with runtime 12050
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Configuring AWS-specific options
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting provider_filter to efa
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting FI_EFA_FORK_SAFE environment variable to 1
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting NCCL_NVLSTREE_MAX_CHUNKSIZE to 512KiB
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting NCCL_NVLS_CHUNKSIZE to 512KiB
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Running on p4d.24xlarge platform, Setting NCCL_TOPO_FILE environment variable to /opt/amazon/ofi-nccl/share/aws-ofi-nccl/xml/p4d-24xl-topo.xml
...
-----------------------------some output truncated-----------------------------------
#                                                              out-of-place                       in-place          
#       size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
#        (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)       
           8             2     float     sum      -1    180.3    0.00    0.00      0    179.3    0.00    0.00      0
          16             4     float     sum      -1    178.1    0.00    0.00      0    177.6    0.00    0.00      0
          32             8     float     sum      -1    178.5    0.00    0.00      0    177.9    0.00    0.00      0
          64            16     float     sum      -1    178.8    0.00    0.00      0    178.7    0.00    0.00      0
         128            32     float     sum      -1    178.2    0.00    0.00      0    177.8    0.00    0.00      0
         256            64     float     sum      -1    178.6    0.00    0.00      0    178.8    0.00    0.00      0
         512           128     float     sum      -1    177.2    0.00    0.01      0    177.1    0.00    0.01      0
        1024           256     float     sum      -1    179.2    0.01    0.01      0    179.3    0.01    0.01      0
        2048           512     float     sum      -1    181.3    0.01    0.02      0    181.2    0.01    0.02      0
        4096          1024     float     sum      -1    184.2    0.02    0.04      0    183.9    0.02    0.04      0
        8192          2048     float     sum      -1    191.2    0.04    0.08      0    190.6    0.04    0.08      0
       16384          4096     float     sum      -1    202.5    0.08    0.15      0    202.3    0.08    0.15      0
       32768          8192     float     sum      -1    233.0    0.14    0.26      0    232.1    0.14    0.26      0
       65536         16384     float     sum      -1    238.6    0.27    0.51      0    235.1    0.28    0.52      0
      131072         32768     float     sum      -1    237.2    0.55    1.04      0    236.8    0.55    1.04      0
      262144         65536     float     sum      -1    248.3    1.06    1.98      0    247.0    1.06    1.99      0
      524288        131072     float     sum      -1    309.2    1.70    3.18      0    307.7    1.70    3.20      0
     1048576        262144     float     sum      -1    408.7    2.57    4.81      0    404.3    2.59    4.86      0
     2097152        524288     float     sum      -1    613.5    3.42    6.41      0    607.9    3.45    6.47      0
     4194304       1048576     float     sum      -1    924.5    4.54    8.51      0    914.8    4.58    8.60      0
     8388608       2097152     float     sum      -1   1059.5    7.92   14.85      0   1054.3    7.96   14.92      0
    16777216       4194304     float     sum      -1   1269.9   13.21   24.77      0   1272.0   13.19   24.73      0
    33554432       8388608     float     sum      -1   1642.7   20.43   38.30      0   1636.7   20.50   38.44      0
    67108864      16777216     float     sum      -1   2446.7   27.43   51.43      0   2445.8   27.44   51.45      0
   134217728      33554432     float     sum      -1   4143.6   32.39   60.73      0   4142.4   32.40   60.75      0
   268435456      67108864     float     sum      -1   7351.9   36.51   68.46      0   7346.7   36.54   68.51      0
   536870912     134217728     float     sum      -1    13717   39.14   73.39      0    13703   39.18   73.46      0
  1073741824     268435456     float     sum      -1    26416   40.65   76.21      0    26420   40.64   76.20      0
...
# Out of bounds values : 0 OK
# Avg bus bandwidth    : 15.5514
```

#### 검증 테스트
<a name="tutorial-efa-validation"></a>

EFA 테스트가 유효한 결과를 반환했는지 검증하려면 다음 테스트를 사용하여 확인합니다.
+ EC2 인스턴스 메타데이터를 사용하여 인스턴스 유형 가져오기:

  ```
  TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
  INSTANCE_TYPE=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-type)
  ```
+ [성능 테스트](#tutorial-efa-using-multinode) 실행 
+  다음 파라미터 설정 

  ```
  CUDA_VERSION
  CUDA_RUNTIME_VERSION
  NCCL_VERSION
  ```
+  다음과 같이 결과 검증: 

  ```
  RETURN_VAL=`echo $?`
  if [ ${RETURN_VAL} -eq 0 ]; then
  
      # [0] NCCL INFO NET/OFI Initializing aws-ofi-nccl 1.13.2-aws
      # [0] NCCL INFO NET/OFI Using CUDA driver version 12060 with runtime 12010
  
      # cudaDriverVersion 12060  --> This is max supported cuda version by nvidia driver
      # NCCL version 2.23.4+cuda12.5 --> This is NCCL version compiled with cuda version
  
      # Validation of logs
      grep "NET/OFI Configuring AWS-specific options" ${TRAINING_LOG} || { echo "AWS-specific options text not found"; exit 1; } 
      grep "busbw" ${TRAINING_LOG} || { echo "busbw text not found"; exit 1; } 
      grep "Avg bus bandwidth " ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; } 
      grep "NCCL version $NCCL_VERSION" ${TRAINING_LOG} || { echo "Text not found: NCCL version $NCCL_VERSION"; exit 1; }
      if [[ ${INSTANCE_TYPE} == "p4d.24xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Text not found: NET/Libfabric/0/GDRDMA"; exit 1; }  
          grep "NET/OFI Selected Provider is efa (found 4 nics)" ${TRAINING_LOG} || { echo "Selected Provider is efa text not found"; exit 1; }   
      elif [[ ${INSTANCE_TYPE} == "p4de.24xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 4 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
      elif [[ ${INSTANCE_TYPE} == "p5.48xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 32 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; } 
      elif [[ ${INSTANCE_TYPE} == "p5e.48xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 32 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
      elif [[ ${INSTANCE_TYPE} == "p5en.48xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 16 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
      elif [[ ${INSTANCE_TYPE} == "p3dn.24xlarge" ]]; then
          grep "NET/OFI Selected Provider is efa (found 4 nics)" ${TRAINING_LOG} || { echo "Selected Provider is efa text not found"; exit 1; }  
      fi
      echo "***************************** check_efa_nccl_all_reduce passed for cuda version ${CUDA_VERSION} *****************************"
  else
      echo "***************************** check_efa_nccl_all_reduce failed for cuda version ${CUDA_VERSION} *****************************"
  fi
  ```
+ 벤치마크 데이터에 액세스하기 위해 다중 노드 all\$1reduce 테스트에서 테이블 출력의 마지막 행을 구문 분석할 수 있습니다.

  ```
  benchmark=$(sudo cat ${TRAINING_LOG} | grep '1073741824' | tail -n1 | awk -F " " '{{print $12}}' | sed 's/ //' | sed  's/  5e-07//')
  if [[ -z "${benchmark}" ]]; then
    echo "benchmark variable is empty"
    exit 1
  fi
  
  echo "Benchmark throughput: ${benchmark}"
  ```

# GPU 모니터링 및 최적화
<a name="tutorial-gpu"></a>

다음 단원에서는 GPU 최적화 및 모니터링 옵션을 안내합니다. 이 단원은 모니터링, 감독, 사전 처리 및 교육의 일반적인 워크플로우처럼 구성되어 있습니다.
+ [모니터링](tutorial-gpu-monitoring.md)
  + [CloudWatch를 이용한 GPU 모니터링](tutorial-gpu-monitoring-gpumon.md)
+ [최적화](tutorial-gpu-opt.md)
  + [사전 처리](tutorial-gpu-opt-preprocessing.md)
  + [학습](tutorial-gpu-opt-training.md)

# 모니터링
<a name="tutorial-gpu-monitoring"></a>

DLAMI는 몇 가지 GPU 모니터링 도구가 사전 설치된 상태로 제공됩니다. 이 설명서에서는 다운로드 및 설치에 사용할 수 있는 도구에 대해서도 설명합니다.
+ [CloudWatch를 이용한 GPU 모니터링](tutorial-gpu-monitoring-gpumon.md) - Amazon CloudWatch에 GPU 사용 통계를 보고하는 사전 설치된 유틸리티입니다.
+ [nvidia-smi CLI](https://developer.nvidia.com/nvidia-system-management-interface) - 전반적인 GPU 컴퓨팅 및 메모리 사용률을 모니터링하는 유틸리티입니다. 이는 AWS Deep Learning AMIs (DLAMI)에 사전 설치되어 있습니다.
+ [NVML C 라이브러리](https://developer.nvidia.com/nvidia-management-library-nvml) - GPU 모니터링 및 관리 기능에 직접 액세스할 수 있는 C 기반 API입니다. 이 API는 후드 아래에서 nvidia-smi CLI에 사용되며 DLAMI에 사전 설치되어 있습니다. 또한 Python 및 Perl 바인딩을 가지고 있어 이러한 언어로 신속하게 개발이 가능합니다. DLAMI에 사전 설치된 gpumon.py 유틸리티는 [nvidia-ml-py](https://pypi.org/project/nvidia-ml-py/)에서 pynvml 패키지를 사용합니다.
+ [NVIDIA DCGM](https://developer.nvidia.com/data-center-gpu-manager-dcgm) - 클러스터 관리 도구입니다. 이 도구를 설치하고 구성하는 방법을 알아보려면 개발자 페이지를 방문하세요.

**작은 정보**  
DLAMI에 설치된 CUDA 도구를 사용하는 방법에 대한 최신 정보는 NVIDIA의 개발자 블로그에서 확인하세요.  
[Nsight IDE 및 nvprof를 사용한 TensorCore 사용률 모니터링](https://devblogs.nvidia.com/using-nsight-compute-nvprof-mixed-precision-deep-learning-models/).

# CloudWatch를 이용한 GPU 모니터링
<a name="tutorial-gpu-monitoring-gpumon"></a>

GPU에서 DLAMI를 사용할 때는 교육 또는 추론 동안 사용량을 추적하는 방법을 찾고 있는 경우일 수 있습니다. 이는 데이터 파이프라인을 최적화하고 딥 러닝 네트워크를 튜닝할 때 유용할 수 있습니다.

CloudWatch GPU 지표 구성 방법은 두 가지입니다.
+ [AWS CloudWatch 에이전트를 사용하여 지표 구성(권장)](#tutorial-gpu-monitoring-gpumon-cloudwatch-agent-guide)
+ [사전 설치된 `gpumon.py` 스크립트로 지표를 구성합니다.](#tutorial-gpu-monitoring-gpumon-script)

## AWS CloudWatch 에이전트를 사용하여 지표 구성(권장)
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-guide"></a>

DLAMI를 [CloudWatch 에이전트와 통합](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html)하여 Amazon EC2 가속화 인스턴스에서 GPU 지표를 구성하고 GPU 공동 프로세스의 사용률을 모니터링할 수 있습니다.

DLAMI를 사용하여 [GPU 지표](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-NVIDIA-GPU.html)를 구성하는 방법은 네 가지입니다.
+ [GPU 지표 최소 구성](#tutorial-gpu-monitoring-gpumon-cloudwatch-agent-minimal)
+ [GPU 지표 부분 구성](#tutorial-gpu-monitoring-gpumon-cloudwatch-agent-partial)
+ [사용 가능한 GPU 지표 전체 구성](#tutorial-gpu-monitoring-gpumon-cloudwatch-agent-all)
+ [사용자 지정 GPU 지표 구성](#tutorial-gpu-monitoring-gpumon-cloudwatch-agent-custom)

업데이트 및 보안 패치에 관한 자세한 내용은 [AWS CloudWatch 에이전트에 대한 보안 패치 적용](#tutorial-gpu-monitoring-gpumon-cloudwatch-agent-security)를 참조하세요.

### 사전 조건
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-prerequisites"></a>

시작하기 전에 인스턴스가 지표를 CloudWatch로 푸시할 수 있도록 Amazon EC2 인스턴스 IAM 권한을 구성해야 합니다. 자세한 구성 방법은 [CloudWatch 에이전트와 함께 사용하기 위한 IAM 역할 및 사용자 생성](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html)을 참조하세요.

### GPU 지표 최소 구성
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-minimal"></a>

`dlami-cloudwatch-agent@minimal` `systemd` 서비스를 사용하여 GPU 최소 지표를 구성합니다. 이 서비스의 지표 구성은 다음과 같습니다.
+ `utilization_gpu`
+ `utilization_memory`

GPU 지표 최소 사전 구성에 대한 `systemd` 서비스는 다음 위치에서 찾을 수 있습니다.

```
/opt/aws/amazon-cloudwatch-agent/etc/dlami-amazon-cloudwatch-agent-minimal.json
```

다음 명령을 사용하여 `systemd` 서비스를 활성화하고 시작합니다.

```
sudo systemctl enable dlami-cloudwatch-agent@minimal
sudo systemctl start dlami-cloudwatch-agent@minimal
```

### GPU 지표 부분 구성
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-partial"></a>

`dlami-cloudwatch-agent@partial` `systemd` 서비스를 사용하여 GPU 부분 지표를 구성합니다. 이 서비스의 지표 구성은 다음과 같습니다.
+ `utilization_gpu`
+ `utilization_memory`
+ `memory_total`
+ `memory_used`
+ `memory_free`

GPU 지표 부분 사전 구성에 대한 `systemd` 서비스는 다음 위치에서 찾을 수 있습니다.

```
/opt/aws/amazon-cloudwatch-agent/etc/dlami-amazon-cloudwatch-agent-partial.json
```

다음 명령을 사용하여 `systemd` 서비스를 활성화하고 시작합니다.

```
sudo systemctl enable dlami-cloudwatch-agent@partial
sudo systemctl start dlami-cloudwatch-agent@partial
```

### 사용 가능한 GPU 지표 전체 구성
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-all"></a>

`dlami-cloudwatch-agent@all` `systemd` 서비스를 사용하여 GPU 전체 지표를 구성합니다. 이 서비스의 지표 구성은 다음과 같습니다.
+ `utilization_gpu`
+ `utilization_memory`
+ `memory_total`
+ `memory_used`
+ `memory_free`
+ `temperature_gpu`
+ `power_draw`
+ `fan_speed`
+ `pcie_link_gen_current`
+ `pcie_link_width_current`
+ `encoder_stats_session_count`
+ `encoder_stats_average_fps`
+ `encoder_stats_average_latency`
+ `clocks_current_graphics`
+ `clocks_current_sm`
+ `clocks_current_memory`
+ `clocks_current_video`

GPU 전체 지표 사전 구성에 대한 `systemd` 서비스는 다음 위치에서 찾을 수 있습니다.

```
/opt/aws/amazon-cloudwatch-agent/etc/dlami-amazon-cloudwatch-agent-all.json
```

다음 명령을 사용하여 `systemd` 서비스를 활성화하고 시작합니다.

```
sudo systemctl enable dlami-cloudwatch-agent@all
sudo systemctl start dlami-cloudwatch-agent@all
```

### 사용자 지정 GPU 지표 구성
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-custom"></a>

사전 구성된 지표가 요구 사항을 충족하지 않는 경우 사용자 지정 CloudWatch 에이전트 구성 파일을 생성할 수 있습니다.

#### 사용자 지정 구성 파일 생성
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-custom-create"></a>

사용자 지정 구성 파일을 생성하려면 [수동으로 CloudWatch 에이전트 구성 파일 생성 또는 편집](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html)에 있는 세부 단계를 참조하세요.

이 예제에서는 스키마 정의 위치를 `/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json`이라고 가정합니다.

#### 사용자 지정 파일로 지표 구성
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-custom-configure"></a>

다음 명령을 실행하여 사용자 지정 파일에 따라 CloudWatch 에이전트를 구성합니다.

```
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -s -c \
file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
```

### AWS CloudWatch 에이전트에 대한 보안 패치 적용
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-security"></a>

새로 릴리스된 DLAMIs는 사용 가능한 최신 AWS CloudWatch 에이전트 보안 패치로 구성됩니다. 선택한 운영 체제에 따라 현재 DLAMI를 최신 보안 패치로 업데이트하려면 다음 섹션을 참조하세요.

#### Amazon Linux 2
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-security-al2"></a>

`yum`를 사용하여 Amazon Linux 2 DLAMI에 대한 최신 AWS CloudWatch 에이전트 보안 패치를 가져옵니다.

```
 sudo yum update
```

#### Ubuntu
<a name="tutorial-gpu-monitoring-gpumon-cloudwatch-agent-security-ubuntu"></a>

Ubuntu를 사용하는 DLAMI에 대한 최신 AWS CloudWatch 보안 패치를 가져오려면 Amazon S3 다운로드 링크를 사용하여 AWS CloudWatch 에이전트를 다시 설치해야 합니다.

```
wget https://s3.region.amazonaws.com/amazoncloudwatch-agent-region/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
```

Amazon S3 다운로드 링크를 사용하여 AWS CloudWatch 에이전트를 설치하는 방법에 대한 자세한 내용은 [ 서버에 CloudWatch 에이전트 설치 및 실행을 참조하세요](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html).

## 사전 설치된 `gpumon.py` 스크립트로 지표를 구성합니다.
<a name="tutorial-gpu-monitoring-gpumon-script"></a>

gpumon.py라는 유틸리티는 DLAMI에 사전 설치되어 있습니다. 이 유틸리티는 CloudWatch에 통합되어 GPU당 사용량(GPU 메모리, GPU 온도 및 GPU 전력)의 모니터링을 지원합니다. 스크립트가 CloudWatch에 모니터링된 데이터를 정기적으로 전송합니다. 스크립트에서 몇 가지 설정을 변경하여 CloudWatch에 전송 중인 데이터에 대한 세부 수준을 구성할 수 있습니다. 하지만 스크립트를 시작하기 전에 지표를 수신하도록 CloudWatch를 설정해야 합니다.

**CloudWatch를 이용해 GPU 모니터링을 설정 및 실행하는 방법**

1. IAM 사용자를 생성하거나 기존 사용자를 수정하여 CloudWatch에 지표를 게시하기 위한 정책을 수립합니다. 새로 사용자를 생성하는 경우에는 다음 단계에서 필요할 수 있기 때문에 자격 증명을 적어두십시오.

   검색할 IAM 정책은 “cloudwatch:PutMetricData”입니다. 추가된 정책은 다음과 같습니다.

------
#### [ JSON ]

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
           {
               "Action": [
                   "cloudwatch:PutMetricData"
                ],
                "Effect": "Allow",
                "Resource": "*"
           }
      ]
   }
   ```

------
**작은 정보**  
IAM 사용자를 생성하고 CloudWatch에서 정책을 추가하는 방법에 대한 자세한 내용은 [CloudWatch 설명서](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html)를 참조하세요.

1. DLAMI에서 [AWS 구성](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration)을 실행하고 IAM 사용자 자격 증명을 지정합니다.

   ```
   $ aws configure
   ```

1. 실행에 앞서 gpumon 유틸리티를 약간 수정해야 할 수 있습니다. 다음 코드 블록에 명시된 위치에서 gpumon 유틸리티 및 README를 찾을 수 있습니다. `gpumon.py` 스크립트에 대한 자세한 내용은 [스크립트의 Amazon S3 위치](https://s3.amazonaws.com/aws-bigdata-blog/artifacts/GPUMonitoring/gpumon.py)를 참조하세요.

   ```
   Folder: ~/tools/GPUCloudWatchMonitor
   Files: 	~/tools/GPUCloudWatchMonitor/gpumon.py
         	~/tools/GPUCloudWatchMonitor/README
   ```

   옵션:
   + 인스턴스가 us-east-1에 없는 경우에는 gpumon.py에서 리전을 변경합니다.
   + CloudWatch `namespace` 또는 `store_reso`의 보고 기간 같은 다른 파라미터를 변경합니다.

1. 현재, 스크립트는 Python 3만 지원합니다. 선호하는 프레임워크의 Python 3 환경을 활성화하거나 DLAMI의 일반적인 Python 3 환경을 활성화합니다.

   ```
   $ source activate python3
   ```

1. 배경에서 gpumon 유틸리티를 실행합니다.

   ```
   (python3)$ python gpumon.py &
   ```

1. 브라우저를 열어 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)로 이동한 다음 지표를 선택합니다. 네임스페이스는 'DeepLearningTrain'이 됩니다.
**작은 정보**  
gpumon.py를 수정하여 네임스페이스를 변경할 수 있습니다. 또한 `store_reso`을 조정하여 보고 간격을 수정할 수도 있습니다.

다음은 gpumon.py를 실행하여 p2.8xlarge 인스턴스에서 교육 작업을 모니터링할 때 CloudWatch 차트 보고의 예제입니다.

![\[CloudWatch에서의 GPU 모니터링\]](http://docs.aws.amazon.com/ko_kr/dlami/latest/devguide/images/gpumon.png)


GPU 모니터링 및 최적화에 대한 이러한 기타 주제들에 관심이 있을 수 있습니다.
+ [모니터링](tutorial-gpu-monitoring.md)
  + [CloudWatch를 이용한 GPU 모니터링](#tutorial-gpu-monitoring-gpumon)
+ [최적화](tutorial-gpu-opt.md)
  + [사전 처리](tutorial-gpu-opt-preprocessing.md)
  + [학습](tutorial-gpu-opt-training.md)

# 최적화
<a name="tutorial-gpu-opt"></a>

GPU를 최대한 활용하기 위해 데이터 파이프라인을 최적화하고 딥 러닝 네트워크를 튜닝할 수 있습니다. 아래 차트에서 설명하듯, 단순하고 기본적인 방식으로 구현된 신경망에서는 GPU를 일관성 있게 사용하지 못해서 잠재력이 충분히 발휘되지 못할 수 있습니다. 사전 처리 및 데이터 로딩을 최적화하면 CPU에서 GPU로의 병목을 줄일 수 있습니다. 하이브리드화를 사용(프레임워크에서 지원할 때)하여 배치 크기를 조정하고, 호출을 동기화하여 신경망 자체를 조정할 수 있습니다. 또한 대부분 프레임워크에서 다중 정밀도(float16 또는 int8) 교육을 사용하여 처리량 개선에 획기적인 영향을 미칠 수도 있습니다.

다음 차트에는 서로 다른 최적화를 적용할 때 누적되는 성능상 이점을 보여줍니다. 처리 중인 데이터와 최적화 중인 네트워크에 따라 결과는 달라집니다.

![\[GPU 성능 개선\]](http://docs.aws.amazon.com/ko_kr/dlami/latest/devguide/images/performance-enhancements.png)


다음 설명서는 DLAMI에서 실행 가능하고 GPU 성능을 높이는 데 도움을 주는 옵션에 대해 설명합니다.

**Topics**
+ [

# 사전 처리
](tutorial-gpu-opt-preprocessing.md)
+ [

# 학습
](tutorial-gpu-opt-training.md)

# 사전 처리
<a name="tutorial-gpu-opt-preprocessing"></a>

변환 또는 증강을 통한 데이터 사전 처리는 CPU 바운드 프로세스인 경우가 종종 있기 때문에 전체 파이프라인에서 병목이 될 수 있습니다. 프레임워크에는 이미지 처리를 위한 연산자가 내장되어 있지만, DALI(Data Augmentation Library)는 프레임워크에 내장된 옵션을 통한 성능 개선을 입증합니다.
+ NVIDIA DALI(Data Augmentation Library): DALI는 GPU에 데이터 증강을 오프로드합니다. DLAMI에 사전 설치되어 있지 않지만, 이를 설치하거나 지원되는 프레임워크 컨테이너를 DLAMI나 다른 Amazon Elastic Compute Cloud 인스턴스에 로드하여 액세스할 수 있습니다. 자세한 내용은 NVIDIA 웹 사이트의 [DALI 프로젝트 페이지](https://docs.nvidia.com/deeplearning/sdk/dali-install-guide/index.html)를 참조하세요. 예제 사용 사례와 코드 샘플을 다운로드하려면 [SageMaker 사전 처리 교육 성능](https://github.com/aws-samples/sagemaker-cv-preprocessing-training-performance) 샘플을 참조하세요.
+ nvJPEG: C 프로그래머를 위한 GPU 기반의 JPEG 디코더 라이브러리입니다. 단일 이미지 또는 배치를 비롯해 딥 러닝에서 일반적인 후속 변환 작업을 디코딩할 수 있도록 지원합니다. nvJPEG에는 DALI가 내장되어 있을 수도 있고, [NVIDIA 웹 사이트의 nvjpeg 페이지](https://developer.nvidia.com/nvjpeg)에서 다운로드하여 별도로 사용할 수 있습니다.

GPU 모니터링 및 최적화에 대한 이러한 기타 주제들에 관심이 있을 수 있습니다.
+ [모니터링](tutorial-gpu-monitoring.md)
  + [CloudWatch를 이용한 GPU 모니터링](tutorial-gpu-monitoring-gpumon.md)
+ [최적화](tutorial-gpu-opt.md)
  + [사전 처리](#tutorial-gpu-opt-preprocessing)
  + [학습](tutorial-gpu-opt-training.md)

# 학습
<a name="tutorial-gpu-opt-training"></a>

혼합 정밀도 교육을 통해 같은 양의 메모리로 더 큰 네트워크를 배포하거나 단일 또는 이중 정밀도 네트워크와 비교해 메모리 사용량을 줄여서 컴퓨팅 성능을 높일 수 있습니다. 또한 보다 소규모로 더 빨리 데이터를 전송할 수 있다는 이점이 있는데, 이는 여러 노드에 분산된 교육에서 중요한 요소입니다. 혼합 정밀도 교육을 활용하려면 데이터 캐스팅 및 손실을 조정해야 합니다. 다음은 혼합 정밀도를 지원하는 프레임워크에서 이를 수행하는 방법을 설명하는 설명서입니다.
+ [NVIDIA 딥 러닝 SDK](https://docs.nvidia.com/deeplearning/sdk/mixed-precision-training/) - MXNet, PyTorch 및 TensorFlow를 위한 혼합 정밀도 구현을 설명하는 NVIDIA 웹 사이트의 문서.

**작은 정보**  
선택한 프레임워크를 위한 웹 사이트를 확인하고 최신 최적화 기법에 대한 "혼합 정밀도" 또는 "fp16"을 검색하세요. 다음과 같이 몇 가지 혼합 정밀도 설명서가 도움이 될 수 있습니다.  
[TensorFlow를 이용한 혼합 정밀도 교육(비디오)](https://devblogs.nvidia.com/mixed-precision-resnet-50-tensor-cores/) - NVIDIA 블로그 사이트에서 제공.
[MXNet에서 float16을 사용한 혼합 정밀도 교육](https://mxnet.apache.org/api/faq/float16) - MXNet 웹 사이트의 FAQ 문서.
[NVIDIA Apex: PyTorch를 이용한 간편한 혼합 정밀도 교육을 위한 도구](https://devblogs.nvidia.com/apex-pytorch-easy-mixed-precision-training/) - NVIDIA 웹 사이트의 블로그 기사.

GPU 모니터링 및 최적화에 대한 이러한 기타 주제들에 관심이 있을 수 있습니다.
+ [모니터링](tutorial-gpu-monitoring.md)
  + [CloudWatch를 이용한 GPU 모니터링](tutorial-gpu-monitoring-gpumon.md)
+ [최적화](tutorial-gpu-opt.md)
  + [사전 처리](tutorial-gpu-opt-preprocessing.md)
  + [학습](#tutorial-gpu-opt-training)

# DLAMI를 사용하는 AWS Inferentia 칩
<a name="tutorial-inferentia"></a>

AWS Inferentia는 고성능 추론 예측에 사용할 수 AWS 있도록에서 설계한 사용자 지정 기계 학습 칩입니다. 칩을 사용하려면 Amazon Elastic Compute Cloud 인스턴스를 설정하고 AWS Neuron 소프트웨어 개발 키트(SDK)를 사용하여 Inferentia 칩을 호출합니다. Inferentia를 최적으로 사용할 수 있도록 DLAMI( AWS Deep Learning AMIs )에 Neuron이 내장되어 있습니다.

다음 섹션에서는 DLAMI에서 Inferentia를 활용하는 방법을 설명합니다.

**Topics**
+ [

# AWS Neuron을 사용하여 DLAMI 인스턴스 시작
](tutorial-inferentia-launching.md)
+ [

# AWS Neuron에서 DLAMI 사용
](tutorial-inferentia-using.md)

# AWS Neuron을 사용하여 DLAMI 인스턴스 시작
<a name="tutorial-inferentia-launching"></a>

 최신 DLAMI는 AWS Inferentia와 함께 사용할 준비가 되었으며 AWS Neuron API 패키지와 함께 제공됩니다. DLAMI 인스턴스를 시작하려면 [DLAMI 시작 및 구성](https://docs.aws.amazon.com/dlami/latest/devguide/launch-config.html)을 참조하세요. DLAMI가 있으면 여기의 단계를 사용하여 AWS Inferentia 칩과 AWS Neuron 리소스가 활성 상태인지 확인합니다.

**Topics**
+ [

## 인스턴스 확인
](#tutorial-inferentia-launching-verify)
+ [

## AWS Inferentia 디바이스 식별
](#tutorial-inferentia-launching-identify)
+ [

## 리소스 사용량 보기
](#tutorial-inferentia-launching-resource-usage)
+ [

## Neuron Monitor 사용(neuron-monitor)
](#tutorial-inferentia-launching-neuron-monitor)
+ [

## Neuron 소프트웨어 업그레이드
](#tutorial-inferentia-launching-upgrade)

## 인스턴스 확인
<a name="tutorial-inferentia-launching-verify"></a>

 인스턴스를 사용하기 전에 인스턴스가 제대로 설정되고 Neuron으로 구성되어 있는지 확인합니다.

## AWS Inferentia 디바이스 식별
<a name="tutorial-inferentia-launching-identify"></a>

 인스턴스의 Inferentia 디바이스 수를 식별하려면 다음 명령을 사용합니다.

```
neuron-ls
```

 인스턴스에 Inferentia 디바이스가 연결되어 있는 경우 다음과 유사하게 출력됩니다.

```
+--------+--------+--------+-----------+--------------+
| NEURON | NEURON | NEURON | CONNECTED |     PCI      |
| DEVICE | CORES  | MEMORY |  DEVICES  |     BDF      |
+--------+--------+--------+-----------+--------------+
| 0      | 4      | 8 GB   | 1         | 0000:00:1c.0 |
| 1      | 4      | 8 GB   | 2, 0      | 0000:00:1d.0 |
| 2      | 4      | 8 GB   | 3, 1      | 0000:00:1e.0 |
| 3      | 4      | 8 GB   | 2         | 0000:00:1f.0 |
+--------+--------+--------+-----------+--------------+
```

 제공된 출력은 INF1.6xlarge 인스턴스에서 가져온 것이며 다음 열을 포함합니다.
+ NEURON DEVICE: NeuronDevice에 할당된 논리적 ID입니다. 이 ID는 여러 NeuronDevices를 사용하도록 다중 런타임을 구성할 때 사용됩니다.
+ NEURON CORES: NeuronDevice에 존재하는 NeuronCores의 수입니다.
+ NEURON MEMORY: NeuronDevice에 있는 DRAM 메모리의 양입니다.
+ CONNECTED DEVICES: NeuronDevice에 연결된 다른 NeuronDevice입니다.,
+ PCI BDF: NeuronDevice의 PCI 버스 디바이스 함수(BDF) ID입니다.

## 리소스 사용량 보기
<a name="tutorial-inferentia-launching-resource-usage"></a>

 `neuron-top` 명령을 사용하여 NeuronCore 및 vCPU 사용률, 메모리 사용량, 로드된 모델 및 Neuron 애플리케이션에 대한 유용한 정보를 볼 수 있습니다. 인수 없이 `neuron-top`를 실행하면 NeuronCores를 사용하는 모든 기계 학습 응용 프로그램의 데이터가 표시됩니다.

```
neuron-top
```

 애플리케이션이 NeuronCore 4개를 사용하는 경우 다음과 유사하게 출력됩니다.

![\[네 개의 NeuronCore 중 하나에 대한 정보가 강조 표시된 neuron-top 명령의 출력입니다.\]](http://docs.aws.amazon.com/ko_kr/dlami/latest/devguide/images/neuron-top-output.png)


Neuron 기반 추론 애플리케이션을 모니터링하고 최적화하기 위한 리소스에 대한 자세한 내용은 [Neuron 도구](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-tools/index.html)를 참조하세요.

## Neuron Monitor 사용(neuron-monitor)
<a name="tutorial-inferentia-launching-neuron-monitor"></a>

Neuron Monitor는 시스템에서 실행되는 Neuron 런타임에서 지표를 수집하고 수집된 데이터를 JSON 형식의 stdout에 스트리밍합니다. 이러한 지표는구성 파일을 제공하여 구성하는 지표 그룹으로 구성됩니다. Neuron Monitor에 대한 자세한 내용은 [Neuron Monitor사용 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-tools/neuron-monitor-user-guide.html)를 참조하세요.

## Neuron 소프트웨어 업그레이드
<a name="tutorial-inferentia-launching-upgrade"></a>

DLAMI 내에서 Neuron SDK 소프트웨어를 업데이트하는 방법에 대한 자세한 내용은 AWS Neuron [Setup Guide](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-intro/neuron-install-guide.html)를 참조하세요.

**다음 단계**  
[AWS Neuron에서 DLAMI 사용](tutorial-inferentia-using.md)

# AWS Neuron에서 DLAMI 사용
<a name="tutorial-inferentia-using"></a>

 AWS Neuron SDK의 일반적인 워크플로는 컴파일 서버에서 이전에 훈련된 기계 학습 모델을 컴파일하는 것입니다. 그런 다음 실행을 위해 아티팩트를 Inf1 인스턴스에 배포합니다. AWS Deep Learning AMIs (DLAMI)에는 Inferentia를 사용하는 Inf1 인스턴스에서 추론을 컴파일하고 실행하는 데 필요한 모든 것이 사전 설치되어 있습니다.

 다음 섹션에서는 Inferentia DLAMI를 사용하는 방법을 설명합니다.

**Topics**
+ [

# TensorFlow-Neuron 및 AWS Neuron 컴파일러 사용
](tutorial-inferentia-tf-neuron.md)
+ [

# AWS Neuron TensorFlow Serving 사용
](tutorial-inferentia-tf-neuron-serving.md)
+ [

# MXNet-Neuron 및 AWS Neuron 컴파일러 사용
](tutorial-inferentia-mxnet-neuron.md)
+ [

# MXNet-Neuron 모델 제공 사용
](tutorial-inferentia-mxnet-neuron-serving.md)
+ [

# PyTorch-Neuron 및 AWS Neuron 컴파일러 사용
](tutorial-inferentia-pytorch-neuron.md)

# TensorFlow-Neuron 및 AWS Neuron 컴파일러 사용
<a name="tutorial-inferentia-tf-neuron"></a>

 이 자습서에서는 AWS Neuron 컴파일러를 사용하여 Keras ResNet-50 모델을 컴파일하고 SavedModel 형식으로 저장된 모델로 내보내는 방법을 보여줍니다. 이 형식은 일반 TensorFlow 모델에서 서로 바꿔 사용할 수 있는 형식입니다. 또한 예제 입력을 사용하여 Inf1 인스턴스에서 추론을 실행하는 방법을 알아봅니다.  

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/tensorflow-neuron/index.html)를 참조하세요.

**Topics**
+ [

## 사전 조건
](#tutorial-inferentia-tf-neuron-prerequisites)
+ [

## Conda 환경 활성화
](#tutorial-inferentia-tf-neuron-activate)
+ [

## Resnet50 컴파일
](#tutorial-inferentia-tf-neuron-compilation)
+ [

## ResNet50 추론
](#tutorial-inferentia-tf-neuron-inference)

## 사전 조건
<a name="tutorial-inferentia-tf-neuron-prerequisites"></a>

 이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-tf-neuron-activate"></a>

 다음 명령을 사용하여 TensorFlow-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_tensorflow_p36
```

 현재 conda 환경을 종료하려면 다음 명령을 실행합니다.

```
source deactivate
```

## Resnet50 컴파일
<a name="tutorial-inferentia-tf-neuron-compilation"></a>

다음 콘텐츠를 가진 **tensorflow\$1compile\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 Python 스크립트는 Keras ResNet50 모델을 컴파일하고 저장된 모델로 내보냅니다.

```
import os
import time
import shutil
import tensorflow as tf
import tensorflow.neuron as tfn
import tensorflow.compat.v1.keras as keras
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.applications.resnet50 import preprocess_input

# Create a workspace
WORKSPACE = './ws_resnet50'
os.makedirs(WORKSPACE, exist_ok=True)

# Prepare export directory (old one removed)
model_dir = os.path.join(WORKSPACE, 'resnet50')
compiled_model_dir = os.path.join(WORKSPACE, 'resnet50_neuron')
shutil.rmtree(model_dir, ignore_errors=True)
shutil.rmtree(compiled_model_dir, ignore_errors=True)

# Instantiate Keras ResNet50 model
keras.backend.set_learning_phase(0)
model = ResNet50(weights='imagenet')

# Export SavedModel
tf.saved_model.simple_save(
 session            = keras.backend.get_session(),
 export_dir         = model_dir,
 inputs             = {'input': model.inputs[0]},
 outputs            = {'output': model.outputs[0]})

# Compile using Neuron
tfn.saved_model.compile(model_dir, compiled_model_dir)

# Prepare SavedModel for uploading to Inf1 instance
shutil.make_archive(compiled_model_dir, 'zip', WORKSPACE, 'resnet50_neuron')
```

 다음 명령을 사용하여 모델을 컴파일합니다.

```
python tensorflow_compile_resnet50.py
```

컴파일 프로세스는 몇 분 정도 걸립니다. 완료되면 출력은 다음과 같아야 합니다.

```
...
INFO:tensorflow:fusing subgraph neuron_op_d6f098c01c780733 with neuron-cc
INFO:tensorflow:Number of operations in TensorFlow session: 4638
INFO:tensorflow:Number of operations after tf.neuron optimizations: 556
INFO:tensorflow:Number of operations placed on Neuron runtime: 554
INFO:tensorflow:Successfully converted ./ws_resnet50/resnet50 to ./ws_resnet50/resnet50_neuron
...
```

 ​ 

 컴파일 후 저장된 모델은 **ws\$1resnet50/resnet50\$1neuron.zip**에서 압축됩니다. 다음 명령을 사용하여 모델의 압축을 풀고 추론을 위해 샘플 이미지를 다운로드합니다.

```
unzip ws_resnet50/resnet50_neuron.zip -d .
curl -O https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg
```

## ResNet50 추론
<a name="tutorial-inferentia-tf-neuron-inference"></a>

다음 콘텐츠를 가진 **tensorflow\$1infer\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 이전에 컴파일된 추론 모델을 사용하여 다운로드한 모델에 대한 추론을 실행합니다.

```
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications import resnet50

# Create input from image
img_sgl = image.load_img('kitten_small.jpg', target_size=(224, 224))
img_arr = image.img_to_array(img_sgl)
img_arr2 = np.expand_dims(img_arr, axis=0)
img_arr3 = resnet50.preprocess_input(img_arr2)
# Load model
COMPILED_MODEL_DIR = './ws_resnet50/resnet50_neuron/'
predictor_inferentia = tf.contrib.predictor.from_saved_model(COMPILED_MODEL_DIR)
# Run inference
model_feed_dict={'input': img_arr3}
infa_rslts = predictor_inferentia(model_feed_dict);
# Display results
print(resnet50.decode_predictions(infa_rslts["output"], top=5)[0])
```

 다음 명령을 사용하여 모델에 대한 추론을 실행합니다.

```
python tensorflow_infer_resnet50.py
```

 출력은 다음과 같아야 합니다.

```
...
[('n02123045', 'tabby', 0.6918919), ('n02127052', 'lynx', 0.12770271), ('n02123159', 'tiger_cat', 0.08277027), ('n02124075', 'Egyptian_cat', 0.06418919), ('n02128757', 'snow_leopard', 0.009290541)]
```

**다음 단계**  
[AWS Neuron TensorFlow Serving 사용](tutorial-inferentia-tf-neuron-serving.md)

# AWS Neuron TensorFlow Serving 사용
<a name="tutorial-inferentia-tf-neuron-serving"></a>

이 자습서에서는 TensorFlow Serving에 사용할 저장된 모델을 내보내기 전에 그래프를 구성하고 AWS Neuron 컴파일 단계를 추가하는 방법을 보여줍니다. TensorFlow Serving은 네트워크를 통해 추론을 확장할 수 있는 지원 시스템입니다. Neuron TensorFlow Serving은 일반적인 TensorFlow Serving과 동일한 API를 사용합니다. 유일한 차이점은 저장된 모델을 AWS Inferentia용으로 컴파일해야 하며 진입점은 라는 다른 바이너리라는 것입니다 `tensorflow_model_server_neuron`. 이진 파일은 `/usr/local/bin/tensorflow_model_server_neuron`에 있으며 DLAMI에 사전 설치되어 있습니다.

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/tensorflow-neuron/index.html)를 참조하세요.

**Topics**
+ [

## 사전 조건
](#tutorial-inferentia-tf-neuron--serving-prerequisites)
+ [

## Conda 환경 활성화
](#tutorial-inferentia-tf-neuron-serving-activate)
+ [

## 저장된 모델 컴파일 및 내보내기
](#tutorial-inferentia-tf-neuron-serving-compile)
+ [

## 저장된 모델 제공
](#tutorial-inferentia-tf-neuron-serving-serving)
+ [

## 모델 서버에 대한 추론 요청 생성
](#tutorial-inferentia-tf-neuron-serving-inference)

## 사전 조건
<a name="tutorial-inferentia-tf-neuron--serving-prerequisites"></a>

이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-tf-neuron-serving-activate"></a>

 다음 명령을 사용하여 TensorFlow-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_tensorflow_p36
```

 현재 conda 환경을 종료해야 하는 경우 다음을 실행합니다.

```
source deactivate
```

## 저장된 모델 컴파일 및 내보내기
<a name="tutorial-inferentia-tf-neuron-serving-compile"></a>

다음 콘텐츠를 통해 `tensorflow-model-server-compile.py` 이름으로 Python 스크립트를 생성합니다. 이 스크립트는 그래프를 구성하고 Neuron을 사용하여 컴파일합니다. 그런 다음 컴파일된 그래프를 저장된 모델로 내보냅니다.  

```
import tensorflow as tf
import tensorflow.neuron
import os

tf.keras.backend.set_learning_phase(0)
model = tf.keras.applications.ResNet50(weights='imagenet')
sess = tf.keras.backend.get_session()
inputs = {'input': model.inputs[0]}
outputs = {'output': model.outputs[0]}

# save the model using tf.saved_model.simple_save
modeldir = "./resnet50/1"
tf.saved_model.simple_save(sess, modeldir, inputs, outputs)

# compile the model for Inferentia
neuron_modeldir = os.path.join(os.path.expanduser('~'), 'resnet50_inf1', '1')
tf.neuron.saved_model.compile(modeldir, neuron_modeldir, batch_size=1)
```

 다음 명령을 사용하여 모델을 컴파일합니다.

```
python tensorflow-model-server-compile.py
```

 출력은 다음과 같아야 합니다.

```
...
INFO:tensorflow:fusing subgraph neuron_op_d6f098c01c780733 with neuron-cc
INFO:tensorflow:Number of operations in TensorFlow session: 4638
INFO:tensorflow:Number of operations after tf.neuron optimizations: 556
INFO:tensorflow:Number of operations placed on Neuron runtime: 554
INFO:tensorflow:Successfully converted ./resnet50/1 to /home/ubuntu/resnet50_inf1/1
```

## 저장된 모델 제공
<a name="tutorial-inferentia-tf-neuron-serving-serving"></a>

모델이 컴파일되면 다음 명령을 사용하여 저장된 모델을 tensorflow\$1model\$1server\$1neuron 이진 파일로 제공할 수 있습니다.

```
tensorflow_model_server_neuron --model_name=resnet50_inf1 \
    --model_base_path=$HOME/resnet50_inf1/ --port=8500 &
```

 출력은 다음과 같아야 합니다. 컴파일된 모델은 추론을 준비하기 위해 서버에 의해 Inferentia 디바이스의 DRAM에 준비됩니다.

```
...
2019-11-22 01:20:32.075856: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:311] SavedModel load for tags { serve }; Status: success. Took 40764 microseconds.
2019-11-22 01:20:32.075888: I tensorflow_serving/servables/tensorflow/saved_model_warmup.cc:105] No warmup data file found at /home/ubuntu/resnet50_inf1/1/assets.extra/tf_serving_warmup_requests
2019-11-22 01:20:32.075950: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: resnet50_inf1 version: 1}
2019-11-22 01:20:32.077859: I tensorflow_serving/model_servers/server.cc:353] Running gRPC ModelServer at 0.0.0.0:8500 ...
```

## 모델 서버에 대한 추론 요청 생성
<a name="tutorial-inferentia-tf-neuron-serving-inference"></a>

다음 콘텐츠를 통해 `tensorflow-model-server-infer.py`라는 Python 스크립트를 생성합니다. 이 스크립트는 서비스 프레임워크인 gRPC를 통해 추론을 실행합니다.

```
import numpy as np
import grpc
import tensorflow as tf
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.resnet50 import preprocess_input
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
from tensorflow.keras.applications.resnet50 import decode_predictions

if __name__ == '__main__':
    channel = grpc.insecure_channel('localhost:8500')
    stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
    img_file = tf.keras.utils.get_file(
        "./kitten_small.jpg",
        "https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg")
    img = image.load_img(img_file, target_size=(224, 224))
    img_array = preprocess_input(image.img_to_array(img)[None, ...])
    request = predict_pb2.PredictRequest()
    request.model_spec.name = 'resnet50_inf1'
    request.inputs['input'].CopyFrom(
        tf.contrib.util.make_tensor_proto(img_array, shape=img_array.shape))
    result = stub.Predict(request)
    prediction = tf.make_ndarray(result.outputs['output'])
    print(decode_predictions(prediction))
```

 다음 명령에서 gRPC를 사용하여 모델에 대한 추론을 실행합니다.

```
python tensorflow-model-server-infer.py
```

 출력은 다음과 같아야 합니다.

```
[[('n02123045', 'tabby', 0.6918919), ('n02127052', 'lynx', 0.12770271), ('n02123159', 'tiger_cat', 0.08277027), ('n02124075', 'Egyptian_cat', 0.06418919), ('n02128757', 'snow_leopard', 0.009290541)]]
```

# MXNet-Neuron 및 AWS Neuron 컴파일러 사용
<a name="tutorial-inferentia-mxnet-neuron"></a>

MXNet-Neuron 컴파일 API는 AWS Inferentia 디바이스에서 실행할 수 있는 모델 그래프를 컴파일하는 방법을 제공합니다.

 이 예에서는 API를 사용하여 ResNet-50 모델을 컴파일하고 추론을 실행하는 데 사용합니다.

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/mxnet-neuron/index.html)를 참조하세요.

**Topics**
+ [

## 사전 조건
](#tutorial-inferentia-mxnet-neuron-prerequisites)
+ [

## Conda 환경 활성화
](#tutorial-inferentia-mxnet-neuron-activate)
+ [

## Resnet50 컴파일
](#tutorial-inferentia-mxnet-neuron-compilation)
+ [

## ResNet50 추론
](#tutorial-inferentia-mxnet-neuron-inference)

## 사전 조건
<a name="tutorial-inferentia-mxnet-neuron-prerequisites"></a>

 이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-mxnet-neuron-activate"></a>

 다음 명령을 사용하여 MXNet-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_mxnet_p36
```

현재 conda 환경을 종료하려면 다음을 실행합니다.

```
source deactivate
```

## Resnet50 컴파일
<a name="tutorial-inferentia-mxnet-neuron-compilation"></a>

다음 콘텐츠를 통해 **mxnet\$1compile\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 MXNet-Neuron 컴파일 Python API를 사용하여 ResNet-50 모델을 컴파일합니다.

```
import mxnet as mx
import numpy as np

print("downloading...")
path='http://data.mxnet.io/models/imagenet/'
mx.test_utils.download(path+'resnet/50-layers/resnet-50-0000.params')
mx.test_utils.download(path+'resnet/50-layers/resnet-50-symbol.json')
print("download finished.")

sym, args, aux = mx.model.load_checkpoint('resnet-50', 0)

print("compile for inferentia using neuron... this will take a few minutes...")
inputs = { "data" : mx.nd.ones([1,3,224,224], name='data', dtype='float32') }

sym, args, aux = mx.contrib.neuron.compile(sym, args, aux, inputs)

print("save compiled model...")
mx.model.save_checkpoint("compiled_resnet50", 0, sym, args, aux)
```

 다음 명령을 사용하여 모델을 컴파일합니다.

```
python mxnet_compile_resnet50.py
```

 컴파일이 끝날 때까지 몇 분 정도 소요될 수 있습니다. 컴파일이 완료되면 다음 파일이 현재 디렉터리에 저장됩니다.

```
resnet-50-0000.params
resnet-50-symbol.json
compiled_resnet50-0000.params
compiled_resnet50-symbol.json
```

## ResNet50 추론
<a name="tutorial-inferentia-mxnet-neuron-inference"></a>

다음 콘텐츠를 통해 **mxnet\$1infer\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 샘플 이미지를 다운로드하고 이를 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
import mxnet as mx
import numpy as np

path='http://data.mxnet.io/models/imagenet/'
mx.test_utils.download(path+'synset.txt')

fname = mx.test_utils.download('https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg')
img = mx.image.imread(fname)

# convert into format (batch, RGB, width, height)
img = mx.image.imresize(img, 224, 224) 
# resize
img = img.transpose((2, 0, 1)) 
# Channel first
img = img.expand_dims(axis=0) 
# batchify
img = img.astype(dtype='float32')

sym, args, aux = mx.model.load_checkpoint('compiled_resnet50', 0)
softmax = mx.nd.random_normal(shape=(1,))
args['softmax_label'] = softmax
args['data'] = img
# Inferentia context
ctx = mx.neuron()

exe = sym.bind(ctx=ctx, args=args, aux_states=aux, grad_req='null')
with open('synset.txt', 'r') as f:
    labels = [l.rstrip() for l in f]

exe.forward(data=img)
prob = exe.outputs[0].asnumpy()
# print the top-5
prob = np.squeeze(prob)
a = np.argsort(prob)[::-1] 
for i in a[0:5]:
    print('probability=%f, class=%s' %(prob[i], labels[i]))
```

 다음 명령을 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
python mxnet_infer_resnet50.py
```

 출력은 다음과 같아야 합니다.

```
probability=0.642454, class=n02123045 tabby, tabby cat
probability=0.189407, class=n02123159 tiger cat
probability=0.100798, class=n02124075 Egyptian cat
probability=0.030649, class=n02127052 lynx, catamount
probability=0.016278, class=n02129604 tiger, Panthera tigris
```

**다음 단계**  
[MXNet-Neuron 모델 제공 사용](tutorial-inferentia-mxnet-neuron-serving.md)

# MXNet-Neuron 모델 제공 사용
<a name="tutorial-inferentia-mxnet-neuron-serving"></a>

이 자습서에서는 사전 교육된 MXNet 모델을 사용하여 다중 모델 서버(MMS)로 실시간 이미지를 분류하는 방법을 알아봅니다. MMS는 기계 학습 또는 딥 러닝 프레임워크를 사용하여 교육 받은 딥 러닝 모델을 제공하기 위한 유연하고 사용하기 쉬운 도구입니다. 이 자습서에는 AWS Neuron을 사용한 컴파일 단계와 MXNet을 사용한 MMS 구현이 포함되어 있습니다.

 Neuron SDK에 대한 자세한 내용은 [AWS Neuron SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/mxnet-neuron/index.html)를 참조하세요.

**Topics**
+ [

## 사전 조건
](#tutorial-inferentia-mxnet-neuron-serving-prerequisites)
+ [

## Conda 환경 활성화
](#tutorial-inferentia-mxnet-neuron-serving-activate)
+ [

## 예제 코드 다운로드
](#tutorial-inferentia-mxnet-neuron-serving-download)
+ [

## 모델 컴파일
](#tutorial-inferentia-mxnet-neuron-serving-compile)
+ [

## 추론 실행
](#tutorial-inferentia-mxnet-neuron-serving-inference)

## 사전 조건
<a name="tutorial-inferentia-mxnet-neuron-serving-prerequisites"></a>

 이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-mxnet-neuron-serving-activate"></a>

 다음 명령을 사용하여 MXNet-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_mxnet_p36
```

 현재 conda 환경을 종료하려면 다음을 실행합니다.

```
source deactivate
```

## 예제 코드 다운로드
<a name="tutorial-inferentia-mxnet-neuron-serving-download"></a>

 이 예제를 실행하려면 다음 명령을 사용하여 예제 코드를 다운로드합니다.

```
git clone https://github.com/awslabs/multi-model-server
cd multi-model-server/examples/mxnet_vision
```

## 모델 컴파일
<a name="tutorial-inferentia-mxnet-neuron-serving-compile"></a>

다음 콘텐츠를 통해 `multi-model-server-compile.py`라는 Python 스크립트를 생성합니다. 이 스크립트는 ResNet50 모델을 Inferentia 디바이스 대상으로 컴파일합니다.

```
import mxnet as mx
from mxnet.contrib import neuron
import numpy as np

path='http://data.mxnet.io/models/imagenet/'
mx.test_utils.download(path+'resnet/50-layers/resnet-50-0000.params')
mx.test_utils.download(path+'resnet/50-layers/resnet-50-symbol.json')
mx.test_utils.download(path+'synset.txt')

nn_name = "resnet-50"

#Load a model
sym, args, auxs = mx.model.load_checkpoint(nn_name, 0)

#Define compilation parameters#  - input shape and dtype
inputs = {'data' : mx.nd.zeros([1,3,224,224], dtype='float32') }

# compile graph to inferentia target
csym, cargs, cauxs = neuron.compile(sym, args, auxs, inputs)

# save compiled model
mx.model.save_checkpoint(nn_name + "_compiled", 0, csym, cargs, cauxs)
```

 모델을 컴파일하려면 다음 명령을 사용합니다.

```
python multi-model-server-compile.py
```

 출력은 다음과 같아야 합니다.

```
...
[21:18:40] src/nnvm/legacy_json_util.cc:209: Loading symbol saved by previous version v0.8.0. Attempting to upgrade...
[21:18:40] src/nnvm/legacy_json_util.cc:217: Symbol successfully upgraded!
[21:19:00] src/operator/subgraph/build_subgraph.cc:698: start to execute partition graph.
[21:19:00] src/nnvm/legacy_json_util.cc:209: Loading symbol saved by previous version v0.8.0. Attempting to upgrade...
[21:19:00] src/nnvm/legacy_json_util.cc:217: Symbol successfully upgraded!
```

 다음 콘텐츠를 통해 `signature.json`이라는 파일을 생성하여 입력 이름과 셰이프를 구성합니다.

```
{
  "inputs": [
    {
      "data_name": "data",
      "data_shape": [
        1,
        3,
        224,
        224
      ]
    }
  ]
}
```

다음 명령을 사용하여 `synset.txt` 파일을 다운로드합니다. 이 파일은 ImageNet 예측 클래스의 이름 목록입니다.

```
curl -O https://s3.amazonaws.com/model-server/model_archive_1.0/examples/squeezenet_v1.1/synset.txt
```

`model_server_template` 폴더의 템플릿에 따라 사용자 지정 서비스 클래스를 생성합니다. 다음 명령을 사용하여 템플릿을 현재 작업 디렉터리에 복사합니다.

```
cp -r ../model_service_template/* .
```

 `mxnet_model_service.py` 모듈을 편집하여 `mx.cpu()` 컨텍스트를 다음과 같이 `mx.neuron()` 컨텍스트로 바꿉니다. 또한 MXNet-Neuron은 NDARray 및 Gluon API를 지원하지 않으므로 `model_input`에 불필요한 데이터 복사본을 주석 처리해야 합니다.

```
...
self.mxnet_ctx = mx.neuron() if gpu_id is None else mx.gpu(gpu_id)
...
#model_input = [item.as_in_context(self.mxnet_ctx) for item in model_input]
```

 다음 명령을 사용하여 model-archiver로 모델을 패키징합니다.

```
cd ~/multi-model-server/examples
model-archiver --force --model-name resnet-50_compiled --model-path mxnet_vision --handler mxnet_vision_service:handle
```

## 추론 실행
<a name="tutorial-inferentia-mxnet-neuron-serving-inference"></a>

다중 모델 서버를 시작하고 다음 명령을 사용하여 RESTful API를 사용하는 모델을 로드합니다. **neuron-rtd**가 기본 설정으로 실행 중인지 확인합니다.

```
cd ~/multi-model-server/
multi-model-server --start --model-store examples > /dev/null # Pipe to log file if you want to keep a log of MMS
curl -v -X POST "http://localhost:8081/models?initial_workers=1&max_workers=4&synchronous=true&url=resnet-50_compiled.mar"
sleep 10 # allow sufficient time to load model
```

 다음 명령을 사용하여 예제 이미지로 추론을 실행합니다.

```
curl -O https://raw.githubusercontent.com/awslabs/multi-model-server/master/docs/images/kitten_small.jpg
curl -X POST http://127.0.0.1:8080/predictions/resnet-50_compiled -T kitten_small.jpg
```

 출력은 다음과 같아야 합니다.

```
[
  {
    "probability": 0.6388034820556641,
    "class": "n02123045 tabby, tabby cat"
  },
  {
    "probability": 0.16900072991847992,
    "class": "n02123159 tiger cat"
  },
  {
    "probability": 0.12221276015043259,
    "class": "n02124075 Egyptian cat"
  },
  {
    "probability": 0.028706775978207588,
    "class": "n02127052 lynx, catamount"
  },
  {
    "probability": 0.01915954425930977,
    "class": "n02129604 tiger, Panthera tigris"
  }
]
```

 테스트 후 정리하려면 RESTful API를 통해 delete 명령을 실행하고 다음 명령을 사용하여 모델 서버를 중지합니다.

```
curl -X DELETE http://127.0.0.1:8081/models/resnet-50_compiled

multi-model-server --stop
```

 다음 결과가 표시됩니다.

```
{
  "status": "Model \"resnet-50_compiled\" unregistered"
}
Model server stopped.
Found 1 models and 1 NCGs.
Unloading 10001 (MODEL_STATUS_STARTED) :: success
Destroying NCG 1 :: success
```

# PyTorch-Neuron 및 AWS Neuron 컴파일러 사용
<a name="tutorial-inferentia-pytorch-neuron"></a>

PyTorch-Neuron 컴파일 API는 AWS Inferentia 디바이스에서 실행할 수 있는 모델 그래프를 컴파일하는 방법을 제공합니다.

훈련된 모델은 Inf1 인스턴스에서 배포하기 전에 Inferentia 대상에 컴파일되어야 합니다. 다음 자습서에서는 torchvision ResNet50 모델을 컴파일하고 저장된 TorchScript 모듈로 내보냅니다. 이러한 모델은 추론을 실행하는 데 사용됩니다.

편의상 이 자습서에서는 컴파일 및 추론 모두에 Inf1 인스턴스를 사용합니다. 실제로는 c5 인스턴스 패밀리와 같은 다른 인스턴스 유형을 사용하여 모델을 컴파일할 수 있습니다. 그런 다음 컴파일된 모델을 Inf1 추론 서버에 배포해야 합니다. 자세한 내용은 [AWS Neuron PyTorch SDK 설명서](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/pytorch-neuron/index.html)를 참조하세요.

**Topics**
+ [

## 사전 조건
](#tutorial-inferentia-pytorch-neuron-prerequisites)
+ [

## Conda 환경 활성화
](#tutorial-inferentia-pytorch-neuron-activate)
+ [

## Resnet50 컴파일
](#tutorial-inferentia-pytorch-neuron-compilation)
+ [

## ResNet50 추론
](#tutorial-inferentia-pytorch-neuron-inference)

## 사전 조건
<a name="tutorial-inferentia-pytorch-neuron-prerequisites"></a>

이 자습서를 사용하기 전에 [AWS Neuron을 사용하여 DLAMI 인스턴스 시작](tutorial-inferentia-launching.md)의 설정 단계를 완료해야 합니다. 또한 딥 러닝 및 DLAMI 사용에 익숙해야 합니다.

## Conda 환경 활성화
<a name="tutorial-inferentia-pytorch-neuron-activate"></a>

다음 명령을 사용하여 PyTorch-Neuron conda 환경을 활성화합니다.

```
source activate aws_neuron_pytorch_p36
```

현재 conda 환경을 종료하려면 다음을 실행합니다.

```
source deactivate
```

## Resnet50 컴파일
<a name="tutorial-inferentia-pytorch-neuron-compilation"></a>

다음 콘텐츠를 통해 **pytorch\$1trace\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 PyTorch-Neuron 컴파일 Python API를 사용하여 ResNet-50 모델을 컴파일합니다.

**참고**  
토치비전 모델과 토치 패키지 버전 간에는 종속성이 있으며, 토치비전 모델을 컴파일할 때 이 점을 알고 있어야 합니다. 이러한 종속성 규칙은 pip를 통해 관리할 수 있습니다. Torchvision==0.6.1은 torch==1.5.1 릴리스와 일치하고, torchvision==0.8.2는 torch==1.7.1 릴리스와 일치합니다.

```
import torch
import numpy as np
import os
import torch_neuron
from torchvision import models

image = torch.zeros([1, 3, 224, 224], dtype=torch.float32)

## Load a pretrained ResNet50 model
model = models.resnet50(pretrained=True)

## Tell the model we are using it for evaluation (not training)
model.eval()
model_neuron = torch.neuron.trace(model, example_inputs=[image])

## Export to saved model
model_neuron.save("resnet50_neuron.pt")
```

컴파일 스크립트를 실행합니다.

```
python pytorch_trace_resnet50.py
```

컴파일이 끝날 때까지 몇 분 정도 소요될 수 있습니다. 컴파일이 완료되면 컴파일된 모델이 로컬 디렉터리에 `resnet50_neuron.pt`로 저장됩니다.

## ResNet50 추론
<a name="tutorial-inferentia-pytorch-neuron-inference"></a>

다음 콘텐츠를 통해 **pytorch\$1infer\$1resnet50.py**라는 Python 스크립트를 생성합니다. 이 스크립트는 샘플 이미지를 다운로드하고 이를 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
import os
import time
import torch
import torch_neuron
import json
import numpy as np

from urllib import request

from torchvision import models, transforms, datasets

## Create an image directory containing a small kitten
os.makedirs("./torch_neuron_test/images", exist_ok=True)
request.urlretrieve("https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg",
                    "./torch_neuron_test/images/kitten_small.jpg")


## Fetch labels to output the top classifications
request.urlretrieve("https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json","imagenet_class_index.json")
idx2label = []

with open("imagenet_class_index.json", "r") as read_file:
    class_idx = json.load(read_file)
    idx2label = [class_idx[str(k)][1] for k in range(len(class_idx))]

## Import a sample image and normalize it into a tensor
normalize = transforms.Normalize(
    mean=[0.485, 0.456, 0.406],
    std=[0.229, 0.224, 0.225])

eval_dataset = datasets.ImageFolder(
    os.path.dirname("./torch_neuron_test/"),
    transforms.Compose([
    transforms.Resize([224, 224]),
    transforms.ToTensor(),
    normalize,
    ])
)

image, _ = eval_dataset[0]
image = torch.tensor(image.numpy()[np.newaxis, ...])

## Load model
model_neuron = torch.jit.load( 'resnet50_neuron.pt' )

## Predict
results = model_neuron( image )

# Get the top 5 results
top5_idx = results[0].sort()[1][-5:]

# Lookup and print the top 5 labels
top5_labels = [idx2label[idx] for idx in top5_idx]

print("Top 5 labels:\n {}".format(top5_labels) )
```

다음 명령을 사용하여 컴파일된 모델에 대한 추론을 실행합니다.

```
python pytorch_infer_resnet50.py
```

출력은 다음과 같아야 합니다.

```
Top 5 labels:
 ['tiger', 'lynx', 'tiger_cat', 'Egyptian_cat', 'tabby']
```

# ARM64 DLAMI
<a name="tutorial-arm64"></a>

AWS ARM64 GPU DLAMIs는 딥 러닝 워크로드에 높은 성능과 비용 효율성을 제공하도록 설계되었습니다. 특히 G5g 인스턴스 유형에는 Arm64-based [AWS Graviton2 프로세서](https://aws.amazon.com/ec2/graviton/)가 탑재되어 있습니다.이 프로세서는 처음부터 클라우드에서 워크로드를 실행하는 방법에 맞게 최적화 AWS 되어 있습니다. AWS ARM64 GPU DLAMIs는 Docker, NVIDIA Docker, NVIDIA 드라이버, CUDA, CuDNN, NCCL뿐만 아니라 TensorFlow 및 PyTorch와 같은 인기 있는 기계 학습 프레임워크로 사전 구성되어 있습니다.

G5g 인스턴스 유형을 사용하면 Graviton2의 가격 및 성능 이점을 활용하여 GPU 가속을 지원하는 x86 기반 인스턴스보다 훨씬 저렴한 비용으로 GPU 가속 딥 러닝 모델을 배포할 수 있습니다.

## ARM64 DLAMI 선택
<a name="tutorial-arm64-select-dlami"></a>

선택한 ARM64 DLAMI로 [G5g 인스턴스](https://aws.amazon.com/ec2/instance-types/g5g/)를 시작합니다.

DLAMI 시작에 대한 단계별 지침은 [DLAMI 시작 및 구성](https://docs.aws.amazon.com/dlami/latest/devguide/launch-config.html)을 참조하세요.

최신 ARM64 DLAMI 목록은 [DLAMI 릴리스 노트](https://docs.aws.amazon.com/dlami/latest/devguide/appendix-ami-release-notes.html)를 참조하세요.

## 시작하기
<a name="tutorial-arm64-get-started"></a>

다음 섹션에서는 ARM64 DLAMI 사용을 시작하는 방법을 보여 줍니다.

**Topics**
+ [

## ARM64 DLAMI 선택
](#tutorial-arm64-select-dlami)
+ [

## 시작하기
](#tutorial-arm64-get-started)
+ [

# ARM64 GPU PyTorch DLAMI 사용
](tutorial-arm64-pytorch.md)

# ARM64 GPU PyTorch DLAMI 사용
<a name="tutorial-arm64-pytorch"></a>

 AWS Deep Learning AMIs 는 Arm64 프로세서 기반 GPUs와 함께 사용할 준비가 되었으며 PyTorch에 최적화되어 제공됩니다. ARM64 GPU PyTorch DLAMI에는 딥 러닝 훈련 및 추론 사용 사례를 위해 [PyTorch](https://aws.amazon.com/pytorch), [TorchVision](https://pytorch.org/vision/stable/index.html) 및 [TorchServe](https://pytorch.org/serve/)로 사전 구성된 Python 환경이 포함되어 있습니다.

**Topics**
+ [

## PyTorch Python 환경 확인
](#tutorial-arm64-pytorch-environment)
+ [

## PyTorch를 사용하여 교육 샘플 실행
](#tutorial-arm64-pytorch-training)
+ [

## PyTorch로 추론 샘플 실행
](#tutorial-arm64-pytorch-inference)

## PyTorch Python 환경 확인
<a name="tutorial-arm64-pytorch-environment"></a>

G5g 인스턴스에 연결하고 다음 명령을 사용하여 기본 Conda 환경을 활성화합니다.

```
source activate base
```

명령 프롬프트는 PyTorch, TorchVision 및 기타 라이브러리가 포함된 기본 Conda 환경에서 작업하고 있음을 나타내야 합니다.

```
(base) $
```

PyTorch 환경의 기본 도구 경로를 확인합니다.

```
(base) $ which python
(base) $ which pip
(base) $ which conda
(base) $ which mamba
>>> import torch, torchvision
>>> torch.__version__
>>> torchvision.__version__
>>> v = torch.autograd.Variable(torch.randn(10, 3, 224, 224))
>>> v = torch.autograd.Variable(torch.randn(10, 3, 224, 224)).cuda()
>>> assert isinstance(v, torch.Tensor)
```

## PyTorch를 사용하여 교육 샘플 실행
<a name="tutorial-arm64-pytorch-training"></a>

샘플 MNIST 교육 작업을 실행합니다.

```
git clone https://github.com/pytorch/examples.git
cd examples/mnist
python main.py
```

출력은 다음과 비슷한 형태가 됩니다.

```
...
Train Epoch: 14 [56320/60000 (94%)]    Loss: 0.021424
Train Epoch: 14 [56960/60000 (95%)]    Loss: 0.023695
Train Epoch: 14 [57600/60000 (96%)]    Loss: 0.001973
Train Epoch: 14 [58240/60000 (97%)]    Loss: 0.007121
Train Epoch: 14 [58880/60000 (98%)]    Loss: 0.003717
Train Epoch: 14 [59520/60000 (99%)]    Loss: 0.001729
Test set: Average loss: 0.0275, Accuracy: 9916/10000 (99%)
```

## PyTorch로 추론 샘플 실행
<a name="tutorial-arm64-pytorch-inference"></a>

다음 명령을 사용하여 사전 학습된 densenet161 모델을 다운로드하고 TorchServe를 사용하여 추론을 실행하세요.

```
# Set up TorchServe
cd $HOME
git clone https://github.com/pytorch/serve.git
mkdir -p serve/model_store
cd serve

# Download a pre-trained densenet161 model
wget https://download.pytorch.org/models/densenet161-8d451a50.pth >/dev/null

# Save the model using torch-model-archiver
torch-model-archiver --model-name densenet161 \
    --version 1.0 \
    --model-file examples/image_classifier/densenet_161/model.py \
    --serialized-file densenet161-8d451a50.pth \
    --handler image_classifier \
    --extra-files examples/image_classifier/index_to_name.json  \
    --export-path model_store 

# Start the model server
torchserve --start --no-config-snapshots \
    --model-store model_store \
    --models densenet161=densenet161.mar &> torchserve.log

# Wait for the model server to start
sleep 30

# Run a prediction request
curl http://127.0.0.1:8080/predictions/densenet161 -T examples/image_classifier/kitten.jpg
```

출력은 다음과 비슷한 형태가 됩니다.

```
{
  "tiger_cat": 0.4693363308906555,
  "tabby": 0.4633873701095581,
  "Egyptian_cat": 0.06456123292446136,
  "lynx": 0.0012828150065615773,
  "plastic_bag": 0.00023322898778133094
}
```

다음 명령을 사용하여 densenet161 모델을 등록 취소하고 서버를 중지하세요.

```
curl -X DELETE http://localhost:8081/models/densenet161/1.0
torchserve --stop
```

출력은 다음과 비슷한 형태가 됩니다.

```
{
  "status": "Model \"densenet161\" unregistered"
}
TorchServe has stopped.
```

# Inference
<a name="tutorial-inference"></a>

이 섹션은 DLAMI의 프레임워크 및 도구를 사용하여 추론 실행 방법에 대한 자습서입니다

## 추론 도구
<a name="tutorial-inference-tools"></a>
+ [TensorFlow Serving](tutorial-tfserving.md)

# 모델 제공
<a name="model-serving"></a>

다음은 Conda를 사용하는 DLAMI에 설치된 모델 제공 옵션입니다. 옵션 중 한 가지를 클릭하여 사용법을 알아보십시오.

**Topics**
+ [

# TensorFlow Serving
](tutorial-tfserving.md)
+ [

# TorchServe
](tutorial-torchserve.md)

# TensorFlow Serving
<a name="tutorial-tfserving"></a>

[TensorFlow Serving은 머신 러닝 모델을 위한 유연한 고성능 서비스 시스템입니다.](https://www.tensorflow.org/tfx/guide/serving)

`tensorflow-serving-api`에는 단일 프레임워크 DLAMI가 사전 설치되어 있습니다. tensorflow serving을 사용하려면 먼저 TensorFlow 환경을 활성화합니다.

```
$ source /opt/tensorflow/bin/activate
```

그런 다음 원하는 텍스트 편집기를 사용하여 다음 내용이 들어 있는 스크립트를 생성합니다. 이름을 `test_train_mnist.py`로 지정합니다. 이 스크립트는 이미지를 분류하는 신경망 기계 학습 모델을 훈련하고 평가하는 [TensorFlow 자습서](https://github.com/tensorflow/docs/blob/master/site/en/tutorials/quickstart/beginner.ipynb)에서 참조할 수 있습니다.

```
import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)
```

이제 서버 위치, 포트 및 허스키 사진의 파일 이름을 파라미터로 전달하는 스크립트를 실행합니다.

```
$ /opt/tensorflow/bin/python3 test_train_mnist.py
```

 이 스크립트에서 결과가 출력되려면 시간이 걸리므로 인내심을 가지고 기다리십시오. 훈련 완료 시 다음과 같은 결과를 보게 됩니다.

```
I0000 00:00:1739482012.389276    4284 device_compiler.h:188] Compiled cluster using XLA!  This line is logged at most once for the lifetime of the process.
1875/1875 [==============================] - 24s 2ms/step - loss: 0.2973 - accuracy: 0.9134 
Epoch 2/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.1422 - accuracy: 0.9582
Epoch 3/5
1875/1875 [==============================] - 3s 1ms/step - loss: 0.1076 - accuracy: 0.9687
Epoch 4/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.0872 - accuracy: 0.9731
Epoch 5/5
1875/1875 [==============================] - 3s 1ms/step - loss: 0.0731 - accuracy: 0.9771
313/313 [==============================] - 0s 1ms/step - loss: 0.0749 - accuracy: 0.9780
```

## 더 많은 기능과 예제
<a name="tutorial-tfserving-project"></a>

TensorFlow Serving에 대한 자세한 내용은 [TensorFlow 웹 사이트](https://www.tensorflow.org/serving/)를 참조하세요.

# TorchServe
<a name="tutorial-torchserve"></a>

TorchServe는 PyTorch에서 내보낸 딥 러닝 모델을 제공하기 위한 유연한 도구입니다. TorchServe에는 Conda를 사용하는 Deep Learning AMI가 사전 설치되어 있습니다.

TorchServe 사용에 대한 자세한 내용은 [PyTorch용 모델 서버 설명서](https://github.com/pytorch/serve/blob/master/docs/README.md)를 참조하세요.

 **주제** 

## TorchServe에서 이미지 분류 모델 서비스
<a name="tutorial-torchserve-serving"></a>

이 자습서에서는 TorchServe로 이미지 분류 모델을 서비스하는 방법을 보여줍니다. PyTorch에서 제공하는 DenseNet-161 모델을 사용합니다. 서버가 실행되면 예측 요청을 수신합니다. 예를 들어 고양이의 이미지와 같은 이미지를 업로드할 때 서버는 모델이 교육한 클래스 가운데 가장 일치하는 5개 클래스에 대한 예측을 반환합니다.

**TorchServe에서 예제 이미지 분류 모델을 서비스하려면**

1. Conda를 사용하는 DLAMI(버전 34 이상)의 Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스에 연결합니다.

1. `pytorch_p310` 환경을 활성화합니다.

   ```
   source activate pytorch_p310
   ```

1. TorchServe 리포지토리를 복제한 다음 모델을 저장할 디렉토리를 생성합니다.  

   ```
   git clone https://github.com/pytorch/serve.git
   mkdir model_store
   ```

1. 모델 아카이버를 사용하여 모델을 보관합니다. `extra-files` 매개변수는 `TorchServe` 리포지토리의 파일을 사용하므로 필요한 경우 경로를 업데이트하세요. 모델 아카이버에 대한 자세한 내용은 [TorchServe용 Torch 모델 아카이버](https://github.com/pytorch/serve/blob/master/model-archiver/README.md)를 참조하세요.

   ```
   wget https://download.pytorch.org/models/densenet161-8d451a50.pth
   torch-model-archiver --model-name densenet161 --version 1.0 --model-file ./serve/examples/image_classifier/densenet_161/model.py --serialized-file densenet161-8d451a50.pth --export-path model_store --extra-files ./serve/examples/image_classifier/index_to_name.json --handler image_classifier
   ```

1. TorchServe를 실행하여 엔드포인트를 시작합니다. `> /dev/null`을 추가하면 로그 출력이 중지됩니다.

   ```
   torchserve --start --ncs --model-store model_store --models densenet161.mar > /dev/null
   ```

1. 고양이의 이미지를 다운로드한 다음 TorchServe 예측 엔드포인트로 전송합니다.

   ```
   curl -O https://s3.amazonaws.com/model-server/inputs/kitten.jpg
   curl http://127.0.0.1:8080/predictions/densenet161 -T kitten.jpg
   ```

   예측 엔드포인트는 다음 상위 5개의 예측과 유사한 예측을 JSON으로 반환합니다. 여기에서 이미지는 47%의 확률로 이집트 고양이를 포함하고, 그 다음으로 46%의 확률로 태비 고양이를 포함합니다.

   ```
   {
    "tiger_cat": 0.46933576464653015,
    "tabby": 0.463387668132782,
    "Egyptian_cat": 0.0645613968372345,
    "lynx": 0.0012828196631744504,
    "plastic_bag": 0.00023323058849200606
   }
   ```

1. 테스트를 마친 후 서버를 중단합니다.

   ```
   torchserve --stop
   ```

 **기타 예제** 

TorchServe에는 사용자가 DLAMI 인스턴스에서 실행할 수 있는 다양한 예제가 있습니다. 이러한 예제는 [TorchServe 프로젝트 리포지토리](https://github.com/pytorch/serve/tree/master/examples)에서 볼 수 있습니다.

 **추가 정보** 

 Docker와 최신 TorchServe 기능을 사용하여 TorchServe를 설정하는 방법을 포함한 더 많은 TorchServe 설명서는 GitHub의 [TorchServe 프로젝트](https://github.com/pytorch/serve) 페이지를 참조하세요.