· 组会汇报  · 40 min read

Monkey 系列仓库分析结论

本文总结了 Monkey 系列仓库(Monkey、TextMonkey、Mini-Monkey)的技术演进、代码定位与核心差异,提供了详尽的论文与代码对照。

1. 仓库中的真实工作边界

结论:当前仓库里真正有成体系实现的 Monkey 系列工作,主要是 3 个:

  1. Monkey
  2. TextMonkey
  3. Mini-Monkey

其中:

  • Monkey 是根目录主线实现,核心代码在根目录与 monkey_model/ 下。
  • TextMonkey 也在同一主线内,和 Monkey 共享一部分 Qwen/Qwen-VL 体系代码,但有独立模型实现、训练脚本、Demo 和文档评测入口。
  • Mini-Monkey 位于 project/mini_monkey/,是相对独立的子项目,技术路线和代码组织都与前两者明显不同。
  • MonkeyOCR 在本仓库内没有对应源码目录,只有 README.md 中的论文、权重、外部仓库链接。
  • MonkeyOCRv2 在当前仓库内完全没有出现,既无 README 条目,也无代码命中。

证据:

  • 根 README 将 Monkey、TextMonkey、Mini-Monkey 分别链接到仓库内 README.md、monkey_model/text_monkey/README.md、project/mini_monkey,而 MonkeyOCR 链接到外部仓库:README.md:18-24、README.md:28-33、README.md:41-46、README.md:59-64
  • 仓库目录层面仅存在根目录主线和 project/mini_monkey/ 子项目,没有 MonkeyOCR 目录。
  • 全仓检索 MonkeyOCR 只命中 README.md;检索 MonkeyOCRv2 无任何命中。

2. 工作到代码入口的映射

2.1 Monkey

类别代码位置说明
模型定义monkey_model/modeling_monkey.pyMonkeyModel / MonkeyLMHeadModel
视觉策略证据monkey_model/modeling_monkey.py:55-76读取图像后同时构建局部窗口特征和 images_448 全局特征,再拼接为视觉输入
训练主程序finetune_multitask.py加载 MonkeyLMHeadModel 训练
训练脚本finetune/finetune_ds_debug.sh默认底座是 Qwen/Qwen-VL
推理入口inference.pyREADME 中明确给出命令行推理方式
Demodemo.pyGradio Demo
评测主程序eval/evaluate_vqa.py14 个 VQA 数据集评测
评测脚本eval/eval.sh分布式启动 evaluate_vqa.py

补充:

  • README 将 Monkey 定位为仓库主标题工作:README.md:1、README.md:18-24
  • README 训练、推理、Demo、评测说明都首先围绕 Monkey 展开:README.md:100-138、README.md:174-213

2.2 TextMonkey

类别代码位置说明
模型定义monkey_model/modeling_textmonkey.pyTextMonkeyModel / TextMonkeyLMHeadModel
文本视觉模块monkey_model/text_monkey/visual_text.py、monkey_model/text_monkey/window.py独立视觉编码、窗口注意力相关实现
训练主程序finetune_multitask_dialouge_doc.py加载 TextMonkeyLMHeadModel
训练脚本finetune/finetune_textmonkey.sh默认底座也是 Qwen/Qwen-VL,并开启 add_window/use_global/resampler
推理入口demo_textmonkey.py仓库内主要提供 Demo 形式入口,没有单独的 inference_textmonkey.py
Demodemo_textmonkey.py文档/文本任务交互 Demo
评测主程序eval/evaluate_vqa_doc.py文档与文本相关评测
评测脚本eval/eval_doc.sh分布式启动 evaluate_vqa_doc.py

补充:

  • 根 README 将 TextMonkey 代码入口直接指向 monkey_model/text_monkey/README.md:README.md:28-33
  • TextMonkey README 明确给出训练与评测命令:monkey_model/text_monkey/README.md:66-79

2.3 Mini-Monkey

类别代码位置说明
模型定义project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.pyMiniMonkeyChatModel
训练主程序project/mini_monkey/internvl/train/minimonkey_chat_finetune.py可从预训练模型直接加载或自行拼装视觉塔 + LLM
训练脚本project/mini_monkey/shell/minimonkey/minimonkey_finetune_full.sh默认 OpenGVLab/InternVL2-2B
LoRA 训练脚本project/mini_monkey/shell/minimonkey/minimonkey_finetune_lora.sh轻量训练变体
推理入口project/mini_monkey/demo.pyREADME 也把它作为 inference 示例
Demoproject/mini_monkey/demo.py多尺度裁剪推理示例
评测入口project/mini_monkey/eval/仓库内包含大量任务评测脚本
VQA 评测主程序project/mini_monkey/eval/vqa/evaluate_vqa.py本地评测实现

补充:

  • 根 README 将 Mini-Monkey 代码入口直接指向 project/mini_monkey:README.md:41-46
  • Mini-Monkey README 说明它是独立环境与独立训练流程:project/mini_monkey/README.md:48-56、project/mini_monkey/README.md:72-79
  • README 虽然主推基于 VLMEvalKit 评测,但仓库内也实际保留了大量 eval/ 代码。

2.4 MonkeyOCR 与 MonkeyOCRv2

工作仓库状态证据
MonkeyOCR仓库外,当前仓库仅 README 展示README.md:59-64 指向外部 GitHub 仓库;全仓检索仅命中 README
MonkeyOCRv2当前仓库未展示、未实现全仓无命中

3. 三个主工作的功能定位与技术差异

3.1 Monkey

Monkey 是这条线的基础版通用多模态模型,重点在提升大多模态模型对高分辨率图像与文本标签的利用能力。

从代码看,它仍然建立在 Qwen/Qwen-VL 体系上:

  • MonkeyLMHeadModel 继承自 QWenLMHeadModel:monkey_model/modeling_monkey.py:96-145
  • 训练脚本默认模型为 Qwen/Qwen-VL:finetune/finetune_ds_debug.sh:11-25

从视觉处理看,Monkey 的关键点是同时保留局部窗口与全局图像特征:

  • self.visual.encode(images) 返回窗口图像与 images_448
  • 局部 patch 特征与全局特征被拼接后送入模型:monkey_model/modeling_monkey.py:65-76

因此它更适合讲成:

  • 通用视觉问答 / 图文理解基线
  • 强调高分辨率输入与文本相关视觉信息的重要性
  • 是后续 TextMonkey 的文档强化路线、Mini-Monkey 的轻量路线的共同出发点

3.2 TextMonkey

TextMonkey 是沿着“文本密集场景 / 文档理解”方向做深化的版本,定位明显比 Monkey 更聚焦。

README 直接给出的定位与增强点包括:

  • OCR-free 文档理解
  • 更高输入分辨率下的窗口间信息交互
  • 重要视觉特征筛选
  • 通过位置相关响应增强可解释性并减少幻觉
  • 具备文本定位与 APP Agent 点击潜力

证据见:monkey_model/text_monkey/README.md:21、monkey_model/text_monkey/README.md:83-91

从代码看,它与 Monkey 的主要区别是视觉编码器独立化:

  • TextMonkeyModel 里显式替换成 VisionTransformer(**config.visual):monkey_model/modeling_textmonkey.py:35-39
  • visual_text.py / window.py 中存在滑窗、cross-window attention、shifted window 等实现:monkey_model/text_monkey/visual_text.py、monkey_model/text_monkey/window.py
  • 训练脚本还额外打开了 --add_window true --use_global true --resampler true --image_size 896,说明其训练配置就是围绕高分辨率文档建模设计的:finetune/finetune_textmonkey.sh:47-54

因此它更适合讲成:

  • Monkey 的文档理解强化版
  • 面向场景文本、文档、图表、表格等文本密集场景
  • 比 Monkey 更强调文本定位、文档问答、结构化文本理解

3.3 Mini-Monkey

Mini-Monkey 不是简单的“小号 Monkey”,而是换了一条轻量化与多尺度输入策略并重的路线。

README 直接给出的关键词是:

  • 轻量化 MLLM
  • MSAC(multi-scale adaptive cropping)
  • SCM(Scale Compression Mechanism)
  • 在 2B 参数规模下兼顾通用多模态与文档能力

证据见:project/mini_monkey/README.md:20

从代码看,它与前两者的差异非常明显:

  • 主模型是 MiniMonkeyChatModel,不是 Qwen 主线:project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:38
  • 默认底座是 OpenGVLab/InternVL2-2B:project/mini_monkey/shell/minimonkey/minimonkey_finetune_full.sh:31-39
  • MiniMonkeyChatModel 可兼容 InternLM2 / Llama / Phi3 / Qwen2 等 LLM 架构:project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:68-77
  • demo.py 中直接实现了动态长宽比匹配、多块裁剪、缩略图补充与二次裁剪拼接:project/mini_monkey/demo.py:37-73、project/mini_monkey/demo.py:76-116、project/mini_monkey/demo.py:144-148
  • 模型内部还实现了 token 压缩与 use_scm 分支:project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:218-252、project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:396-398

因此它更适合讲成:

  • 轻量化、部署友好
  • 通过多尺度裁剪而非单纯堆大模型来提升细粒度视觉理解
  • 在小参数量下兼顾通用视觉问答和文档/OCR 类能力

3.4 三者对比表

维度MonkeyTextMonkeyMini-Monkey
仓库位置根目录主线根目录主线 + monkey_model/text_monkeyproject/mini_monkey 独立子项目
核心定位通用多模态理解基线OCR-free 文档/文本理解强化轻量化多模态模型
主底座Qwen / Qwen-VL 体系Qwen / Qwen-VL 体系InternVL2-2B 主线
主要视觉策略局部窗口 + 全局特征拼接高分辨率窗口交互、特征筛选、位置信息多尺度自适应裁剪 + token 压缩
输入处理特点高分辨率图像与文本标签更偏文本密集图像、文档和定位动态裁剪、多 patch、缩略图辅助
文档能力有,但不是唯一重心是核心重心兼顾,且在小模型下表现强
参数 / 规模叙事作为系列早期主线在 Monkey 基础上增强文本能力2B 级轻量路线
典型入口inference.py / demo.pydemo_textmonkey.py / evaluate_vqa_doc.pyproject/mini_monkey/demo.py / internvl/train/minimonkey_chat_finetune.py
汇报角色系列起点文档强化主线轻量化延伸主线

3.5 论文关键点到代码实现的细粒度对应

这一节不是再重复“哪个文件负责什么”,而是把论文里常出现的术语,继续压到“哪个配置项、哪个函数、哪一段数据流”。

3.5.1 Monkey / TextMonkey 的共同入口:图片先以特殊 token 形式进入 LLM

这条主线最关键的一点是:图像并不是作为额外 tensor 分支单独传入接口,而是先在文本 prompt 里写成 <img>...</img>,再在模型内部根据特殊 token 区间把图片路径解析出来,最后把视觉特征回填到语言模型输入中。

  • demo_textmonkey.py:66-87 先构造 "<img>{input_image}</img> {input_str}",再调用 model.generate(...)
  • demo_textmonkey.py:37 将 tokenizer.IMG_TOKEN_SPAN 设为 config.visual["n_queries"]
  • eval/evaluate_vqa_doc.py:499-505 评测阶段同样把 IMG_TOKEN_SPAN 绑定到 config.visual["n_queries"],说明训练、Demo、评测共享同一套“图像 token 长度”约定

这个设计对应论文里的一个核心叙事:视觉信息并不是脱离 LLM 主干单独建模,而是被组织成和文本统一的序列输入,再由 Qwen 主干一起处理。

3.5.2 Monkey:高分辨率图像被拆成“局部窗口 + 全局视图”两路特征

Monkey 的论文叙事重点,是“高分辨率图像”和“文本相关细节”不能只靠单张缩放图解决。代码里最直接的落点就是 MonkeyModel.forward(...) 的图像解析和特征拼接流程:

  • monkey_model/modeling_monkey.py:55-64 从 input_ids 中定位 image_start_id / image_end_id,并解码出图像路径
  • monkey_model/modeling_monkey.py:65 调用 self.visual.encode(images),拿到窗口图像与 images_448
  • monkey_model/modeling_monkey.py:68-75 对每个窗口单独提特征,再对 images_448 提取全局特征,最后 torch.cat([local_feat, global_feat], dim=1) 拼接

所以如果汇报里要把 Monkey 讲得更“像论文”,更准确的说法不是笼统地说“它支持高分辨率”,而是:

  • 局部分支负责保留高分辨率下的小文字、小区域、小目标细节
  • 全局分支负责补足整图上下文
  • 两路特征最终在送入 Qwen 主干前完成拼接

3.5.3 TextMonkey:关键超参数不是写死在配置类里,而是在训练入口动态覆盖到 config.visual

这里有一个很值得在报告里点明的小结论:monkey_model/configuration_monkey.py:13-65 里的 MonkeyConfig 主要定义的是通用 LLM 配置,本身并没有把 TextMonkey 那些视觉增强项硬编码死。真正决定文档理解行为的,是训练脚本在加载预训练配置后,对 config.visual 的二次覆盖:

  • finetune_multitask_dialouge_doc.py:332-345
    • config.visual["image_size"] = (training_args.image_height, training_args.image_width)
    • config.visual["n_queries"] = training_args.n_queries
    • config.visual["add_window"] = training_args.add_window
    • config.visual["use_global"] = training_args.use_global
    • config.visual["resampler"] = training_args.resampler
    • config.visual["r"] = training_args.remain
  • finetune/finetune_textmonkey.sh:48-54 进一步给出实际训练值:image_size=896、add_window=true、use_global=true、resampler=true

这说明论文里那些增强项,在工程上不是抽象概念,而是被落实成一组可以直接开关和调参的视觉入口。

3.5.4 TextMonkey 的视觉主链:窗口交互、特征压缩、全局补充

TextMonkeyModel 和 MonkeyModel 的一个重要区别,是它不再只是简单复用原始视觉分支,而是显式换成了文档理解定制的 VisionTransformer(**config.visual):

  • monkey_model/modeling_textmonkey.py:35-38 初始化独立视觉编码器
  • monkey_model/modeling_textmonkey.py:57-72 在 forward 阶段解析图片路径并调用 self.visual.encode(images)

更细一点看,论文里的几个关键词在 visual_text.py 中都有明确落点:

  • “窗口建模 / window interaction”
    • monkey_model/text_monkey/visual_text.py:36-48 用 sliding_window(...) 把图像切成窗口
    • monkey_model/text_monkey/visual_text.py:417-429 指定 window_pos = [2, 6, 24, 46],在若干层插入 CrossWindowAttention
    • monkey_model/text_monkey/visual_text.py:443-475 在 Transformer forward 中重建整图、做跨窗口注意力、再切回窗口
  • “重要视觉特征筛选 / token 压缩”
    • monkey_model/text_monkey/visual_text.py:547-559 构建 Resampler 与可选 PerceiverResampler
    • monkey_model/text_monkey/visual_text.py:638-640 当 self.resampler 打开时,用 downresampler(local_feat, r=self.r) 压缩局部特征
    • monkey_model/text_monkey/resampler.py:107-144 给出 PerceiverResampler 的具体实现,先做 token merge,再用 perceiver attention 聚合
  • “全局视图补充”
    • monkey_model/text_monkey/visual_text.py:631-643 先生成 images_448,再在 use_global=True 时把局部特征与全局特征拼接返回

因此 TextMonkey 对论文里“高分辨率文档 + 窗口交互 + 重要特征筛选 + 全局上下文”的落地方式,可以概括成:

  1. 先按窗口保留高分辨率局部文本
  2. 在部分层引入跨窗口注意力,让不同窗口交换信息
  3. 用 resampler / perceiver resampler 压缩高成本视觉 token
  4. 再拼一条 448 全局分支,避免只见局部不见整体

3.5.5 n_queries 与 IMG_TOKEN_SPAN 的真实关系

论文里如果提到“视觉 token 数量”或“query 数量”,在这套实现里最应该对应的是 n_queries 和 tokenizer 侧的 IMG_TOKEN_SPAN。

  • finetune_multitask_dialouge_doc.py:372-380
    • 默认先令 tokenizer.IMG_TOKEN_SPAN = training_args.n_queries
    • 若启用 resampler,则 IMG_TOKEN_SPAN = training_args.remain
    • 若再启用 use_global,还会再加上一个 training_args.n_queries
  • demo_textmonkey.py:37 与 eval/evaluate_vqa_doc.py:499 都说明推理时最终以 config.visual["n_queries"] 作为 tokenizer 侧图像 span

这背后的含义是:

  • n_queries 决定单路视觉特征映射到语言序列时预留多少 token
  • resampler 会把局部高分辨率分支压到 remain
  • use_global 再额外加上一段全局视觉 token

所以 TextMonkey 里“视觉 token 长度”不是固定值,而是会随局部分支压缩策略和全局分支开关一起变化。

3.5.6 Mini-Monkey:论文里的 MSAC 在代码里就是动态裁剪 + 双阶段拼接

Mini-Monkey 的论文关键词是 MSAC 和 SCM。这两个词在代码里都能找到直接落点。

先看 MSAC:

  • project/mini_monkey/demo.py:22-35 的 find_closest_aspect_ratio(...) 会为原图选择最接近的目标网格比例
  • project/mini_monkey/demo.py:37-73 的 dynamic_preprocess(...) 根据目标比例把图像 resize 后切成多个 448 x 448 block,并在需要时补一个 thumbnail
  • project/mini_monkey/demo.py:76-116 的 dynamic_preprocess2(...) 再做第二轮裁剪,但会避开与第一次比例完全重复的划分
  • project/mini_monkey/demo.py:144-148 最终把两轮裁剪结果按 torch.cat([pixel_values2[:-1], pixel_values[:-1], pixel_values2[-1:]], 0) 拼起来

也就是说,论文里的“multi-scale adaptive cropping”在实现层面并不是一句口号,而是:

  1. 先根据原图长宽比选裁块网格
  2. 生成多块局部 patch
  3. 追加缩略图保留全局语义
  4. 再做第二轮不同尺度裁剪并重新拼接

3.5.7 Mini-Monkey:论文里的 SCM 在代码里就是基于注意力的视觉 token 筛选

再看 SCM:

  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:54-55 先用 image_size / patch_size 和 downsample_ratio 计算 num_image_token
  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:218-252 在 extract_feature(...) 里做 pixel_shuffle + mlp1,把视觉特征映射到 LLM 隐空间
  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:282-283 与 335-336 按 self.num_image_token * num_patches 构造 <IMG_CONTEXT> 序列
  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:396-438 当 use_scm=True 时,先根据早期层注意力估计高价值图像 token,再保留 top-k 部分,最后用筛选后的 input_embeds 继续生成

这里特别关键的一点是:Mini-Monkey 的 token 压缩并不是 TextMonkey 那种“先用 resampler 压缩视觉分支,再送入 LLM”,而是直接在生成前根据语言模型早期层注意力,对图像 token 做一次选择性保留。这是它和 TextMonkey 在“降 token 成本”上的重要实现差异。

3.5.8 Monkey / TextMonkey 的主干注入位置:直接覆盖 Qwen 隐藏状态片段

如果老师继续追问“视觉特征最终是怎么进 Qwen 的”,最值得展示的不是视觉编码器本身,而是 modeling_qwen.py 里的注入位置。

  • monkey_model/modeling_qwen.py:704-717 在 images is None 时,基础 Qwen-VL 风格逻辑会先从 input_ids 里解析图片路径并调用 self.visual.encode(images)
  • monkey_model/modeling_qwen.py:780-781 先把 input_ids 映射成标准的词向量 inputs_embeds = self.wte(input_ids)
  • monkey_model/modeling_qwen.py:811-813 若检测到图像特征,则直接执行 hidden_states[i][a + 1 : b] = images[idx]

这说明 Monkey / TextMonkey 这条线的融合方式不是“额外 cross-attention 分支再慢慢融合”,而是:

  1. 先保留文本序列框架不变
  2. 再找到 <img>...</img> 在序列中的占位区间
  3. 用视觉编码结果直接覆盖这一段隐藏状态
  4. 后续所有 Transformer 层都把这段视觉 token 当作序列的一部分继续处理

这也是为什么前面 IMG_TOKEN_SPAN、n_queries 会这么关键,因为它们本质上决定了这段“视觉 token 插槽”到底有多长。

3.5.9 Mini-Monkey 的主干注入位置:先构造 <IMG_CONTEXT>,再替换成视觉 embedding

Mini-Monkey 的做法与 Monkey / TextMonkey 很像,但实现接口更显式,因为它先在 prompt 中扩展出一串 <IMG_CONTEXT> 占位 token,再把这些位置替换成视觉特征。

  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:282-283 与 335-336 用 self.num_image_token * num_patches 构造图像 token 序列
  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:152-167 在 forward 阶段先拿到语言模型 embedding,再找出 selected = (input_ids == self.img_context_token_id)
  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:167-177 用 vit_embeds.reshape(-1, C) 覆盖 input_embeds[selected]
  • project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:383-390 generate 阶段同样重复这一替换过程,保证推理时图像 token 真正进入 LLM

因此从架构视角看,Mini-Monkey 的关键不是“视觉塔和 LLM 并列”,而是:

  1. 先把图像块数转成 prompt 里明确可数的图像上下文 token
  2. 再把这些 token 的 embedding 全部替换成视觉特征
  3. 若开启 SCM,则在生成前再根据早期注意力结果缩减图像 token

如果把三者放在同一张架构图里,最容易讲清的差异其实是:

  • Monkey:局部 + 全局视觉特征先拼好,再注入 Qwen 序列
  • TextMonkey:窗口交互与 resampler 先把视觉表示整理好,再注入 Qwen 序列
  • Mini-Monkey:多尺度裁块先决定 token 数,再把视觉 embedding 替换进 <IMG_CONTEXT> 序列

也就是说,三者的共同点是“都把视觉信息写回语言序列”,差异在于写回之前如何组织、筛选和压缩视觉 token。

4. 组会汇报的收敛建议

建议主线直接讲成:

  1. Monkey:系列起点,解决“大模型如何更好看高分辨率图像和文本”
  2. TextMonkey:沿文档/文本密集场景继续强化,强调 OCR-free 文档理解
  3. Mini-Monkey:换到轻量化与多尺度裁剪路线,在小参数下继续保持综合能力

这样讲的好处是:

  • 与仓库里的真实代码结构一致
  • 三个工作之间有明确演进关系
  • 不会把 README 里外部项目和后续系列工作混进主汇报正文

4.1 适合直接做 PPT 的页级顺序

下面这个版本按“论文点 -> 代码落点 -> 为什么这样讲”来组织,适合做 8-10 页组会。

页码页面主题这一页讲什么最好引用的代码/证据
第 1 页仓库边界先讲清当前仓库真正有完整实现的只有 Monkey、TextMonkey、Mini-Monkey;MonkeyOCR 只是外链,MonkeyOCRv2 不在仓库里README.md:18-24、README.md:28-33、README.md:41-46、README.md:59-64
第 2 页系列演进主线把三者讲成一条演进链:Monkey 解决高分辨率图像理解,TextMonkey 往文档/OCR-free 理解深化,Mini-Monkey 转向轻量化与多尺度裁剪本文第 3.1、3.2、3.3 节
第 3 页Monkey 的论文点重点讲“高分辨率图像 + 全局上下文不能只靠单尺度缩放解决”,它是系列起点README.md 标题区、monkey_model/modeling_monkey.py:55-76
第 4 页Monkey 的代码落点展示 Monkey 如何从 input_ids 里解析图片,再形成“局部窗口 + 全局 448 图”两路特征并拼接进 Qwenmonkey_model/modeling_monkey.py:55-76
第 5 页TextMonkey 的论文点重点讲 OCR-free 文档理解、窗口交互、重要视觉特征筛选、减少幻觉monkey_model/text_monkey/README.md:21、monkey_model/text_monkey/README.md:83-91
第 6 页TextMonkey 的代码落点讲 config.visual 的关键参数入口,以及 add_window/use_global/resampler/n_queries 如何落实成窗口交互、token 压缩、全局补充finetune_multitask_dialouge_doc.py:338-380、finetune/finetune_textmonkey.sh:48-54、monkey_model/text_monkey/visual_text.py:417-429、monkey_model/text_monkey/visual_text.py:638-643
第 7 页Mini-Monkey 的论文点重点讲 MSAC 与 SCM:为什么 2B 级小模型也能保住细粒度视觉理解project/mini_monkey/README.md:20
第 8 页Mini-Monkey 的代码落点讲动态裁剪、缩略图补充、二次裁剪拼接,以及 use_scm 下的注意力式 token 筛选project/mini_monkey/demo.py:37-73、project/mini_monkey/demo.py:76-116、project/mini_monkey/demo.py:144-148、project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:396-438
第 9 页三者横向对比对比底座、输入处理、压缩方式、文档能力、适合场景;这一页是帮助老师快速记住差异本文第 3.4 节表格
第 10 页结论与边界给出一句话总结,并强调 MonkeyOCR/MonkeyOCRv2 不属于本次代码分析主线本文第 6 节

4.2 如果每页只留一句核心讲稿

为了方便你直接写到 PPT 备注区,下面给每页一个“一句话主讲词”版本。

  1. 第 1 页:这个仓库真正能展开做代码分析的 Monkey 工作只有 3 个,其他 OCR 分支在本仓库里没有实现。
  2. 第 2 页:整个系列的演进方向很清楚,就是从通用高分辨率多模态理解,走向文档强化,再走向轻量化。
  3. 第 3 页:Monkey 的核心问题是大模型不能只看缩小后的整图,否则高分辨率细节会被抹平。
  4. 第 4 页:代码里它把图像拆成局部窗口和全局视图两路特征,再一起送进 Qwen 主干。
  5. 第 5 页:TextMonkey 是把 Monkey 推到文档场景,重点增强窗口交互、特征筛选和定位能力。
  6. 第 6 页:这些增强不是停留在论文描述里,而是被 add_window/use_global/resampler/n_queries 这些参数直接控制。
  7. 第 7 页:Mini-Monkey 走的是另一条路线,不是继续堆模型,而是靠多尺度裁剪和 token 压缩把小模型做强。
  8. 第 8 页:代码里它先动态裁块,再按块数扩展图像 token,并在 use_scm 时按注意力保留更重要的视觉 token。
  9. 第 9 页:三者最大的差别,不只是大小不同,而是视觉信息保留和压缩的方式不同。
  10. 第 10 页:所以本次组会最合理的主线就是 Monkey -> TextMonkey -> Mini-Monkey,OCR 分支只做补充说明。

4.3 如果时间只够讲 6 页

可以压缩成下面这个顺序:

  1. 仓库边界 + 主线工作只有 3 个
  2. Monkey:论文点 + 代码落点
  3. TextMonkey:论文点 + 代码落点
  4. Mini-Monkey:论文点 + 代码落点
  5. 三者对比表
  6. 最终结论 + MonkeyOCR 不展开

这个 6 页版本最适合组会时间紧、但老师又希望“既讲论文也讲代码”的场景。

4.4 可直接贴进 PPT 的每页 bullet 文案

第 1 页:仓库范围与分析对象

  • 当前仓库真正有完整实现的 Monkey 工作只有 3 个:Monkey、TextMonkey、Mini-Monkey
  • MonkeyOCR 在本仓库只有 README 外链,没有仓库内源码
  • MonkeyOCRv2 在当前仓库没有出现,本次不纳入代码分析主线

第 2 页:Monkey 系列的演进逻辑

  • Monkey:通用高分辨率多模态理解起点
  • TextMonkey:沿文档 / 文本密集场景继续强化,强调 OCR-free 理解
  • Mini-Monkey:转向轻量化与多尺度裁剪,在 2B 级规模保持综合能力

第 3 页:Monkey 的论文核心点

  • 目标是提升大模型对高分辨率图像与文本标签的利用能力
  • 关键问题是单尺度整图输入容易丢失局部细节
  • 因此需要同时保留局部细节与全局上下文

第 4 页:Monkey 的代码落点

  • modeling_monkey.py 会先从 input_ids 中解析 <img>...</img> 对应的图片路径
  • 视觉分支把图像编码成两路特征:局部窗口特征 + 448 全局特征
  • 两路特征拼接后再送入 Qwen 主干,实现“局部细节 + 全局语义”的联合建模

第 5 页:TextMonkey 的论文核心点

  • 面向文档、图表、表格、场景文字等文本密集图像
  • 重点增强窗口间信息交互、重要视觉特征筛选和定位能力
  • 目标是做 OCR-free 文档理解,并降低幻觉

第 6 页:TextMonkey 的代码落点

  • 训练入口把 image_size、n_queries、add_window、use_global、resampler 写入 config.visual
  • VisionTransformer(**config.visual) 负责文档视觉建模主链
  • add_window 对应跨窗口交互,resampler 对应视觉 token 压缩,use_global 对应全局视图补充

第 7 页:TextMonkey 的一个关键实现结论

  • n_queries 不只是普通超参数,它直接关联 tokenizer 侧的 IMG_TOKEN_SPAN
  • 开启 resampler 后,局部分支 token 会压缩到 remain
  • 开启 use_global 后,还会额外拼上一段全局视觉 token

第 8 页:Mini-Monkey 的论文核心点

  • 核心关键词是 MSAC 和 SCM
  • 它不是继续放大模型,而是通过更聪明的输入裁剪与 token 压缩提升性能
  • 重点是在轻量参数规模下兼顾通用多模态能力和文档能力

第 9 页:Mini-Monkey 的代码落点

  • dynamic_preprocess(...) 会按长宽比自适应决定裁块网格
  • 第一轮裁剪后还会补缩略图保留全局信息,再做第二轮不同尺度裁剪
  • 最终把不同尺度 patch 拼接后送入 model.chat(...)

第 10 页:Mini-Monkey 的 SCM 落点

  • 模型先根据 num_image_token * num_patches 构造图像 token 序列
  • extract_feature(...) 通过 pixel_shuffle + mlp1 把视觉特征映射到 LLM 空间
  • use_scm=True 时,会根据早期层注意力筛选更重要的图像 token,再继续生成

第 11 页:三者横向对比

  • Monkey:局部窗口 + 全局视图拼接,适合作为系列起点
  • TextMonkey:窗口交互 + token 压缩 + 全局补充,更适合文档和文本密集场景
  • Mini-Monkey:多尺度裁剪 + 注意力式 token 筛选,更强调轻量化与部署友好

第 12 页:最终结论

  • 本仓库最值得展开讲的主线只有 Monkey -> TextMonkey -> Mini-Monkey
  • 三者不是简单大小差别,而是视觉信息保留与压缩策略逐步分化
  • MonkeyOCR 及后续版本只适合做时间线补充,不适合作为本次代码分析主体

可选加一页:视觉特征如何进入 LLM 主干

  • Monkey / TextMonkey:在 Qwen 的 hidden states 中直接用视觉特征覆盖 <img>...</img> 对应区间
  • Mini-Monkey:先扩展 <IMG_CONTEXT> token,再把这些位置的 embedding 替换成视觉特征
  • 三者共同点都是“把视觉写回语言序列”,差异在于写回前如何组织和压缩视觉 token

MonkeyOCR 的最小讲法

推荐只讲一句或一页:

MonkeyOCR 是 Monkey 系列后续在文档解析方向的外部扩展工作,但当前仓库并未内置其源码,这里只作为系列延伸补充,不作为本次代码分析主线。

MonkeyOCRv2 的最小讲法

推荐只讲一句:

MonkeyOCRv2 属于当前仓库展示范围之外的后续进展,本次组会不展开,只在时间线末尾口头补充即可。

5. 最终可直接回答的问题

这仓库里到底有哪些 Monkey 工作?

可作为主线讲的只有 3 个:Monkey、TextMonkey、Mini-Monkey。

代码分别在哪?

  • Monkey:根目录 + monkey_model/
  • TextMonkey:根目录 + monkey_model/text_monkey/
  • Mini-Monkey:project/mini_monkey/

MonkeyOCR 和 MonkeyOCRv2 呢?

  • MonkeyOCR:当前仓库只有 README 外链,没有仓库内实现
  • MonkeyOCRv2:当前仓库没有展示,也没有代码

为什么这三者不同?

  • Monkey:通用多模态基线
  • TextMonkey:文档/文本理解增强
  • Mini-Monkey:轻量化 + 多尺度裁剪路线

6. 一句话版汇报结论

如果组会时间有限,就直接讲:

这个仓库真正值得展开讲的 Monkey 主工作只有 3 个:Monkey 是基础通用多模态版本,TextMonkey 是面向文档和文本密集场景的增强版,Mini-Monkey 是基于 InternVL2-2B 的轻量化多尺度版本;MonkeyOCR 及其后续版本不在本仓库实现范围内,只适合作为时间线补充。

7. 论文-代码对照表附录

这一节适合直接做备份页。建议每张表只讲前两三行,剩下的留作老师追问时展开。

7.1 Monkey 对照表

论文关键点工程化含义代码落点汇报时怎么说
高分辨率图像很重要不能只把整图缩小后再送入模型monkey_model/modeling_monkey.py:65-75Monkey 不是只看一张缩略图,而是保留了局部高分辨率窗口和全局图两路特征
文本相关视觉细节不能丢小字、局部区域、细粒度目标需要单独保留monkey_model/modeling_monkey.py:68-75局部分支负责保细节,全局分支负责补上下文
图像要和文本统一进入主干图像最终要以序列 token 的形式进入 Qwenmonkey_model/modeling_qwen.py:780-813视觉特征最后不是旁路融合,而是直接覆盖到 Qwen 序列中的图像占位区间
系列起点是 Qwen/Qwen-VL 主线Monkey 不是独立新底座,而是在 Qwen-VL 主干上扩展monkey_model/modeling_monkey.py:34-36、monkey_model/modeling_monkey.py:96-145它更像是在 Qwen-VL 上强化高分辨率视觉输入的版本

7.2 TextMonkey 对照表

论文关键点工程化含义代码落点汇报时怎么说
OCR-free 文档理解不先显式跑 OCR,而是直接做端到端视觉-语言建模monkey_model/modeling_textmonkey.py:35-38、demo_textmonkey.py:66-87TextMonkey 直接把文档图像送入模型,让视觉编码器和 Qwen 一起完成理解和生成
窗口间信息交互文档里不同局部区域之间要交换信息monkey_model/text_monkey/visual_text.py:417-429、443-475它不是只做局部切块,而是在若干层插入 cross-window attention 让窗口之间通信
重要视觉特征筛选高分辨率文档 token 太多,需要压缩monkey_model/text_monkey/visual_text.py:547-559、638-640、monkey_model/text_monkey/resampler.py:107-144resampler 负责把最有用的视觉特征保留下来,降低 token 成本
全局上下文补充只看窗口容易丢掉整页结构monkey_model/text_monkey/visual_text.py:631-643TextMonkey 在局部分支之外还拼了一条 448 全局分支
关键视觉策略可调论文增强项对应到显式配置参数,而非写死逻辑finetune_multitask_dialouge_doc.py:338-345、372-380、finetune/finetune_textmonkey.sh:48-54add_window/use_global/resampler/n_queries 就是论文能力在工程里的开关和超参数
图像 token 长度受策略影响token 数量会随压缩策略和全局分支一起变化finetune_multitask_dialouge_doc.py:372-380、demo_textmonkey.py:37、eval/evaluate_vqa_doc.py:499n_queries 不只是 query 数,它还决定 tokenizer 侧为图像预留多长 span
最终仍回到 Qwen 主干文档视觉增强后的结果仍然写回语言序列monkey_model/modeling_qwen.py:811-813TextMonkey 的特殊之处主要在视觉组织方式,不在主干注入机制本身

7.3 Mini-Monkey 对照表

论文关键点工程化含义代码落点汇报时怎么说
轻量化 MLLM不靠继续堆大模型,而是优化输入和 token 使用效率project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:45-87Mini-Monkey 的核心思路是用更聪明的输入组织方式,把 2B 级模型做强
MSAC根据图片长宽比做多尺度自适应裁剪project/mini_monkey/demo.py:22-35、37-73、76-116它会先判断最合适的裁块比例,再做多轮裁剪,而不是固定切法
缩略图保留全局语义多块裁剪之外还要留住整图上下文project/mini_monkey/demo.py:70-72、113-115每轮裁剪都可能补一张 thumbnail,避免模型只看局部不看整体
双阶段拼接不同尺度 patch 要重新组合后再送入模型project/mini_monkey/demo.py:144-148最终输入不是单一尺度 patch,而是两轮裁剪结果拼接后的序列
图像 token 数量由块数驱动patch 数越多,图像上下文 token 越长project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:54-55、282-283、335-336Mini-Monkey 先根据 patch 数决定 <IMG_CONTEXT> 要放多长
视觉特征映射到 LLM 空间ViT 输出不能直接给语言模型,需要重排和投影project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:218-252pixel_shuffle + mlp1 就是在把视觉表示压到适合 LLM 接收的 token 表示
SCM根据早期层注意力筛掉低价值视觉 tokenproject/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:396-438它不是先静态压缩,而是在生成前按注意力保留更重要的图像 token
图像进入主干的方式更显式先造 <IMG_CONTEXT> 占位,再做 embedding 替换project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:152-177、383-390Mini-Monkey 的图像注入机制比 Monkey 主线更容易画成架构图

7.4 数据处理与输入格式对照表

论文关键点工程化含义代码落点汇报时怎么说
统一的图文交错格式图片在文本流中表现为特殊的占位符或标签finetune_multitask_dialouge_doc.py:153-162Monkey / TextMonkey 把图片路径写在 <img>...</img> 之间,完全复用语言模型的 tokenizer 流程
视觉 token 的补齐与占位语言序列要给图片留出足够的 token 位置finetune_multitask_dialouge_doc.py:179-191在 preprocess 阶段,通过将 IMG_TOKEN_SPAN 设置为需要的长度,确保文本输入给视觉特征留了“空槽”
多尺度裁块的特征输入Mini-Monkey 的输入不只是一张图,而是裁块数组project/mini_monkey/demo.py:144-148Mini-Monkey 最终输入的是两轮不同尺度裁剪并拼接起来的 pixel_values,在送入模型时会自动计算出 <IMG_CONTEXT> 的总长
数据流闭环无论预处理怎么做,最后都是特征对齐demo_textmonkey.py:66-87、project/mini_monkey/demo.py:153Monkey 系是在前向传播里查找 <img> 标签覆盖,Mini-Monkey 是查找 <IMG_CONTEXT> 覆盖

7.5 三者最值得老师追问时展开的差异

比较维度MonkeyTextMonkeyMini-Monkey
主要目标高分辨率通用多模态理解文档 / 文本密集场景强化小模型下保住细粒度能力
视觉组织策略局部窗口 + 全局图拼接窗口交互 + resampler + 全局补充多尺度裁剪 + SCM
token 压缩方式主要靠视觉组织改善表示视觉侧先做 resampler 压缩生成前按注意力筛 token
主干注入方式写回 Qwen 图像区间写回 Qwen 图像区间替换 <IMG_CONTEXT> embedding
最适合一句话概括系列起点文档增强版轻量化路线

7.6 这组附录页的使用建议

  • 如果老师先问“论文贡献是什么”,先看 7.1 / 7.2 / 7.3 每张表的前两行
  • 如果老师追问“代码到底落在哪里”,直接指向每行的代码落点列
  • 如果老师问“三篇论文最本质的差别”,直接用 7.5 的横向对比表回答
Back to Blog

Related Posts

View All Posts »