PDF → OCR → NER → Summarization → TTS (audio)
PDF → [Nginx] → [API Gateway] → [CPU Worker: render + postprocess]
↓
[GPU Worker: OCR → Summarize → TTS]
↓
[MinIO: artifacts]
↓
[Audio WAV]
- Docker & Docker Compose
- NVIDIA GPU (RTX 3060+)
- NVIDIA Container Toolkit
- 16GB+ RAM
# 1. Clone and configure
cp .env.example .env
# Edit .env with your settings (HF_TOKEN, API_KEYS, etc.)
# 2. Start all services
make up
# 3. Upload a PDF
curl -X POST -F "file=@document.pdf" http://localhost:8000/pdf
# 4. Check job status
curl http://localhost:8000/jobs/<job_id>
# 5. Health check
curl http://localhost:8000/health| Service | Role | GPU | Port |
|---|---|---|---|
| nginx | Reverse proxy | ❌ | 80/443 |
| redis | Job queue (RQ) | ❌ | 6379 |
| minio | Artifact storage | ❌ | 9000/9001 |
| api-gateway | FastAPI + upload endpoint | ❌ | 8000 |
| cpu-worker | PDF render + NER postprocess | ❌ | — |
| gpu-worker | OCR → Summarize → TTS | ✅ | — |
| ollama | Llama 3.1 8B for summarization | ✅ | 11434 |
- Upload — PDF → job created → enqueue render
- Render — PyMuPDF → PNG pages → MinIO → enqueue OCR
- OCR — PaddleOCR (GPU, Russian) → JSON → MinIO → enqueue postprocess
- Postprocess — Natasha NER + regex cleanup → entities → MinIO → enqueue summarize
- Summarize — Ollama + Llama 3.1 8B → summary text → MinIO → enqueue TTS
- Translate — EN → RU (if summary contains English)
- TTS — Silero v5_ru → WAV audio → MinIO → complete
cp .env.example .envEdit .env:
# Required
HF_TOKEN=hf_your_token_here
API_KEYS=your-secret-key-1,your-secret-key-2
# Optional (defaults work for local dev)
REDIS_URL=redis://redis:6379/0
MINIO_USER=minioadmin
MINIO_PASSWORD=minioadmin
STORAGE_BACKEND=minio
LOG_FORMAT=console # or "json" for productionmake ssl-genOr use Let's Encrypt:
certbot certonly --standalone -d your-domain.com
cp /etc/letsencrypt/live/your-domain.com/fullchain.pem ssl/cert.pem
cp /etc/letsencrypt/live/your-domain.com/privkey.pem ssl/key.pemmake up# Health check
curl http://localhost/health
# Upload test
curl -X POST -F "file=@test.pdf" http://localhost/pdf \
-H "X-API-Key: your-secret-key-1"
# Check status
curl http://localhost/jobs/<job_id>make logs # All services
make logs | grep gpu-worker # GPU worker onlymake test # Run tests
make lint # Run ruff
make logs # Tail logs
make shell-api # Shell into api-gateway
make shell-gpu # Shell into gpu-workerocr-pipeline/
├── shared/ # Shared code (config, schemas, storage)
├── services/
│ ├── api_gateway/ # FastAPI gateway + middleware
│ ├── cpu_worker/ # Render + postprocess
│ └── gpu_worker/ # OCR + summarize + TTS
├── tests/ # Unit + integration tests
├── nginx.conf # Reverse proxy config
├── docker-compose.yml
├── Makefile
├── .env # Secrets (not in git)
└── .env.example # Template
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /pdf |
API Key | Upload PDF, start pipeline |
| GET | /jobs/{id} |
API Key | Get job status + result |
| GET | /health |
No | Health check |
| GET | /docs |
No | Swagger UI |
MIT