端侧多模态 | HuggingFace端侧家族新成员解读&实战

大模型向量数据库机器学习
  • 引言
  • 简介
  • 架构
  • 训练
  • 性能
  • 实战
  • 总结
引言

近年来,多模态领域发展迅猛,涌现出一大批大型视觉语言模型。从最初一味追求计算规模的扩张,到利用大模型生成合成数据以扩展数据多样性,再到近期愈发注重提升模型效率,技术趋势不断演进。如今,小型开源模型的崛起,展现了其独特的优势:它们可以轻松部署到浏览器或边缘设备,显著降低推理成本,同时支持用户自定义,满足更多实际应用场景的需求。典型代表包括 PaliGemma 3B、moondream2 和 Qwen2VL 等。

picture.image

简介

SmolVLM是HuggingFace推出的一款精巧型视觉语言模型(VLM)。该模型仅有2B参数,以高效内存占用著称。模型完全开源,包括模型权重、数据集和训练方案。

Q1: 这篇文章想要解决什么问题?

A1: 旨在解决现有大型视觉语言模型计算资源需求高、部署成本大的问题,探索如何构建高效且轻量级的多模态模型。

Q2: 这篇文章如何解决这些问题?

A2: 通过创新的架构设计和优化策略:

  • 使用SmolLM2 1.7B作为语言模型基座
  • 采用9倍像素重排压缩策略
  • 优化图像处理块大小(384×384)
  • 改进视觉主干网络(SigLIP)

Q3: 文章所提出方法的效果如何?

A3: 在资源效率方面表现优异:

  • 内存占用最优,单图仅需编码1.2k个token
  • 与Qwen2-VL相比,预填充吞吐量提升3.3-4.5倍
  • 生成吞吐量提升7.5-16倍
  • 在多个视觉语言基准测试中达到可竞争水平

Q4: 文章所提方法还有哪些不足?

A4: 主要局限性包括:

  • 中文能力相对较弱
  • 时序理解能力有限
  • 在某些专业领域任务(如DocVQA)的表现随训练进行会出现性能下降
架构

SmolVLM的架构与Idefics3(https://arxiv.org/abs/2408.12637)非常接近,使用了相同的transformers实现。主要区别在于:

  • 语言模型上将Llama 3.1 8B替换为SmolLM2 1.7B
  • 使用像素重排策略将图像信息压缩9倍,而Idefics3仅压缩4倍
  • 使用384×384的图像块(而非364×364),因为384可被3整除,这对像素重排策略至关重要
  • 视觉主干网络改用针对像素大小为384×384和patch大小为14×14进行形状优化的SigLIP

picture.image

训练

数据集

首先需要训练SmolLM2以扩展其上下文长度,这将在下一小节讨论。获得长上下文的SmolLM2后,使用与Idefics3相同的数据训练SmolVLM,主要包括The Cauldron和Docmatix数据集。

picture.image

完整的数据集列表可在相关文档中查阅:https://huggingface.co/HuggingFaceTB/SmolVLM-Instruct/blob/main/smolvlm-data.pdf

拓展上下文长度

SmolLM2的预训练上下文窗口(8k)对VLM来说不够。由于图像被编码为大量token,且需要支持多图像输入,因此将其扩展到16k个token。这是通过将RoPE基值从10k提高到273k实现的,遵循了"Scaling Laws of RoPE-based Extrapolation(https://arxiv.org/abs/2310.05209)"中的指导原则。在长上下文和短上下文数据集的混合上对模型进行了微调:

  • 长上下文数据集(各占20%):

    • Dolma的"books"子集(主要来自Gutenberg项目)
    • Stack中超过8k个token的代码文档
  • 短上下文数据集(各占20%):

    • FineWeb-Edu
    • DCLM
    • 数学数据集(即将发布)

picture.image

提高数学数据集的采样率是为了缓解在上下文扩展过程中观察到的GSM8k性能下降。所有实验都使用EasyContext代码库(https://github.com/jzhang38/EasyContext)实现。

检查点选择

在训练过程中,每25个优化步骤保存一次检查点,这使得可以在训练的不同阶段评估和恢复模型状态。这一做法对识别最优模型版本至关重要,因为更长时间的训练并不总能保证更好的性能。

使用多个视觉语言基准评估性能,根据重要性为每个基准赋予权重。核心基准包括:

  • 通用多模态理解(MMMU和MMStar),这是最全面的基准测试
  • 文档和基于文本的视觉问答(DocVQA和TextVQA)
  • 数学推理(MathVista)
  • 图表理解(AI2D)

为选择最优检查点,将这些基准测试结合不同的手动分配权重,创建单一度量标准来评估模型能力。通常,随着训练的进行,模型在大多数基准上表现良好,但在DocVQA上的相对性能会显著下降。

性能

基准测试

基准测试结果涵盖了训练细节中提到的各项任务。

picture.image

内存使用

在transformers框架上现有的视觉语言模型中,SmolVLM展现出最佳的内存使用效率,这使其能够在笔记本电脑等设备上高效运行。测试显示了各个模型在处理一张或两张输入图像时的GPU内存使用量(GB),所有测试使用相同的图像和文本提示。SmolVLM的图像编码效率是模型本身的固有特性。SmolVLM将每个384×384的图像块编码为81个token。这导致SmolVLM在编码测试提示和单张图像时仅使用1.2k个token,而Qwen2-VL则需要16k个token。这也解释了为什么在处理两张图像时,Qwen和InternVL的内存消耗增长如此显著,而采用类似方法的SmolVLM和PaliGemma的增长则相对温和。

picture.image

吞吐量

SmolVLM的内存占用少意味着它在预填充(prefill阶段)和生成时需要的计算量大大减少。与Qwen2-VL相比,预填充吞吐量提高了3.3到4.5倍,生成吞吐量提高了7.5到16倍。picture.image

视频处理

考虑到SmolVLM的长上下文能力和内部帧大小可调整的功能,在计算资源有限的情况下,它可以作为基础视频分析任务的选择。

在评估SmolVLM的视频理解能力时,实现了一个直接的视频处理pipeline代码,从每个视频中最多均匀采样50帧,同时避免内部帧大小调整。这种简单方法在CinePile基准测试中取得了27.14%的竞争性成绩,性能介于InterVL2(2B)和Video LlaVa(7B)之间。

基于给定视频进行问答示例:


        
        
            

          Question: what is shown 
          
 in
 
           the close-up? 
          
   

 
          Assistant: In the close-up, there are bottles of Heinz tomato ketchup,
          
   

 
            honey, soy sauce, and garlic on a kitchen counter.
          
   

 
          
   

 
          Question: describe what is happening 
          
 in
 
           the video. 
          
   

 
          Assistant: The video shows a man cooking 
          
 in
 
           a kitchen.
          
   

 
            He is wearing a black shirt and a black apron.
          
   

 
            He is standing 
          
 in
 
           front of a counter and is holding a bottle of Heinz tomato ketchup,
          
   

 
            a bottle of honey, soy sauce, and a bowl of minced garlic
          
   

 
          
   

 
        
      

定量结果与定性测试相符。尽管在第二个问题中显示出一些时序理解的局限性(厨师是依次指向各种配料,而不是同时指向/持有所有配料),但SmolVLM展现出出色的场景理解和物体识别能力。

实战

VLMEvalKit集成

SmolVLM已与 VLMEvalKit 集成,便于在其他基准测试上进行评估。通过运行相应命令,可以评估SmolVLM或经过微调的SmolVLM模型。


        
        
            

          python3 run.py --data <benchmarks> --model SmolVLM --work-dir <output\_directory>
          
   

 
        
      

例如,可以在MMMU开发验证集和MathVista mini上进行评估,并将结果存储在名为smol的文件夹中。


        
        
            

          python3 run.py --data MMMU\_DEV\_VAL MathVista\_MINI --model SmolVLM --work-dir smol
          
   

 
        
      

SmolVLM模型inference

可以使用transformers中的Auto类快速加载SmolVLM。在底层,模型和处理器映射到与Idefics3相同的实现。


        
        
            

          from transformers import AutoProcessor, AutoModelForVision2Seq
          
   

 
          import torch
          
   

 
          DEVICE = 
          
 "cuda"
 
           
          
 if
 
           torch.cuda.is\_available() 
          
 else
 
           
          
 "cpu"
 
          
   

 
          
   

 
          processor = AutoProcessor.from\_pretrained(
          
 "HuggingFaceTB/SmolVLM-Instruct"
 
          )
          
   

 
          model = AutoModelForVision2Seq.from\_pretrained(
          
 "HuggingFaceTB/SmolVLM-Instruct"
 
          ,
          
   

 
                                                          torch\_dtype=torch.bfloat16,
          
   

 
                                                          \_attn\_implementation=
          
 "flash\_attention\_2"
 
           
          
 if
 
           DEVICE == 
          
 "cuda"
 
           
          
 else
 
           
          
 "eager"
 
          ).to(DEVICE)
          
   

 
        
      

图像和文本可以任意交错,且可以传入多个图像。可以使用chat template并将格式化的输入传递给处理器,然后使用预处理的输入开始生成并解码生成的输出。


        
        
            

          from PIL import Image
          
   

 
          from transformers.image\_utils import load\_image
          
   

 
          
   

 
          
   

 
          
 # Load images
 
          
   

 
          image1 = load\_image(
          
 "https://huggingface.co/spaces/HuggingFaceTB/SmolVLM/resolve/main/example\_images/rococo.jpg"
 
          )
          
   

 
          image2 = load\_image(
          
 "https://huggingface.co/spaces/HuggingFaceTB/SmolVLM/blob/main/example\_images/rococo\_1.jpg"
 
          )
          
   

 
          
   

 
          
 # Create input messages
 
          
   

 
          messages = [
          
   

 
              {
          
   

 
                  
          
 "role"
 
          : 
          
 "user"
 
          ,
          
   

 
                  
          
 "content"
 
          : [
          
   

 
                      {
          
 "type"
 
          : 
          
 "image"
 
          },
          
   

 
                      {
          
 "type"
 
          : 
          
 "image"
 
          },
          
   

 
                      {
          
 "type"
 
          : 
          
 "text"
 
          , 
          
 "text"
 
          : 
          
 "Can you describe the two images?"
 
          }
          
   

 
                  ]
          
   

 
              },
          
   

 
          ]
          
   

 
          
   

 
          
 # Prepare inputs
 
          
   

 
          prompt = processor.apply\_chat\_template(messages, add\_generation\_prompt=True)
          
   

 
          inputs = processor(text=prompt, images=[image1, image2], return\_tensors=
          
 "pt"
 
          )
          
   

 
          inputs = inputs.to(DEVICE)
          
   

 
          
   

 
          
 # Generate outputs
 
          
   

 
          generated\_ids = model.generate(**inputs, max\_new\_tokens=500)
          
   

 
          generated\_texts = processor.batch\_decode(
          
   

 
              generated\_ids,
          
   

 
              skip\_special\_tokens=True,
          
   

 
          )
          
   

 
          
   

 
          
 print
 
          (generated\_texts[0])
          
   

 
        
      

微调

使用transformers库对SmolVLM进行微调,并使用TRL应用对齐技术。官方还提供了在VQAv2数据集上进行微调的notebook:https://github.com/huggingface/smollm/blob/main/finetuning/Smol\_VLM\_FT.ipynb, 可选择使用LoRA、QLoRA或完全微调。在notebook中可以找到一些节省内存和增加批量大小的技巧,使SmolVLM能够在消费级GPU(如L4)上训练。为了在L4上实现微调,可以设置batch size=4、8-bit加载QLoRA和梯度检查点。此时的内存消耗约16GB VRAM。这意味着可以在Colab上微调SmolVLM!可以调整参数以在训练时长和内存使用之间取得平衡。

SmolVLM还集成了TRL,可以通过命令行界面轻松应用直接偏好优化(DPO)。安装必要包后,可以在 RLAIF-V数据集 上进行微调。


        
        
            

          accelerate launch \
          
   

 
            --config\_file examples/accelerate\_configs/multi\_gpu.yaml examples/scripts/dpo\_vlm.py  \
          
   

 
            --dataset\_name HuggingFaceH4/rlaif-v\_formatted \
          
   

 
            --model\_name\_or\_path HuggingFaceTB/SmolVLM-Instruct \
          
   

 
            --per\_device\_train\_batch\_size 8 \
          
   

 
            --gradient\_accumulation\_steps 32 \
          
   

 
            --dataset\_num\_proc 32 \
          
   

 
            --output\_dir dpo\_smolvlm\_rlaif-v \
          
   

 
            --bf16 --torch\_dtype bfloat16 \
          
   

 
            --use\_peft --lora\_target\_modules=all-linear
          
   

 
        
      

生成的LoRA适配器权重即为 SmolVLM-Instruct-DPO 。 关于基于视觉LLM的调优教程可以参考这里: dpo_vlm 。

效果实测

英文:识物

picture.image

picture.image

英文:表格理解

picture.image

在表格问答任务上,直接翻车~

中文:识物

picture.image

可以看出,并不支持中文。

总结

SmolVLM是一款开源的视觉语言多模态模型,以其小巧而不失强大的特点引人注目。目前,该模型在英文性能上处于中等水平,而在中文表现上仍有较大提升空间。尽管如此,其完全开源的特性——包括数据集和训练代码的透明公开,加之在计算效率和资源占用上的显著优势,使其在当前多模态模型赛道中依然保持一定的竞争力。对于追求轻量级、高性价比模型的开发者而言,SmolVLM无疑是一个值得关注的选择。对于有志于提升其中文能力的研究者,在中文语料上进行针对性微调可能是一个极具潜力的方向。

0
0
0
0
相关资源
边缘计算在视频直播场景的应用与实践
视频直播作为当前视频行业的核心场景之一,对于高清化、实时性、交互性要求较高,需要强大算力保障用户流畅观看与互动体验。本次分享主要从视频直播场景需求切入,介绍基于边缘计算的视频直播场景方案及其架构、应用与实践。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论