ML Zoomcamp 2023 – Serverless – Part 5

Preparing a Docker image

In this part we want to package everything into a docker container. We use an AWS base image for our Dockerfile. You can find the public images from aws here (public.ecr.aws –> gallery.ecr.aws). In the gallery you can search for “python lambda” and we can find “python by AWS Lambda”. Then go to the “image tags” and find 3.8 or 3.9 or sth else and copy the link (like: public.ecr.aws/lambda/python:3.8)

FROM public.ecr.aws/lambda/python:3.9

RUN pip install keras-image-helper
RUN pip install tflite-runtime

COPY clothing-model.tflite .
COPY lambda_function.py .

CMD [ "lambda_function.lambda_handler" ]

Then let’s build the dockerfile.

docker build -t clothing-model .
docker run -it --rm -p 8080:8080 clothing-model:latest

Now we can write a python test file (test.py) with the following content and run it to test our lamda function.

import requests

url = 'http://localhost:8080/2015-03-31/functions/function/invocations'
data = {'url': 'http://bit.ly/mlbookcamp-pants'}

result = requests.post(url, json=data).json()
print(result)

But we’re getting one error: “{‘errorMessage’: “Unable to import module ‘lambda_function’: /lib64/libm.so.6: version `GLIBC_2.27′ not found (required by /var/lang/lib/python3.9/site-packages/tflite_runtime/_pywrap_tensorflow_interpreter_wrapper.so)”, ‘errorType’: ‘Runtime.ImportModuleError’, ‘requestId’: ‘3ad9eb7e-b087-4495-a376-d8d3506e699f’, ‘stackTrace’: []}” The reason is that the libraries were compiled for a different version of linux. Our Docker image is a aws based linux but the libraries were compiled for a debian based linux. So we need to compile the libraries for the aws environment.

But you don’t really need to do it by your own. Alexey provide a compiled version on his github repo (github.com/alexeygrigorev/tflite-aws-lambda) We can use that precompiled version but we need to rebuild our docker image with the adapted line.

FROM public.ecr.aws/lambda/python:3.9

RUN pip install keras-image-helper
#RUN pip install tflite-runtime
RUN pip install https://github.com/alexeygrigorev/tflite-aws-lambda/raw/main/tflite/tflite_runtime-2.7.0-cp39-cp39-linux_x86_64.whl

COPY clothing-model.tflite .
COPY lambda_function.py .

CMD [ "lambda_function.lambda_handler" ]

Still we get an error: “{‘errorMessage’: ‘Unable to marshal response: Object of type float32 is not JSON serializable’, ‘errorType’: ‘Runtime.MarshalError’, ‘requestId’: ‘c72d4226-6f20-4377-b666-7d05f4367099’, ‘stackTrace’: []}”

This error is an expected error. This means that it doesn’t know what to do with object of type “float32”. This error is a know error from previous sessions. With flask we had the same error. What we need to do is converting the elements of numpy array into usual python floats. That means we need to adapt the code of lambda_function.py

def predict(url): 
     X = preprocessor.from_url(url)

     interpreter.set_tensor(input_index, X)
     interpreter.invoke()
     preds = interpreter.get_tensor(output_index)

     # What happens here is we take an numpy array and it will converted to usual   
     # python list with usul python floats.
     float_predictions = preds[0].tolist()

     return dict(zip(classes, float_predictions))

Now we can rerun again and it should work now.

docker build -t clothing-model . docker run -it --rm -p 8080:8080 clothing-model:latest

Output of test.py: {‘dress’: -1.8251237869262695, ‘hat’: -5.563746929168701, ‘longsleeve’: -1.7097409963607788, ‘outwear’: -1.1727796792984009, ‘pants’: 8.934737205505371, ‘shirt’: -2.175368070602417, ‘shoes’: -2.9585258960723877, ‘shorts’: 2.3701159954071045, ‘skirt’: -1.7067642211914062, ‘t-shirt’: -4.354998588562012}

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.