Views
No views yet
1# Install dependencies
2make setup
3source venv/bin/activate
4
5# Download the example model
6make download
7
8# Run it
9make serve1# Process an example input
2./prompt.sh cat.jsonhttp://127.0.0.1:8000. Check /docs for the interactive API documentation.1# Build
2make docker-build
3
4# Run
5make docker-run1# Using curl
2curl -X POST http://localhost:8000/predict \
3 -H "Content-Type: application/json" \
4 -d '{
5 "image": {
6 "mediaType": "image/jpeg",
7 "data": "<base64-encoded-image>"
8 }
9 }'1{
2 "logprobs": [-0.859380304813385,-1.2701971530914307,-2.1918208599090576,-1.69235098361969],
3 "localizationMask": {
4 "mediaType":"image/png",
5 "data":"iVBORw0KGgoAAAANSUhEUgAAA8AAAAKDAQAAAAD9Fl5AAAAAu0lEQVR4nO3NsREAMAgDMWD/nZMVKEwn1T5/FQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCl3g5f+HC24TRhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj70gwKsTlmdBwAAAABJRU5ErkJggg=="
6 }
7}example-submission/
├── main.py # Entry point
├── app/
│ ├── core/
│ │ ├── app.py # <= INSTANTIATE YOUR DETECTOR HERE
│ │ └── logging.py # Logging setup
│ ├── api/
│ │ ├── models.py # Request/response schemas
│ │ ├── controllers.py # Business logic
│ │ └── routes/
│ │ └── prediction.py # POST /predict
│ └── services/
│ ├── base.py # <= YOUR DETECTOR IMPLEMENTS THIS INTERFACE
│ └── inference.py # Example service based on ResNet-18
├── models/
│ └── microsoft/
│ └── resnet-18/ # Model weights and config
├── scripts/
│ ├── model_download.bash
│ ├── generate_test_datasets.py
│ └── test_datasets.py
├── Dockerfile
├── .env.example # Environment config template
├── cat.json # An example /predict request object
├── makefile
├── prompt.sh # Script that makes a /predict request
├── requirements.in
├── requirements.txt
├── response.json # An example /predict response object
└──InferenceService abstract class defined in app/services/base.py. You can follow the example implementation in app/services/inference.py, which is based on ResNet-18. After implementing the required interface, instantiate your model in the lifespan() function in app/core/app.py, replacing the ResNetInferenceService instance.1# app/services/your_model_service.py
2from app.services.base import InferenceService
3from app.api.models import ImageRequest, PredictionResponse
4
5class YourModelService(InferenceService[ImageRequest, PredictionResponse]):
6 def __init__(self, model_name: str):
7 self.model_name = model_name
8 self.model_path = f"models/{model_name}"
9 self.model = None
10 self._is_loaded = False
11
12 def load_model(self) -> None:
13 """Load your model here. Called once at startup."""
14 self.model = load_your_model(self.model_path)
15 self._is_loaded = True
16
17 def predict(self, request: ImageRequest) -> PredictionResponse:
18 """Actual inference happens here."""
19 image = decode_base64_image(request.image.data)
20 result = self.model(image)
21
22 logprobs = ...
23 mask = ...
24
25 return PredictionResponse(
26 logprobs=logprobs,
27 localizationMask=mask,
28 )
29
30 @property
31 def is_loaded(self) -> bool:
32 return self._is_loadedapp/core/app.py and find the lifespan function:1# Change this line:
2service = ResNetInferenceService(model_name="microsoft/resnet-18")
3
4# To this:
5service = YourModelService(...)/predict endpoint now serves your model.models/ directory:models/
└── your-org/
└── your-model/
├── config.json
├── weights.bin
└── (other files).env file. See .env.example for all available options.APP_NAME: "ML Inference Service"APP_VERSION: "0.1.0"DEBUG: falseHOST: "0.0.0.0"PORT: 8000MODEL_NAME: "microsoft/resnet-18"1# Copy the example
2cp .env.example .env
3
4# Edit values
5vim .env1export MODEL_NAME="google/vit-base-patch16-224"
2uvicorn main:app --reloaduvicorn main:app --reloadgunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000appuser)INFO: Starting ML Inference Service...
INFO: Initializing ResNet service: models/microsoft/resnet-18
INFO: Loading model from models/microsoft/resnet-18
INFO: Model loaded: 1000 classes
INFO: Startup completed successfully
INFO: Uvicorn running on http://0.0.0.0:8000POST /predict1{
2 "image": {
3 "mediaType": "image/jpeg", // or "image/png"
4 "data": "<base64 string>"
5 }
6}1{
2 "logprobs": [float], // Log-probabilities of each label
3 "localizationMask": { // [Optional] binary mask
4 "mediaType": "image/png", // Always png
5 "data": "<base64 string>" // Image data
6 }
7}http://localhost:8000/docshttp://localhost:8000/redochttp://localhost:8000/openapi.jsonpython scripts/generate_test_datasets.pyscripts/test_datasets/*.parquet - Test data (images, requests, expected responses)scripts/test_datasets/*_metadata.json - Human-readable descriptionsscripts/test_datasets/datasets_summary.json - Overview of all datasets1# Start your service first
2make serve1# Quick test (5 samples per dataset)
2python scripts/test_datasets.py --quick
3
4# Full validation
5python scripts/test_datasets.py
6
7# Test specific category
8python scripts/test_datasets.py --category edge_casestandard_test_*.parquet)edge_case_*.parquet)performance_test_*.parquet)model_comparison_*.parquet)DATASET TESTING SUMMARY
============================================================
Datasets tested: 100
Successful datasets: 95
Failed datasets: 5
Total samples: 1,247
Overall success rate: 87.3%
Test duration: 45.2s
Performance:
Avg latency: 123.4ms
Median latency: 98.7ms
p95 latency: 342.1ms
Max latency: 2,341.0ms
Requests/sec: 27.6
Category breakdown:
standard: 25 datasets, 94.2% avg success
edge_case: 25 datasets, 76.8% avg success
performance: 25 datasets, 91.1% avg success
model_comparison: 25 datasets, 89.3% avg success1# Find what's using it
2lsof -i :8000
3
4# Or just use a different port
5uvicorn main:app --port 8080models/<org>/<model-name>/make download to fetch the model weights.