# Qwen2.5-VL 视觉语言模型

阿里巴巴的 Qwen2.5-VL（2024 年 12 月）是表现最好的开源权重视觉-语言模型（VLM）。提供 3B、7B 和 72B 参数规模，能够理解图像、视频帧、PDF、图表和复杂的视觉布局。7B 变体最为均衡——在基准测试中优于许多更大的模型，同时可以在单个 24 GB GPU 上舒适运行。

在 [Clore.ai](https://clore.ai/) 上，你可以按需租用精确的 GPU —— 从用于 7B 模型的 RTX 3090 到用于 72B 版本的多 GPU 配置 —— 并在几分钟内开始分析视觉内容。

## 主要特性

* **多模态输入** —— 在单一模型中处理图像、视频、PDF、截图、图表和示意图。
* **三种规模** —— 3B（边缘/移动）、7B（生产的最佳选择）、72B（SOTA 质量）。
* **动态分辨率** —— 以图像的原生分辨率处理；不强制调整为 224×224。
* **视频理解** —— 接受多帧视频输入并具备时间推理能力。
* **文档 OCR** —— 从扫描文档、收据和手写笔记中提取文本。
* **多语言** —— 在英语、中文及 20+ 其他语言上表现强劲。
* **Ollama 支持** —— 使用以下方式在本地运行 `ollama run qwen2.5vl:7b` 以实现零代码部署。
* **Transformers 集成** — `Qwen2_5_VLForConditionalGeneration` 在 HuggingFace `transformers`.

## 要求

| 组件     | 3B    | 7B       | 72B           |
| ------ | ----- | -------- | ------------- |
| GPU 显存 | 8 GB  | 16–24 GB | 80+ GB（多 GPU） |
| 系统内存   | 16 GB | 32 GB    | 128 GB        |
| 磁盘     | 10 GB | 20 GB    | 150 GB        |
| Python | 3.10+ | 3.10+    | 3.10+         |
| CUDA   | 12.1+ | 12.1+    | 12.1+         |

**Clore.ai 的 GPU 推荐：** 对于 **7B 模型**，一块 **512x512** （24 GB，约 $0.5–2/天）或 **速度** （24 GB，约 $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:
    """通过 Ollama API 将图像发送到 Qwen2.5-VL。"""
    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 变体在 4-bit 量化下可适配 16 GB 显存，并提供与更大模型相竞争的质量。
3. **动态分辨率很重要** —— Qwen2.5-VL 以原生分辨率处理图像。对于超大图像（>4K），将最大宽度调整为 1920px 以避免显存过度使用。
4. **视频 fps 设置** —— 对于视频输入，设置 `fps=1.0` 以每秒采样 1 帧。更高的值会快速消耗显存；对于大多数分析任务，1 fps 足够。
5. **持久化存储** —— 设置 `HF_HOME=/workspace/hf_cache`；7B 模型约为 15 GB。对于 ollama，模型存放在 `~/.ollama/models/`.
6. **结构化输出** —— Qwen2.5-VL 很好地遵循 JSON 格式化指令。要求“以 JSON 返回”，大多数情况下你会得到可解析的输出。
7. **多图比较** —— 你可以在一条消息中传递多张图片以进行比较任务（例如，“这两款产品中哪一款看起来更高端？”）。
8. **tmux** —— 在 Clore.ai 的租用环境中始终在 `tmux` 中运行。

## # 使用固定种子以获得一致结果

| 问题                           | 修复                                                                      |
| ---------------------------- | ----------------------------------------------------------------------- |
| `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-zh/shi-jue-mo-xing/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.
