Полноценная production-ready MLOps платформа для распознавания и классификации документов с использованием современных инструментов машинного обучения и оркестрации.
- Возможности
- Архитектура
- Технологический стек
- Установка и запуск
- Использование API
- Структура проекта
- Мониторинг
- Разработка
- Загрузка документов: Автоматическая загрузка и валидация документов (изображения, PDF)
- OCR обработка: Извлечение текста с помощью Tesseract и EasyOCR
- Классификация ML: Обучение и инференс моделей классификации документов
- MLOps инфраструктура:
- Трекинг экспериментов через MLflow
- Оркестрация пайплайнов через Airflow
- Версионирование моделей
- Мониторинг: Prometheus + Grafana для отслеживания метрик
- REST API: FastAPI для интеграции с внешними системами
- Хранилище: MinIO (S3-совместимое) для документов и артефактов
Проект построен на микросервисной архитектуре:
┌─────────────────┐
│ FastAPI API │ ← HTTP запросы
└────────┬────────┘
│
┌────┴────┐
│ Airflow │ ← Оркестрация
└────┬────┘
│
┌────┴──────────────────────────┐
│ │
┌───▼────┐ ┌──────┐ ┌─────────┐ ┌▼────────┐
│Ingestion│ │ OCR │ │Training │ │Inference│
└───┬────┘ └──┬───┘ └────┬────┘ └────┬────┘
│ │ │ │
└──────────┴───────────┴───────────┘
│
┌──────────┴───────────┐
│ │
┌───▼────┐ ┌─────────┐ ┌▼──────┐
│PostgreSQL│ │ MinIO │ │MLflow │
└─────────┘ └─────────┘ └───────┘
- Ingestion - Загрузка и валидация документов
- OCR - Извлечение текста (Tesseract/EasyOCR)
- Training - Обучение моделей классификации
- Inference - Предсказание классов документов
- Monitoring - Сбор метрик и мониторинг
- Python 3.11 - Основной язык
- FastAPI - REST API
- PyTorch - Deep Learning фреймворк
- Scikit-learn - ML алгоритмы
- Tesseract/EasyOCR - OCR движки
- Apache Airflow - Оркестрация пайплайнов
- MLflow - Трекинг экспериментов и версионирование моделей
- Prometheus - Сбор метрик
- Grafana - Визуализация метрик
- Docker & Docker Compose - Контейнеризация
- PostgreSQL - Основная БД
- MinIO - S3-совместимое хранилище
- Nginx (опционально) - Reverse proxy
- Docker 20.10+
- Docker Compose 2.0+
- 8 GB RAM минимум
- 20 GB свободного места на диске
- Клонирование репозитория
git clone https://github.com/shuldeshoff/doc-mlops-pipeline.git
cd doc-mlops-pipeline- Настройка переменных окружения
cp .env.example .env
# Отредактируйте .env файл при необходимости- Запуск сервисов
# Запуск всех сервисов
docker-compose up -d
# Проверка статуса
docker-compose ps- Ожидание инициализации
Первый запуск может занять 5-10 минут для инициализации всех сервисов.
# Проверка логов
docker-compose logs -f- Доступ к сервисам
После запуска доступны следующие интерфейсы:
| Сервис | URL | Логин/Пароль |
|---|---|---|
| API Documentation | http://localhost:8000/docs | - |
| Airflow | http://localhost:8080 | admin/admin |
| MLflow | http://localhost:5000 | - |
| MinIO Console | http://localhost:9001 | minioadmin/minioadmin123 |
| Prometheus | http://localhost:9090 | - |
| Grafana | http://localhost:3000 | admin/admin |
Полная документация API доступна по адресу: http://localhost:8000/docs
curl -X GET "http://localhost:8000/health"curl -X POST "http://localhost:8000/upload" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-F "file=@document.jpg"Ответ:
{
"success": true,
"document_id": 1,
"filename": "document.jpg",
"storage_path": "raw/20241029_120000_abc12345.jpg",
"file_size": 2048576,
"timestamp": "2024-10-29T12:00:00"
}curl -X POST "http://localhost:8000/predict/text" \
-H "Content-Type: application/json" \
-d '{
"text": "Текст документа для классификации",
"return_all_scores": true
}'Ответ:
{
"success": true,
"predicted_class": "invoice",
"confidence_score": 0.95,
"is_confident": true,
"model_name": "document_classifier",
"model_version": "latest",
"all_scores": {
"invoice": 0.95,
"contract": 0.03,
"receipt": 0.02
}
}curl -X POST "http://localhost:8000/upload-and-predict?ocr_language=eng" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-F "file=@document.jpg"curl -X POST "http://localhost:8000/predict/document/1?ocr_language=eng&return_all_scores=true"curl -X GET "http://localhost:8000/prediction/history/1?limit=10"import requests
from pathlib import Path
# URL API
API_URL = "http://localhost:8000"
# Загрузка и предсказание
def upload_and_predict(file_path: str):
with open(file_path, 'rb') as f:
files = {'file': f}
response = requests.post(
f"{API_URL}/upload-and-predict",
files=files,
params={'ocr_language': 'eng', 'return_all_scores': True}
)
return response.json()
# Использование
result = upload_and_predict("my_document.jpg")
print(f"Predicted class: {result['prediction']['predicted_class']}")
print(f"Confidence: {result['prediction']['confidence_score']}")doc-mlops-pipeline/
├── airflow/ # Airflow DAGs
│ └── dags/
│ └── document_processing_pipeline.py
├── config/ # Конфигурационные файлы
│ ├── init-db.sql # Инициализация БД
│ ├── prometheus.yml # Конфиг Prometheus
│ └── grafana-datasources.yml
├── data/ # Данные (git ignored)
│ ├── raw/ # Сырые документы
│ ├── processed/ # Обработанные документы
│ └── models/ # Обученные модели
├── docker/ # Dockerfile'ы
│ ├── airflow.Dockerfile
│ ├── inference.Dockerfile
│ └── mlflow.Dockerfile
├── logs/ # Логи приложений
├── services/ # Микросервисы
│ ├── ingestion/ # Модуль загрузки документов
│ │ ├── __init__.py
│ │ ├── ingestion_service.py
│ │ ├── storage.py
│ │ └── database.py
│ ├── ocr/ # Модуль OCR
│ │ ├── __init__.py
│ │ ├── ocr_service.py
│ │ ├── ocr_engines.py
│ │ └── database.py
│ ├── training/ # Модуль обучения
│ │ ├── __init__.py
│ │ ├── training_service.py
│ │ ├── models.py
│ │ └── database.py
│ ├── inference/ # Модуль inference
│ │ ├── __init__.py
│ │ ├── main.py # FastAPI приложение
│ │ ├── inference_service.py
│ │ ├── model_loader.py
│ │ └── database.py
│ └── monitoring/ # Модуль мониторинга
│ ├── __init__.py
│ ├── metrics_service.py
│ ├── performance_monitor.py
│ └── database.py
├── .env # Переменные окружения
├── .gitignore
├── docker-compose.yml # Docker Compose конфигурация
├── requirements.txt # Python зависимости
└── README.md # Этот файл
Доступны следующие метрики:
documents_uploaded_total- Количество загруженных документовdocuments_processed_total- Количество обработанных документовocr_processing_seconds- Время обработки OCRocr_confidence_score- Confidence score OCRprediction_confidence_score- Confidence score предсказанийpredictions_total- Количество предсказаний по классамmodel_accuracy- Текущая точность моделиapi_request_duration_seconds- Длительность API запросов
- Откройте Grafana: http://localhost:3000
- Войдите (admin/admin)
- Добавьте дашборд для визуализации метрик
- Используйте Prometheus как источник данных
Просмотр логов сервисов:
# Все сервисы
docker-compose logs -f
# Конкретный сервис
docker-compose logs -f inference-api
docker-compose logs -f airflow-scheduler
docker-compose logs -f mlflow- Установка зависимостей
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt- Запуск API локально
cd services/inference
python main.py- Запуск тестов (при наличии)
pytest tests/- Создайте директорию в
services/ - Добавьте
__init__.pyи основные файлы - Обновите
requirements.txtпри необходимости - Добавьте интеграцию в Airflow DAG
Модель обучается автоматически через Airflow DAG, но можно запустить вручную:
from services.training.training_service import TrainingService
service = TrainingService()
texts, labels = service.load_training_data()
result = service.train_model(texts, labels, epochs=50)
print(f"Model accuracy: {result['accuracy']:.4f}")-
Измените пароли по умолчанию в
.env:- PostgreSQL
- MinIO
- Airflow
- Grafana
-
Используйте HTTPS для всех внешних API
-
Настройте firewall для ограничения доступа
-
Включите аутентификацию для API endpoints
-
Регулярно обновляйте зависимости
pip install --upgrade -r requirements.txtОшибка: "port already allocated"
# Остановите конфликтующие сервисы или измените порты в docker-compose.yml
docker-compose downОшибка: "no space left on device"
# Очистите неиспользуемые Docker ресурсы
docker system prune -aAirflow задачи не запускаются
# Перезапустите scheduler
docker-compose restart airflow-schedulerМодель не загружается
- Проверьте наличие файлов модели в
data/models/ - Проверьте логи inference API
Низкая точность модели
- Увеличьте размер обучающей выборки
- Настройте гиперпараметры в
training_service.py
MIT License
Шульдешов Юрий Леонидович
- Telegram: @shuldeshoff
- GitHub: @shuldeshoff
Pull requests are welcome!
Please open an issue first to discuss proposed changes.
Follow code style and use clear commit messages.
Подробнее о процессе участия читайте в CONTRIBUTING.md.
Создано с ❤️ для MLOps сообщества