Деплоим модель с Seldon MLServer
Полное руководство по интеграции и использованию YOLOv8 с Seldon MLServer для задач компьютерного зрения
Введение
В данной статье мы рассмотрим процесс проектирования и развертывания модели машинного обучения с использованием Seldon MLServer, особенно акцентируя внимание на использовании модели YOLOv8 от Ultralytics для задач компьютерного зрения. Seldon MLServer — это мощная среда для обслуживания моделей машинного обучения, основанная на Python, которая обеспечивает удобное взаимодействие с моделями в различных средах.
Что такое Seldon MLServer?
Seldon MLServer — это специализированный сервер для обслуживания моделей, который поддерживает множество стандартов и фреймворков машинного обучения. Он позволяет легко интегрировать, масштабировать и управлять жизненным циклом моделей ML. MLServer поддерживает такие фреймворки, как Scikit-learn, XGBoost, MLflow и многие другие, обеспечивая при этом совместимость с стандартом Open Model Interface (OMI).
Интеграция YOLOv8 с Seldon MLServer
YOLO (You Only Look Once) - это популярный алгоритм объектного обнаружения, который был разработан для выполнения обнаружения объектов в реальном времени. Версия YOLOv8 представляет собой последнее улучшение в этой серии, обеспечивающее еще большую точность и скорость.
Шаги для интеграции:
Установка зависимостей:
Установите необходимые пакеты для работы YOLOv8 и Seldon MLServer.
pip install mlserver ultralytics
Создание обертки для модели YOLOv8
Для интеграции с MLServer модель YOLOv8 должна быть обернута в специальный класс, который наследует MLModel
from mlserver.types import InferenceRequest, InferenceResponse, ResponseOutput
from ultralytics import YOLO # Импорт класса YOLO для объектного обнаружения
import base64 # Импорт библиотеки для работы с base64 кодировкой
from PIL import Image # Импорт класса Image для работы с изображениями
import numpy as np # Импорт библиотеки NumPy для работы с массивами
from io import BytesIO # Импорт класса BytesIO для работы с бинарными потоками
import json # Импорт библиотеки для работы с JSON
import mlserver # Импорт mlserver для серверной работы с ML моделями
# Определение класса модели YOLOv8 на основе MLModel из mlserver
class YOLOv8Model(mlserver.MLModel):
async def load(self) -> bool:
self._model = YOLO('yolov8n.pt') # Загрузка официальной модели YOLOv8n
return await super().load() # Вызов метода загрузки базового класса
async def predict(self, payload: InferenceRequest) -> InferenceResponse:
img = self.base64_to_img(payload.inputs[0].data[0]) # Преобразование входной строки base64 в изображение
results = self._model(img) # Выполнение обнаружения объектов на изображении
response_outputs = [] # Список для хранения результатов
# Обход результатов обнаружения объектов
for result in results:
# Добавление информации о прямоугольниках объектов
response_outputs.append(ResponseOutput(
name="boxes",
shape=result.boxes.xywh.shape,
datatype="FP32",
data=self.serialize_numpy(result.boxes.xywh)
))
# Добавление информации о вероятностях обнаружения
response_outputs.append(ResponseOutput(
name="probs",
shape=result.boxes.conf.shape,
datatype="FP32",
data=self.serialize_numpy(result.boxes.conf)
))
# Добавление информации о классах объектов
response_outputs.append(ResponseOutput(
name="cls",
shape=result.boxes.cls.shape,
datatype="FP32",
data=self.serialize_numpy(result.boxes.cls)
))
return InferenceResponse(
model_name="yolov8n",
model_version="v1",
outputs=response_outputs
)
def base64_to_img(self, b64str):
"""Преобразование строки base64 в изображение."""
image_data = base64.b64decode(b64str) # Декодирование строки base64
image = Image.open(BytesIO(image_data)) # Создание изображения из бинарных данных
image = image.convert('RGB') # Преобразование изображения в формат RGB
return np.array(image) # Возврат изображения в виде массива numpy
def serialize_numpy(self, np_array):
"""Сериализация массива numpy в строку JSON."""
return json.dumps(np.array(np_array).tolist()) # Преобразование и сериализация массива numpy в JSON
Запуск сервера:
Запустите MLServer с указанной конфигурацией.
mlserver start .
Теперь напишем код для тестирования модели
import requests # Импортируем библиотеку для отправки HTTP-запросов
import json # Импортируем библиотеку для работы с JSON
import base64 # Импортируем библиотеку для кодирования и декодирования в Base64
import matplotlib.pyplot as plt # Импортируем модуль pyplot из библиотеки matplotlib для визуализации данных
import matplotlib.patches as patches # Импортируем модуль patches для создания фигур
from PIL import Image # Импортируем класс Image из библиотеки PIL для работы с изображениями
# Словарь меток классов (можно расширить в соответствии с классами вашей модели)
class_labels = {
15: 'Cat', # ID 15 соответствует категории "Кошка"
16: 'Dog' # ID 16 соответствует категории "Собака"
}
def encode_image_to_base64(image_path):
"""
Кодирует изображение в строку Base64.
:param image_path: Путь к файлу изображения.
:return: Строка, закодированная в Base64.
"""
with open(image_path, "rb") as image_file: # Открываем файл в бинарном режиме
base64_encoded = base64.b64encode(image_file.read()).decode('utf-8') # Читаем, кодируем в Base64 и декодируем в строку
return base64_encoded # Возвращаем закодированную строку
def send_image_to_mlserver(image_path, url):
"""
Отправляет POST запрос на MLServer с изображением в формате Base64.
:param image_path: Путь к файлу изображения.
:param url: URL MLServer для обработки запросов.
:return: Ответ сервера.
"""
encoded_image = encode_image_to_base64(image_path) # Кодируем изображение
request_data = {
"inputs": [
{
"name": "image", # Имя входного параметра
"shape": [1], # Форма данных
"datatype": "BYTES", # Тип данных
"data": [encoded_image] # Данные
}
]
} # Формируем тело запроса в формате JSON
response = requests.post(url, json=request_data) # Отправляем POST-запрос
return response.json() # Возвращаем ответ сервера в виде JSON
image_path = './image-2.jpeg' # Путь к изображению
mlserver_url = 'http://localhost:8080/v2/models/yolov8-model/infer' # URL вашего MLServer
response = send_image_to_mlserver(image_path, mlserver_url) # Отправляем изображение на сервер и получаем ответ
boxes = json.loads(response['outputs'][0]['data']) # Разбираем JSON ответ для получения координат рамок
probs = json.loads(response['outputs'][1]['data']) # Разбираем JSON ответ для получения вероятностей
classes = json.loads(response['outputs'][2]['data']) # Разбираем JSON ответ для получения классов объектов
img = Image.open(image_path) # Загружаем изображение
fig, ax = plt.subplots() # Создаем фигуру и оси для рисования
ax.imshow(img) # Отображаем изображение
for box, prob, cls in zip(boxes, probs, classes): # Для каждого объекта
x, y, w, h = box # Координаты и размеры рамки
rect = patches.Rectangle((x-w/2, y-h/2), w, h, linewidth=2, edgecolor='r', facecolor='none') # Создаем прямоугольник
ax.add_patch(rect) # Добавляем прямоугольник на график
label = f"{class_labels[int(cls)]}: {prob:.2f}" # Текст метки
plt.text(x-w/2, y-h/2, label, color='white', fontsize=12, bbox=dict(facecolor='red', alpha=0.5)) # Добавляем текст метки
plt.show() # Отображаем результат
Выполним код для теста модели на выходе получим изобрежение с готовой разметкой
Добавляем кастомные метрики
Теперь нам необходимо понимать какие запросы отправляет пользователь, для этого можно использовать экспорт касмтоных метрик
С помощью mlserver.register
можно создать метрику для экпорта в модуль Prometheus. как пример мы добавим экпосрт меитрики в количесте обнаруженных объектов. Модифицируем метод load
async def load(self) -> bool:
self._model = YOLO('yolov8n.pt') # Загрузка официальной модели YOLOv8n
# Регистрация функции логирования для обнаружения объектов
mlserver.register("count_obj_detection", "This is a count objects detection")
return await super().load() # Вызов метода загрузки базового класса
C помощью команды mlserver.register
регистрируем кастомную метрику и теперь заполняем ее в методе predict
async def predict(self, payload: InferenceRequest) -> InferenceResponse:
...остальной код...
# Логирование количества обнаруженных объектов
mlserver.log(count_obj_detection=len(response_outputs))
return InferenceResponse(
model_name="yolov8n",
model_version="v1",
outputs=response_outputs
)
Метрики по умолчанию доступны http://0.0.0.0:8082/metrics
Сборка орбраза
Соберем все используемые библиоетеки в файлы requirements.txt
Запустем сборку образа черещ mlserver
mlserver build ./ -t 'yolov8_ml_service'
Полный репозиторий с кодом можете найти в репозитории https://github.com/MLSystem-Design/mlserver-yolov8
Заключение
MLServer от Seldon предоставляет мощные и гибкие возможности для развертывания моделей машинного обучения в производственной среде. Используя интеграцию с YOLOv8, разработчики могут эффективно обрабатывать задачи компьютерного зрения, улучшая при этом мониторинг и анализ производительности моделей с помощью кастомных метрик.
Подписывайтесь на телеграмм канал там больше материла про ML https://t.me/ml_pops
No comments yet. Login to start a new discussion Start a new discussion