<jupyter_start><jupyter_text>SageMaker Edge Manager Example***본 노트북 코드는 [AWS 공식 예제에 등록된 영문 노트북](https://github.com/aws/amazon-sagemaker-examples/blob/master/sagemaker_edge_manager/sagemaker_edge_example/sagemaker_edge_example.ipynb)의 한국어 번역본으로 직역이 아닌 추가 설명을 덧붙였습니다.***1. [Introduction](Introduction)2. [Demo Setup](Demo-Setup)    1. [Launch EC2 Instance](Launch-EC2-Instance)3. [Compile Model using SageMaker Neo](Compile-Model-using-SageMaker-Neo)    1. [Load pretrained model](Load-pretrained-model)6. [Deploy Model using Sagemaker Edge Manager](Deploy-Model-using-Sagemaker-Edge-Manager)    1. [Package Model](Package-Model)    2. [Create AWS IoT thing](Create-AWS-IoT-thing)    3. [Create Device Fleet](Create-Device-Fleet)    4. [Create and register client certificate with AWS IoT](Create-and-register-client-certificate-with-AWS-IoT)7. [Inference on Edge](Inference-on-Edge)    1. [Setup Sagemaker Edge Manager Agent](Setup-Sagemaker-Edge-Manager-Agent)     2. [Load Model](Load-Model)    3. [List Models](List-Models)    4. [Run Predict](Run-Predict)    5. [Capture Data](Capture-Data)    6. [Unload Model](Unload-Model)8. [Clean Up](Clean-Up)9. [Appendix](Appendix)    1. [(Optional)Install CloudWatch Agent]((Optional)Install-CloudWatch-Agent )  IntroductionSageMaker Edge Manager는 Amazon SageMaker의 서비스로 다음을 수행할 수 있습니다.+ 엣지 디바이스 하드웨어용 커스텀 모델 준비+ 엣지 디바이스에서 머신 러닝 추론을 효율적으로 실행하기위한 런타임 포함+ 디바이스가 각 모델의 데이터 샘플을 SageMaker로 안전하게 전송하여 재레이블링 및 재훈련 수행이 서비스에는 두 가지 주요 구성 요소들이 있습니다.+ SageMaker Edge Manager in the Cloud + SageMaker Edge Agent on the Edge device이 노트북은 엣지 디바이스에서 실행중인 SageMaker Edge를 가져오기 위한 end-to-end 워크플로를 보여줍니다. 여기에는 다음 단계가 포함됩니다.+ SageMaker Neo를 사용하여 모델 컴파일+ Sagemaker Edge Manager로 컴파일된 모델 패키징+ Sagemaker Edge Manager Agent로 배포+ 모델로 추론 실행+ 모델의 입력 및 출력 데이터를 S3로 캡처**Note**:일반적으로 SageMaker Edge Agent는 실제 Edge 디바이스에서 실행되지만, 본 핸즈온에서는 EC2 인스턴스를 가상의 엣지 디바이스로 가정하여 EC2 인스턴스에서 Agent를 실행합니다.- 컴파일된 모델을 패키징한 다음 엣지 디바이스의 Agent에 로드하여 예측을 수행하는 방법- Agent를 통해 모델의 입력 및 출력을 S3에 캡처하는 방법을 보여줍니다.이 노트북은 SageMaker 노트북 인스턴스(noteboook instance) 전용으로, `conda_tensorflow_p36` 커널에서 실행해야 합니다. (SageMaker Studio에서의 동작을 보증하지 않습니다.) **Please note**: 비용에 대한 자세한 내용은 [Edge Manager](https://aws.amazon.com/sagemaker/edge-manager/pricing) 를 참조하십시오.  Demo Setup SageMaker 액세스 권한이 있는 AWS account role이 필요합니다. 이 role은 SageMaker에게 S3에 대한 액세스 권한을 부여하고, EC2 인스턴스를 시작하고, Systems Manager로 명령을 보내는 데 사용됩니다.<jupyter_code>import sagemaker
from sagemaker import get_execution_role
import boto3
import botocore
import json

role = get_execution_role()
sess = sagemaker.Session()
region = boto3.Session().region_name
print(role)<jupyter_output>arn:aws:iam::387793684046:role/service-role/AmazonSageMaker-ExecutionRole-20200701T171346<jupyter_text>[IAM console](https://console.aws.amazon.com/iam)에서 위에 인쇄된 SageMakerrole을 찾아 아래의 Policy들을 role에 연결합니다.- AmazonEC2FullAccess - AmazonEC2RoleforSSM - AmazonSSMManagedInstanceCore - AmazonSSMFullAccess - AWSIoTFullAccess [여기](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.htmladd-policies-console)에서 role에 polucy를 연결하는 방법에 대한 자세한 정보를 찾을 수 있습니다.**실제 디바이스에서 이 예제를 시도하는 경우, AWSIoTFullAccess Policy만 연결하여 AWS IoT에서 인증서를 생성하십시오.** 그런 다음 컴파일 후 생성된 모델 아티팩트와 엣지 패키징 작업 후에 생성된 패키지 아티팩트를 저장하는 데 사용할 S3 버킷이 필요합니다.<jupyter_code># S3 bucket and folders for saving model artifacts.
# Feel free to specify different bucket/folders here if you wish.
bucket = sess.default_bucket() 
folder = 'DEMO-Sagemaker-Edge'
compilation_output_sub_folder = folder + '/compilation-output'
iot_folder = folder + '/iot'

# S3 Location to save the model artifact after compilation
s3_compilation_output_location = 's3://{}/{}'.format(bucket, compilation_output_sub_folder)<jupyter_output><empty_output><jupyter_text>마지막으로 테스트 이미지들을 S3 버킷에 업로드합니다. 이 이미지들은 나중에 추론에 사용됩니다.<jupyter_code>darknet_img_path = sess.upload_data('darknet.bmp', bucket, iot_folder)
keras_img_path = sess.upload_data('keras.bmp', bucket, iot_folder)<jupyter_output><empty_output><jupyter_text>Launch EC2 Instance 앞서 언급했듯이, 이 EC2 인스턴스는 Agent 소프트웨어를 실행하기 위해 엣지 디바이스 대신 사용됩니다.<jupyter_code>ec2_client = boto3.client('ec2', region_name=region)<jupyter_output><empty_output><jupyter_text>EC2 인스턴스에 대한 키 페어(key pair)를 생성하고 key pem 파일을 저장합니다. 이 키를 SSH와 함께 사용하여 인스턴스에 연결할 수 있습니다. 하지만, 이 노트북 예제에서는 SSH를 사용하지 않고 대신 AWS Systems Manager를 사용하여 인스턴스에 명령을 보냅니다.<jupyter_code>key_pairs = ec2_client.describe_key_pairs()
key_names = list(map(lambda x : x['KeyName'], key_pairs['KeyPairs']))

key_name = 'ec2-key-pair'

if key_name in key_names:
    ec2_key_pair = ec2_client.delete_key_pair(
        KeyName=key_name,
    )
ec2_key_pair = ec2_client.create_key_pair(
    KeyName=key_name,
)

key_pair = str(ec2_key_pair['KeyMaterial'])
key_pair_file = open('ec2-key-pair.pem','w')
key_pair_file.write(key_pair)
key_pair_file.close()<jupyter_output><empty_output><jupyter_text>사용할 EC2 인스턴스에 대한 role을 생성합니다. 자세한 내용은 [IAM roles for Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)를 참조하십시오.여기에 있는 단계에 따라 [IAM role을 생성](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.htmlcreate-iam-role) 합니다.이 때, role 이름과 role ARN을 기록해 둡니다. role 이름은 EC2 인스턴스를 시작할 때 사용되며, role ARN은 inline policy를 생성하는 데 필요합니다.그런 다음, 다음의 policy들을 role에 연결해 주세요.- AmazonS3FullAccess- AmazonSSMManagedInstanceCore- CloudWatchAgentAdminPolicy[IAM console](https://console.aws.amazon.com/iam)의 [데모 설정](Demo-Setup)에서 이 노트북에 사용하는 동일한 SageMaker role을 찾고 role 요약 페이지에서 `Add inline policy` 버튼을 클릭한 다음, JSON 포맷을 선택하고 내용을 아래 코드로 변경해 주세요.아래 내용을 복사하기 전에 `iam:PassRole` action에 대해 `Resource` 필드에서 방금 생성한 EC2 role ARN을 사용해야 합니다.```{    "Version": "2012-10-17",    "Statement": [        {            "Effect": "Allow",            "Action": "iam:PassRole",            "Resource": "arn:aws:iam:::role/"        }    ]}``` EC2 C5 인스턴스를 시작합니다. 이 예시에서는 AWS Deep Learning AMI를 사용합니다.<jupyter_code>ami_map = {
    'us-east-1': 'ami-063585f0e06d22308',
    'us-east-2': 'ami-01bd6a1621a6968d7',
    'us-west-2': 'ami-0bc87a16c757a7f07',
    'eu-central-1': 'ami-01227276a4e5a4a31',
    'ap-northeast-1': 'ami-03b8cfea5460e4881',
    'eu-west-1': 'ami-006ff58f5247c50eb'
}
#ec2_profile_name = <ec2_role_name>  # the name of the role created for EC2
ec2_profile_name = 'EC2-hol'

ec2_instance = ec2_client.run_instances(
     ImageId=ami_map[region],
     MinCount=1,
     MaxCount=1,
     InstanceType='c5.large',
     KeyName='ec2-key-pair',
     IamInstanceProfile={
        'Name': ec2_profile_name}
)
instance_id = ec2_instance['Instances'][0]['InstanceId'] # will used for running inference later
print(instance_id)<jupyter_output>i-04d363413121b888a<jupyter_text>Compile Model using SageMaker NeoSageMaker client를 생성합니다.<jupyter_code>sagemaker_client = boto3.client('sagemaker', region_name=region)<jupyter_output><empty_output><jupyter_text>Download pretrained darknet model<jupyter_code>!wget -O yolov3-tiny.cfg https://github.com/pjreddie/darknet/blob/master/cfg/yolov3-tiny.cfg?raw=true
!wget https://pjreddie.com/media/files/yolov3-tiny.weights
import tarfile

with tarfile.open('yolov3-tiny.tar.gz', mode='w:gz') as archive:
    archive.add('yolov3-tiny.cfg')
    archive.add('yolov3-tiny.weights')
darknet_model_path = sess.upload_data('yolov3-tiny.tar.gz', bucket, folder)<jupyter_output><empty_output><jupyter_text>**Note**: `create_compilation_job()`을 호출할 때 사용자는 성공적인 컴파일을 위해 모델에 필요한 올바른 input shape을 제공해야 합니다. 다른 모델을 사용하는 경우, 프레임워크와 input shape를 확인하십시오.<jupyter_code>darknet_model_data_shape = '{"data":[1,3,416,416]}'
darknet_model_framework = 'darknet'
target_device = 'ml_c5'
import time
darknet_compilation_job_name = 'Sagemaker-Edge-'+ str(time.time()).split('.')[0]
print('Compilation job for %s started' % darknet_compilation_job_name)

response = sagemaker_client.create_compilation_job(
        CompilationJobName=darknet_compilation_job_name,
        RoleArn=role,
        InputConfig={
            'S3Uri': darknet_model_path,
            'DataInputConfig': darknet_model_data_shape,
            'Framework': darknet_model_framework.upper()
        },
        OutputConfig={
            'S3OutputLocation': s3_compilation_output_location,
            'TargetDevice': target_device 
        },
        StoppingCondition={
            'MaxRuntimeInSeconds': 900
        }
    )

print(response)

# Poll every 30 sec
while True:
    response = sagemaker_client.describe_compilation_job(CompilationJobName=darknet_compilation_job_name)
    if response['CompilationJobStatus'] == 'COMPLETED':
        break
    elif response['CompilationJobStatus'] == 'FAILED':
        raise RuntimeError('Compilation failed')
    print('Compiling ...')
    time.sleep(30)
print('Done!')<jupyter_output>Compilation job for Sagemaker-Edge-1616301271 started
{'CompilationJobArn': 'arn:aws:sagemaker:us-east-1:387793684046:compilation-job/Sagemaker-Edge-1616301271', 'ResponseMetadata': {'RequestId': '750ef142-3673-4b53-bbb0-d5b8a0fcaa20', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '750ef142-3673-4b53-bbb0-d5b8a0fcaa20', 'content-type': 'application/x-amz-json-1.1', 'content-length': '106', 'date': 'Sun, 21 Mar 2021 04:34:32 GMT'}, 'RetryAttempts': 0}}
Compiling ...
Compiling ...
Done!<jupyter_text>Package Model using Sagemaker Edge Manager이 섹션에서는 서로 다른 두 가지 모델을 패키징하는 방법을 살펴 봅니다. 하나는 Image Classification 모델 (Keras 프레임워크 기반) 이고 다른 하나는 DarkNet 프레임워크의 Object Detection 모델입니다. 이는 SageMaker Edge Manager의 다양성을 보여줍니다.  Package Darknet Model컴파일된 모델을 엣지 디바이스에 배포하려면, 먼저 Sagemaker Edge Manager 클라우드 서비스로 모델을 패키징해야합니다.<jupyter_code>darknet_packaged_model_name = "darknet-model"
darknet_model_version = "1.0"
darknet_model_package = '{}-{}.tar.gz'.format(darknet_packaged_model_name, darknet_model_version)
darknet_packaging_job_name=darknet_compilation_job_name+"-packaging"
response = sagemaker_client.create_edge_packaging_job(
    RoleArn=role,
    OutputConfig={
        'S3OutputLocation': s3_compilation_output_location,
    },
    ModelName=darknet_packaged_model_name,
    ModelVersion=darknet_model_version,
    EdgePackagingJobName=darknet_packaging_job_name,
    CompilationJobName=darknet_compilation_job_name,
)

print(response)

# Poll every 30 sec
while True:
    job_status = sagemaker_client.describe_edge_packaging_job(EdgePackagingJobName=darknet_packaging_job_name)
    if job_status['EdgePackagingJobStatus'] == 'COMPLETED':
        break
    elif job_status['EdgePackagingJobStatus'] == 'FAILED':
        raise RuntimeError('Edge Packaging failed')
    print('Packaging ...')
    time.sleep(30)
print('Done!')
darknet_model_data = job_status["ModelArtifact"]<jupyter_output><empty_output><jupyter_text>Download pretrained Keras model<jupyter_code>import tensorflow as tf

model = tf.keras.applications.MobileNetV2()
model.save('mobilenet_v2.h5')
import tarfile

with tarfile.open('mobilenet_v2.tar.gz', mode='w:gz') as archive:
    archive.add('mobilenet_v2.h5')
keras_model_path = sess.upload_data('mobilenet_v2.tar.gz', bucket, folder)<jupyter_output><empty_output><jupyter_text>**Note**: `create_compilation_job()`을 호출할 때 사용자는 성공적인 컴파일을 위해 모델에 필요한 올바른 input shape을 제공해야 합니다. 다른 모델을 사용하는 경우, 프레임워크와 input shape를 확인하십시오.<jupyter_code>keras_model_data_shape = '{"input_1":[1,3,224,224]}'
keras_model_framework = 'keras'
target_device = 'ml_c5'
import time
keras_compilation_job_name = 'Sagemaker-Edge-'+ str(time.time()).split('.')[0]
print('Compilation job for %s started' % keras_compilation_job_name)

response = sagemaker_client.create_compilation_job(
        CompilationJobName=keras_compilation_job_name,
        RoleArn=role,
        InputConfig={
            'S3Uri': keras_model_path,
            'DataInputConfig': keras_model_data_shape,
            'Framework': keras_model_framework.upper()
        },
        OutputConfig={
            'S3OutputLocation': s3_compilation_output_location,
            'TargetDevice': target_device 
        },
        StoppingCondition={
            'MaxRuntimeInSeconds': 900
        }
    )

print(response)

# Poll every 30 sec
while True:
    response = sagemaker_client.describe_compilation_job(CompilationJobName=keras_compilation_job_name)
    if response['CompilationJobStatus'] == 'COMPLETED':
        break
    elif response['CompilationJobStatus'] == 'FAILED':
        raise RuntimeError('Compilation failed')
    print('Compiling ...')
    time.sleep(30)
print('Done!')<jupyter_output>Compilation job for Sagemaker-Edge-1616301401 started
{'CompilationJobArn': 'arn:aws:sagemaker:us-east-1:387793684046:compilation-job/Sagemaker-Edge-1616301401', 'ResponseMetadata': {'RequestId': '0a7fd886-d9d6-46f5-8d38-fd5ae9efd2e3', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '0a7fd886-d9d6-46f5-8d38-fd5ae9efd2e3', 'content-type': 'application/x-amz-json-1.1', 'content-length': '106', 'date': 'Sun, 21 Mar 2021 04:36:40 GMT'}, 'RetryAttempts': 0}}
Compiling ...
Compiling ...
Compiling ...
Done!<jupyter_text>Package Keras Model<jupyter_code>keras_packaged_model_name = "keras-model"
keras_model_version = "1.0"
keras_model_package = '{}-{}.tar.gz'.format(keras_packaged_model_name, keras_model_version)
keras_packaging_job_name=keras_compilation_job_name+"-packaging"
response = sagemaker_client.create_edge_packaging_job(
    RoleArn=role,
    OutputConfig={
        'S3OutputLocation': s3_compilation_output_location,
    },
    ModelName=keras_packaged_model_name,
    ModelVersion=keras_model_version,
    EdgePackagingJobName=keras_packaging_job_name,
    CompilationJobName=keras_compilation_job_name,
)

print(response)

# Poll every 30 sec
while True:
    job_status = sagemaker_client.describe_edge_packaging_job(EdgePackagingJobName=keras_packaging_job_name)
    if job_status['EdgePackagingJobStatus'] == 'COMPLETED':
        break
    elif job_status['EdgePackagingJobStatus'] == 'FAILED':
        raise RuntimeError('Edge Packaging failed')
    print('Packaging ...')
    time.sleep(30)
print('Done!')
keras_model_data = job_status["ModelArtifact"]<jupyter_output><empty_output><jupyter_text>Create AWS IoT thingSageMaker Edge Manager는 AWS IoT core를 사용하여 디바이스를 인증하므로 AWS Cloud에서 SageMaker Edge Manager 엔드포인트를 호출할 수 있습니다.Edge 디바이스 AWS에서 AWS 서비스를 사용하려면 먼저 인증이 필요하며, AWS IoT 기반 인증 방법을 권장합니다. 자세한 내용은 아래 링크를 참조해 주십시오.- https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html- https://aws.amazon.com/blogs/security/how-to-eliminate-the-need-for-hardcoded-aws-credentials-in-devices-by-using-the-aws-iot-credentials-provider<jupyter_code>iot_client = boto3.client('iot', region_name=region)
iot_thing_name = 'sagemaker-edge-thing-demo'
iot_thing_type = 'SagemakerEdgeDemo'
iot_client.create_thing_type(
    thingTypeName=iot_thing_type
)
iot_client.create_thing(
    thingName=iot_thing_name,
    thingTypeName=iot_thing_type
)<jupyter_output><empty_output><jupyter_text>Create Device Fleet  Create IAM role for device fleet device fleet의 디바이스를 대신하여 자격 증명 공급자가 맡을 IAM role을 AWS 계정에 설정합니다.**Notice**: role의 이름은 반드시 `SageMaker`로 시작해야 합니다.[IAM console](https://console.aws.amazon.com/iam)으로 접속하여 IoT role을 생성하고 아래 policy를 추가해 주세요.- AmazonSageMakerEdgeDeviceFleetPolicy아래 코드를 `trust relationship`에 추가해 주세요.```{  "Version": "2012-10-17",  "Statement": [      {        "Effect": "Allow",        "Principal": {"Service": "credentials.iot.amazonaws.com"},        "Action": "sts:AssumeRole"      },      {        "Effect": "Allow",        "Principal": {"Service": "sagemaker.amazonaws.com"},        "Action": "sts:AssumeRole"      }  ]}```role ARN을 별도로 기록해 주세요. 이후 device fleet을 생성할 때 사용됩니다. **[주의] 아래 코드 셀을 그대로 실행하지 말고, IAM role에서 생성된 RoleArn을 붙여넣어야 합니다.**<jupyter_code>device_fleet_name ="demo-device-fleet" + str(time.time()).split('.')[0]

sagemaker_client.create_device_fleet(
    DeviceFleetName=device_fleet_name,
    RoleArn=<device-role-arn>, # arn:aws:iam::<account>:role/SageMaker*
    #RoleArn='arn:aws:iam::387793684046:role/SageMaker-Edge-hol',
    OutputConfig={
        'S3OutputLocation': s3_compilation_output_location
    }
)<jupyter_output><empty_output><jupyter_text>Register device to the fleet<jupyter_code>device_name = "sagemaker-edge-demo-device" + str(time.time()).split('.')[0] # device name should be 36 charactors

sagemaker_client.register_devices(
    DeviceFleetName=device_fleet_name,
    Devices=[
        {          
            "DeviceName": device_name,
            "IotThingName": iot_thing_name,
            "Description": "this is a sample virtual device"
        }
    ]
)<jupyter_output><empty_output><jupyter_text>Create and register client certificate with AWS IoT 프라이빗 키(private key), 퍼블릭 키(public key) 및 X.509 인증서 파일을 생성하고 AWS IoT에 인증서를 등록 및 활성화합니다.<jupyter_code>iot_cert = iot_client.create_keys_and_certificate(
    setAsActive=True
)<jupyter_output><empty_output><jupyter_text>파일을 저장하고 S3 버킷에 업로드합니다. 이 파일은 AWS 서비스와 통신하기 위해 디바이스에서 자격 증명을 제공하는 데 사용됩니다.<jupyter_code>with open('./iot.pem.crt', 'w') as f:
    for line in iot_cert['certificatePem'].split('\n'):
        f.write(line)
        f.write('\n')
with open('./iot_key.pem.key', 'w') as f:
    for line in iot_cert['keyPair']['PrivateKey'].split('\n'):
        f.write(line)
        f.write('\n')
with open('./iot_key_pair.pem.key', 'w') as f:
    for line in iot_cert['keyPair']['PublicKey'].split('\n'):
        f.write(line)
        f.write('\n')<jupyter_output><empty_output><jupyter_text>`create_device_fleet()`에서 생성된 role 별칭(alias)을 AWS IoT와 연결합니다.<jupyter_code>role_alias_name = 'SageMakerEdge-' + device_fleet_name

role_alias = iot_client.describe_role_alias(
    roleAlias=role_alias_name
)<jupyter_output><empty_output><jupyter_text>디바이스의 성공적인 인증을 위해 앞서 AWS IoT에 인증서를 생성하고 등록했습니다. 이제 보안 토큰에 대한 요청을 승인하는 policy를 생성하고 인증서에 연결해야 합니다.<jupyter_code>alias_policy = {
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "iot:AssumeRoleWithCertificate",
    "Resource": role_alias['roleAliasDescription']['roleAliasArn']
  }
}
policy_name = 'aliaspolicy-'+ str(time.time()).split('.')[0]
aliaspolicy = iot_client.create_policy(
    policyName=policy_name,
    policyDocument=json.dumps(alias_policy),
)
iot_client.attach_policy(
    policyName=policy_name,
    target=iot_cert['certificateArn']
)<jupyter_output><empty_output><jupyter_text>자격 증명 공급자에 대한 AWS 계정별 엔드포인트 정보를 확인합니다.<jupyter_code>iot_endpoint = iot_client.describe_endpoint(
    endpointType='iot:CredentialProvider'
)
endpoint = "https://{}/role-aliases/{}/credentials".format(iot_endpoint['endpointAddress'], role_alias_name)<jupyter_output><empty_output><jupyter_text>공식 Amazon Root CA 파일을 가져와 S3 버킷에 업로드합니다.<jupyter_code>!wget https://www.amazontrust.com/repository/AmazonRootCA1.pem<jupyter_output>--2021-03-21 04:51:37--  https://www.amazontrust.com/repository/AmazonRootCA1.pem
Resolving www.amazontrust.com (www.amazontrust.com)... 172.16.17.32, 192.168.3.11, 192.168.3.11, ...
Connecting to www.amazontrust.com (www.amazontrust.com)|172.16.17.32|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1188 (1.2K) [text/plain]
Saving to: ‘AmazonRootCA1.pem’

AmazonRootCA1.pem   100%[===================>]   1.16K  --.-KB/s    in 0s      

2021-03-21 04:51:37 (132 MB/s) - ‘AmazonRootCA1.pem’ saved [1188/1188]<jupyter_text>엔드포인트를 사용하여 자격 증명 공급자(Credential Provider)에게 HTTPS 요청을 보내 보안 토큰을 반환합니다. 다음 예제 커맨드는 curl을 사용하지만 모든 HTTP 클라이언트를 사용할 수 있습니다. **Optional: verify the credentials.**<jupyter_code>!curl --cert iot.pem.crt --key iot_key.pem.key --cacert AmazonRootCA1.pem $endpoint<jupyter_output>{"credentials":{"accessKeyId":"ASIAVUSSOAZHJTH7PRUE","secretAccessKey":"<KEY>","sessionToken":"<KEY>...]<jupyter_text>엔드포인트에서 오류 없이 인증서를 확인할 수 있는 경우, 인증서 파일을 S3 버킷에 업로드합니다.이 인증서 파일은 EC2/디바이스의 [Setup Sagemaker Edge Manager Agent](Setup-Sagemaker-Edge-Manager-Agent) 섹션에서 자격 증명 공급자로 사용됩니다.<jupyter_code>root_ca_path = sess.upload_data('AmazonRootCA1.pem', bucket, iot_folder)
device_cert_path = sess.upload_data('iot.pem.crt', bucket, iot_folder)
device_key_path = sess.upload_data('iot_key.pem.key', bucket, iot_folder)<jupyter_output><empty_output><jupyter_text>Inference on Edge 이 예시에서는 [AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html)를 사용하여 EC2 인스턴스에서 원격으로 작업을 수행합니다. CloudWatch에서 SSM 로그를 보려면 [Install CouldWatch Agent]((Optional)Install-CloudWatch-Agent)를 참조하십시오.send 명령의 실행 상태는 [AWS Systems Manager console](https://console.aws.amazon.com/systems-manager/run-command/complete-commands)에서 확인할 수 있습니다.<jupyter_code>ssm_client = boto3.client('ssm', region_name=region)<jupyter_output><empty_output><jupyter_text>Setup SageMaker Edge Manager Agent SageMaker Edge Manager Agent binary exaple을 EC2 인스턴스에 다운로드합니다.SageMaker Edge 릴리스 버킷에서 최신 버전의 바이너리를 가져옵니다. 자세한 정보는 [Inference engine (Edge Manager agent)](https://docs.aws.amazon.com/sagemaker/latest/dg/edge-device-fleet-about.html)를 참조하십시오.<jupyter_code>release_bucket_map = {
    'armv8' : 'sagemaker-edge-release-store-us-west-2-linux-armv8',
    'linux' : 'sagemaker-edge-release-store-us-west-2-linux-x64',
    'win64' : 'sagemaker-edge-release-store-us-west-2-windows-x64',
    'win32' : 'sagemaker-edge-release-store-us-west-2-windows-x86',
}
# In this example, we will run inference on linux platform
release_bucket = release_bucket_map['linux']<jupyter_output><empty_output><jupyter_text>아티팩트를 다운로드하려면 `VERSION`을 지정합니다. `VERSION`은 `.-`의 세 가지 구성 요소로 나뉩니다.- MAJOR_VERSION : 릴리즈 버전입니다. 릴리즈 버전은 현재 1로 설정되어 있습니다.- `` : 아티팩트 릴리즈의 타임스탬프입니다.- SHA-7 : 릴리즈가 빌드된 저장소 커밋 ID입니다.최신 아티팩트 릴리즈 타임스탬프를 사용하는 것이 좋습니다. 최신 타임 스탬프를 얻으려면 아래 코드 셀을 실행하세요.<jupyter_code>!aws s3 ls s3://$release_bucket/Releases/ | sort -r
version = 1
#version = <version_number>
response = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "#!/bin/bash",
            "mkdir /demo",
            "aws s3 cp s3://{}/Releases/{}/{}.tgz demo.tgz".format(release_bucket, version, version),
            "tar -xf demo.tgz -C /demo",
            "cd /demo/bin",
            "chmod +x sagemaker_edge_agent_binary",
            "chmod +x sagemaker_edge_agent_client_example"
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=response['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>릴리즈 버킷에서 모델 서명 루트 인증서를 가져옵니다.<jupyter_code>response = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "#!/bin/bash",
            "cd /demo",
            "mkdir certificates",
            "aws s3 cp s3://{}/Certificates/{}/{}.pem certificates".format(release_bucket, region, region)
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=response['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>IoT 인증서 및 프라이빗 키를 EC2 인스턴스에 다운로드합니다. 모델 및 테스트 이미지를 EC2 인스턴스로 다운로드합니다.<jupyter_code>response = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "#!/bin/bash",
            "cd /demo",
            "mkdir iot-credentials",
            "cd iot-credentials",
            "aws s3 cp " + root_ca_path + " .",  
            "aws s3 cp " + device_cert_path + " .",
            "aws s3 cp " + device_key_path + " .",
            "cd /demo",
            "aws s3 cp " + darknet_img_path + " .",
            "aws s3 cp " + darknet_model_data + " .",
            "mkdir darknet_model",
            "tar -xf " + darknet_model_package + " -C darknet_model",
            "aws s3 cp " + keras_img_path + " .",
            "aws s3 cp " + keras_model_data + " .",
            "mkdir keras_model",
            "tar -xf " + keras_model_package + " -C keras_model"
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=response['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Configure SageMaker Edge Manager AgentSageMaker Edge Agent 설정 파일을 생성합니다.<jupyter_code>sagemaker_edge_config = {
    "sagemaker_edge_core_device_uuid": device_name,
    "sagemaker_edge_core_device_fleet_name": device_fleet_name,
    "sagemaker_edge_core_capture_data_buffer_size": 30,
    "sagemaker_edge_core_capture_data_batch_size": 10,
    "sagemaker_edge_core_capture_data_push_period_seconds": 4,
    "sagemaker_edge_core_folder_prefix": "demo_capture",
    "sagemaker_edge_core_region": region,
    "sagemaker_edge_core_root_certs_path": "/demo/certificates",
    "sagemaker_edge_provider_aws_ca_cert_file": "/demo/iot-credentials/AmazonRootCA1.pem",
    "sagemaker_edge_provider_aws_cert_file": "/demo/iot-credentials/iot.pem.crt",
    "sagemaker_edge_provider_aws_cert_pk_file": "/demo/iot-credentials/iot_key.pem.key",
    "sagemaker_edge_provider_aws_iot_cred_endpoint": endpoint,
    "sagemaker_edge_provider_provider": "Aws",
    "sagemaker_edge_provider_s3_bucket_name": bucket,
    "sagemaker_edge_core_capture_data_destination": "Cloud"
}
edge_config_file = open("sagemaker_edge_config.json", "w")
json.dump(sagemaker_edge_config, edge_config_file, indent = 6)
edge_config_file.close()<jupyter_output><empty_output><jupyter_text>SageMaker Edge Agent 설정을 S3 버킷에 업로드합니다.<jupyter_code>config_path = sess.upload_data('sagemaker_edge_config.json', bucket, iot_folder)<jupyter_output><empty_output><jupyter_text>SageMaker Edge Agent 설정 파일을 EC2 인스턴스에 다운로드합니다.<jupyter_code>response = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "#!/bin/bash",
            "aws s3 cp " + config_path + ' /demo'
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=response['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Launch SageMaker Edge Agent<jupyter_code>agent_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    TimeoutSeconds=24*60*60,
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "rm -f /tmp/sagemaker_edge_agent_example.sock",
            "./bin/sagemaker_edge_agent_binary -a /tmp/sagemaker_edge_agent_example.sock -c sagemaker_edge_config.json" 
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=agent_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Load Model이 섹션에서는 SageMaker Edge Manager에서 제공하는 모델 관리 기능을 보여줍니다. SageMaker Edge Agent를 사용하여 컴파일되고 패키징된 두 개의 모델을 로드합니다. 이렇게 하면 두 모델에 대한 추론을 모두 실행할 수 있습니다. 보시다시피 모델이 로드되면, 모델이 언로드될 때까지 필요한 만큼 여러 번 추론을 실행할 수 있습니다. 이를 통해, 클라이언트 애플리케이션을 개별적으로 관리하는 운영 부담에서 벗어날 수 있습니다. SageMaker Edge Agent를 사용하여 모델을 로드할 때, API points argument는 패키지된 모델이 포함된 디렉토리를 가리킵니다 .(디렉터리 내에 관련 없는 파일 없음).  Load darknet model`darknet_model`은 이 노트북의 패키징된 모델을 포함하는 경로입니다. `demo-darknet`은 이 모델에 주어진 이름입니다. 이 이름은 나중에 예측, 데이터 캡처, 언로드를 위해 이 모델을 참조하는 데 사용됩니다.<jupyter_code>load_darknet_model_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example LoadModel darknet_model demo-darknet"
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=load_darknet_model_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Load keras model`keras_model`은 이 노트북에 패키지된 모델을 포함하는 경로입니다. `demo-keras`는 이 모델에 주어진 이름입니다. 이 이름은 나중에 예측, 데이터 캡처, 언로드를 위해 이 모델을 참조하는 데 사용됩니다.<jupyter_code>load_keras_model_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example LoadModel keras_model demo-keras"
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=load_keras_model_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>List Models이 API는 SageMaker Edge Agent로 로드된 모든 모델과 해당 이름을 나열합니다. 여기에 표시된 이름은 이전 섹션에서 LoadModel 중에 제공된 이름과 동일합니다.<jupyter_code>list_model_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example ListModels"
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=list_model_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Run Predict이 API에서는 모델 이름, 신경망에 직접 공급될 입력 데이터 파일, 컴파일 단계에서 이전에 전달된 입력 텐서 이름, 크기 및 모양을 전달합니다.  Run prediction on darknet model<jupyter_code>darknet_predict_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example Predict demo-darknet darknet.bmp data 416 416 3"
        ]
    }
)
ssm_client.get_command_invocation(
    CommandId=darknet_predict_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Run prediction on keras model<jupyter_code>keras_predict_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example Predict demo-keras keras.bmp input_1 224 224 3"
        ]
    }
)<jupyter_output><empty_output><jupyter_text>아래 코드 셀에서 에러가 발생하면 몇 초 후에 코드 셀을 재실행하세요.<jupyter_code>ssm_client.get_command_invocation(
    CommandId=keras_predict_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Capture Data클라우드 또는 디스크에 대한 추론 호출의 입출력을 캡처합니다. 특정 파라메터는 설정 파일에서 이미 설정되었습니다.<jupyter_code>darknet_capture_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example PredictAndCapture demo-darknet darknet.bmp data 416 416 3"
        ]
    }
)<jupyter_output><empty_output><jupyter_text>아래 코드 셀에서 에러가 발생하면 몇 초 후에 코드 셀을 재실행하세요.<jupyter_code>ssm_client.get_command_invocation(
    CommandId=darknet_capture_out['Command']['CommandId'],
    InstanceId=instance_id,
)
keras_capture_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example PredictAndCapture demo-keras keras.bmp input_1 224 224 3"
        ]
    }
)<jupyter_output><empty_output><jupyter_text>아래 코드 셀에서 에러가 발생하면 몇 초 후에 코드 셀을 재실행하세요.<jupyter_code>ssm_client.get_command_invocation(
    CommandId=keras_capture_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Unload Model모델을 언로드한 후, 동일한 이름을 향후 `LoadModel` API 호출에 재사용할 수 있습니다.<jupyter_code>unload_model_out = ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "cd /demo",
            "./bin/sagemaker_edge_agent_client_example UnloadModel demo-darknet",
            "./bin/sagemaker_edge_agent_client_example UnloadModel demo-keras"
        ]
    }
)<jupyter_output><empty_output><jupyter_text>아래 코드 셀에서 에러가 발생하면 몇 초 후에 코드 셀을 재실행하세요.<jupyter_code>ssm_client.get_command_invocation(
    CommandId=unload_model_out['Command']['CommandId'],
    InstanceId=instance_id,
)<jupyter_output><empty_output><jupyter_text>Clean Up Agent를 중단합니다.<jupyter_code>ssm_client.cancel_command(
    CommandId=agent_out['Command']['CommandId'],
    InstanceIds=[instance_id]
)<jupyter_output><empty_output><jupyter_text>EC2 인스턴스를 중단합니다.<jupyter_code>ec2_client.stop_instances(
    InstanceIds=[instance_id]
)<jupyter_output><empty_output><jupyter_text>Policy를 detach하고 삭제합니다.<jupyter_code>iot_client.detach_policy(
    policyName=policy_name,
    target=iot_cert['certificateArn']
)

iot_client.delete_policy(
    policyName=policy_name
)<jupyter_output><empty_output><jupyter_text>디바이스 등록을 해제(Deregister)하고 device fleet을 삭제합니다.<jupyter_code>sagemaker_client.deregister_devices(
    DeviceFleetName=device_fleet_name,
    DeviceNames=[device_name]
)

sagemaker_client.delete_device_fleet(
    DeviceFleetName=device_fleet_name
)<jupyter_output><empty_output><jupyter_text>Appendix  (Optional)Install CloudWatch Agent<jupyter_code>CW_log_config = {
      "agent": {
        "metrics_collection_interval": 10,
        "logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log"
      },
      "logs": {
        "logs_collected": {
          "files": {
            "collect_list": [
              {
                "file_path": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log",
                "log_group_name": "amazon-cloudwatch-agent.log",
                "log_stream_name": "amazon-cloudwatch-agent.log",
                "timezone": "UTC"
              },
              {
                "file_path": "/opt/aws/amazon-cloudwatch-agent/logs/test.log",
                "log_group_name": "test.log",
                "log_stream_name": "test.log",
                "timezone": "Local"
              }
            ]
          }
        },
        "log_stream_name": "my_log_stream_name",
        "force_flush_interval" : 15
      }
}
CW_file = open("cloudwatch.json", "w") 
json.dump(CW_log_config, CW_file, indent = 6) 
CW_file.close() 
CW_config_path = sess.upload_data('cloudwatch.json', bucket, iot_folder)
ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "#!/bin/bash",
            "aws s3 cp " + CW_config_path + " /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json"
        ]
    }
)
ssm_client.send_command(
    InstanceIds=[instance_id],
    DocumentName="AWS-RunShellScript",
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Parameters={
        'commands':[
            "#!/bin/bash",
            "wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb",
            "sudo dpkg -i -E ./amazon-cloudwatch-agent.deb",
        ]
    }
)<jupyter_output><empty_output><jupyter_text>Cloud Watch Agent를 SSM agent로 설치합니다.<jupyter_code>ssm_client.send_command(
    DocumentName="AWS-ConfigureAWSPackage",
    DocumentVersion='1',
    OutputS3BucketName=bucket,
    OutputS3KeyPrefix=folder,
    Targets=[
        {
            'Key': 'InstanceIds',
            'Values': [instance_id]
        },
    ],
    TimeoutSeconds=600,
    Parameters={
        'action': ['Install'],
        "name": ["AmazonCloudWatchAgent"]
    },
    MaxConcurrency='50',
    MaxErrors='0'
)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11743642823173972, 'fraction_numerical': 0.020589140347441744, 'mean_word_length': 4.388604160385891, 'pattern_counts': {'":': 61, '<': 201, '<?xml version=': 0, '>': 202, 'https://': 19, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '50', 'dir': 'jupyter-structured-clean-dedup', 'id': '68707', 'license': 'MIT', 'n_tokens_mistral': 15649, 'n_tokens_neox': 16681, 'n_words': 2382, 'path': 'sagemaker_edge_example.ipynb', 'repo_name': 'daekeun-ml/sagemaker-edge-manager', 'size': '36652'}