CoolFace
Modelpublic

gabfssilva/lift-MLX-oQ4

sourceHugging Faceopenrailupdated 3mo agoView on Hugging Face
1likes28downloads
Model Card

lift-MLX-oQ4

MLX conversion of **datalab-to/lift** — a 9B qwen3_5 vision-language model for structured extraction (PDF / image → schema-constrained JSON).

This repo is the oQ4 variant: data-driven, per-layer mixed-precision quantization (~4.6 bits/weight) produced with oMLX. Runs on Apple Silicon via mlx-vlm. Not affiliated with Datalab — a community conversion of their openly released weights.

Variants

RepoMethod~bpwSizePeak RAM\*Gen\*
lift-MLX-BF16full bf161618 GB19.9 GB31 t/s
lift-MLX-oQ8oQ~8.69.7 GB12.3 GB58 t/s
lift-MLX-oQ6oQ~67.7 GB9.4 GB73 t/s
lift-MLX-oQ5oQ~56.7 GB8.4 GB83 t/s
lift-MLX-oQ4 (this repo)oQ~4.65.6 GB7.2 GB100 t/s
lift-MLX-oQ3.5oQ~4.04.9 GB6.5 GB109 t/s
lift-MLX-oQ3oQ~3.54.6 GB6.2 GB119 t/s

\* Peak RAM and generation speed measured on a single-image invoice extraction on an Apple M5 Max (128 GB, 40-core GPU). Indicative, not a benchmark.

Usage

Generate (CLI)

bash
uvx --from mlx-vlm mlx_vlm.generate \
  --model gabfssilva/lift-MLX-oQ4 \
  --image invoice.png \
  --prompt "Extract the invoice as JSON." \
  --max-tokens 800

OpenAI-compatible server + structured outputs

lift is built for schema-constrained extraction. mlx_vlm.server enforces a JSON Schema at decode time (via llguidance), so output is guaranteed valid and well-typed.

bash
uvx --from mlx-vlm mlx_vlm.server --model gabfssilva/lift-MLX-oQ4 --port 8080
python
import base64, json
from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="local")
img = base64.b64encode(open("invoice.png", "rb").read()).decode()

schema = {
    "type": "object",
    "properties": {
        "invoice_number": {"type": "string"},
        "total": {"type": "number"},
        "line_items": {"type": "array", "items": {"type": "object", "properties": {
            "description": {"type": "string"}, "amount": {"type": "number"}}}},
    },
    "required": ["invoice_number", "total"],
}

resp = client.chat.completions.create(
    model="gabfssilva/lift-MLX-oQ4",   # the server lists your whole HF cache — name the model explicitly
    messages=[{"role": "user", "content": [
        {"type": "text", "text": "Extract this invoice."},
        {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img}"}},
    ]}],
    response_format={"type": "json_schema", "json_schema": {"name": "invoice", "schema": schema}},
    temperature=0.0, max_tokens=800,
)
print(json.loads(resp.choices[0].message.content))

Notes

  • —eos fix applied. generation_config.json here sets eos_token_id: [248044, 248046]. Upstream only sets 248044, but the chat turn closes with <|im_end|> = 248046; without this, MLX servers reading generation_config never stop and flood <|im_end|>. If you re-convert from the source, reapply this.
  • —Quality. Upstream FP lift (9B) scores 90.2% field / 20.9% full-document on Datalab's 225-doc benchmark. Every variant in this set extracted a simple test invoice correctly — that only rules out collapse, it does not rank them. Lower bit-widths may degrade on harder/adversarial documents; these were not re-benchmarked at scale.

License

Code Apache-2.0; weights under a modified OpenRAIL-M (free for research, personal use, and startups under $5M; not for use competitive with Datalab's API). See the base model.