Video-Text-to-Text
MLX
Safetensors
English
qwen2_vl
apple-silicon
video-captioning
qwen2-vl
tarsier
4-bit precision
Instructions to use viavicdev/Tarsier2-Recap-7b-MLX-4bit with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use viavicdev/Tarsier2-Recap-7b-MLX-4bit with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir Tarsier2-Recap-7b-MLX-4bit viavicdev/Tarsier2-Recap-7b-MLX-4bit
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
Upload README.md with huggingface_hub
Browse files
README.md
CHANGED
|
@@ -17,31 +17,31 @@ tags:
|
|
| 17 |
|
| 18 |
A 4-bit [MLX](https://github.com/ml-explore/mlx) conversion of
|
| 19 |
[omni-research/Tarsier2-Recap-7b](https://huggingface.co/omni-research/Tarsier2-Recap-7b),
|
| 20 |
-
|
| 21 |
|
| 22 |
-
Tarsier2 is
|
| 23 |
-
official MLX build exists. This
|
| 24 |
-
4-bit
|
| 25 |
|
| 26 |
- **Base model:** omni-research/Tarsier2-Recap-7b (Apache-2.0)
|
| 27 |
- **Format:** MLX, 4-bit affine quantization (group size 64)
|
| 28 |
- **Size on disk:** ~5.3 GB
|
| 29 |
- **Underlying architecture:** Qwen2-VL 7B (see conversion notes below)
|
| 30 |
-
- **
|
| 31 |
|
| 32 |
-
##
|
| 33 |
|
| 34 |
-
Tarsier2-Recap-7b produces unusually specific, grounded video descriptions
|
| 35 |
-
|
| 36 |
-
architectural features
|
| 37 |
-
the
|
| 38 |
-
|
| 39 |
-
(hundreds of seconds per clip). This conversion
|
| 40 |
-
**7 seconds per short clip** on an M4 Pro.
|
| 41 |
|
| 42 |
## Usage
|
| 43 |
|
| 44 |
-
Run with [`mlx-vlm`](https://github.com/Blaizzy/mlx-vlm) (0.6.3 or
|
| 45 |
|
| 46 |
```python
|
| 47 |
from mlx_vlm import load, generate
|
|
@@ -49,7 +49,7 @@ from mlx_vlm.prompt_utils import apply_chat_template
|
|
| 49 |
|
| 50 |
model, processor = load("viavicdev/Tarsier2-Recap-7b-MLX-4bit")
|
| 51 |
|
| 52 |
-
#
|
| 53 |
frames = ["frame_00.jpg", "frame_01.jpg", "frame_02.jpg", "frame_03.jpg"]
|
| 54 |
prompt = apply_chat_template(
|
| 55 |
processor, model.config,
|
|
@@ -58,38 +58,39 @@ prompt = apply_chat_template(
|
|
| 58 |
)
|
| 59 |
out = generate(
|
| 60 |
model, processor, prompt,
|
| 61 |
-
image=frames, #
|
| 62 |
max_tokens=300,
|
| 63 |
temperature=0.3,
|
| 64 |
-
repetition_penalty=1.3, # see
|
| 65 |
repetition_context_size=40,
|
| 66 |
)
|
| 67 |
print(out)
|
| 68 |
```
|
| 69 |
|
| 70 |
-
###
|
| 71 |
|
| 72 |
-
1. **
|
| 73 |
-
decoder path is unreliable and
|
| 74 |
-
and pass them as a list of images (`image=[...]` with
|
| 75 |
-
`num_images=N`)
|
| 76 |
-
2. **The chat template is included** in this
|
| 77 |
-
`chat_template.jinja`). Some MLX
|
| 78 |
-
`apply_chat_template`.
|
| 79 |
-
3. **
|
| 80 |
-
`repetition_penalty=1.3`, `repetition_context_size=40`,
|
| 81 |
-
|
|
|
|
| 82 |
|
| 83 |
-
##
|
| 84 |
|
| 85 |
-
Tarsier2
|
| 86 |
-
but its text and vision towers
|
| 87 |
-
names
|
| 88 |
-
(it
|
| 89 |
-
handler does.
|
| 90 |
-
followed by a standard MLX
|
| 91 |
|
| 92 |
-
Only three key prefixes
|
| 93 |
|
| 94 |
```
|
| 95 |
language_model.model.* -> model.*
|
|
@@ -97,35 +98,35 @@ language_model.lm_head.* -> lm_head.*
|
|
| 97 |
vision_tower.* -> visual.*
|
| 98 |
```
|
| 99 |
|
| 100 |
-
|
| 101 |
`vision_config` (preserving `rope_scaling: mrope`, the vision/image/video token
|
| 102 |
-
ids,
|
| 103 |
|
| 104 |
```bash
|
| 105 |
mlx_vlm.convert --hf-path ./tarsier2-qwen2vl-hf -q --q-bits 4
|
| 106 |
```
|
| 107 |
|
| 108 |
-
This
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
|
| 113 |
## Limitations
|
| 114 |
|
| 115 |
-
- 4-bit quantization trades some fidelity for size
|
| 116 |
-
use the original bf16 weights on a CUDA
|
| 117 |
-
- English captioning model
|
| 118 |
-
language in the clip.
|
| 119 |
-
- Vision only (no audio). It captions what is
|
| 120 |
-
-
|
| 121 |
-
a captioner rather than a strict classifier.
|
| 122 |
|
| 123 |
## License and attribution
|
| 124 |
|
| 125 |
This conversion inherits the **Apache-2.0** license of the base model. All
|
| 126 |
-
credit for the model itself
|
| 127 |
([omni-research/Tarsier2-Recap-7b](https://huggingface.co/omni-research/Tarsier2-Recap-7b)).
|
| 128 |
-
This repository
|
| 129 |
-
quantization
|
| 130 |
|
| 131 |
-
|
|
|
|
| 17 |
|
| 18 |
A 4-bit [MLX](https://github.com/ml-explore/mlx) conversion of
|
| 19 |
[omni-research/Tarsier2-Recap-7b](https://huggingface.co/omni-research/Tarsier2-Recap-7b),
|
| 20 |
+
prepared for fast, native inference on Apple Silicon.
|
| 21 |
|
| 22 |
+
Tarsier2 is among the most detailed open video captioners available, yet no
|
| 23 |
+
official MLX build exists. This repository provides one: the same model,
|
| 24 |
+
quantized to 4-bit (~5.3 GB) and accelerated on the Mac GPU through MLX.
|
| 25 |
|
| 26 |
- **Base model:** omni-research/Tarsier2-Recap-7b (Apache-2.0)
|
| 27 |
- **Format:** MLX, 4-bit affine quantization (group size 64)
|
| 28 |
- **Size on disk:** ~5.3 GB
|
| 29 |
- **Underlying architecture:** Qwen2-VL 7B (see conversion notes below)
|
| 30 |
+
- **Tested on:** Apple M4 Pro, 24 GB unified memory
|
| 31 |
|
| 32 |
+
## Purpose
|
| 33 |
|
| 34 |
+
Tarsier2-Recap-7b produces unusually specific, grounded video descriptions. It
|
| 35 |
+
identifies small details — a sail number, an object held in a subject's hand,
|
| 36 |
+
architectural features — rather than generic scene summaries. On Apple Silicon,
|
| 37 |
+
the practical way to run a 7B vision-language model at usable speed is MLX
|
| 38 |
+
4-bit; the full bf16 weights under `transformers` on MPS are prohibitively slow
|
| 39 |
+
(hundreds of seconds per clip). This conversion reduces inference to
|
| 40 |
+
approximately **7 seconds per short clip** on an M4 Pro.
|
| 41 |
|
| 42 |
## Usage
|
| 43 |
|
| 44 |
+
Run with [`mlx-vlm`](https://github.com/Blaizzy/mlx-vlm) (0.6.3 or later).
|
| 45 |
|
| 46 |
```python
|
| 47 |
from mlx_vlm import load, generate
|
|
|
|
| 49 |
|
| 50 |
model, processor = load("viavicdev/Tarsier2-Recap-7b-MLX-4bit")
|
| 51 |
|
| 52 |
+
# Provide the video as a list of extracted frame images (see note 1)
|
| 53 |
frames = ["frame_00.jpg", "frame_01.jpg", "frame_02.jpg", "frame_03.jpg"]
|
| 54 |
prompt = apply_chat_template(
|
| 55 |
processor, model.config,
|
|
|
|
| 58 |
)
|
| 59 |
out = generate(
|
| 60 |
model, processor, prompt,
|
| 61 |
+
image=frames, # parameter is image= (not images=)
|
| 62 |
max_tokens=300,
|
| 63 |
temperature=0.3,
|
| 64 |
+
repetition_penalty=1.3, # see note 3
|
| 65 |
repetition_context_size=40,
|
| 66 |
)
|
| 67 |
print(out)
|
| 68 |
```
|
| 69 |
|
| 70 |
+
### Practical notes
|
| 71 |
|
| 72 |
+
1. **Provide frames as images rather than a video file.** The `mlx-vlm` 0.6.3
|
| 73 |
+
video decoder path is unreliable and may produce hallucinated output. Extract
|
| 74 |
+
frames with ffmpeg and pass them as a list of images (`image=[...]` with
|
| 75 |
+
`num_images=N`); this delivers the actual frames to the model.
|
| 76 |
+
2. **The chat template is included** in this repository (`chat_template.json`
|
| 77 |
+
and `chat_template.jinja`). Some MLX repackings omit it, which causes
|
| 78 |
+
`apply_chat_template` to fail.
|
| 79 |
+
3. **Apply a repetition penalty.** At 4-bit precision the model can occasionally
|
| 80 |
+
loop. The settings `repetition_penalty=1.3`, `repetition_context_size=40`,
|
| 81 |
+
and `temperature=0.3` keep the output stable. In internal testing, 1 of 22
|
| 82 |
+
clips degenerated without a penalty and none did with it.
|
| 83 |
|
| 84 |
+
## Conversion notes
|
| 85 |
|
| 86 |
+
Tarsier2 is distributed as `TarsierForConditionalGeneration` with
|
| 87 |
+
`model_type: llava`, but its text and vision towers are Qwen2-VL weights under
|
| 88 |
+
different key names. The `mlx-vlm` llava handler does not support Qwen2-VL's
|
| 89 |
+
mRoPE (it raises `rope_scaling type only supports linear`), whereas the
|
| 90 |
+
`qwen2_vl` handler does. The conversion therefore consists of a key-remap into
|
| 91 |
+
the native Qwen2-VL layout, followed by a standard MLX quantization.
|
| 92 |
|
| 93 |
+
Only three key prefixes require remapping:
|
| 94 |
|
| 95 |
```
|
| 96 |
language_model.model.* -> model.*
|
|
|
|
| 98 |
vision_tower.* -> visual.*
|
| 99 |
```
|
| 100 |
|
| 101 |
+
A flat `qwen2_vl` configuration is then built from Tarsier's `text_config` and
|
| 102 |
`vision_config` (preserving `rope_scaling: mrope`, the vision/image/video token
|
| 103 |
+
ids, and related fields), and the remapped weights are quantized:
|
| 104 |
|
| 105 |
```bash
|
| 106 |
mlx_vlm.convert --hf-path ./tarsier2-qwen2vl-hf -q --q-bits 4
|
| 107 |
```
|
| 108 |
|
| 109 |
+
This reflects a general pattern: custom Qwen2-VL-based models such as Tarsier,
|
| 110 |
+
which lack an official MLX or HF remote-code path, can often be run on MLX
|
| 111 |
+
through a key-remap, provided they are routed through the `qwen2_vl` handler so
|
| 112 |
+
that mRoPE is respected.
|
| 113 |
|
| 114 |
## Limitations
|
| 115 |
|
| 116 |
+
- 4-bit quantization trades some fidelity for reduced size and higher speed.
|
| 117 |
+
For maximum quality, use the original bf16 weights on a CUDA device.
|
| 118 |
+
- This is an English captioning model; it describes in English regardless of any
|
| 119 |
+
spoken language in the clip.
|
| 120 |
+
- Vision only (no audio). It captions what is seen, not what is heard.
|
| 121 |
+
- It follows free-form description more reliably than rigid output schemas, and
|
| 122 |
+
is best used as a captioner rather than a strict classifier.
|
| 123 |
|
| 124 |
## License and attribution
|
| 125 |
|
| 126 |
This conversion inherits the **Apache-2.0** license of the base model. All
|
| 127 |
+
credit for the model itself belongs to the Tarsier2 authors
|
| 128 |
([omni-research/Tarsier2-Recap-7b](https://huggingface.co/omni-research/Tarsier2-Recap-7b)).
|
| 129 |
+
This repository provides only a format conversion — a weight key-remap and MLX
|
| 130 |
+
4-bit quantization — for the Apple Silicon community.
|
| 131 |
|
| 132 |
+
When citing Tarsier2, please cite the original authors.
|