# Языково-визуальная модель 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` формат                       |
| Вывод на китайском при запросе на английском | Добавьте «Отвечайте только на английском.» в ваш запрос                                            |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-ru/modeli-zreniya/qwen-vl.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
