BentoML - Serving đơn giản mà hiệu quả

0 0 0

Người đăng: Duong Quang Minh B

Theo Viblo Asia

Introduction

Trong quá trình triển khai mô hình machine learning/deep learning lên sản phẩm thực tế, những thách thức lớn không chỉ nằm ở việc huấn luyện mô hình, mà còn nằm ở khâu triển khai (serving) sao cho nhanh chóng, ổn định và dễ bảo trì. Trước kia, rất nhiều người bắt đầu bằng cách tự viết Flask hoặc FastAPI để dựng API cho mô hình, kết hợp với Docker nhằm mục đích đóng gói. Nhưng khi số lượng mô hình tăng lên, tỉ lệ thuận với nhiều yêu cầu phức tạp, hoặc khi cần tracking version, rollback model,... thì những giải pháp "tự làm" dần trở nên khó khăn. Đó chính là lúc BentoML thể hiện khả năng của mình – open-source framework giúp bạn triển khai mô hình nhanh chóng chỉ với vài dòng code, mà vẫn đảm bảo các yếu tố modular, production-ready và dễ tích hợp với các hệ thống lớn.

Overview

BentoML là một Unified Inference Platform để triển khai và mở rộng các mô hình AI. Nó cho phép developers xây dựng hệ thống AI nhanh hơn nhiều lần với custom models, mở rộng hiệu quả trên Cloud. Nói ngắn gọn thì, BentoML là thư viện Python dùng để xây dựng online serving systems được tối ưu hóa cho AI apps và model inference.

Một số điểm chính khiến BentoML cũng khá được ưa chuộng:

  • Dễ dàng build APIs cho mô hình AI chỉ cần vài dòng code
  • Quản lý environments, dependencies và model version dễ dàng, tự động tạo Docker images, đơn giản hóa việc triển khai lên các environment khác.
  • Tối đa hóa CPU/GPU utilization: dynamic batching, model parallelism, multi-stage pipeline và multi-model inference-graph orchestration.
  • Fully customizable: Custom logic, model inference, hỗ trợ nhiều framework và inference runtime
  • Có thể phát triển, debug dưới local, triển khai lên BentoCloud, ...
  • ...

Cho tới thời điểm hiện tại, BentoML cũng đã support vô cùng nhiều các kịch bản khác nhau bao gồm:

  • LLMs: Triển OpenAI-compatible LLM API service với vLLM (DeepSeek, LLama, ...) và có thể custom LLM Inference Runtime (TensorRT-LLM, Triton, vLLM, ...)
  • AI Systems: Scalable AI system (Agent, RAG, ...)
  • Text-to-image và image-to-image models: ComfyUI workflow, Stable Diffusion, ...
  • Audios, Computer Vision, ....

Installation

Chắc thông tin cơ bản thế là đủ để biết BentoML support rất nhiều bài toán liên quan đến AI models rồi nhỉ, trong bài viết lần này mình sẽ nghịch thử một chút thằng BentoML này nhé.

Bước đầu tiên và muôn thuở là việc cài đặt môi trường. BentoML là 1 thư viện Python nên việc cài đặt cũng đơn giản thôi. Trước tiên ta cần tạo môi trường Python trước đã, như thường lệ, mọi người có thể cài conda hay pip đều được:

conda create -n bento python=3.11 -y
conda activate bento

Tiếp theo, ta cần cài thư viện bentoml (cũng như các thư viện liên quan khác nếu cần):

pip install bentoml

Vậy là xong, việc cài đặt cũng chỉ có thể thôi, hẹ hẹ hẹ.

Serving

OK, trước tiên để serving thì bước đầu phải có model nhỉ, mọi người có thể chuẩn bị bất cứ model nào cũng được không cần đặt nặng vấn đề này đâu, bài viết của mình chỉ mang tính tham khảo cách thức sử dụng thôi nên trong bài viết này mình vẫn sử dụng 1 Torchscript model cho bài toán phân đoạn (y hệt với model được dùng trong các bài viết trước của mình cho nhanh :v ).

Trước tiên, mình sẽ save thằng torchscript model này vào trong bentoml như sau:

import torch
import bentoml device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = torch.jit.load("model.pt") saved_model = bentoml.torchscript.save_model( "unet34-torchscript", model, signatures={ "__call__": { "batchable": True, "batch_dim": 0, } },
) print(f"Model saved: {saved_model}") # Model saved: Model(tag="unet34-torchscript:x3yngrb346ardhbp")

Sau khi chạy đoạn code trên thì ta có thể thấy model đã được save với tag vào id. Để kiểm tra tất cả các model đã được save trong local thì có thể dùng:

bentoml models list # Output Tag Module Size Creation Time unet34-torchscript:x3yngrb346ardhbp bentoml.torchscript 84.20 MiB 2025-05-29 00:18:17 ....

Tiếp theo, ta cần define cách mà model được chạy:

import cv2
import torch
import bentoml
import numpy as np
from bentoml.io import Image
import albumentations as A
from albumentations import Compose
from albumentations.pytorch.transforms import ToTensorV2 # Initialize Runner
runner = bentoml.torchscript.get("unet34-torchscript:x3yngrb346ardhbp").to_runner() # Initialize BentoML Service
ship_segment = bentoml.Service( "airbus-segmentation", runners=[runner],
) def preprocess(image): transform = Compose([ A.Resize(768, 768), A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ToTensorV2(), ]) return transform(image=image)['image'] # API Creation
@ship_segment.api(input=Image(), output=Image())
def segment(input_image): input_image = np.array(input_image) transformed_image = preprocess(input_image).unsqueeze(0) mask = runner.run(transformed_image) mask = (torch.sigmoid(mask.squeeze(0)) >= 0.5).cpu().numpy().transpose((1,2,0)).astype(np.uint8) mask = cv2.resize(mask, (input_image.shape[1], input_image.shape[0])) return mask_overlay(input_image, mask)

Đoạn code trên nhằm mục đích tạo API service locally, để chạy nó, bạn có thể dùng câu lệnh dưới đây trong Terminal:

bentoml serve service:ship_segment

Hãy cùng check logs một tí nhỉ, ta có thể thất Bento Service của ta đang được listen trên port 3000 (bỏ qua mấy cái warning deprecated nếu có nhé :v ):

2025-05-29T00:27:02+0700 [INFO] [cli] Environ for worker 0: set CUDA_VISIBLE_DEVICES to 0
2025-05-29T00:27:02+0700 [INFO] [cli] Prometheus metrics for HTTP BentoServer from "service:ship_segment" can be accessed at http://localhost:3000/metrics.
2025-05-29T00:27:04+0700 [INFO] [cli] Starting production HTTP BentoServer from "service:ship_segment" listening on http://0.0.0.0:3000 (Press CTRL+C to quit)

Để test API thì các bạn dùng gì cũng được, mình sẽ test thử thằng Postman xem như thế nào, các bạn có thể set up như mình để test:

Screenshot from 2025-05-29 00-34-17.png

Và đó là kết quả visualize mask lên ảnh gốc. Thật dễ dàng phải không, chỉ với vài dòng code thôi là ta đã test được luồng API cho model rồi.

Build

Phần tiếp theo sẽ là cách xác định cách build bento cho deployment, ta sẽ cần tạo 1 file bentoml.yaml như dưới đây:

service: "service:ship_segment"
labels: owner: minh-b stage: dev
include: - "*.py" python: packages: - numpy - opencv-python - albumentations - torch - torchvision
docker: system_packages: - ffmpeg - libsm6 - libxext6

Tiếp theo chỉ cần build BentoML thôi:

bentoml build

Sau khi thành công thì các bạn có thể thấy logs như sau:

██████╗ ███████╗███╗ ██╗████████╗ ██████╗ ███╗ ███╗██╗
██╔══██╗██╔════╝████╗ ██║╚══██╔══╝██╔═══██╗████╗ ████║██║
██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║ ██║██╔████╔██║██║
██╔══██╗██╔══╝ ██║╚██╗██║ ██║ ██║ ██║██║╚██╔╝██║██║
██████╔╝███████╗██║ ╚████║ ██║ ╚██████╔╝██║ ╚═╝ ██║███████╗
╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ Successfully built Bento(tag="airbus-segmentation:xuez2ob35k6wfhbp"). Next steps: * Deploy to BentoCloud: $ bentoml deploy airbus-segmentation:xuez2ob35k6wfhbp -n ${DEPLOYMENT_NAME} * Update an existing deployment on BentoCloud: $ bentoml deployment update --bento airbus-segmentation:xuez2ob35k6wfhbp ${DEPLOYMENT_NAME} * Containerize your Bento with `bentoml containerize`: $ bentoml containerize airbus-segmentation:xuez2ob35k6wfhbp * Push to BentoCloud with `bentoml push`: $ bentoml push airbus-segmentation:xuez2ob35k6wfhbp 

Trong đoạn logs trên thì thư viên cũng đã note cho mình một số next step mình có thể thử rồi, bao gồm việc deploy lên BentoCloud, Containerize, .... Ta cũng có thể check các bentoml đã sẵn sàng với:

bentoml list Tag Size Model Size Creation Time airbus-segmentation:xuez2ob35k6wfhbp 22.17 KiB 84.20 MiB 2025-05-29 00:39:51 

Tiếp theo, ta có thể thử build 1 Docker images nhé, dựa trên câu lệnh gợi ý mà BentoML logs ra cho mình ở trên thôi :v :

bentoml containerize airbus-segmentation:xuez2ob35k6wfhbp 

Sau một khoảng thời gian dài chờ đợi nó build xong thì các bạn có thể kiểm tra Docker images cũng như có thể run nó lên:

docker images
docker run -p 3000:3000 airbus-segmentation:xuez2ob35k6wfhbp

Ngoài ra, nếu các bạn không muốn dùng nữa và muốn xóa đi thì có thể sử dụng:

docker image rm <ID> # Delete in BentoML
bentoml list
bentoml delete airbus-segmentation:tag

Vậy đó là xong.

Summary

Trong bài viết này, mình có đề cập với mọi người một serving framework đơn giản mà vô cùng hiệu quả cho mô hình AI, hiện tại đã hỗ trợ cho rất nhiều kịch bản và bài toán. Bài viết của mình chỉ mang tính chất tham khảo thôi và không thể bao quát hết được toàn bộ tính năng mà BentoML đem lại, các bạn có thể đọc trực tiếp trong tài liệu của thư viện BentoML nhé. Cảm ơn mọi người đã dành thời gian đọc.

References

Bình luận

Bài viết tương tự

- vừa được xem lúc

Hướng dẫn finetune mô hình LLM đơn giản và miễn phí với Unsloth

Chào mừng các bạn đến với bài viết hướng dẫn chi tiết cách finetune (tinh chỉnh) một mô hình ngôn ngữ lớn (LLM) một cách đơn giản và hoàn toàn miễn phí sử dụng thư viện Unsloth. Trong bài viết này, ch

0 0 7

- vừa được xem lúc

SERIES INDEX NÂNG CAO - BÀI 1: PHÂN TÍCH NHỮNG SAI LẦM PHỔ BIẾN KHI SỬ DỤNG INDEX TRONG MYSQL

Nếu anh em thấy hay thì ủng hộ tôi 1 follow + 1 upvote + 1 bookmark + 1 comment cho bài viết này tại Mayfest 2025 nhé. Còn nếu bài viết chưa hữu ích thì tôi cũng hi vọng anh em để lại những góp ý thẳn

0 0 8

- vừa được xem lúc

"Hack" Não Số Lớn Với Digit DP!

Xin chào anh em, những chiến binh thuật toán kiên cường. Phản ứng đầu tiên của nhiều anh em (có cả tôi): "Ối dào, dễ! Quất cái for từ 1 đến 101810^{18}1018 rồi check thôi!".

0 0 10

- vừa được xem lúc

So Sánh StatelessWidget và StatefulWidget & Các Widget Nâng Cao

Chào mọi người! Hôm nay chúng ta sẽ tiếp tục hành trình khám phá Flutter và đến với bài học về StatelessWidget và StatefulWidget. Trong bài này, mình sẽ giúp các bạn phân biệt sự khác nhau giữa hai lo

0 0 7

- vừa được xem lúc

React Lifecycle & Hooks Cơ Bản

React cung cấp các phương thức lifecycle và hooks để quản lý các giai đoạn khác nhau trong vòng đời của component. Việc hiểu rõ các phương thức này giúp bạn có thể tối ưu hóa ứng dụng React của mình.

0 0 7

- vừa được xem lúc

Kafka Fundamental - Bài 4: Consumers, Deserialization, Consumer Groups & Consumer Offsets

Xin chào, lại là mình - Đức Phúc, anh chàng hơn 6 năm trong nghề vẫn nghèo technical nhưng thích viết Blog để chia sẻ kiến thức bản thân học được trong quá trình “cơm áo gạo tiền” đây. Các bạn có thể

0 0 5