# Визуально-языковая модель Qwen2.5-VL

Qwen2.5-VL от Alibaba (декабрь 2024) — лучшая открытая модель визуально-языковой обработки (VLM) по производительности при открытых весах. Доступна в вариантах с 3B, 7B и 72B параметрами, понимает изображения, кадры видео, PDF, диаграммы и сложные визуальные макеты. Вариант 7B — это золотая середина: он превосходит многие более крупные модели в бенчмарках и при этом комфортно работает на одной 24 ГБ GPU.

На [Clore.ai](https://clore.ai/) вы можете арендовать именно ту GPU, которая вам нужна — от RTX 3090 для модели 7B до конфигураций с несколькими GPU для варианта 72B — и начать анализировать визуальный контент за считанные минуты.

## Ключевые особенности

* **Мультимодальный ввод** — изображения, видео, PDF, скриншоты, диаграммы и схемы в одной модели.
* **Три масштаба** — 3B (edge/мобильный), 7B (производственная золотая середина), 72B (качество SOTA).
* **Динамическое разрешение** — обрабатывает изображения в их родном разрешении; нет принудительного изменения размера до 224×224.
* **Понимание видео** — принимает многокадровый видео ввод с временным рассуждением.
* **OCR для документов** — извлекает текст из отсканированных документов, чеков и рукописных заметок.
* **Мультиязычность** — высокая производительность на английском, китайском и более чем на 20 других языках.
* **Поддержка Ollama** — запуск локально с `ollama run qwen2.5vl:7b` для развертывания без кода.
* **Интеграция с Transformers** — `Qwen2_5_VLForConditionalGeneration` в HuggingFace `transformers`.

## Требования

| Компонент   | 3B    | 7B       | 72B                    |
| ----------- | ----- | -------- | ---------------------- |
| VRAM GPU    | 8 ГБ  | 16–24 ГБ | 80+ ГБ (несколько GPU) |
| ОЗУ системы | 16 ГБ | 32 ГБ    | 128 ГБ                 |
| Диск        | 10 ГБ | 20 ГБ    | 150 ГБ                 |
| Python      | 3.10+ | 3.10+    | 3.10+                  |
| CUDA        | 12.1+ | 12.1+    | 12.1+                  |

**Рекомендация Clore.ai по GPU:** Для **модели 7B**, **RTX 4090** (24 ГБ, \~$0.5–2/день) или **RTX 3090** (24 ГБ, \~$0.3–1/день) являются идеальными. Для **72B**, отфильтруйте маркетплейс по **A100 80 GB** или конфигурациям с несколькими GPU.

## Быстрый старт

### Вариант A: Ollama (проще всего)

```bash
# Установите ollama
curl -fsSL https://ollama.ai/install.sh | sh

# Загрузите и запустите 7B визуальную модель
ollama run qwen2.5vl:7b
```

Затем в приглашении ollama:

```
>>> Опишите это изображение: /path/to/photo.jpg
```

### Вариант B: Python / Transformers

```bash
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
pip install transformers accelerate qwen-vl-utils pillow
```

## Примеры использования

### Понимание изображений с помощью Transformers

```python
import torch
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info

model_name = "Qwen/Qwen2.5-VL-7B-Instruct"

model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
    model_name,
    torch_dtype=torch.bfloat16,
    device_map="auto",
)
processor = AutoProcessor.from_pretrained(model_name)

messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "image": "https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg"},
            {"type": "text", "text": "Какой это вид насекомого? Опишите его ключевые идентифицирующие признаки."},
        ],
    }
]

text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)

inputs = processor(
    text=[text],
    images=image_inputs,
    videos=video_inputs,
    padding=True,
    return_tensors="pt",
).to(model.device)

output_ids = model.generate(**inputs, max_new_tokens=512)
response = processor.batch_decode(
    output_ids[:, inputs.input_ids.shape[1]:],
    skip_special_tokens=True,
)[0]

print(response)
```

### Анализ видео

```python
import torch
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info

model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
    "Qwen/Qwen2.5-VL-7B-Instruct",
    torch_dtype=torch.bfloat16,
    device_map="auto",
)
processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-7B-Instruct")

messages = [
    {
        "role": "user",
        "content": [
            {"type": "video", "video": "file:///workspace/clip.mp4", "max_pixels": 360 * 420, "fps": 1.0},
            {"type": "text", "text": "Суммируйте, что происходит в этом видео. Перечислите ключевые события по порядку."},
        ],
    }
]

text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)

inputs = processor(
    text=[text],
    images=image_inputs,
    videos=video_inputs,
    padding=True,
    return_tensors="pt",
).to(model.device)

output_ids = model.generate(**inputs, max_new_tokens=1024)
print(processor.batch_decode(output_ids[:, inputs.input_ids.shape[1]:], skip_special_tokens=True)[0])
```

### OCR и извлечение из документов

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "image": "file:///workspace/receipt.jpg"},
            {"type": "text", "text": "Извлеките все позиции, количества и цены из этого чека. Вернуть в формате JSON."},
        ],
    }
]

# Обработка с использованием той же настройки модели/процессора, что и выше
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)
inputs = processor(text=[text], images=image_inputs, videos=video_inputs, padding=True, return_tensors="pt").to(model.device)
output_ids = model.generate(**inputs, max_new_tokens=2048)
print(processor.batch_decode(output_ids[:, inputs.input_ids.shape[1]:], skip_special_tokens=True)[0])
```

### Ollama API для пакетной обработки

```python
import ollama
import base64
from pathlib import Path

def analyze_image(image_path: str, question: str) -> str:
    """Отправляет изображение в Qwen2.5-VL через API Ollama."""
    image_data = base64.b64encode(Path(image_path).read_bytes()).decode()
    response = ollama.chat(
        model="qwen2.5vl:7b",
        messages=[{
            "role": "user",
            "content": question,
            "images": [image_data],
        }],
    )
    return response["message"]["content"]

# Пакетная обработка папки с изображениями
from pathlib import Path
for img in sorted(Path("./photos").glob("*.jpg")):
    result = analyze_image(str(img), "Опишите это изображение в одном предложении.")
    print(f"{img.name}: {result}")
```

## Советы для пользователей Clore.ai

1. **Ollama для быстрого развёртывания** — `ollama run qwen2.5vl:7b` — это самый быстрый путь к рабочей VLM. Для интерактивного использования Python код не требуется.
2. **7B — это золотая середина** — вариант 7B Instruct помещается в 16 ГБ VRAM с 4-битной квантизацией и обеспечивает качество, сопоставимое с гораздо большими моделями.
3. **Динамическое разрешение имеет значение** — Qwen2.5-VL обрабатывает изображения в родном разрешении. Для больших изображений (>4K) уменьшите до максимальной ширины 1920px, чтобы избежать чрезмерного использования VRAM.
4. **Настройка fps для видео** — для ввода видео установите `fps=1.0` чтобы отбирать 1 кадр в секунду. Более высокие значения быстро потребляют VRAM; 1 fps достаточно для большинства задач анализа.
5. **Постоянное хранилище** — установите `HF_HOME=/workspace/hf_cache`; модель 7B занимает \~15 ГБ. Для ollama модели размещаются в `~/.ollama/models/`.
6. **Структурированный вывод** — Qwen2.5-VL хорошо следует инструкциям по форматированию JSON. Попросите «Вернуть в формате JSON», и вы получите парсируемый вывод большинство времени.
7. **Сравнение нескольких изображений** — вы можете передавать несколько изображений в одном сообщении для задач сравнения (например, «Какие из этих двух продуктов выглядят более премиально?»).
8. **tmux** — всегда запускайте внутри `tmux` на арендуемых Clore.ai GPU.

## Устранение неполадок

| Проблема                                     | Исправить                                                                                          |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `OutOfMemoryError` с 7B                      | Используйте `load_in_4bit=True` в `from_pretrained()` с `bitsandbytes`; или используйте вариант 3B |
| Модель Ollama не найдена                     | `ollama pull qwen2.5vl:7b` — убедитесь, что у вас правильный тег                                   |
| Медленная обработка видео                    | Уменьшите `fps` до 0.5 и `max_pixels` до `256 * 256`; меньше кадров = более быстрое инференс       |
| Испорченный или пустой вывод                 | Увеличьте `max_new_tokens`; значение по умолчанию может быть слишком низким для подробных описаний |
| `ImportError: qwen_vl_utils`                 | `pip install qwen-vl-utils` — требуется для `process_vision_info()`                                |
| Модель 72B не помещается                     | Используйте 2× A100 80 GB с `device_map="auto"` или примените квантизацию AWQ                      |
| Путь к изображению не найден                 | Для локальных файлов в сообщениях используйте `file:///absolute/path` формат                       |
| Вывод на китайском при запросе на английском | Добавьте «Отвечайте только на английском.» в ваш запрос                                            |
