kartik4949 / AutoDeploy

AutoDeploy is a single configuration deployment library
MIT License
41 stars 12 forks source link
deployment deployment-automation monioring tensorflow

AutoDeploy AutoDeploy - Automated machine learning model deployment. | Product Hunt

Awesome Badge Star Badge
Stars Badge Forks Badge Pull Requests Badge Issues Badge GitHub contributors License Badge

What is AutoDeploy?

Autodeploy src

A one liner : For the DevOps nerds, AutoDeploy allows configuration based MLOps.

For the rest : So you're a data scientist and have the greatest model on planet earth to classify dogs and cats! :). What next? It's a steeplearning cusrve from building your model to getting it to production. MLOps, Docker, Kubernetes, asynchronous, prometheus, logging, monitoring, versioning etc. Much more to do right before you The immediate next thoughts and tasks are

Architecture

AutoDeploy architecture

What if you could only configure a single file and get up and running with a single command. That is what AutoDeploy is!

Read our documentation to know how to get setup and get to serving your models.

AutoDeploy monitoring dashboard

AutoDeploy dashboard AutoDeploy dashboard

and many more...

Feature Support.

Prerequisites

Steps

Example (Docker deployment) - Iris Model Detection (Sci-Kit Learn).

Tada!! your model is deployed.

Example (Docker deployment) - Classification Detection

model:
        model_type: 'onnx'
        model_path: 'horse_zebra.onnx'
        model_file_type: 'onnx'
        version: '1.0.0'
        model_name: 'computer vision classification model.'
        endpoint: 'predict'
        protected: 0
        input_type: 'serialized'
        input_shape: [224, 224, 3]
        server:
                name: 'autodeploy'
                port: 8000
preprocess: 'custom_preprocess_classification'
input_schema:
        input: 'string'
out_schema:
        out: 'int'
        probablity: 'float'
        status: 'int'
dependency:
        path: '/app/model_dependencies'
monitor:
        server:
                name: 'rabbitmq'
                port: 5672
        data_drift:
                name: 'KSDrift'
                reference_data: 'structured_ref.npy'
                type: 'info'
        custom_metrics: 'image_brightness'
        metrics:
                average_per_day:
                        type: 'info'

from register import PREPROCESS

@PREPROCESS.register_module(name='custom_preprocess') def iris_pre_processing(input): return input

@PREPROCESS.register_module(name='custom_preprocess_classification') def custom_preprocess_fxn(input): _channels = 3 _input_shape = (224, 224) _channels_first = 1 input = cv2.resize( input[0], dsize=_input_shape, interpolation=cv2.INTER_CUBIC) if _channels_first: input = np.reshape(input, (_channels, _input_shape)) else: input = np.reshape(input, (_input_shape, _channels)) return np.asarray(input, np.float32)

- Make postproces.py

from register import POSTPROCESS

@POSTPROCESS.register_module(name='custom_postprocess') def custom_postprocess_fxn(output): out_class, out_prob = output[0], output[1] output = {'out': output[0], 'probablity': output[1], 'status': 200} return output

- Make custom_metrics.py we will make a custom_metric to expose image_brightness

import numpy as np from PIL import Image from register import METRICS

@METRICS.register_module(name='image_brightness') def calculate_brightness(image): image = Image.fromarray(np.asarray(image[0][0], dtype='uint8')) greyscale_image = image.convert('L') histogram = greyscale_image.histogram() pixels = sum(histogram) brightness = scale = len(histogram)

for index in range(0, scale): ratio = histogram[index] / pixels brightness += ratio * (-scale + index)

return 1.0 if brightness == 255 else brightness / scale

- run ``` bash build.sh -r model_dependencies/reqs.txt -c configs/classification/config.yaml ```
- run ``` bash start.sh -f configs/classification/config.yaml ```
- To monitor the custom metric `image_brightness`: goto grafana and add panel to the dashboard with image_brightness as metric.

## After deployment steps
### Model Endpoint
- http://address:port/endpoint is your model endpoint e.g http://localhost:8000/predict

### Grafana 
- Open http://address:3000
- Username and password both are `admin`.
- Goto to add datasource.
- Select first option prometheus.
- Add http://prometheus:9090 in the source
- Click save and test at bottom.
- Goto dashboard and click import json file.
- Upload dashboard/model.json avaiable in repository.
- Now you have your dashboard ready!! feel free to add more panels with queries.

## Preprocess
- Add preprocess.py in model_dependencies folder
- from register module import PROCESS register, to register your preprocess functions.

from register import PREPROCESS

- decorate your preprocess function with `@PREPROCESS.register_module(name='custom_preprocess')`

@PREPROCESS.register_module(name='custom_preprocess') def function(input):

process input

input = process(input) return input

- Remeber we will use `custom_preprocess` name in our config file, add this in your config file.

preprocess: custom_preprocess


## Postprocess
- Same as preprocess
- Just remember schema of output from postprocess method should be same as definde in config file
- i.e

out_schema: out: 'int' probablity: 'float' status: 'int'


## Custom Metrics
- from register import METRICS
- register your function with METRIC decorator similar to preprocess
- Example 1 : Simple single metric

import numpy as np from PIL import Image from register import METRICS

@METRICS.register_module(name='image_brightness') def calculate_brightness(image): image = Image.fromarray(np.asarray(image[0][0], dtype='uint8')) greyscale_image = image.convert('L') histogram = greyscale_image.histogram() pixels = sum(histogram) brightness = scale = len(histogram)

for index in range(0, scale): ratio = histogram[index] / pixels brightness += ratio * (-scale + index)

return 1.0 if brightness == 255 else brightness / scale

- We will use `image_brightness` in config file to expose this metric function.

monitor: server: name: 'rabbitmq' port: 5672 data_drift: name: 'KSDrift' reference_data: 'structured_ref.npy' type: 'info' custom_metrics: ['metric1', 'metric2'] metrics: average_per_day: type: 'info'

- Example 2: Advance metric with multiple metrcis functions

import numpy as np from PIL import Image from register import METRICS

@METRICS.register_module(name='metric1') def calculate_brightness(image): return 1

@METRICS.register_module(name='metric2') def metric2(image): return 2

- config looks like

monitor: server: name: 'rabbitmq' port: 5672 data_drift: name: 'KSDrift' reference_data: 'structured_ref.npy' type: 'info' custom_metrics: ['metric1', 'metric2'] metrics: average_per_day: type: 'info'



<!-- LICENSE -->
## License

Distributed under the MIT License. See `LICENSE` for more information.

<!-- CONTACT -->
## Contact

Kartik Sharma  - kartik4949@gmail.com
Nilav Ghosh - nilavghosh@gmail.com