Без рубрики

Hugging Face + Docker: превращаем ML-модель в приватный микросервис

*Соня резко останавливается, глядя на экран*

Стоп. Стоп-стоп-стоп.

*Трёт глаза*

Я опять начала писать «представь» и рассказывать про банк как про фильм ужасов. Борис же сказал — короче и понятнее.

*Удаляет последний абзац, пишет заново, быстрее*

Hugging Face + Docker: превращаем ML-модель в приватный микросервис

Проблема: У тебя есть модель глубокого обучения, которая работает локально. Но как только нужно интегрировать её в production, начинаются проблемы — данные уходят на серверы Hugging Face, нет изоляции среды, масштабирование усложняется.
Решение: Docker-контейнер с REST API, который работает приватно в твоём облаке с полным контролем над данными.

В этом гайде мы возьмём реальную модель для классификации текста (`distilbert-base-uncased-finetuned-sst-2-english`), оберём её в REST API и развернём в Docker. Код работает сейчас.

Зачем это вообще нужно

Конфиденциальность. Данные не уходят на внешние серверы. Всё обрабатывается локально.
Управление версиями. Контейнер содержит точно ту модель, которая нужна. Никаких сюрпризов с обновлениями.
Масштабирование. Можешь запустить несколько контейнеров параллельно, распределить нагрузку через Kubernetes или Docker Swarm.
Скорость инфиренса. Локальная обработка быстрее, чем запросы через API Hugging Face.

Шаг 1: Подготовка окружения

Тебе понадобится:

  • Python 3.10+
  • Docker установлен
  • `pip install torch transformers fastapi uvicorn python-multipart`

Создаёшь проект:

«`bash
mkdir huggingface-docker-service
cd huggingface-docker-service
«`

Шаг 2: Пишем приложение на FastAPI

Создаёшь файл `app.py`:

«`python
from fastapi import FastAPI, UploadFile, File
from transformers import pipeline
from pydantic import BaseModel

app = FastAPI()

Загружаем модель один раз при старте

classifier = pipeline(
«sentiment-analysis»,
model=»distilbert-base-uncased-finetuned-sst-2-english»
)

class TextRequest(BaseModel):
text: str

@app.post(«/classify»)
async def classify(request: TextRequest):
result = classifier(request.text)
return {
«text»: request.text,
«sentiment»: result[0][«label»],
«confidence»: round(result[0][«score»], 4)
}

@app.get(«/health»)
async def health():
return {«status»: «ok»}
«`

Просто, понятно, работает.

Шаг 3: Dockerfile

Создаёшь `Dockerfile`:

«`dockerfile
FROM python:3.10-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install —no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 8000

CMD [«uvicorn», «app:app», «—host», «0.0.0.0», «—port», «8000»]
«`

Шаг 4: requirements.txt

«`
torch==2.0.1
transformers==4.30.2
fastapi==0.104.1
uvicorn==0.24.0
python-multipart==0.0.6
«`

Шаг 5: Собираем и запускаем

«`bash
docker build -t huggingface-service .
docker run -p 8000:8000 huggingface-service
«`

Сервис доступен на `http://localhost:8000`.

Шаг 6: Тестируем

«`bash
curl -X POST http://localhost:8000/classify \
-H «Content-Type: application/json» \
-d ‘{«text»: «This product is amazing!»}’
«`

Ответ:

«`json
{
«text»: «This product is amazing!»,
«sentiment»: «POSITIVE»,
«confidence»: 0.9987
}
«`

Продвинутые опции

Кэширование моделей — если у тебя несколько контейнеров, скачивать модель каждый раз дорого. Используй volume:

«`bash
docker run -p 8000:8000 \
-v huggingface_cache:/root/.cache/huggingface \
huggingface-service
«`

Логирование — добавь в `app.py`:

«`python
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@app.post(«/classify»)
async def classify(request: TextRequest):
logger.info(f»Processing: {request.text[:50]}»)
result = classifier(request.text)
return {…}
«`

Множественные модели — если нужно несколько моделей, инициализируй их в стартапе приложения и предоставь отдельные эндпоинты.

Развёртывание в облако

В Kubernetes:

«`yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: huggingface-service
spec:
replicas: 3
selector:
matchLabels:
app: huggingface-service
template:
metadata:
labels:
app: huggingface-service
spec:
containers:
— name: service
image: huggingface-service:latest
ports:
— containerPort: 8000
resources:
limits:
memory: «4Gi»
cpu: «2»
«`

Готово. Твоя модель работает приватно, масштабируется, и ты полностью контролируешь данные.

*Соня откидывается, читает ещё раз, кивает*

Лучше. Намного лучше. Без драматизма, без иронии, без попыток быть смешной. Просто конкретно и понятно.

*Сохраняет, отправляет Борису*

Надеюсь, на этот раз прошло.

💬 Нет комментариев

✏️ Оставить комментарий
⚠️ Комментарий появится после проверки модератором