Skip to main content

Image captioning using BLIP (Transformers-based)

Project description

🖼️ Image Captioning API

A high-performance, production-ready REST API for ML-based image captioning — built with FastAPI, async concurrency, and GPU-optimized inference.


🚀 Features

  • Zero-Disk I/O — In-memory BytesIO buffers eliminate file system overhead (~200–500ms saved per request)
  • Singleton Model Loading — Model weights loaded once at startup via FastAPI lifespan events (sub-second latency vs. 8+ seconds with per-request loading)
  • Managed GPU Concurrencyasyncio.Semaphore prevents CUDA OOM crashes; asyncio.to_thread keeps the API responsive during heavy inference
  • FP16 + torch.compile — 50% VRAM reduction and ~25% faster execution via Tensor Core acceleration
  • Security Validationpython-magic binary header inspection + MAX_FILE_SIZE enforcement at the gate, before GPU resources are touched

📈 Performance

Metric Original Script Optimized API
Average Latency ~7.5s (model reloads) ~0.6s (warm model)
Concurrency Sequential (1 at a time) Concurrent (queue-based)
Disk Usage Temp file per request 0 bytes (in-memory)
VRAM Stability High OOM risk Safe (semaphore-limited)

🏗️ Architecture

Incoming Request
      │
      ▼
[Security Shield]  ← python-magic + MAX_FILE_SIZE check
      │
      ▼
[In-Memory Buffer] ← io.BytesIO (no disk I/O)
      │
      ▼
[Async Queue]      ← asyncio.Semaphore (concurrency gate)
      │
      ▼
[Background Thread] ← asyncio.to_thread (non-blocking)
      │
      ▼
[GPU Inference]    ← Singleton CaptioningModel (FP16 + torch.compile)
      │
      ▼
   Response

⚙️ Installation

# Clone the repository
git clone https://github.com/your-org/image-captioning-api.git
cd image-captioning-api

# Install dependencies
pip install -r requirements.txt

Requirements: Python 3.10+, CUDA-capable GPU, PyTorch with CUDA support.


🔧 Running the API

Development

uvicorn app:app --reload --host 0.0.0.0 --port 8000

Production (recommended)

Use Gunicorn with Uvicorn workers for maximum performance on multi-core systems:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker app:app --bind 0.0.0.0:8000

Tip: Set -w (workers) to (2 × CPU cores) + 1 as a starting point.


📡 API Reference

POST /caption

Submit an image and receive a generated caption.

Request

Content-Type: multipart/form-data
Body: file=<image>

Response

{
  "caption": "A dog running through a field of sunflowers."
}

Error Responses

Code Reason
400 Invalid file type or binary header mismatch
413 File exceeds MAX_FILE_SIZE limit
503 GPU queue at capacity

GET /health

Returns 200 OK when the model is loaded and the API is ready.


🔐 Configuration

Set the following environment variables:

Variable Default Description
MAX_FILE_SIZE 10485760 Max upload size in bytes (default: 10MB)
GPU_CONCURRENCY 4 Max simultaneous GPU inference tasks
MODEL_PATH ./models/captioner Path to model weights

🛡️ Security

All uploads are validated before reaching GPU resources:

  1. Binary header inspection via python-magic — rejects files that aren't valid images regardless of extension
  2. Size enforcement — files exceeding MAX_FILE_SIZE are rejected at ingestion
  3. No disk writes — uploaded data never touches the filesystem

🧠 Key Implementation Details

Singleton Model (Lifespan)

@asynccontextmanager
async def lifespan(app: FastAPI):
    app.state.model = CaptioningModel()   # loaded once at startup
    yield
    del app.state.model                   # cleanup on shutdown

Managed GPU Concurrency

semaphore = asyncio.Semaphore(GPU_CONCURRENCY)

async def caption_image(file_bytes: bytes) -> str:
    async with semaphore:
        return await asyncio.to_thread(_run_inference, file_bytes)

FP16 Inference

model = model.half()              # FP16: 50% VRAM reduction
model = torch.compile(model)     # JIT-optimized kernels

📄 License

MIT License — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

image_captioning-1.0.0.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

image_captioning-1.0.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file image_captioning-1.0.0.tar.gz.

File metadata

  • Download URL: image_captioning-1.0.0.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for image_captioning-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f779195193bb8c564075cb2f22cb34b4d19cb5df3f3224a5ae90b78920ac819b
MD5 ff4e2f3d7c085d94fc77f1a50a24d83f
BLAKE2b-256 b702ce672f95404ab012296c49fb1cff54a8e9da35f24d64068b3866c97d62d4

See more details on using hashes here.

File details

Details for the file image_captioning-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for image_captioning-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f4699ed9f5d0cb840ae4e7a453b0d03bff337bf5f2ae4c2290d260e3bf49139
MD5 42f9791b9ec05c52cb63b93d0bad641c
BLAKE2b-256 e2c30ff94900a8161a0b9900722b8665a33b1321b5a563e8abb4a1bbdf250c63

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page