7.3 KiB
marker-api
Flask API wrapper around marker — converts PDFs, DOCX, XLSX, PPTX, EPUB, images (PNG/JPG/BMP/GIF/TIFF/WEBP/HEIC), and HTML to Markdown (JSON/HTML/chunks).
Quick Start
Container (recommended)
# Build and run with Podman/Docker
podman build -t marker-api -f Containerfile .
podman run -d --rm \
--name marker-api \
-p 8000:8000 \
-e AMD_COMPUTE=false \
-e TORCH_DEVICE=cpu \
marker-api
# Or use docker-compose
docker-compose up -d
Bare-metal
git clone https://github.com/your-org/marker-api.git /app/marker-api
pip install -e /app/marker-api/marker[full] flask gunicorn
PORT=8000 python /app/marker-api/app.py
Health Check
curl http://localhost:8000/health
# {"status":"ok","ollama":"http://10.0.1.127:11434","torch_device":"cuda","supported_formats":["docx","epub","html","jpg",...]}
Endpoints
GET /
HTML documentation page listing all endpoints and parameters.
GET /health
Returns server status, torch device, supported file formats, and configuration.
POST /marker
Convert a single file. Accepts multipart/form-data or application/json.
Multipart form-data
curl -X POST http://localhost:8000/marker \
-F "file=@document.pdf" \
-F "output_format=markdown" \
-F "force_ocr=false"
When output_format=markdown, the response is the raw .md content as a file download. All other formats return JSON.
JSON body (base64)
curl -X POST http://localhost:8000/marker \
-H "Content-Type: application/json" \
-d '{
"file_b64": "<base64>",
"filename": "document.pdf",
"output_format": "markdown",
"force_ocr": false
}'
POST /v1/conversions
Same as /marker but always returns JSON, wrapping the result with an id (UUID) field and filename.
POST /v1/files/convert
Same as /marker but always returns JSON with filename, format, output, images_b64, and metadata.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
file / file_b64 |
file / string | required | The document to convert |
output_format |
string | markdown |
markdown, json, html, chunks |
force_ocr |
bool | false |
Force OCR on all pages (fixes garbled text) |
paginate_output |
bool | false |
Separate pages with horizontal rules |
page_range |
string | all | Comma-separated pages/ranges: "0,5-10" |
disable_image_extraction |
bool | false |
Skip embedded image extraction |
processors |
string | auto | Comma-separated full module paths for custom processors |
config_json |
string | none | Path to JSON config file |
converter_cls |
string | auto | Full module path of converter (e.g. marker.converters.table.TableConverter) |
use_llm |
bool | false |
Use an LLM to improve accuracy |
llm_service |
string | marker.services.ollama.OllamaService |
LLM service class: gemini, vertex, claude, openai, azure_openai, ollama |
block_correction_prompt |
string | none | Custom prompt for LLM block correction |
redo_inline_math |
bool | false |
Re-process inline math with LLM |
strip_existing_ocr |
bool | false |
Remove existing OCR text and re-OCR |
debug |
bool | false |
Enable debug logging |
Supported Formats
PDF, DOCX, XLSX, PPTX, EPUB, PNG, JPG, BMP, GIF, TIFF, WEBP, HEIC, HTML, HTM.
Environment Variables
| Variable | Default | Description |
|---|---|---|
OLLAMA_HOST |
http://10.0.1.127:11434 |
Ollama instance for OCR fallback / LLM |
DEESEEK_OCR_MODEL |
deepseek-ocr |
OCR model name in Ollama |
AMD_COMPUTE |
false |
Enable AMD ROCm GPU support |
TORCH_DEVICE |
auto | PyTorch device: rocm, cuda, cpu |
MODEL_DTYPE |
float32 |
Model dtype: float32, bfloat16 |
PORT |
8000 |
Listening port |
HOST |
0.0.0.0 |
Listening host |
PowerShell Batch Script
A PowerShell script (marker-convert-powershell/marker-convert.ps1) is provided for batch conversion.
Usage
.\marker-convert-powershell\marker-convert.ps1 -TargetFolder .\documents
# With options
.\marker-convert-powershell\marker-convert.ps1 .\documents `
-Force -MaxConcurrency 8 -OutputFormat json -UseLlm -LlmService marker.services.ollama.OllamaService
# Remote API
.\marker-convert-powershell\marker-convert.ps1 .\documents -ApiUrl http://10.0.0.5:8000/marker
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
-TargetFolder |
string | (required) | Folder to scan recursively |
-ApiUrl |
uri | http://localhost:8000/marker |
Marker API endpoint |
-OutputFormat |
string | markdown |
markdown, json, html, chunks |
-Force |
switch | off | Overwrite existing .md files |
-MaxConcurrency |
int | 4 | Concurrent workers (1-32) |
-Timeout |
int | 300 | HTTP timeout in seconds (30-1800) |
-PageRange |
string | "" | Page range e.g. "0,5-10" |
-ForceOcr |
switch | off | Force OCR on all pages |
-DisableImageExtraction |
switch | off | Skip image extraction |
-UseLlm |
switch | off | Enable LLM enhancement |
-LlmService |
string | marker.services.ollama.OllamaService |
LLM service class |
-Processors |
string | "" | Custom processor module paths |
-ConfigJson |
string | "" | Path to JSON config file |
-ConverterCls |
string | "" | Custom converter class path |
The script writes a CSV report (_marker_convert_results.csv) next to each converted file.
Deployment
AMD GPU (ROCm)
Set AMD_COMPUTE=true and TORCH_DEVICE=cuda in the container environment.
Vega 20 / GFX906 Support (e.g., powermac)
For older AMD GPU architectures like Vega 20 (GFX906), AMD dropped standard ROCm PyTorch support. This project fully supports GFX906 out of the box by using a patched GFX906 PyTorch base image (mixa3607/pytorch-gfx906:v2.7.1-rocm-6.3.3).
To run the container on GFX906 GPUs with hardware acceleration:
docker run -d --name marker-api \
--network=host \
--device /dev/kfd --device /dev/dri \
--group-add 984 --group-add 988 \
-e AMD_COMPUTE=true \
-e TORCH_DEVICE=cuda \
-e CUDA_VISIBLE_DEVICES=1 \
-e HSA_OVERRIDE_GFX_VERSION=9.0.6 \
marker-api:latest \
gunicorn --bind 0.0.0.0:8000 --workers 1 --timeout 300 --worker-class gthread --threads 4 app:app_instance
Note on first run: The very first conversion on a ROCm GPU will take 2-3 minutes as MIOpen compiles convolution kernels for your exact GPU. Subsequent runs are fully cached and take ~4-5 seconds per document.
Note on memory: If other services (e.g., llama-servers) are utilizing GPU 0, restrict marker-api to GPU 1 (CUDA_VISIBLE_DEVICES=1) and use a single worker (--workers 1) to prevent HIP Out-Of-Memory errors.
CPU-only
TORCH_DEVICE=cpu AMD_COMPUTE=false podman run ... marker-api
GPU (CUDA)
Override the PyTorch index URL during build, or use the existing ROCm image with TORCH_DEVICE=cuda.
Response Codes
| Code | Meaning |
|---|---|
200 |
Successful conversion (markdown returned as file download, others as JSON) |
400 |
Missing file or invalid body |
500 |
Conversion error (details in JSON body) |
Error responses have the shape:
{"success": false, "error": "error message"}