Image-Text-to-Text
Transformers
Safetensors
qwen3_5
clef
cloudflare
systemone
decision-model
qwen3.8
post-train
image-text-to-typed-output
multimodal
structured-output
classification
custom-code
conversational
Eval Results
Instructions to use Cloudflare/clef with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Cloudflare/clef with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="Cloudflare/clef") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("Cloudflare/clef") model = AutoModelForMultimodalLM.from_pretrained("Cloudflare/clef", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Cloudflare/clef with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Cloudflare/clef" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Cloudflare/clef", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/Cloudflare/clef
- SGLang
How to use Cloudflare/clef with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Cloudflare/clef" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Cloudflare/clef", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Cloudflare/clef" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Cloudflare/clef", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use Cloudflare/clef with Docker Model Runner:
docker model run hf.co/Cloudflare/clef
Add model card
Browse files
README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
library_name: transformers
|
| 4 |
+
pipeline_tag: image-text-to-text
|
| 5 |
+
base_model: Qwen/Qwen3.8-27B
|
| 6 |
+
tags:
|
| 7 |
+
- clef
|
| 8 |
+
- cloudflare
|
| 9 |
+
- systemone
|
| 10 |
+
- qwen3.8
|
| 11 |
+
- post-train
|
| 12 |
+
- image-text-to-typed-output
|
| 13 |
+
- multimodal
|
| 14 |
+
- structured-output
|
| 15 |
+
- classification
|
| 16 |
+
- custom-code
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
# Clef
|
| 20 |
+
|
| 21 |
+
Clef is a 27B multimodal model that turns a state and a schema of typed
|
| 22 |
+
questions into decisions. It reads the state as text, JSON, images, or video, and returns a
|
| 23 |
+
probability for every allowed option of every question in a single forward pass. There is no
|
| 24 |
+
free-form text generation and no output parsing.
|
| 25 |
+
|
| 26 |
+
Clef is post-trained from [Qwen/Qwen3.8-27B](https://huggingface.co/Qwen/Qwen3.8-27B). See
|
| 27 |
+
[Clef-Flash](https://huggingface.co/Cloudflare/clef-flash) for the
|
| 28 |
+
smaller, faster variant.
|
| 29 |
+
|
| 30 |
+
## Model
|
| 31 |
+
|
| 32 |
+
- **Backbone:** Qwen/Qwen3.8-27B with its vision encoder, stored as standard sharded safetensors.
|
| 33 |
+
- **Joint schema head:** a small transformer head that reads the backbone's final hidden states,
|
| 34 |
+
routes evidence from the state to each question, and scores all options of all questions jointly.
|
| 35 |
+
- **Output:** one logit per allowed option for each question. Apply a softmax per question to get
|
| 36 |
+
probabilities.
|
| 37 |
+
|
| 38 |
+
## Files
|
| 39 |
+
|
| 40 |
+
| File | Purpose |
|
| 41 |
+
|---|---|
|
| 42 |
+
| `model-*.safetensors`, `model.safetensors.index.json`, `config.json`, `generation_config.json` | Backbone, including the vision encoder |
|
| 43 |
+
| `joint_head.safetensors`, `joint_head_config.json` | Joint schema head |
|
| 44 |
+
| `joint_schema_model.py` | Record encoding, batching, the model, and `load_release_model` |
|
| 45 |
+
| `tokenizer.json`, `tokenizer_config.json`, `chat_template.jinja`, `processor_config.json` | Tokenizer and image/video processor |
|
| 46 |
+
| `LICENSE` | Apache-2.0 license |
|
| 47 |
+
|
| 48 |
+
## Usage
|
| 49 |
+
|
| 50 |
+
Tested with `torch` 2.11 and `transformers` 5.10.2 on a single H200. Image and video inputs also
|
| 51 |
+
need `pillow`.
|
| 52 |
+
|
| 53 |
+
```python
|
| 54 |
+
import sys
|
| 55 |
+
|
| 56 |
+
import torch
|
| 57 |
+
from huggingface_hub import snapshot_download
|
| 58 |
+
|
| 59 |
+
path = snapshot_download("Cloudflare/clef")
|
| 60 |
+
sys.path.insert(0, path)
|
| 61 |
+
from joint_schema_model import collate_records, encode_record, load_release_model
|
| 62 |
+
|
| 63 |
+
model, processor = load_release_model(path, device="cuda")
|
| 64 |
+
|
| 65 |
+
record = {
|
| 66 |
+
"state": {"invoice": {"vendor": "Acme", "total": 1250.0, "currency": "USD", "status": "overdue"}},
|
| 67 |
+
"questions": {
|
| 68 |
+
"status": {
|
| 69 |
+
"type": "choice",
|
| 70 |
+
"instructions": "What is the invoice status?",
|
| 71 |
+
"criteria": {"paid": "Invoice is paid.", "overdue": "Invoice is past due.", "draft": "Not sent."},
|
| 72 |
+
},
|
| 73 |
+
"large": {"type": "noul", "instructions": "Is the total above 1000 USD?"},
|
| 74 |
+
},
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
encoded = encode_record(processor.tokenizer, record, processor=processor)
|
| 78 |
+
batch = collate_records([encoded], processor.tokenizer.pad_token_id, torch.device("cuda"))
|
| 79 |
+
with torch.inference_mode():
|
| 80 |
+
logits = model(batch)[0]
|
| 81 |
+
|
| 82 |
+
for question, question_logits in zip(encoded.questions, logits):
|
| 83 |
+
probabilities = question_logits.float().softmax(-1).tolist()
|
| 84 |
+
print(question.question_id, dict(zip(question.option_ids, probabilities)))
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
### Images and video
|
| 88 |
+
|
| 89 |
+
Add `images` (PIL images) or `videos` (frame arrays) to the record and pass the processor to
|
| 90 |
+
`encode_record`. Optional processor arguments go in `media_kwargs`.
|
| 91 |
+
|
| 92 |
+
```python
|
| 93 |
+
from PIL import Image
|
| 94 |
+
|
| 95 |
+
record = {
|
| 96 |
+
"state": {"task": "Review the attached receipt."},
|
| 97 |
+
"images": [Image.open("receipt.jpg")],
|
| 98 |
+
"questions": {
|
| 99 |
+
"legible": {"type": "noul", "instructions": "Is the receipt total legible?"},
|
| 100 |
+
},
|
| 101 |
+
}
|
| 102 |
+
encoded = encode_record(processor.tokenizer, record, processor=processor)
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
Text-only and multimodal records can be mixed in the same batch.
|
| 106 |
+
|
| 107 |
+
## Input format
|
| 108 |
+
|
| 109 |
+
| Field | Description |
|
| 110 |
+
|---|---|
|
| 111 |
+
| `state` | Any string or JSON value describing the situation to decide on |
|
| 112 |
+
| `images`, `videos` | Optional lists of images or video frame arrays |
|
| 113 |
+
| `media_kwargs` | Optional keyword arguments for the image/video processor |
|
| 114 |
+
| `questions` | Mapping of question ID to question |
|
| 115 |
+
|
| 116 |
+
Each question has:
|
| 117 |
+
|
| 118 |
+
- `type`: `noul` (true/false), `choice` (named options), or `score` (ordered options)
|
| 119 |
+
- `instructions`: what to decide
|
| 120 |
+
- `criteria`: for `choice`, a mapping of option ID to description; for `score`, a list of option
|
| 121 |
+
descriptions indexed from 0; for `noul`, optional descriptions for `true` and `false`
|
| 122 |
+
|
| 123 |
+
`encode_record` accepts `max_length` (default 16,384 tokens) and `max_state_tokens` to bound the input.
|
| 124 |
+
|
| 125 |
+
## Results
|
| 126 |
+
|
| 127 |
+
### Decision Index
|
| 128 |
+
|
| 129 |
+
Per-benchmark results from our internal run of the [Decision Index](https://huggingface.co/spaces/multimodalart/jev-decision-index) 0.2.1 suite. Scores are percentages; ForecastBench is a Brier score, where lower is better. The best score in each row is in bold.
|
| 130 |
+
|
| 131 |
+
| # | Benchmark | Clef | Clef-flash | Jev | DiffusionGemma Jev | Kev 9B | Laya |
|
| 132 |
+
|---|---|---|---|---|---|---|---|
|
| 133 |
+
| 1 | BFCL (case exact accuracy) | 98.5 | **98.8** | 95.8 | 96.5 | 94.5 | 38.1 |
|
| 134 |
+
| 2 | ToolRet (nDCG@10) | **69.2** | 66.4 | 65.3 | 61.2 | 64.3 | 12.8 |
|
| 135 |
+
| 3 | API-Bank (accuracy) | 91.9 | **93.1** | 88.2 | 83.7 | 56.3 | 11.5 |
|
| 136 |
+
| 4 | BANKING77 (macro-F1) | **94.2** | 90.9 | 79.7 | 74.3 | 84.8 | 14.3 |
|
| 137 |
+
| 5 | CLINC150+OOS (macro-F1) | **97.4** | 66.8 | 89.3 | 83.5 | 79.0 | 3.2 |
|
| 138 |
+
| 6 | RouterBench (selected quality) | 79.7 | 79.9 | 79.9 | 79.0 | **80.0** | 57.1 |
|
| 139 |
+
| 9 | Home appliance simulator (case exact accuracy) | 83.0 | **97.7** | 52.3 | 42.0 | 25.0 | 0.0 |
|
| 140 |
+
| 10 | SGD/SGD-X (macro-F1) | 43.8 | 34.2 | 43.0 | 40.6 | **64.0** | 42.4 |
|
| 141 |
+
| 11 | ContractNLI (macro-F1) | 81.4 | **84.3** | 71.7 | 76.0 | 57.8 | 29.0 |
|
| 142 |
+
| 12 | ANLI (macro-F1) | 69.8 | 59.1 | **74.8** | 66.4 | 56.3 | 48.7 |
|
| 143 |
+
| 20 | BPoMP (accuracy) | **96.9** | 95.4 | 90.6 | 86.9 | 67.0 | 51.6 |
|
| 144 |
+
| 21 | Humicroedit (accuracy) | 66.7 | **75.1** | 61.9 | 63.0 | 55.8 | 47.2 |
|
| 145 |
+
| 22 | POP909-CL (accuracy) | 15.8 | 1.6 | **18.1** | 2.5 | 10.8 | 5.1 |
|
| 146 |
+
| 23 | cfcolor (accuracy) | **66.0** | 65.8 | 64.7 | 58.2 | 56.3 | 52.3 |
|
| 147 |
+
| 24 | MMLU (accuracy) | 90.3 | **91.8** | 91.7 | 79.3 | 75.3 | 30.7 |
|
| 148 |
+
| 25 | GPQA Diamond (accuracy) | 48.0 | 51.0 | **78.3** | 44.9 | 38.8 | 27.6 |
|
| 149 |
+
| 26 | ARC-Easy (accuracy) | 99.0 | **99.5** | 99.3 | 98.2 | 97.7 | 47.0 |
|
| 150 |
+
| 27 | ARC-Challenge (accuracy) | 97.7 | **98.3** | 97.8 | 94.5 | 93.7 | 28.6 |
|
| 151 |
+
| 28 | WinoGrande (accuracy) | 93.5 | **97.5** | 92.0 | 73.6 | 73.2 | 50.5 |
|
| 152 |
+
| 29 | HellaSwag (accuracy) | 98.2 | **98.6** | 94.5 | 83.3 | 81.9 | 33.1 |
|
| 153 |
+
| 30 | GSM8K (accuracy) | **80.8** | 67.3 | 79.9 | 50.3 | 48.7 | 21.6 |
|
| 154 |
+
| 31 | ChessBench (accuracy) | **24.7** | 23.0 | 17.2 | 14.2 | 11.2 | 7.7 |
|
| 155 |
+
| 32 | MuSR (accuracy) | 83.5 | **86.0** | 66.1 | 61.2 | 57.9 | 43.2 |
|
| 156 |
+
| 33 | SATA-Bench (case exact accuracy) | 33.8 | **36.7** | 26.4 | 27.5 | 26.7 | 0.3 |
|
| 157 |
+
| 36 | BRIGHT (nDCG@10) | 45.9 | 39.3 | **47.5** | 42.9 | 38.5 | 19.9 |
|
| 158 |
+
| 37 | Amazon ESCI (macro-F1) | **57.5** | 57.4 | 55.2 | 53.4 | 49.2 | 24.4 |
|
| 159 |
+
| 38 | ACOS (per-review F1) | **33.3** | 25.9 | 29.5 | 24.5 | 18.3 | 3.5 |
|
| 160 |
+
| 39 | FinEntity (macro-F1) | 96.2 | **97.1** | 87.0 | 89.0 | 88.4 | 61.0 |
|
| 161 |
+
| 41 | VAST (macro-F1) | 59.5 | 49.6 | **64.6** | 55.7 | 55.4 | 40.5 |
|
| 162 |
+
| 42 | NLI4CT (macro-F1) | 82.9 | 78.6 | **84.1** | 78.4 | 74.9 | 47.7 |
|
| 163 |
+
| 43 | CRUXEval (accuracy) | **86.7** | 86.1 | 73.0 | 64.7 | 51.2 | 40.2 |
|
| 164 |
+
| 44 | CLadder (accuracy) | 94.0 | **97.7** | 72.6 | 67.8 | 62.0 | 52.9 |
|
| 165 |
+
| 48 | ForecastBench (Brier, lower is better) | 13.9 | **10.6** | 17.4 | 29.6 | 17.6 | 41.1 |
|
| 166 |
+
| 50 | Habermas Machine (accuracy) | 68.7 | **71.8** | 45.9 | 45.0 | 39.4 | 33.4 |
|
| 167 |
+
| 56 | PhishNChips (accuracy) | 79.6 | 75.0 | 62.5 | **85.4** | 50.7 | 50.1 |
|
| 168 |
+
| 57 | MMLU-Pro (accuracy) | 65.9 | 65.3 | **82.7** | 56.9 | 51.1 | 13.6 |
|
| 169 |
+
| 58 | BBH (accuracy) | 73.7 | 68.9 | **92.9** | 70.7 | 65.2 | 34.1 |
|
| 170 |
+
| 59 | RAGTruth (hallucination F1) | **79.4** | 35.6 | 76.5 | 70.4 | 46.2 | 48.8 |
|
| 171 |
+
| 61 | HoVer (accuracy) | 65.2 | 61.2 | **72.9** | 70.9 | 58.8 | 55.8 |
|
| 172 |
+
| 62 | When2Call MCQ (accuracy) | 72.4 | 65.6 | **81.0** | 75.4 | 49.6 | 11.9 |
|
| 173 |
+
| 64 | New Yorker (accuracy) | 69.5 | 66.1 | **70.1** | 63.6 | 58.1 | 27.1 |
|
| 174 |
+
|
| 175 |
+
### Workflow evals
|
| 176 |
+
|
| 177 |
+
Decision accuracy on four end-to-end business workflows from [Typesafe Evals](https://evals.typesafe.ai/), scored against consensus reference labels. All models are scored on the same dataset revision and case cohort.
|
| 178 |
+
|
| 179 |
+
| Workflow | Metric | Cases | Clef | Clef-flash | Jev |
|
| 180 |
+
|---|---|---:|---:|---:|---:|
|
| 181 |
+
| Invoice processing | Exact actions | 150 | **64.7** | 57.1 | 61.8 |
|
| 182 |
+
| Invoice processing | Primary action | 150 | **86.2** | 73.3 | 83.1 |
|
| 183 |
+
| Customer service | Exact actions | 204 | 76.3 | **77.0** | 76.0 |
|
| 184 |
+
| Security incidents | Exact actions | 240 | **62.9** | 61.7 | 61.7 |
|
| 185 |
+
| Agent trace observability | Primary action | 111 | 68.5 | 69.8 | **71.6** |
|
| 186 |
+
|
| 187 |
+
## License
|
| 188 |
+
|
| 189 |
+
Released under the Apache-2.0 license, following the base model
|
| 190 |
+
[Qwen/Qwen3.8-27B](https://huggingface.co/Qwen/Qwen3.8-27B).
|