【AI】MiniCPM-V:端侧图像大模型

 

MiniCPM-V2.6:面壁智能端侧图像大模型

  • 标题:MiniCPM-V: A GPT-4V Level MLLMonYourPhone
  • 时间:2024.8.03
  • 作者团队:面壁智能
  • 作者:Yuan Yao, Tianyu Yu, Ao Zhang, Chongyi Wang, Junbo Cui
  • 有用指数:⭐️⭐️⭐️⭐️⭐️
  • 贡献程度:⭐️⭐️⭐️⭐️⭐️
  • 简单评价:
    • 优点:代码完备,基本无缝在自建场景开启训练;可配置化图片占据的token数量,如果场景需要建模视频,可直接配置减少一张图片token数量。
    • 缺点:目前只有和Qwen2对齐的节点,实际训练结果有些许不理想。

Existing Gap

作者认为现在模型参数都太大了,很难在端侧运行起来,于是他们的目标就是做一个小点的,能在quantize之后运行在端上且效果还不错的多模态大模型。

Proposed Solution

虽然目标是小模型,但是MiniCPM这次有在Qwen-2上训练的版本,本身并不算小,所以作者建议用Quantize之后的模型运行在端侧。本文的创新更多还是训练数据上的,其他方法是比较常见的。

目前大家做多模态大模型能够提升性能的常规操作是

  1. 提升训练时的图片分辨率;
  2. 加大训练数据的量;
  3. 调和训练数据的比例和优化训练过程。

MiniCPM的整体架构如下图所示

image-20240905171507066

整体架构

  1. 图像切分(基本上对于高分辨率图片都得有类似步骤,比如LLaVA这里用的切分+pooling):使用adaptive visual encoding(下文会细讲)
  2. Visual encoder:ViT
  3. 模态对齐:一层cross-attention token压缩层对齐文本和视觉模态;
  4. LLM

实现细节

Adaptive Visual Encoding

如何能建模高分辨率图片?切分+合并。理想状态是,合理切分图片以对齐ViT预训练的分辨率。

for image in _images:
  # 图片切分,默认配置最多切成9块
  image_patches = self.get_sliced_images(image, max_slice_nums)
  # 对patches进行normalization
  image_patches = [to_numpy_array(image).astype(np.float32) / 255 for image in image_patches]
  # standardization
  image_patches = [
      self.normalize(image=image, mean=self.mean, std=self.std, input_data_format=input_data_format)
          for image in image_patches
  ]
  # HWC转化成CHW,图像channel在前
  image_patches = [
      to_channel_dimension_format(image, ChannelDimension.FIRST, input_channel_dim=input_data_format) 
          for image in image_patches
  ]
  # 合并成新的图像数组
  for slice_image in image_patches:
    # 每一张图都变成了多个小patches
      new_images.append(self.reshape_by_patch(slice_image))
      tgt_sizes.append(np.array((slice_image.shape[1] // self.patch_size, slice_image.shape[2] // self.patch_size)))

Compression layer

上面这种做法有个明显的坏处就是,如果是多图输入,明显这个输入被放大了很多,如果直接把原始结果给到LLM,那么能装下的图片数量肯定很少。所以作者在这里加了一个compression layer,主要目的就是压缩直接产出的token数量。(他们源码还没更新到最新的模型,所以如果看源码到Huggingface上面看)。这个compression layer就是一个单层的cross attention layer,一般来说Resampler架构的架构,cross attention模块都是更新learnable Query。MiniCPM-V2.6在Qwen2 LM上默认对齐的Query embedding的size是64,就是一组slice(单张图)占用64个tokens。

训练过程

Training Stage 目的 Trainable modules Data
Pretraining 1 warmup compression layer
224x224分辨率
Compression layer only 200M Image captioning
  2 extend the resolution of pretrained vision encoder vision encoder(SigLIP-SoViT-400m/14) Another 200M image captioning
  3 further adapt to high resolution with adaptive strategy compression layer + vision encoder OCR + image captioning
SFT 1 downstream tasks vision encoder + compression layer + LLM 只用Human label过和GPT-4生成的数据做训练
DPO - RLAIF 1 reduce hallucination 原文没写,但大部分的DPO主要训练的是LM和fusion模块 6k preference pairs

这里唯一的问题就是DPO阶段训练的参数没写,不知道训练了什么。常见的是训练LLM和模态Fusion模块(Compression layer),但这个确实没写。如果有知道的麻烦留个言。

DPO RLAIF就用SFT之后的Base Model,在High temperature下生成10个回复,然后先用LLaMA 3给回复划分claims,再针对这些claims中的每一个用LLaVA-next Yi-34B给这些claims打分,从而获得有打分分数的回复。训练的时候,会针对这10个回复sample出来一些pair,用这些pair的相对分数来决定reject和accept的数据集。

Results

部分Benchmark上在8B的size上能够实现这个大小下SOTA的结果,对于有需要压缩图片占用tokens数量的应用有比较高的应用价值。

image-20240910190555121

Conclusion

总结来看面壁智能的这个release还是非常有诚意的,SFT的代码比较完善,基本上改改数据就能在应用场景里直接用上;其次由于他有这个compression的模块,对于图片压缩能力还是提升比较明显的。有需要多帧输入的也完全可以直接用上。注意这个MiniCPM-V2.6的代码要直接在Huggingface上看,开源的代码库还没更新到这个模型的代码。