BentoML: Model Serving, Runners & Bento Packaging
BentoML standardizes how you package and serve ML models. Define a Service once, get an HTTP API, Docker image, and cloud deployment — with automatic batching and horizontal scaling built in.
Related Products
on GumroadDeveloper Productivity Bundle
Stop rebuilding the same setup every project. 51 VSCode snippets, 40 Git aliases, 5 Docker Compose stacks, 5 GitHub Actions workflows, 5 README templates, and a dotfiles kit. Set up a professional dev environment in under an hour.
Buy on Gumroad →AI Prompt Engineering Toolkit
58 structured prompt templates for Claude, ChatGPT, and Gemini — organized by use case. Code Review, Debugging, Documentation, Architecture, and 10 model-specific tips. Stop writing prompts from scratch.
Buy on Gumroad →Developer Cheat Sheet Bundle
10 print-ready cheat sheets for the tools developers use every day: Git, Docker, Linux CLI, SQL, Regex, HTTP Status codes, VS Code shortcuts, Bash scripting, jq/JSON, and Markdown.
Buy on Gumroad →You Might Also Need
JSON Formatter & Validator
Format, beautify, and validate JSON online. Paste your JSON to instantly pretty-print it with 2-space, 4-space, or tab indentation. Minify JSON too. Free, runs in your browser.
Open free tool →
Regex Tester
Free regex tester. Test regular expressions against multiple strings with expected match/no-match assertions — see instant pass/fail results. Built-in presets for email, URL, IPv4, and phone. Pro: unl
Open free tool →
Base64 Encoder & Decoder
Free Base64 Encoder & Decoder. Convert text, images, and any file to Base64 and back. Supports URL-safe Base64, image data URIs, and file download from Base64. Runs 100% in your browser — no data sent
Open free tool →
More Free Tools
Related Articles
curl 深度使用手冊:API 測試從入門到進階
curl 是每位開發者必備的 CLI 工具。本文涵蓋 GET/POST/PUT/DELETE 請求、認證、header 設定、檔案上傳、除錯技巧,以及 REST API 測試的完整實戰範例。
Best AI Code Review Tools 2026: CodeRabbit, Sourcery, DeepCode & Bito Compared
Compare top AI code review tools for 2026: CodeRabbit, Sourcery, DeepCode, and Bito. Features, pricing, GitHub/GitLab integration, and choosing the right tool for your team.
AI Code Review Tools 2026: GitHub Copilot, CodeRabbit, Qodo Merge Ranked
Compare AI code review tools for 2026: GitHub Copilot code review, CodeRabbit, Qodo Merge, Sourcery, and PR-Agent. Pricing, accuracy, and GitHub integration.
AI Coding Tools Comparison 2026: GitHub Copilot vs Cursor vs Windsurf vs Cline
Comprehensive comparison of the best AI coding tools in 2026: GitHub Copilot, Cursor, Windsurf, and Cline. Pricing, features, model support, and real-world benchmarks.
AI Pair Programming in 2026: GitHub Copilot vs Cursor vs Claude Code
Master AI pair programming in 2026. Compare GitHub Copilot, Cursor, and Claude Code for autocomplete, chat, and agentic workflows. Includes setup guides and productivity tips.
Enjoying this tool? Get more like it.
Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.
Unlock AI-Powered Dev Tools
- ⚡ AI Code Review, Doc Generator & SQL Builder
- ⚡ All premium templates & early access
- ⚡ Member discounts on Gumroad products
$9/mo after trial · Cancel anytime
Want the full toolkit?
Get DevPlaybook Pro
Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.
MIT licensed · Instant download · No subscription
See what's included → Browse all deals →Defining a BentoML Service
Install with pip install bentoml. A Service is a Python class decorated with @bentoml.service:
import bentoml
import numpy as np
from pydantic import BaseModel
# Save your model to BentoML's model store first:
# bentoml.sklearn.save_model("iris_classifier", clf)
class ClassifyInput(BaseModel):
sepal_length: float
sepal_width: float
petal_length: float
petal_width: float
@bentoml.service(
resources={"cpu": "2", "memory": "1Gi"},
traffic={"timeout": 10},
)
class IrisClassifier:
# Model is loaded once at startup and reused across requests
model_ref = bentoml.models.get("iris_classifier:latest")
def __init__(self):
import joblib
self.model = joblib.load(self.model_ref.path_of("model.pkl"))
@bentoml.api(input_spec=ClassifyInput)
def classify(self, input_data: ClassifyInput) -> dict:
features = np.array([[
input_data.sepal_length, input_data.sepal_width,
input_data.petal_length, input_data.petal_width
]])
pred = self.model.predict(features)[0]
prob = self.model.predict_proba(features)[0]
return {"species": str(pred), "confidence": float(prob.max())} Run locally with bentoml serve service:IrisClassifier. The service exposes POST /classify and a Swagger UI at /docs.
Runner API: Scaling Inference Separately
Runners decouple inference from your HTTP server, enabling independent scaling of each model component:
import bentoml
from PIL import Image
import io
# Define runners from saved models
embedding_runner = bentoml.pytorch.get("clip-vit:latest").to_runner()
classifier_runner = bentoml.sklearn.get("image-classifier:latest").to_runner()
@bentoml.service
class ImagePipelineService:
# Runners are injected and managed by BentoML
runners = [embedding_runner, classifier_runner]
@bentoml.api()
async def predict(self, image: bytes) -> dict:
img = Image.open(io.BytesIO(image)).convert("RGB")
# Async calls — HTTP server is never blocked
embedding = await embedding_runner.encode.async_run(img)
label = await classifier_runner.predict.async_run(embedding)
return {"label": label, "embedding_dim": len(embedding)}
# Scale runners independently in bentofile.yaml:
# runners:
# clip-vit: {replicas: 2, resources: {gpu: 1}}
# image-classifier: {replicas: 4, resources: {cpu: 1}} Building & Containerizing a Bento
Package your service and all dependencies into a Bento, then convert to Docker:
# bentofile.yaml — defines what goes into the Bento
service: "service:ImagePipelineService"
include:
- "service.py"
- "*.py"
python:
packages:
- torch==2.2.0
- torchvision
- Pillow
- scikit-learn
docker:
base_image: "pytorch/pytorch:2.2.0-cuda11.8-cudnn8-runtime"
cuda_version: "11.8"
# Build the Bento (bundles model artifacts + code + deps)
$ bentoml build
# Output: Successfully built Bento(tag="image-pipeline:a3f9b2c1")
# Convert to Docker image (optimized, layered)
$ bentoml containerize image-pipeline:a3f9b2c1
# Deploy anywhere
$ docker run --gpus all -p 3000:3000 image-pipeline:a3f9b2c1 BentoML vs Ray Serve vs TorchServe vs Triton
| Feature | BentoML | Ray Serve | TorchServe | Triton |
|---|---|---|---|---|
| Framework support | All (agnostic) | All (agnostic) | PyTorch only | TensorRT/ONNX/TF/PT |
| Adaptive batching | Built-in | Manual | Partial | Dynamic batching |
| Pipeline DAG | Runner composition | Deployment graph | No | Ensemble models |
| Packaging | Bento (artifact bundle) | Docker + Ray cluster | .mar archive | Model repository |
| GPU throughput | Good | Good | Good | Best (TensorRT) |
| Learning curve | Low | Medium | Medium | High |
| Best for | Multi-framework APIs | Distributed serving | PyTorch production | Max GPU throughput |
Frequently Asked Questions
What is BentoML and why use it for model serving?▼
BentoML is an open-source framework that standardizes how ML models are packaged and served. It solves the 'packaging hell' problem: instead of writing custom Flask/FastAPI wrappers for each model, BentoML provides a unified abstraction. You define a Service with input/output schemas, and BentoML generates an HTTP API, handles serialization, manages model loading, and supports batching automatically.
What is a Bento and how is it different from a Docker image?▼
A Bento is BentoML's deployment artifact — a self-contained package that bundles your model artifacts, Python dependencies, service code, and runner configurations. bento build creates a Bento from your project. Unlike a raw Docker image, a Bento is platform-aware: bentoml containerize converts it into an optimized Docker image with the right Python environment, CUDA drivers, and BentoML runtime.
What is a Runner in BentoML?▼
A Runner is BentoML's abstraction for model inference that enables horizontal scaling. Each Runner runs in a separate process pool optimized for its workload — CPU-bound Runners can scale to multiple processes, GPU Runners lock to a GPU device. Your Service calls runners asynchronously via await runner.async_run(), so the HTTP server process is never blocked by inference.
How does BentoML Adaptive Batching work?▼
Adaptive Batching automatically collects concurrent inference requests and processes them as a batch, improving GPU utilization without changing your model code. BentoML dynamically adjusts batch size based on observed latency and throughput. You set max_batch_size and max_latency_ms thresholds, and the batcher optimizes within those bounds. This is critical for transformer models where batch inference is 5-10x more efficient than single-sample.
How do I deploy a BentoML service to production?▼
Options include: (1) Docker — bentoml containerize MyService:latest produces an image deployable to Kubernetes, ECS, or any container platform. (2) BentoCloud — managed serving platform by BentoML team with autoscaling and built-in monitoring. (3) Serverless — community deployers for AWS Lambda, Google Cloud Run. For Kubernetes, BentoML provides a Helm chart and supports KEDA-based autoscaling on queue depth.
Can BentoML serve models from multiple frameworks simultaneously?▼
Yes. A single BentoML Service can include Runners for different frameworks: a PyTorch image encoder, an ONNX text model, and a scikit-learn post-processor can all run as separate Runners in the same service. The Service orchestrates calls between them. This enables building multi-stage pipelines (preprocess → embed → classify → postprocess) as a single deployable unit.