<jupyter_start><jupyter_text>Hosting Detectron2 model on Sagemaker Inference endpointNote that if you only wnat to deploy to a SageMaker Endpoint, you can skip the first few cells that require detectron2 to be built locally.   Register the Test Set into D2 for metadata class info<jupyter_code>from detectron2.data.datasets import register_coco_instances
from detectron2.data.catalog import MetadataCatalog, DatasetCatalog
import os
import json

# Use this if you have the dataset locally referencable 
# dataset_name = "test"
# dataset_location = "/data/"
# annotation_file = "test.json"
# image_dir = "test"

# Use this if you want to just create an empty dataset that has the classmap 
dataset_name = "tmp"
dataset_location = ""
annotation_file = ""
image_dir = ""

register_coco_instances(dataset_name, {}, os.path.join(dataset_location, annotation_file), 
                        os.path.join(dataset_location, image_dir))
cb_meta = MetadataCatalog.get(dataset_name)

# This section should be run just to be explicit to Detectron which classes are which! 
MetadataCatalog.get(val_dataset_name).thing_classes = ['OBJECT_1', 'OBJECT_2', 'OBJECT_3', 'OBJECT_4', 'OBJECT_5'] # put more here! 
MetadataCatalog.get(val_dataset_name).thing_dataset_id_to_contiguous_id={1: 0, 2: 1, 3: 2, 4: 3, 5: 4} # Update the mapping here as so too for class 0 to be background!<jupyter_output><empty_output><jupyter_text>Deploying Model as SageMaker Endpoint<jupyter_code>from sagemaker.pytorch import PyTorchModel
import sagemaker
from time import gmtime, strftime

# consts 
sess = sagemaker.Session()
role = sagemaker.get_execution_role()
account = sess.boto_session.client('sts').get_caller_identity()['Account']
region = 'us-east-1'
n = 'deploy'
model_name = f"d2-{n}"
endpoint_name = f"d2-{n}"

# Update this with the model output location `model.tar.gz` file
model_url = d2.latest_training_job.describe()['ModelArtifacts']['S3ModelArtifacts'] # Should look like s3://PATH_TO_OUTPUT/model.tar.gz

remote_model = PyTorchModel(
                     name = model_name, 
                     model_data=model_url,
                     role=role,
                     sagemaker_session = sess,
                     entry_point="inference.py",
                     # image=image, 
                     framework_version="1.6.0",
                     py_version='py3'
                    )

remote_predictor = remote_model.deploy(
                         instance_type='ml.g4dn.xlarge', 
                         initial_instance_count=1,
                         # update_endpoint = True, # comment or False if endpoint doesns't exist
                         endpoint_name=endpoint_name, # define a unique endpoint name; if ommited, Sagemaker will generate it based on used container
                         wait=True 
                         )<jupyter_output><empty_output><jupyter_text>Call inference on some local test images!<jupyter_code>import boto3
from io import BytesIO
from container_serving.d2_deserializer import json_to_d2
from detectron2.utils.visualizer import ColorMode, Visualizer
import cv2
from google.colab.patches import cv2_imshow
import time 

client = boto3.client('sagemaker-runtime')

accept_type = "json" 
content_type = 'image/jpeg'
headers = {'content-type': content_type}
device = "cpu" # cuda:0 for GPU, cpu for CPU
test_pics_dir = '<PATH_TO_SOME_TEST_IMGS>'

classID_name = {
    0: 'OBJECT1',
    1: 'OBJECT2',
    2: 'OBJECT3',
    3: 'OBJECT4',
    4: 'OBJECT5',
}

for img_ in os.listdir(test_pics_dir): 
    
    img_name = test_pics_dir + img_ 
    print(img_name) 
    
    payload = open(img_name, 'rb')
    device = "cpu"

    response = client.invoke_endpoint(
        EndpointName=endpoint_name,
        Body=payload,
        ContentType=content_type,
        Accept = accept_type
    )
    
    if accept_type=="json":
        predictions = json_to_d2(response['Body'].read(), device)
    elif accept_type=="detectron2":
        print(response['Body'].read())
        stream = BytesIO(response['Body'].read())
        predictions = pickle.loads(stream.read())
        
    # Extract preds: 
    preds = predictions["instances"].to("cpu")
    boxes = preds.pred_boxes.tensor.numpy()
    scores = preds.scores.tolist()
    classes = preds.pred_classes.tolist()
    
    for i in range(len(boxes)):
        left, top, right, bot = boxes[i] #x0, y0, x1, y1
        print(f'DETECTED: {classID_name[classes[i]]}, confidence: {scores[i]}, box: {int(left)} {int(top)} {int(right)} {int(bot)}\n') # left top right bot 
    
    # visualize
    im = cv2.imread(img_name)
    v = Visualizer(im[:, :, ::-1],
                   metadata=cb_meta, 
                   scale=0.8)
    out = v.draw_instance_predictions(predictions["instances"].to("cpu"))
    cv2_imshow(out.get_image()[:, :, ::-1])<jupyter_output><empty_output><jupyter_text>Delete endpoint for cost saving<jupyter_code>remote_predictor.delete_endpoint()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10630159049728206, 'fraction_numerical': 0.01268371250251661, 'mean_word_length': 3.2497861420017107, 'pattern_counts': {'":': 2, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '443483', 'license': 'MIT-0', 'n_tokens_mistral': 1618, 'n_tokens_neox': 1562, 'n_words': 374, 'path': 'd2_inference.ipynb', 'repo_name': 'POPPININ/end-to-end-object-detection-detectron2-sagemaker', 'size': '4967'}