I want to perform SageMaker inference from PHP

TL;DR --I think you often make SageMaker inferences from Python, but I think the front end may be PHP. I wrote how to perform SageMaker inference from PHP running on EC2. --PHP can't handle numpy, so if it's an image, it's encoded in Base64 and sent.

Determine the data format between EC2 and SageMaker

This is a necessary task, not just PHP. Let's decide between the front end and the ML Engineer.

Since SageMaker is basic Python, you may want to use the convenient numpy. With numpy, you can easily pass data to various models such as TensorFlow, PyTorch, MXNet. On the other hand, if the sender is PHP, it is difficult to send data with the Python library numpy. So, instead of numpy, try using a format that PHP can handle, such as json or Base64 for images. For now, consider encoding an image on EC2 to Base64 and sending it to SageMaker.

Create an endpoint for SageMaker

Here, I will host the model of DeepLab, which is a pretrained model of Semantic segmentation of GluonCV. The flow up to deployment has been raised to Gist. https://gist.github.com/harusametime/ac3050d25c47b23534784ce8fb09da6b

Deployment requires a script for inference, and here we also implement how to handle Base64 images. First is the implementation of the model_fn function for loading the model. This can be called with a single function of gluoncv. Since we are assuming an instance that can use GPU, if you only have CPU, please set mx.cpu () to ctx.

def model_fn(model_dir):
    net = gluoncv.model_zoo.get_deeplab_resnet50_ade(pretrained=True, ctx=mx.gpu())
    return net

Now next is the implementation of transform_fn that passes data to the above model and predicts it. After first decoding base64, the image file will be in data, so open it with PIL Image and convert it to numpy conversion and mxnet array. It is a flow to predict with predict after executing test_transform of DeepLab preprocessing. Since it is Semantic Segmentation, multiple label candidates are displayed for each pixel. Here, the most plausible label is given, and the one with the highest probability with argmax is given. Finally, it returns the response in json format.

def transform_fn(net, data, input_content_type, output_content_type):
    
    data = base64.b64decode(data)
    data = Image.open(BytesIO(data))
    data = np.array(data)
    data = mx.nd.array(data,ctx=mx.gpu())
    data = test_transform(data,ctx=mx.gpu())
    output = net.predict(data)
    predict = mx.nd.squeeze(mx.nd.argmax(output, 1)).asnumpy().tolist()
    response_body = json.dumps(predict)
    return response_body, output_content_type

PHP implementation on the EC2 side

I think it's been about 15 years since I've touched PHP, but let's do it. PHP requires the AWS SDK for PHP, just as you need the Python SDK (Boto3) to perform SageMaker inference from Python.

Grant IAM Role so that SageMaker can be inferred from EC2

Select EC2 from the new IAM Role creation screen to create a role that can be used with EC2.

Grant an AmazonSageMakerFullAccess policy so that you can work with SageMaker from that role. Then give it a name and save it.

The saved role can be given to the instance on the EC2 screen. pic3.png

Installing the AWS SDK for PHP

Please refer to the Official Installation Guide. First, PHP version 5.5 or later is recommended. I'm using PHP 5.3, so I upgraded it. Just uninstall and reinstall php. There may be a smarter way. I included php-xml because it was needed for the AWS SDK.

yum -y remove php-*
yum -y remove httpd-tools
yum clean all
yum -y install php
yum -y install php-xml

Once you have php, it's time to install Composer. You can follow the Installation Guide (https://getcomposer.org/download/), but I created the How do I install Composer programmatically? file linked from the guide and ran it from the shell.

Once Composer is in place, it's time to install the AWS SDK.

composer require aws/aws-sdk-php

When you execute this, the installation is completed. There will be a folder called vendor in the executed directory, and a file called autoload.php in it. If you call this file from a PHP script, it will read the entire AWS SDK.

Run PHP script

When you perform inference, you run InvokeEndpoint, so look for usage in the AWS SDK for PHP documentation.

https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-runtime.sagemaker-2017-05-13.html


$result = $client->invokeEndpoint([
    'Accept' => '<string>',
    'Body' => <string || resource || Psr\Http\Message\StreamInterface>, // REQUIRED
    'ContentType' => '<string>',
    'CustomAttributes' => '<string>',
    'EndpointName' => '<string>', // REQUIRED
    'InferenceId' => '<string>',
    'TargetModel' => '<string>',
    'TargetVariant' => '<string>',
]);

REQUIRED is Body and EndpointName. For Body, put the Base64 image, and for EndpointName, put the name of the endpoint created above. If you don't know, you can check it from the SageMaker console.

Then, if you put this around and write the php code, it looks like this.

<?php
require 'vendor/autoload.php';
use Aws\SageMakerRuntime\SageMakerRuntimeClient;

$im = file_get_contents("./image.jpg ");
$base64img = base64_encode($im);
$client = new SageMakerRuntimeClient([
    'region'  => 'us-west-2',
        'version' => '2017-05-13'
]);

$result = $client->invokeEndpoint([
    'Body' => $base64img, // REQUIRED
    'EndpointName' => 'Endpoint name', // REQUIRED
   ]);
print($result['Body']);
?>

When I run it, it looks like this.

[ec2-user@ip-10-0-0-144 ~]$ php predict.php
 [[5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
...(Omitted on the way)
 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
3.0, 3.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]

Since it is a two-dimensional array, it corresponds to the vertical and horizontal directions of the image, and labels 5, 3 and 0 are included as values. In the ADE20K dataset, 5 is the ceiling, 3 is the floor, and 0 is the wall, so you can expect the image given to be an indoor image, with the ceiling at the beginning (upper).

Recommended Posts

I want to perform SageMaker inference from PHP
I want to use jar from python
I want to connect to PostgreSQL from various languages
I want to email from Gmail using Python.
[Python] I want to manage 7DaysToDie from Discord! 1/3
I want to make fits from my head
I want to use ceres solver from python
[Python] I want to manage 7DaysToDie from Discord! 2/3
I want to make C ++ code from Python code!
I want to see the file name from DataLoader
I want to detect images of cats from Instagram
I want to install a package of Php Redis
[Python3] I want to generate harassment names from Japanese!
Cheating from PHP to Python
I want to solve Sudoku (Sudoku)
I want to start a lot of processes from python
I want to calculate the allowable downtime from the operating rate
I want to install a package from requirements.txt with poetry
I want to send a message from Python to LINE Bot
I want to understand systemd roughly
I want to scrape images to learn
I want to do ○○ with Pandas
I want to copy yolo annotations
I want to debug with Python
I want to automatically find high-quality parts from the videos I shot
I want to make a parameter list from CloudFormation code (yaml)
I want to mess with ALB's default security group from CDK
I want to pin Spyder to the taskbar
I want to detect objects with OpenCV
I want to output to the console coolly
Why I moved from Java to Dart
I want to print in a comprehension
I want to operate DB using Django's ORM from an external application
I want to scrape them all together.
I want to handle the rhyme part1
I want to send a signal only from the sub thread to the main thread
Tips for manipulating numpy.ndarray from c ++ -I want to use an iterator-
I want to know how LINUX works!
I want to blog with Jupyter Notebook
[Python memo] I want to get a 2-digit hexadecimal number from a decimal number
I want to handle the rhyme part3
I want to build a Python environment
I want to use Linux on mac
I want to pip install with PythonAnywhere
I want to analyze logs with Python
I want to play with aws with python
I want to use IPython Qt Console
I want to display the progress bar
I want to make an automation program!
I want to embed Matplotlib in PySimpleGUI
I want to handle the rhyme part2
I want to develop Android apps on Android
I want CAPTCHA to say HIWAI words
I want to handle the rhyme part5
I want to handle the rhyme part4
I want to pass an argument to a python function and execute it from PHP on a web server
[LINE Messaging API] I want to send a message from the program to everyone's LINE
[Ansible] I want to call my own function from the template module (macro)
I want to get / execute variables / functions / classes of external files from Python
I want to make matplotlib a dark theme
I want to do Dunnett's test in Python