· 组会汇报 · 40 min read
Monkey 系列仓库分析结论
本文总结了 Monkey 系列仓库(Monkey、TextMonkey、Mini-Monkey)的技术演进、代码定位与核心差异,提供了详尽的论文与代码对照。
1. 仓库中的真实工作边界
结论:当前仓库里真正有成体系实现的 Monkey 系列工作,主要是 3 个:
MonkeyTextMonkeyMini-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.py | MonkeyModel / MonkeyLMHeadModel |
| 视觉策略证据 | monkey_model/modeling_monkey.py:55-76 | 读取图像后同时构建局部窗口特征和 images_448 全局特征,再拼接为视觉输入 |
| 训练主程序 | finetune_multitask.py | 加载 MonkeyLMHeadModel 训练 |
| 训练脚本 | finetune/finetune_ds_debug.sh | 默认底座是 Qwen/Qwen-VL |
| 推理入口 | inference.py | README 中明确给出命令行推理方式 |
| Demo | demo.py | Gradio Demo |
| 评测主程序 | eval/evaluate_vqa.py | 14 个 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.py | TextMonkeyModel / 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 |
| Demo | demo_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.py | MiniMonkeyChatModel |
| 训练主程序 | 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.py | README 也把它作为 inference 示例 |
| Demo | project/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-39visual_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-77demo.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 三者对比表
| 维度 | Monkey | TextMonkey | Mini-Monkey |
|---|---|---|---|
| 仓库位置 | 根目录主线 | 根目录主线 + monkey_model/text_monkey | project/mini_monkey 独立子项目 |
| 核心定位 | 通用多模态理解基线 | OCR-free 文档/文本理解强化 | 轻量化多模态模型 |
| 主底座 | Qwen / Qwen-VL 体系 | Qwen / Qwen-VL 体系 | InternVL2-2B 主线 |
| 主要视觉策略 | 局部窗口 + 全局特征拼接 | 高分辨率窗口交互、特征筛选、位置信息 | 多尺度自适应裁剪 + token 压缩 |
| 输入处理特点 | 高分辨率图像与文本标签 | 更偏文本密集图像、文档和定位 | 动态裁剪、多 patch、缩略图辅助 |
| 文档能力 | 有,但不是唯一重心 | 是核心重心 | 兼顾,且在小模型下表现强 |
| 参数 / 规模叙事 | 作为系列早期主线 | 在 Monkey 基础上增强文本能力 | 2B 级轻量路线 |
| 典型入口 | inference.py / demo.py | demo_textmonkey.py / evaluate_vqa_doc.py | project/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_448monkey_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-345config.visual["image_size"] = (training_args.image_height, training_args.image_width)config.visual["n_queries"] = training_args.n_queriesconfig.visual["add_window"] = training_args.add_windowconfig.visual["use_global"] = training_args.use_globalconfig.visual["resampler"] = training_args.resamplerconfig.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],在若干层插入CrossWindowAttentionmonkey_model/text_monkey/visual_text.py:443-475在 Transformer forward 中重建整图、做跨窗口注意力、再切回窗口
- “重要视觉特征筛选 / token 压缩”
monkey_model/text_monkey/visual_text.py:547-559构建Resampler与可选PerceiverResamplermonkey_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 对论文里“高分辨率文档 + 窗口交互 + 重要特征筛选 + 全局上下文”的落地方式,可以概括成:
- 先按窗口保留高分辨率局部文本
- 在部分层引入跨窗口注意力,让不同窗口交换信息
- 用 resampler / perceiver resampler 压缩高成本视觉 token
- 再拼一条 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决定单路视觉特征映射到语言序列时预留多少 tokenresampler会把局部高分辨率分支压到remainuse_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 448block,并在需要时补一个 thumbnailproject/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”在实现层面并不是一句口号,而是:
- 先根据原图长宽比选裁块网格
- 生成多块局部 patch
- 追加缩略图保留全局语义
- 再做第二轮不同尺度裁剪并重新拼接
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_tokenproject/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 分支再慢慢融合”,而是:
- 先保留文本序列框架不变
- 再找到
<img>...</img>在序列中的占位区间 - 用视觉编码结果直接覆盖这一段隐藏状态
- 后续所有 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-390generate 阶段同样重复这一替换过程,保证推理时图像 token 真正进入 LLM
因此从架构视角看,Mini-Monkey 的关键不是“视觉塔和 LLM 并列”,而是:
- 先把图像块数转成 prompt 里明确可数的图像上下文 token
- 再把这些 token 的 embedding 全部替换成视觉特征
- 若开启
SCM,则在生成前再根据早期注意力结果缩减图像 token
如果把三者放在同一张架构图里,最容易讲清的差异其实是:
Monkey:局部 + 全局视觉特征先拼好,再注入 Qwen 序列TextMonkey:窗口交互与 resampler 先把视觉表示整理好,再注入 Qwen 序列Mini-Monkey:多尺度裁块先决定 token 数,再把视觉 embedding 替换进<IMG_CONTEXT>序列
也就是说,三者的共同点是“都把视觉信息写回语言序列”,差异在于写回之前如何组织、筛选和压缩视觉 token。
4. 组会汇报的收敛建议
建议主线直接讲成:
Monkey:系列起点,解决“大模型如何更好看高分辨率图像和文本”TextMonkey:沿文档/文本密集场景继续强化,强调 OCR-free 文档理解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 图”两路特征并拼接进 Qwen | monkey_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 页:这个仓库真正能展开做代码分析的 Monkey 工作只有 3 个,其他 OCR 分支在本仓库里没有实现。
- 第 2 页:整个系列的演进方向很清楚,就是从通用高分辨率多模态理解,走向文档强化,再走向轻量化。
- 第 3 页:Monkey 的核心问题是大模型不能只看缩小后的整图,否则高分辨率细节会被抹平。
- 第 4 页:代码里它把图像拆成局部窗口和全局视图两路特征,再一起送进 Qwen 主干。
- 第 5 页:TextMonkey 是把 Monkey 推到文档场景,重点增强窗口交互、特征筛选和定位能力。
- 第 6 页:这些增强不是停留在论文描述里,而是被
add_window/use_global/resampler/n_queries这些参数直接控制。 - 第 7 页:Mini-Monkey 走的是另一条路线,不是继续堆模型,而是靠多尺度裁剪和 token 压缩把小模型做强。
- 第 8 页:代码里它先动态裁块,再按块数扩展图像 token,并在
use_scm时按注意力保留更重要的视觉 token。 - 第 9 页:三者最大的差别,不只是大小不同,而是视觉信息保留和压缩的方式不同。
- 第 10 页:所以本次组会最合理的主线就是
Monkey -> TextMonkey -> Mini-Monkey,OCR 分支只做补充说明。
4.3 如果时间只够讲 6 页
可以压缩成下面这个顺序:
- 仓库边界 + 主线工作只有 3 个
Monkey:论文点 + 代码落点TextMonkey:论文点 + 代码落点Mini-Monkey:论文点 + 代码落点- 三者对比表
- 最终结论 +
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-75 | Monkey 不是只看一张缩略图,而是保留了局部高分辨率窗口和全局图两路特征 |
| 文本相关视觉细节不能丢 | 小字、局部区域、细粒度目标需要单独保留 | monkey_model/modeling_monkey.py:68-75 | 局部分支负责保细节,全局分支负责补上下文 |
| 图像要和文本统一进入主干 | 图像最终要以序列 token 的形式进入 Qwen | monkey_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-87 | TextMonkey 直接把文档图像送入模型,让视觉编码器和 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-144 | resampler 负责把最有用的视觉特征保留下来,降低 token 成本 |
| 全局上下文补充 | 只看窗口容易丢掉整页结构 | monkey_model/text_monkey/visual_text.py:631-643 | TextMonkey 在局部分支之外还拼了一条 448 全局分支 |
| 关键视觉策略可调 | 论文增强项对应到显式配置参数,而非写死逻辑 | finetune_multitask_dialouge_doc.py:338-345、372-380、finetune/finetune_textmonkey.sh:48-54 | add_window/use_global/resampler/n_queries 就是论文能力在工程里的开关和超参数 |
| 图像 token 长度受策略影响 | token 数量会随压缩策略和全局分支一起变化 | finetune_multitask_dialouge_doc.py:372-380、demo_textmonkey.py:37、eval/evaluate_vqa_doc.py:499 | n_queries 不只是 query 数,它还决定 tokenizer 侧为图像预留多长 span |
| 最终仍回到 Qwen 主干 | 文档视觉增强后的结果仍然写回语言序列 | monkey_model/modeling_qwen.py:811-813 | TextMonkey 的特殊之处主要在视觉组织方式,不在主干注入机制本身 |
7.3 Mini-Monkey 对照表
| 论文关键点 | 工程化含义 | 代码落点 | 汇报时怎么说 |
|---|---|---|---|
| 轻量化 MLLM | 不靠继续堆大模型,而是优化输入和 token 使用效率 | project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:45-87 | Mini-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-336 | Mini-Monkey 先根据 patch 数决定 <IMG_CONTEXT> 要放多长 |
| 视觉特征映射到 LLM 空间 | ViT 输出不能直接给语言模型,需要重排和投影 | project/mini_monkey/internvl/model/internvl_chat/modeling_minimonkey_chat.py:218-252 | pixel_shuffle + mlp1 就是在把视觉表示压到适合 LLM 接收的 token 表示 |
| SCM | 根据早期层注意力筛掉低价值视觉 token | project/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-390 | Mini-Monkey 的图像注入机制比 Monkey 主线更容易画成架构图 |
7.4 数据处理与输入格式对照表
| 论文关键点 | 工程化含义 | 代码落点 | 汇报时怎么说 |
|---|---|---|---|
| 统一的图文交错格式 | 图片在文本流中表现为特殊的占位符或标签 | finetune_multitask_dialouge_doc.py:153-162 | Monkey / 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-148 | Mini-Monkey 最终输入的是两轮不同尺度裁剪并拼接起来的 pixel_values,在送入模型时会自动计算出 <IMG_CONTEXT> 的总长 |
| 数据流闭环 | 无论预处理怎么做,最后都是特征对齐 | demo_textmonkey.py:66-87、project/mini_monkey/demo.py:153 | Monkey 系是在前向传播里查找 <img> 标签覆盖,Mini-Monkey 是查找 <IMG_CONTEXT> 覆盖 |
7.5 三者最值得老师追问时展开的差异
| 比较维度 | Monkey | TextMonkey | Mini-Monkey |
|---|---|---|---|
| 主要目标 | 高分辨率通用多模态理解 | 文档 / 文本密集场景强化 | 小模型下保住细粒度能力 |
| 视觉组织策略 | 局部窗口 + 全局图拼接 | 窗口交互 + resampler + 全局补充 | 多尺度裁剪 + SCM |
| token 压缩方式 | 主要靠视觉组织改善表示 | 视觉侧先做 resampler 压缩 | 生成前按注意力筛 token |
| 主干注入方式 | 写回 Qwen 图像区间 | 写回 Qwen 图像区间 | 替换 <IMG_CONTEXT> embedding |
| 最适合一句话概括 | 系列起点 | 文档增强版 | 轻量化路线 |
7.6 这组附录页的使用建议
- 如果老师先问“论文贡献是什么”,先看 7.1 / 7.2 / 7.3 每张表的前两行
- 如果老师追问“代码到底落在哪里”,直接指向每行的代码落点列
- 如果老师问“三篇论文最本质的差别”,直接用 7.5 的横向对比表回答
