跳到正文
北京时间
原文
Hugging Face:Blog·· 2025-05-21精选AI 评分71

Hugging Face 发布 nanoVLM:用纯 PyTorch 训练视觉语言模型的最简仓库

nanoVLM: The simplest repository to train your VLM in pure PyTorch

AI 导读

Hugging Face 团队发布 nanoVLM,一个用纯 PyTorch 训练视觉语言模型的极简工具仓库,可在免费版 Colab 上启动训练。

推荐理由

官方团队介绍 nanoVLM 的架构与训练流程,读者可以据此理解 VLM 的多模态对齐原理并低成本动手训练。

正文 · AI 翻译

Image 1: Hugging Face's logoHugging Face


返回文章

nanoVLM:用纯 PyTorch 训练你的 VLM 的最简仓库

发布于 2025 年 5 月 21 日

在 GitHub 上更新

- [x] 点赞 265

  • Image 2
  • Image 3
  • Image 4
  • Image 5
  • Image 6
  • Image 7
  • +259

Image 8: Aritra Roy Gosthipaty's avatar

Aritra Roy Gosthipaty ariG23498 关注

Image 9: Luis's avatar

Luis lusxvr 关注

Image 10: Andres Marafioti's avatar

Andres Marafioti andito 关注

Image 11: Sergio Paniego's avatar

Sergio Paniego sergiopaniego 关注

Image 12: merve's avatar

merve merve 关注

Image 13: Pedro Cuenca's avatar

Pedro Cuenca pcuenq 关注

Image 14: Vaibhav Srivastav's avatar

Vaibhav Srivastav reach-vb 关注

nanoVLM 是使用纯 PyTorch 训练你自己的视觉语言模型(VLM)的最简单方式。它是一个轻量级工具包,让你可以在免费版 Colab notebook 上启动 VLM 训练。

我们受到 Andrej Karpathy 的 nanoGPT 启发,为视觉领域提供了一个类似的项目。

nanoVLM 的核心是一个工具包,帮助你构建和训练一个既能理解图像又能理解文本,并据此生成文本的模型。nanoVLM 的美妙之处在于它的简洁。整个代码库刻意保持极简和易读,非常适合初学者,或任何想一窥 VLM 内部机制而不被淹没的人。

在这篇博文中,我们介绍该项目背后的核心思想,并提供一种与该仓库交互的简单方式。我们不仅深入探讨项目细节,还将其全部整合起来,让你能快速上手。

目录:

TL;DR

你可以按照以下步骤,使用我们的 nanoVLM 工具包开始训练一个视觉语言模型:

# Clone the repo
git clone https://github.com/huggingface/nanoVLM.git

# Execute the training script
python train.py

这里有一个 Colab notebook,可帮助你启动一次训练运行,无需任何本地设置!

什么是视觉语言模型?

顾名思义,视觉语言模型(VLM)是一种多模态模型,处理两种模态:视觉和文本。这类模型通常以图像和/或文本作为输入,并生成文本作为输出。

根据对图像和文本(输入)的理解来生成文本(输出)是一种强大的范式。它支持广泛的应用,从图像描述和目标检测到回答关于视觉内容的问题(如下表所示)。需要注意的是,nanoVLM 仅将视觉问答作为训练目标。

Image 15: image of a cat为图像添加描述 两只猫躺在床上,旁边有遥控器 图像描述 检测图像中的物体<locxx><locxx><locxx><locxx>目标检测 分割图像中的物体<segxx><segxx><segxx>语义分割 图像中有几只猫?2 视觉问答

如果你有兴趣了解更多关于 VLM 的知识,我们强烈推荐阅读我们关于该主题的最新博客:视觉语言模型(更好、更快、更强)

使用代码库

“空谈无益,放码过来” - Linus Torvalds

在本节中,我们将引导你了解代码库。在跟随学习时,打开一个标签页作为参考会很有帮助。

以下是我们代码库的文件夹结构。为简洁起见,我们移除了辅助文件。

.
├── data
│   ├── collators.py
│   ├── datasets.py
│   └── processors.py
├── generate.py
├── models
│   ├── config.py
│   ├── language_model.py
│   ├── modality_projector.py
│   ├── utils.py
│   ├── vision_language_model.py
│   └── vision_transformer.py
└── train.py

架构

.
├── data
│   └── ...
├── models      # 👈 You are here
│   └── ...
└── train.py

nanoVLM 的建模基于两个知名且广泛使用的架构。我们的视觉骨干(models/vision_transformer.py)是标准的视觉 transformer,更具体地说是 Google 的 SigLIP 视觉编码器。我们的语言骨干遵循 Llama 3 架构。

视觉和文本模态通过模态投影模块进行对齐。该模块将视觉骨干产生的图像嵌入作为输入,并将其转换为与语言模型嵌入层的文本嵌入兼容的嵌入。然后这些嵌入被拼接并输入到语言解码器。模态投影模块由一个像素重排操作后跟一个线性层组成。

Image 16: diagram of the model architecture
模型架构(来源:作者)

像素重排减少了图像 token 的数量,这有助于降低计算成本并加速训练,特别是对于对输入长度敏感的基于 transformer 的语言解码器。下图展示了这一概念。

Image 17: diagram of pixel shuffle
像素重排可视化(来源:作者)

所有文件都非常轻量且文档齐全。我们强烈鼓励你单独查看它们,以更好地理解实现细节(models/xxx.py)

在训练时,我们使用以下预训练骨干权重:

  1. 视觉骨干:google/siglip-base-patch16-224
  2. 语言骨干:HuggingFaceTB/SmolLM2-135M

也可以将骨干替换为 SigLIP/SigLIP 2 的其他变体(用于视觉骨干)和 SmolLM2(用于语言骨干)。

训练你自己的 VLM

现在我们已经熟悉了架构,让我们换个话题,讨论如何使用 train.py 训练你自己的视觉语言模型。

.
├── data
│   └── ...
├── models
│   └── ...
└── train.py     # 👈 You are here

你可以通过以下方式启动训练:

python train.py

这个脚本是你整个训练流程的一站式解决方案,包括:

  • 数据集加载和预处理
  • 模型初始化
  • 优化和日志记录

配置

首先,脚本从 models/config.py 加载两个配置类:

  • TrainConfig:对训练有用的配置参数,如学习率、检查点路径等。
  • VLMConfig:用于初始化 VLM 的配置参数,如隐藏维度、注意力头数等。

数据加载

数据管道的核心是 get_dataloaders 函数。它:

  • 通过 Hugging Face 的 load_dataset API 加载数据集。
  • 组合并打乱多个数据集(如果提供)。
  • 通过索引进行训练/验证集划分。
  • 将它们包装在自定义数据集(VQADataset、MMStarDataset)和整理器(VQACollator、MMStarCollator)中。

这里有一个有用的标志 data_cutoff_idx,便于在小规模子集上进行调试。

模型初始化

模型通过 VisionLanguageModel 类构建。如果你要从检查点恢复,只需:

from models.vision_language_model import VisionLanguageModel

model = VisionLanguageModel.from_pretrained(model_path)

否则,你将获得一个全新初始化的模型,可选地预加载视觉和语言的主干网络。

优化器设置:两个学习率

由于模态投影器(MP)是全新初始化的,而主干网络是预训练的,优化器被分成两个参数组,每组有自己的学习率:

  • 为 MP 设置较高的学习率
  • 为编码器/解码器堆栈设置较小的学习率

这种平衡确保 MP 快速学习,同时保留视觉和语言主干网络中的知识。

训练循环

这部分相当标准但结构经过深思熟虑:

  • 使用混合精度配合 torch.autocast 来提升性能。
  • 通过 get_lr 实现带线性预热的余弦学习率调度。
  • 每批次记录 token 吞吐量(tokens/秒)以进行性能监控。

每 250 步(可配置),模型在验证集和 MMStar 测试数据集上进行评估。如果准确率提高,则对模型进行检查点保存。

日志记录与监控

如果启用了 log_wandb,训练统计信息如 batch_loss、val_loss、accuracy 和 tokens_per_second 会记录到 Weights & Biases 以进行实时跟踪。

运行会自动命名,使用样本大小、批次大小、轮数、学习率和日期等元数据,全部由辅助函数 get_run_name 处理。

推送到 Hub

使用以下命令将训练好的模型推送到 Hub,供他人查找和测试:

model.save_pretrained(save_path)

你可以轻松地使用以下命令推送它们:

model.push_to_hub("hub/id")

在预训练模型上运行推理

使用 nanoVLM 作为工具包,我们训练了一个模型并发布到了 Hub。我们使用了 google/siglip-base-patch16-224 和 HuggingFaceTB/SmolLM2-135M 作为主干网络。该模型在单张 H100 GPU 上使用 cauldron 的约 170 万样本训练了约 6 小时。

这个模型并非旨在与 SoTA 模型竞争,而是为了揭开 VLM 的组件和训练过程的神秘面纱。

.
├── data
│   └── ...
├── generate.py     # 👈 You are here
├── models
│   └── ...
└── ...

让我们使用 generate.py 脚本在训练好的模型上运行推理。你可以使用以下命令运行生成脚本:

python generate.py

这将使用默认参数,并对图像 assets/image.png 运行查询“What is this?”。
你可以像这样在自己的图像和提示上使用此脚本:

python generate.py --image path/to/image.png --prompt "You prompt here"

如果你想查看脚本的核心,就是这几行:

model = VisionLanguageModel.from_pretrained(source).to(device)
model.eval()

tokenizer = get_tokenizer(model.cfg.lm_tokenizer)
image_processor = get_image_processor(model.cfg.vit_img_size)

template = f"Question: {args.prompt} Answer:"
encoded = tokenizer.batch_encode_plus([template], return_tensors="pt")
tokens = encoded["input_ids"].to(device)

img = Image.open(args.image).convert("RGB")
img_t = image_processor(img).unsqueeze(0).to(device)

print("\nInput:\n ", args.prompt, "\n\nOutputs:")
for i in range(args.generations):
    gen = model.generate(tokens, img_t, max_new_tokens=args.max_new_tokens)
    out = tokenizer.batch_decode(gen, skip_special_tokens=True)[0]
    print(f"  >> Generation {i+1}: {out}")

我们创建模型并将其设置为 eval。初始化分词器,用于对文本提示进行分词,以及图像处理器,用于处理图像。下一步是处理输入并运行 model.generate 以生成输出文本。最后,使用 batch_decode 解码输出。

图像 提示 生成
Image 18: image of a cat What is this? 在图片中我可以看到粉色的床单。我可以看到两只猫躺在床单上。
Image 19: yoga What is the woman doing? 在这里,她正在中间做瑜伽

如果你想在 UI 界面中对训练好的模型运行推理,这里是 Hugging Face Space,供你与模型交互。

结论

在这篇博客文章中,我们介绍了什么是 VLM,探讨了为 nanoVLM 提供支持的架构选择,并详细解析了训练和推理工作流程。

通过保持代码库轻量且可读,nanoVLM 旨在既作为学习工具,又作为你可以在此基础上构建的基础。无论你是想了解多模态输入是如何对齐的,还是想在自己的数据集上训练 VLM,这个仓库都能让你抢先一步。

如果你尝试了它、基于它进行构建,或者只是有问题,我们很乐意听到你的声音。祝你玩得开心!

参考文献

  1. GitHub - huggingface/nanoVLM:用于训练/微调小型 VLM 的最简单、最快的仓库。
  2. 视觉语言模型(更好、更快、更强)
  3. 视觉语言模型详解
  4. 深入探索视觉-语言模型
  5. SmolVLM:重新定义小型高效多模态模型

本文提到的模型 3

Image 20 #### HuggingFaceTB/SmolLM2-135M 文本生成 • 0.1B•更新于 2025年2月6日• 1.81M• 242Image 21 #### google/siglip-base-patch16-224 零样本图像分类 • 0.2B•更新于 2024年9月26日• 1.92M• 92Image 22 #### lusxvr/nanoVLM-222M 图像到文本 • 0.2B•更新于 2025年5月8日• 415• 103

本文提到的数据集 1

HuggingFaceM4/the_cauldron 查看器 •更新于 2024年5月6日•1.88M• 412k• 560

本文提到的 Space 1

Running on Zero Agents 6 #### Nanovlm 🌍 6 一个用于 nanoVLM 模型的 Space

本文提到的论文 2

使用高效子像素卷积神经网络的实时单图像和视频超分辨率 论文 • 1609.05158 •发表于 2016年9月16日• 2#### SmolVLM:重新定义小型高效多模态模型 论文 • 2504.05299 •发表于 2025年4月7日• 212

我们博客的更多文章

Image 23 vlm data nanovlm ## 高效多模态数据管道 * Image 24 * Image 25 * Image 26 * Image 27 * +1 74 2025年7月8日 ariG23498 等

Image 28 audio vision llm ## Gemma 3n 已在开源生态系统中完全可用! * Image 29 * Image 30 * Image 31 * Image 32 * +4 123 2025年6月26日 ariG23498 等

社区

Image 33

slwang-ustc

1月26日

大家好!👋

我一直在开发一个名为 Nano-vLLM-v1 的 Nano-vLLM 分支,它重新设计了核心架构,以紧密复现 vLLM v1 调度器,并引入了 分块预填充 以获得更好的性能。

目标是构建一个轻量、可读且高效的推理引擎,既忠于原始 vLLM 设计,又易于理解和扩展。

🔥 主要特性

  • ✅ 完全复现 vLLM v1 调度器 – 实现了与 vLLM v1 相同的调度逻辑。
  • ✅ 分块预填充 – 为更长的上下文提高预填充效率。
  • ✅ 简洁的代码库​ – 基于 Nano vLLM 复现 vLLM v1 调度器并实现分块预填充的最简单方式
  • ✅ 快速的离线与在线推理 – 在离线吞吐量和在线延迟(TTFT 和 TPOT)方面性能与 vLLM v1 相当。

📂 仓库

在这里查看:https://github.com/slwang-ustc/nano-vllm-v1/tree/main

我很希望社区能尝试它、提供反馈或做出贡献!代码设计为可读且模块化,便于试验新功能或优化。

如果你对轻量、高性能且不复杂的 LLM 推理感兴趣,给它点个星 ⭐ 并告诉我你的想法!

🚀 快速开始

离线示例:

from nanovllm import LLM, SamplingParams

llm = LLM("/path/to/model", enforce_eager=True, tensor_parallel_size=1)
sampling_params = SamplingParams(temperature=0.6, max_tokens=256)
outputs = llm.generate(["Hello, Nano-vLLM."], sampling_params)
print(outputs[0]["text"])

在线基准测试:

python serving_bench.py \
--model /path/to/Qwen3-14B/ \
--request-rate 10 \
--num-requests 1024 \
--tensor-parallel-size 1 \
--max-num-batched-tokens 1024 \
--max-num-seqs 1024 \
--random-input-len 128 \
--random-output-len 100 \
--chunked-prefill \
--enforce-eager

回复

编辑预览

在文本输入框中拖拽、粘贴或点击此处上传图片、音频和视频。

点击或粘贴此处上传图片

评论 ·注册或登录以发表评论

- [x] 点赞 265

  • Image 34
  • Image 35
  • Image 36
  • Image 37
  • Image 38
  • Image 39
  • Image 40
  • Image 41
  • Image 42
  • Image 43
  • Image 44
  • Image 45
  • +253

本文提及的模型 3

Image 46 #### HuggingFaceTB/SmolLM2-135M 文本生成 • 0.1B•更新于 2025年2月6日• 1.81M• 242Image 47 #### google/siglip-base-patch16-224 零样本图像分类 • 0.2B•更新于 2024年9月26日• 1.92M• 92Image 48 #### lusxvr/nanoVLM-222M 图像-文本到文本 • 0.2B•更新于 2025年5月8日• 415• 103

本文提及的数据集 1

HuggingFaceM4/the_cauldron 查看器 •更新于 2024年5月6日•1.88M• 412k• 560

本文提及的 Spaces 1

Running on Zero Agents 6 #### Nanovlm 🌍 6 一个用于 nanoVLM 模型的 Space

本文提及的论文 2

Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network 论文 • 1609.05158 •发表于 2016年9月16日• 2#### SmolVLM: Redefining small and efficient multimodal models 论文 • 2504.05299 •发表于 2025年4月7日• 212

系统主题

公司

服务条款隐私关于招聘

网站

模型数据集Spaces定价文档

来源:Hugging Face:Blog · huggingface.co