Media Transcription & OCR + Document Ingest API powered by:
faster-whisper (auto CPU/GPU via CTranslate2)yt-dlp → audio → ASR/__docs__)docker run --rm -p 9002:9002 \
-e ASR_MODEL=large-v3 \
-e OCR_LANGS=en \
-e VLM_MODEL_ID=microsoft/Florence-2-large \
ghcr.io/knowusuboaky/asr_ocr:latest
# Docs: http://localhost:9002/__docs__
# Health: http://localhost:9002/health
docker run --rm --gpus all -p 9002:9002 \
-e ASR_MODEL=large-v3 \
-e OCR_LANGS=en \
-e VLM_MODEL_ID=microsoft/Florence-2-large \
ghcr.io/knowusuboaky/asr_ocr:cuda
The server listens on port 9002. GPU builds accelerate ASR and Florence-2.
GET /healthLiveness probe. Returns:
ok
GET /Plain-text summary of active ASR/VLM/OCR setup (model, device, langs).
POST /transcribe_fileASR for audio/video (any ffmpeg-readable format).
X-Filename: yourfile.ext (optional)curl -X POST http://localhost:9002/transcribe_file \
-H "X-Filename: clip.mp3" \
--data-binary @clip.mp3
POST /transcribe_imageOCR + optional captioning for a single image.
X-Filename: image.png (optional)curl -X POST http://localhost:9002/transcribe_image \
-H "X-Filename: slide.png" \
--data-binary @slide.png
POST /extract_documentFull document ingest to Markdown (front-matter + grouped contents). Supported: .pdf, .pptx, .docx, .doc, .xlsx, .csv, .txt
Query params (all optional – shown with defaults):
ocr=paddle|none (default paddle)lang=en (primary OCR language)dpi=300 (page OCR raster DPI)ocr_threshold=50 (page OCR if native text < N chars)vlm=hf_local|none (default hf_local)vlm_model=microsoft/Florence-2-largevlm_max_tokens=128vlm_prompt=<MORE_DETAILED_CAPTION>caption_pages=false (page-level captions)vlm_dpi=256 (page render DPI for captions)image_columns= (CSV: comma-sep column names that hold image refs)fetch_http=false (allow HTTP fetch for CSV/XLSX image links)image_root=. (resolve relative paths for linked images)caption_xlsx_charts=false (try page-captions via PDF export if LibreOffice present)soffice_bin= (path to LibreOffice/soffice if installed)max_rows=-1 (tables → show all rows; set to N to truncate)vlm_only=false (emit only captions; skip native/OCR text)curl -X POST "http://localhost:9002/extract_document?ocr=paddle&vlm=hf_local&lang=en" \
-H "X-Filename: deck.pptx" \
--data-binary @deck.pptx
POST /transcribe_urlOrdered handling:
Body:
{ "url": "https://example.com/...", "user_agent": "Optional UA string" }
Example:
curl -X POST http://localhost:9002/transcribe_url \
-H "Content-Type: application/json" \
-d '{"url":"https://youtu.be/xyz"}'
| Variable | Default | Description |
|---|---|---|
ASR_MODEL | large-v3 | faster-whisper size (large-v3, medium, small, …) |
VAD_MIN_SIL_MS | 500 | VAD min silence (ms) between segments |
KEEP_WAV | false | Keep temp WAV after processing |
KEEP_WAV_ON_ERROR | true | Keep WAV if an error occurs |
FETCH_UA | Chrome-like UA | Default User-Agent for /transcribe_url |
MAX_FETCH_BYTES | 26214400 (25 MiB) | Cap for single URL fetch |
HTTP_TIMEOUT_S | 30 | Per-request timeout for URL fetch |
| Variable | Default | Description |
|---|---|---|
VLM_MODEL_ID | microsoft/Florence-2-large | HF model id |
VLM_CAPTION_TASK | <MORE_DETAILED_CAPTION> | Caption task token |
VLM_MAX_TOKENS_CAPTION | 768 | Max tokens for captioning |
| Device/dtype | auto | CUDA→float16, else CPU |
| Variable | Default | Description |
|---|---|---|
OCR_LANGS | en | Primary OCR lang (first in list is used) |
OCR_UPSCALE | 1.5 | Pre-resize factor for images |
OCR_RECOG_HEAD | english_g2 | Kept for compatibility (not used by Florence) |
OCR_ALLOWLIST | alnum+punct | Characters allowed by OCR |
Mount caches to avoid repeated downloads:
/root/.cache/huggingface/root/.paddleocrservices:
asr_ocr:
image: ghcr.io/knowusuboaky/asr_ocr:latest
ports: ["9002:9002"]
environment:
- ASR_MODEL=large-v3
- OCR_LANGS=en
- VLM_MODEL_ID=microsoft/Florence-2-large
volumes:
- hf-cache:/root/.cache/huggingface
- paddle-cache:/root/.paddleocr
restart: unless-stopped
volumes:
hf-cache:
paddle-cache:
services:
asr_ocr:
image: ghcr.io/knowusuboaky/asr_ocr:cuda
ports: ["9002:9002"]
environment:
- ASR_MODEL=large-v3
- OCR_LANGS=en
- VLM_MODEL_ID=microsoft/Florence-2-large
gpus: all
volumes:
- hf-cache:/root/.cache/huggingface
- paddle-cache:/root/.paddleocr
restart: unless-stopped
volumes:
hf-cache:
paddle-cache:
Health:
http://localhost:9002/health• Docs:http://localhost:9002/__docs__
fetch_http=true)..doc: If LibreOffice is available, the server converts .doc → .docx/.pdf to recover text + images; otherwise it falls back to CLI text extractors.caption_xlsx_charts=true) so pages can be VLM-captioned as images./__docs__.python -m venv .venv && source .venv/bin/activate
pip install -U pip
pip install fastapi "uvicorn[standard]" httpx faster-whisper imageio-ffmpeg \
pillow transformers accelerate safetensors \
paddleocr paddlepaddle \
beautifulsoup4 lxml pandas openpyxl python-docx python-pptx pymupdf \
tabulate chardet yt-dlp
uvicorn transcribe_server:app --host 0.0.0.0 --port 9002
38 commits
Python
91.0%
Shell
5.1%
Dockerfile
3.1%
Media Transcription & OCR + Document Ingest API powered by:
faster-whisper (auto CPU/GPU via CTranslate2)yt-dlp → audio → ASR/__docs__)docker run --rm -p 9002:9002 \
-e ASR_MODEL=large-v3 \
-e OCR_LANGS=en \
-e VLM_MODEL_ID=microsoft/Florence-2-large \
ghcr.io/knowusuboaky/asr_ocr:latest
# Docs: http://localhost:9002/__docs__
# Health: http://localhost:9002/health
docker run --rm --gpus all -p 9002:9002 \
-e ASR_MODEL=large-v3 \
-e OCR_LANGS=en \
-e VLM_MODEL_ID=microsoft/Florence-2-large \
ghcr.io/knowusuboaky/asr_ocr:cuda
The server listens on port 9002. GPU builds accelerate ASR and Florence-2.
GET /healthLiveness probe. Returns:
ok
GET /Plain-text summary of active ASR/VLM/OCR setup (model, device, langs).
POST /transcribe_fileASR for audio/video (any ffmpeg-readable format).
X-Filename: yourfile.ext (optional)curl -X POST http://localhost:9002/transcribe_file \
-H "X-Filename: clip.mp3" \
--data-binary @clip.mp3
POST /transcribe_imageOCR + optional captioning for a single image.
X-Filename: image.png (optional)curl -X POST http://localhost:9002/transcribe_image \
-H "X-Filename: slide.png" \
--data-binary @slide.png
POST /extract_documentFull document ingest to Markdown (front-matter + grouped contents). Supported: .pdf, .pptx, .docx, .doc, .xlsx, .csv, .txt
Query params (all optional – shown with defaults):
ocr=paddle|none (default paddle)lang=en (primary OCR language)dpi=300 (page OCR raster DPI)ocr_threshold=50 (page OCR if native text < N chars)vlm=hf_local|none (default hf_local)vlm_model=microsoft/Florence-2-largevlm_max_tokens=128vlm_prompt=<MORE_DETAILED_CAPTION>caption_pages=false (page-level captions)vlm_dpi=256 (page render DPI for captions)image_columns= (CSV: comma-sep column names that hold image refs)fetch_http=false (allow HTTP fetch for CSV/XLSX image links)image_root=. (resolve relative paths for linked images)caption_xlsx_charts=false (try page-captions via PDF export if LibreOffice present)soffice_bin= (path to LibreOffice/soffice if installed)max_rows=-1 (tables → show all rows; set to N to truncate)vlm_only=false (emit only captions; skip native/OCR text)curl -X POST "http://localhost:9002/extract_document?ocr=paddle&vlm=hf_local&lang=en" \
-H "X-Filename: deck.pptx" \
--data-binary @deck.pptx
POST /transcribe_urlOrdered handling:
Body:
{ "url": "https://example.com/...", "user_agent": "Optional UA string" }
Example:
curl -X POST http://localhost:9002/transcribe_url \
-H "Content-Type: application/json" \
-d '{"url":"https://youtu.be/xyz"}'
| Variable | Default | Description |
|---|---|---|
ASR_MODEL | large-v3 | faster-whisper size (large-v3, medium, small, …) |
VAD_MIN_SIL_MS | 500 | VAD min silence (ms) between segments |
KEEP_WAV | false | Keep temp WAV after processing |
KEEP_WAV_ON_ERROR | true | Keep WAV if an error occurs |
FETCH_UA | Chrome-like UA | Default User-Agent for /transcribe_url |
MAX_FETCH_BYTES | 26214400 (25 MiB) | Cap for single URL fetch |
HTTP_TIMEOUT_S | 30 | Per-request timeout for URL fetch |
| Variable | Default | Description |
|---|---|---|
VLM_MODEL_ID | microsoft/Florence-2-large | HF model id |
VLM_CAPTION_TASK | <MORE_DETAILED_CAPTION> | Caption task token |
VLM_MAX_TOKENS_CAPTION | 768 | Max tokens for captioning |
| Device/dtype | auto | CUDA→float16, else CPU |
| Variable | Default | Description |
|---|---|---|
OCR_LANGS | en | Primary OCR lang (first in list is used) |
OCR_UPSCALE | 1.5 | Pre-resize factor for images |
OCR_RECOG_HEAD | english_g2 | Kept for compatibility (not used by Florence) |
OCR_ALLOWLIST | alnum+punct | Characters allowed by OCR |
Mount caches to avoid repeated downloads:
/root/.cache/huggingface/root/.paddleocrservices:
asr_ocr:
image: ghcr.io/knowusuboaky/asr_ocr:latest
ports: ["9002:9002"]
environment:
- ASR_MODEL=large-v3
- OCR_LANGS=en
- VLM_MODEL_ID=microsoft/Florence-2-large
volumes:
- hf-cache:/root/.cache/huggingface
- paddle-cache:/root/.paddleocr
restart: unless-stopped
volumes:
hf-cache:
paddle-cache:
services:
asr_ocr:
image: ghcr.io/knowusuboaky/asr_ocr:cuda
ports: ["9002:9002"]
environment:
- ASR_MODEL=large-v3
- OCR_LANGS=en
- VLM_MODEL_ID=microsoft/Florence-2-large
gpus: all
volumes:
- hf-cache:/root/.cache/huggingface
- paddle-cache:/root/.paddleocr
restart: unless-stopped
volumes:
hf-cache:
paddle-cache:
Health:
http://localhost:9002/health• Docs:http://localhost:9002/__docs__
fetch_http=true)..doc: If LibreOffice is available, the server converts .doc → .docx/.pdf to recover text + images; otherwise it falls back to CLI text extractors.caption_xlsx_charts=true) so pages can be VLM-captioned as images./__docs__.python -m venv .venv && source .venv/bin/activate
pip install -U pip
pip install fastapi "uvicorn[standard]" httpx faster-whisper imageio-ffmpeg \
pillow transformers accelerate safetensors \
paddleocr paddlepaddle \
beautifulsoup4 lxml pandas openpyxl python-docx python-pptx pymupdf \
tabulate chardet yt-dlp
uvicorn transcribe_server:app --host 0.0.0.0 --port 9002
38 commits
Python
91.0%
Shell
5.1%
Dockerfile
3.1%