# MinerU 低显存部署踩坑：hybrid OOM 而 Vlm 反而能跑


最近需要在本地用 [MinerU](https://github.com/opendatalab/MinerU) 处理一些 PDF，结果在手头的 8GB 显存机器上踩了一路坑。最反直觉的发现是：**理论上更"轻量"的 hybrid 模式反而 OOM，而看似更重的 vlm 模式却能跑通。** 翻了一下源码才搞清楚怎么回事，记下来给同样低显存环境的朋友参考。

## 第一关：默认后端直接 OOM

MinerU 3.x 默认的后端是 `hybrid-auto-engine`，装完直接跑：

```bash
mineru -p input.pdf -o output
```

结果没一会就崩了：

```plaintext
CUDA out of memory. Tried to allocate 20.00 MiB. GPU 0 has a total
capacity of 80 GiB of which 65.56 MiB is free.
```

8GB 的显存，可用只剩 65MB，连 20MB 都分不出来。

## 尝试调参，没用

先翻文档，找到了几个控制显存占用的环境变量：

```bash
MINERU_HYBRID_BATCH_RATIO=1 \
MINERU_API_MAX_CONCURRENT_REQUESTS=1 \
MINERU_PROCESSING_WINDOW_SIZE=1 \
mineru -p input.pdf -o output
```

特别是 `MINERU_HYBRID_BATCH_RATIO`，文档给了一张对照表，6GB 以下建议设成 8 或更低。但我的 8GB 自动检测会设成 1（源码里的 `get_batch_ratio` 函数：<8GB 就给 1）。

但不管怎么调，依然 OOM。因为 **`batch_ratio` 只控制小模型推理的 batch 大小，不控制模型加载数量。**

## 反直觉的发现：vlm 模式反而能跑

抱着试一试的心态，切到 `vlm-auto-engine`：

```bash
mineru -p input.pdf -o output -b vlm-auto-engine
```

居然跑通了。速度比 hybrid 慢，但至少不崩。

这就很奇怪了——vlm 模式每页都走大模型推理，理论上不是更吃显存吗？

## 翻源码搞清楚原因

看了看 MinerU 的 `model_init.py`，两种模式加载的模型完全不一样：

**hybrid-auto-engine（HybridModelSingleton）：**

| 模型             | 用途         |  是否常驻显存  |
| ---------------- | ------------ | :------------: |
| PPDocLayoutV2    | 版面检测     |       是       |
| PytorchPaddleOCR | OCR 文字识别 |       是       |
| MFR (UniMerNet)  | 数学公式识别 | 是（如果开启） |
| 表格识别模型     | 表格结构解析 |       是       |
| VLM (约 2B 参数) | 复杂内容     |       是       |

4-5 个模型同时驻留显存，8GB 根本放不下。

**vlm-auto-engine：**

| 模型             | 用途           | 是否常驻显存 |
| ---------------- | -------------- | :----------: |
| VLM (约 2B 参数) | 所有任务一把梭 |      是      |

只加载 1 个模型，约 4-5GB 显存，8GB 放得下。

所以结论就很清楚了：**hybrid 模式虽然每个小模型单独看很轻，但加在一起的总显存占用比单跑一个 VLM 还大。** 低显存环境下，反而应该选 vlm。

## 再踩一坑：http-client 接第三方 LLM 格式不兼容

既然本地显存紧张，那就试试把 VLM 推理卸载到远程 API 吧：

```bash
mineru -p input.pdf -o output -b hybrid-http-client -u http://some-api:30000/v1
```

结果日志报了一行 WARNING：

````plaintext
WARNING | mineru_vl_utils.mineru_client:parse_layout_output:251 -
Layout output does not match expected format: ```json
[
    {"bbox_2d": [145, 83, 853, 442], "label": "Table I"},
    ...
]
````

LLM 返回的内容被 ` ```json ` 包裹了，MinerU 解析不了。

抓了一下 MinerU 发给 LLM 的请求，发现 prompt 极其简单：

```json
{"role": "system", "content": "You are a helpful assistant."}
{"text": "\nLayout Detection:", "type": "text"}
```

它期望远程模型大概是 MinerU 微调过的 VLM（基于 Qwen2-VL），那个模型经过训练，看到 "Layout Detection:" 就会用特殊 token 格式输出：

```plaintext
<|box_start|>145 83 853 442<|box_end|><|ref_start|>Table I<|ref_end|>
```

而通用 LLM 根本不知道这些特殊 token，自然就按自己理解返回了 JSON + markdown 代码块。

## 最终方案

对于 8GB 显存的环境，直接用 vlm-auto-engine：

```bash
# 安装
uv pip install -U "mineru[all]"

# 运行
mineru -p input.pdf -o output -b vlm-auto-engine
```

如果 vlm 也 OOM（极端情况），退回纯 CPU：

```bash
mineru -p input.pdf -o output -b pipeline
```

慢是慢了点，但稳。

## 参考

- [MinerU 官方文档](https://opendatalab.github.io/MinerU/zh/)
- [MinerU GitHub](https://github.com/opendatalab/MinerU)
- [mineru-vl-utils 源码 - http client 实现](https://github.com/opendatalab/mineru-vl-utils/blob/main/mineru_vl_utils/mineru_client.py)
- [MinerU model_init.py - 模型加载逻辑](https://github.com/opendatalab/MinerU/blob/master/mineru/backend/pipeline/model_init.py)


---

> 作者: Nite  
> URL: https://www.nite07.com/zh-cn/posts/mineru-low-vram/  

