# 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` 格式                                |
| 用英语提示时输出为中文                  | 在你的提示中加入 “仅用英文回复。”                                                      |
