ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

InternVL2-4B动态分辨率深度揭秘:动态切图、缩略图与Pixel Shuffle原理代码级解析

InternVL2-4B动态分辨率深度揭秘:动态切图、缩略图与Pixel Shuffle原理代码级解析 InternVL2-4B动态分辨率深度揭秘动态切图、缩略图与Pixel Shuffle原理代码级解析【免费下载链接】InternVL2-4B项目地址: https://ai.gitcode.com/hf_mirrors/OpenGVLab/InternVL2-4BInternVL2-4B 是 OpenGVLab 开源的视觉语言多模态大模型它的最大亮点之一就是动态分辨率机制无论输入是 1000×747 的横图、手机竖拍照片还是超长截图模型都会通过动态切图把大图切成若干 448×448 的图块、缩略图追加一张全局小图和Pixel Shuffle特征压缩三步流水线把图像信息恰到好处地喂给语言模型。本文从代码层面拆解这套机制的完整原理帮助你彻底理解 InternVL2-4B 是如何看清任意尺寸图片的。为什么需要动态分辨率传统做法的痛点传统视觉模型如 CLIP会把图片强制缩放成固定尺寸如 224×224带来两个问题小图被放大细节被插值模糊大图被压缩一张 4000px 宽的高清图被压到 224px文字、小目标全部丢失。InternVL2-4B 的答案是不再固定一张图 一个向量而是让每张图按自身比例切成 1~12 个 448×448 的图块tile每个图块独立过视觉编码器视觉 token 数量随之动态变化。相关配置就在 config.json 中配置项值含义force_image_size448每个图块的边长像素max_dynamic_patch12单张图最多切 12 块min_dynamic_patch1单张图最少 1 块不放大use_thumbnailtrue切多块时追加一张全局缩略图downsample_ratio0.5Pixel Shuffle 压缩比例ps_versionv2Pixel Shuffle 修正版select_layer-1取视觉编码器最后一层特征 448 这个数字不是凭空来的视觉编码器的 patch 尺寸为 14config.json中patch_size: 14448 ÷ 14 32恰好是整除关系。动态切图dynamic_preprocess 如何决定切几块切图逻辑核心函数dynamic_preprocess位于 README.md 第 239~275 行算法分三步枚举候选比例遍历所有(i, j)组合满足i × j ≤ max_num12比如 1×1、2×2、3×4 等得到一张比例候选表找最接近的宽高比辅助函数find_closest_aspect_ratioREADME.md 第 205~237 行计算原图宽高比与每个候选的差值选出最贴近的一个缩放到目标尺寸并逐块裁剪把图片 resize 成448×i × 448×j再按 448 为步长切成i×j张小图。以本文配图examples/image1.jpg1000×747宽高比 ≈ 1.34为例最接近的候选比例是 4:31.333即4 列 × 3 行 12 块因为切了多块还会追加一张 448×448 的缩略图最终这张图进入模型的视觉输入是13 张 448×448 的小图。不同图片的切块数完全不同正方形照片 1 块、超长截图 12 块、A4 竖版文档可能 6 块。这就是动态二字的由来——token 预算随图片复杂度自适应。缩略图use_thumbnail 给模型一张全景图切块带来的副作用是模型看每个块时丢失了全局位置感——不知道这块在整张图的哪里、整体是什么布局。InternVL2-4B 的解法很巧妙README.md 第 272~274 行只要切出的块数大于 1就把原图整体 resize 成一张 448×448 缩略图追加在切块列表末尾。于是12 个图块负责细节文字、小物体1 张缩略图负责全局整体构图、物体相对位置。这相当于让人先远观、再近察。这也是为什么 README 示例中num_patches_list每个样本的图块总数是切图结果的自然统计而不是人为设定。Pixel Shuffle视觉特征如何压缩 4 倍448×448 的图块经视觉编码器后会产生 32×32 1024 个视觉 token直接送入语言模型成本太高。InternVL2-4B 用Pixel Shuffle把空间分辨率降一半、特征维度升 4 倍token 数从 1024 压缩到256再经 MLP 投射到 64 个。核心实现在 modeling_internvl_chat.py 第 169~183 行的pixel_shuffle方法三步纯张量变形无参数、零计算量损失N, W, H, C → N, H×s, W, C/s → N, H×s, W×s, C/s²s即downsample_ratio0.5把相邻的 2×2 特征拼在一起空间尺寸缩小 4 倍通道数扩大 4 倍。值得一提的是ps_version从v1升级到v2修正了一个高宽未还原导致的特征图转置 bug第 178~182 行本模型默认使用v2。紧接着的extract_feature方法第 185~203 行完成整条特征链路视觉编码器输出last_hidden_stateselect_layer: -1时vit_embeds[:, 1:, :]剔除 CLS tokenreshape 成h×w网格后做 Pixel Shuffle 压缩送入mlp1第 79~84 行LayerNorm Linear GELU Linear投影到语言模型的隐藏维度。每个图块最终贡献的 token 数由第 53 行的公式决定num_image_token (448 // 14)² × (0.5)² 32² × 0.25 256再经 mlp1 与 4:1 的空间合并每个图块对应64 个视觉 token。前文 13 张图12 块 1 缩略图合计832 个视觉 token——这就是动态 token 长度。视觉 Token 如何注入语言模型图片特征如何替换进文本序列看 modeling_internvl_chat.py 的chat方法第 284~286 行用户问题里的占位符image会被展开成imgIMG_CONTEXT× (64 × 图块数) /img生成阶段generate方法第 333~335 行找到所有IMG_CONTEXT的位置把词嵌入原地替换为视觉特征向量之后语言模型就像处理普通文字一样对这串视觉 token做自注意力推理。配合 conversation.py 中的对话模板与 modeling_intern_vit.py 中的 InternViT 视觉编码器整条图像 → 切块 → 特征 → 语言链路闭环完成。实战速览三行代码启用动态分辨率完整示例见 README.md 第 277~300 行核心流程pixel_values load_image(./examples/image1.jpg, max_num12) num_patches_list [pixel_values.size(0)] # 本例为 1312 块 缩略图 response model.chat(tokenizer, pixel_values, question, generation_config, num_patches_listnum_patches_list)几个实用要点max_num控制切块上限显存紧张时调小如 6显存充裕时调到 12 可获得更高分辨率理解多张图同时输入时num_patches_list记录每张图片各自的图块数模型会逐一展开对应的IMG_CONTEXT视频场景README.md 第 389~409 行按帧取 8 段每帧限 1 块max_num1以平衡时长与 token 预算。总结InternVL2-4B 动态分辨率的三件套动态切图dynamic_preprocess按宽高比把图片切成 1~12 个 448×448 图块token 数自适应小图不放大、大图不压缩缩略图use_thumbnail多块时追加一张 448×448 全局小图补齐位置与构图信息Pixel Shufflepixel_shufflemlp1零参数地把 1024 个视觉特征压缩成 256 个最终每块输出 64 个视觉 token 注入语言模型。这套设计让 InternVL2-4B 在 4B 参数规模下同时兼顾了高分辨率细节理解与推理成本可控是中小参数多模态模型中动态分辨率方案的教科书级实现。想动手体验可参考 README.md 中的完整示例如需克隆仓库源码仓库地址为 https://gitcode.com/hf_mirrors/OpenGVLab/InternVL2-4B 。【免费下载链接】InternVL2-4B项目地址: https://ai.gitcode.com/hf_mirrors/OpenGVLab/InternVL2-4B创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表