ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

如何微调InternVL3-2B-AWQ:SWIFT与XTuner定制视觉数据完整实战

如何微调InternVL3-2B-AWQ:SWIFT与XTuner定制视觉数据完整实战

【免费下载链接】InternVL3-2B-AWQ

项目地址:https://ai.gitcode.com/OpenGVLab/InternVL3-2B-AWQ
点击查看免费下载

InternVL3-2B-AWQ 微调,是把通用视觉语言模型"改造"成行业专属模型的关键一步。InternVL3-2B-AWQ 是 OpenGVLab 出品的 InternVL3-2B 多模态大模型的 AWQ 4-bit 量化版,采用「ViT-MLP-LLM」架构,支持单图/多图对话、文档 OCR、视频理解等任务。本文带你用 SWIFT 和 XTuner 两大主流框架,从零完成:整理自己的视觉数据 → 训练 → 验证 → 导出量化版,全程可复制落地。

一、动手前先搞懂 InternVL3-2B-AWQ

1.1 AWQ 量化是什么?适合直接微调吗?

打开 config.json,可以看到核心量化配置:

"quantization_config": { "bits": 4, "group_size": 128, "quant_method": "awq", "zero_point": true }

AWQ(Activation-aware Weight Quantization)按激活值重要性保留关键权重,把权重压到 4-bit,显存占用大幅下降,推理更快。

⚠️ 重要提示:4-bit 量化权重不建议直接做梯度更新。标准做法是:用原始精度(bf16)权重训练 LoRA/全量参数,训练完成后再导出 AWQ 量化版。这也是本仓库的定位——它是量化后的推理版,微调时请使用对应的原始精度权重。

1.2 一张图会被切成多少 token?

InternVL 的动态分辨率机制决定了上下文长度估算:

  • 图片按448×448的 tile 切分,最多 12 个 tile(见 config.json 中force_image_size: 448、max_dynamic_patch: 12)
  • 经downsample_ratio: 0.5的 pixel shuffle 降采样后,每个 tile 对应256个视觉 token(计算逻辑见 modeling_internvl_chat.py)
  • 图像预处理参数(ImageNet 均值/方差、448 分辨率)定义在 preprocessor_config.json
  • <img>、<IMG_CONTEXT>等视觉特殊 token 定义在 added_tokens.json

含义:一张复杂图片最多可产生 12×256 = 3072 个视觉 token,配置训练max_length时要留足空间。

二、准备自定义视觉数据(数据集格式一步到位)

SWIFT(ms-swift)采用 messages 对话格式,准备一个 JSON 文件即可,例如:

[ { "messages": [ {"role": "user", "content": "<image>这张图片里的产品是什么?"}, {"role": "assistant", "content": "这是一款智能手表,表盘显示时间为 10:08。"} ], "images": ["/data/images/product1.jpg"] }, { "messages": [ {"role": "user", "content": "<image>请提取单据中的发票号码和金额。"}, {"role": "assistant", "content": "发票号码:12345678,金额:¥2,580.00。"} ], "images": ["/data/images/invoice1.jpg"] } ]

💡 数据准备三原则:

  1. 提示中必须带<image>占位符,位置与图片对应;多图则多个占位符
  2. 回答要"示范"你想要的风格——想让模型输出 JSON,答案就写成 JSON
  3. 数量先求少而精:几百条高质量样本即可完成场景适配,再逐步扩充

XTuner 的自定义数据集则使用conversations(human/gpt 角色)结构,字段略有差异,以其官方示例为准。

三、SWIFT 微调全流程(从安装到出模型)

3.1 安装 SWIFT

pip install "ms-swift[all]"

3.2 一键启动 LoRA 微调

CUDA_VISIBLE_DEVICES=0 \ swift sft \ --model OpenGVLab/InternVL3-2B \ --train_type lora \ --target_modules mlp1 \ --freeze_vit true \ --freeze_llm false \ --dataset /path/to/your_data.json \ --max_length 4096 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps 8 \ --learning_rate 1e-4 \ --num_train_epochs 3 \ --output_dir output/internvl3_2b_lora

核心参数速查:

参数作用新手建议
--train_type loraLoRA 低秩微调,显存友好首选
--target_modules mlp1只调视觉-语言投影层mlp1数据少时最稳
--freeze_vit true冻结视觉编码器 InternViT通用视觉任务保持 true
--max_length上下文上限多图/长文档场景调大到 4096+
--dataset你的 JSON 数据路径见第二节格式

💡mlp1是 ViT 特征与 LLM 之间的"翻译官"(定义于 modeling_internvl_chat.py),只调它就能让模型快速适应新视觉场景,且几乎不掉语言能力;需要大幅增强语言能力时,再把target_modules改为 LLM 侧的all-linear。

3.3 微调后导出 AWQ 量化版

训练完成后,用 SWIFT 的导出能力重新量化,得到类似本仓库的轻量推理模型:

swift export \ --adapters output/internvl3_2b_lora/checkpoint-best \ --merge_lora true \ --quant_method awq \ --output_dir output/internvl3_2b_awq

四、XTuner 微调方案(配置驱动,适合多卡)

XTuner 采用「配置文件 + 命令行」的方式,适合需要 DeepSpeed 多卡训练的场景:

  1. 创建训练配置internvl3_2b_finetune.py(基于 XTuner 官方 InternVL 系列示例改写):
# internvl3_2b_finetune.py(精简示例) model_path = 'OpenGVLab/InternVL3-2B' train_dataset = '/path/to/your_data.json' max_length = 4096 train_type = 'lora' lora_rank = 32 lora_alpha = 64 target_modules = 'mlp1' freeze_vit = True per_device_train_batch_size = 2 gradient_accumulation_steps = 8 learning_rate = 1e-4 num_train_epochs = 3
  1. 启动训练(可开启 DeepSpeed ZeRO):
xtuner train internvl3_2b_finetune.py --deepspeed zero2
  1. 训练结束后在work_dir下找到 checkpoint,用xtuner merge-lora合并 LoRA 权重即可部署。

五、微调不翻车的 5 个关键点 📌

  1. 模板不用你操心:对话模板internvl2_5已内置在 config.json,模板实现见 conversation.py,SWIFT/XTuner 会自动套用,数据里只写自然语言即可
  2. 先用 20 条数据跑通流程,确认 loss 正常下降,再上全量数据
  3. 学习率别贪大:LoRA 建议1e-4起步,出现 loss 尖刺就降到5e-5
  4. 显存参考:2B 模型 + LoRA(只调mlp1/LLM,冻结 ViT),单张 24GB 显卡即可训练;解冻 ViT 建议 2 卡以上
  5. 模型结构溯源:视觉编码器 InternViT 在 modeling_intern_vit.py,LLM 交互与chat接口在 modeling_internvl_chat.py,微调框架遇到不兼容时可优先对照这两个文件排查。官方微调生态推荐(InternVL、SWIFT、XTuner)见 README.md

六、快速验证微调效果

用 transformers 加载微调后的模型,跑一条真实业务图片即可:

from transformers import AutoModel, AutoTokenizer path = 'output/internvl3_2b_awq' # 替换为你的微调/量化模型路径 model = AutoModel.from_pretrained( path, trust_remote_code=True, torch_dtype='bfloat16', low_cpu_mem_usage=True).cuda().eval() tokenizer = AutoTokenizer.from_pretrained(path, trust_remote_code=True, use_fast=False) from PIL import Image import torchvision.transforms as T from modeling_internvl_chat import dynamic_preprocess # 图像处理函数见 README Quick Start pixel_values = dynamic_preprocess(Image.open('test.jpg').convert('RGB'), image_size=448, use_thumbnail=True, max_num=12) print(model.chat(tokenizer, pixel_values, '<image>这张图里的产品是什么?', dict(max_new_tokens=256)))

完整的加载与推理示例(含多图、视频、流式输出)可参考 README.md 的 Quick Start 章节,模型权重文件为 pytorch_model-00001-of-00002.bin 与 pytorch_model-00002-of-00002.bin,分片索引见 pytorch_model.bin.index.json。


小结:InternVL3-2B-AWQ 微调的最佳路径是「原始权重 + SWIFT/XTuner LoRA 训练 + 训练后 AWQ 重量化」。数据准备占成功的 70%,先小规模验证、再放量训练,你就能用几百条自有视觉数据,低成本得到一个贴合业务的专属多模态模型。

【免费下载链接】InternVL3-2B-AWQ

项目地址:https://ai.gitcode.com/OpenGVLab/InternVL3-2B-AWQ
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进