多模态模型拼接实战:用12M参数给Qwen3-0.6B装上眼睛

发布时间:2026/9/2 13:33:38
多模态模型拼接实战:用12M参数给Qwen3-0.6B装上眼睛 多模态模型拼接实战用12M参数给Qwen3-0.6B装上眼睛【免费下载链接】happy-llm 从零开始构建大模型项目地址: https://gitcode.com/GitHub_Trending/ha/happy-llm只训练12M参数占总参数1.81%0.6B的中文小模型Qwen3就长出了眼睛happy-llm项目的这篇实践把SmolVLM2的93M视觉塔通过模型拼接接到Qwen3上得到一个0.69B的多模态模型约4GB显存就能做中文视觉问答。 定位与取舍为什么拼接而不是重训重训一个中文VLM需要海量图文对数据而拼接的思路是复用两个已经训好的小模型只训练它们之间的桥接层。它的价值只有一个轴成本极低——可训练参数只有12M8卡1.5小时即可收敛换来的是Qwen3完整保留中文对话、思考与函数调用能力同时新增看图能力。模型总参数视觉模块文本模块Qwen3-0.6B0.6B00.6BSmolVLM2-256M0.256B0.093B0.135BQwen3-SmVL0.69B0.093B0.6BSmolVLM2能端侧1GB显存推理但词表只有49280、中文几乎不可用Qwen3-0.6B中文强却看不见。两个短板恰好互补。这0.69B是怎么拼出来的改动只有三处全部在配置层面。 技术原理模型拼接的三处必须改对的配置Qwen3-SmVL整体拼接架构把SmolLM-135M整体换成Qwen3-0.6B替换本身只是两行赋值真正的坑在嵌套配置Transformers把backbone和任务头分开封装image_token_id、eos_token_id、vocab_size在模型对象、内层模型、config里各有一份必须同步更新。smolvlm.model.text_model qwen.model smolvlm.lm_head qwen.lm_head # 以下必须逐层同步含config与内层model smolvlm.vocab_size qwen.vocab_size # 49280 - 151936 smolvlm.image_token_id smolvlm.model.image_token_id 151655 # Qwen3的image_pad smolvlm.generation_config.eos_token_id 151645如果做错会怎样作者实测只改了顶层image_token_id、漏掉内层SmolVLMModel视觉特征根本进不了语言模型——loss飞快降到0.1以下、grad_norm看着很收敛一推理模型却完全看不见图。文本模块与语言模型头的替换位置重写chat_template用image_pad顶掉image占位符Qwen3和SmolVLM2的上下文格式差异极大后者塞满image占位符和row_1_col_1位置标记。作者的取舍是保留Qwen3的骨架包括/think思考标记和函数调用控制文本只把图像特征插入点换成Qwen3预留的image_pad令牌。简化后的格式大致如下user: [vision_start] row_1_col_1 图像特征占位(image_pad) [vision_end] 图中有几只狗 assistant: ... 图中有三只狗如果做错会怎样模板与预训练分布偏离太远小模型能力明显打折。这部分改的是Jinja模板而非Python作者花了两小时调试并把格式化后的模板单独放出方便阅读。重建Connector对齐768到1024维度SigLip输出768维Qwen3隐藏层是1024维SmolVLM2原有的768→576连接器直接作废重建一个即可——它是全模型里唯一需要从头学的组件new_connector SmolVLMConnector(ConnectConfig()) # 768 - 1024 smolvlm.model.connector new_connector.to(device).to(torch.bfloat16)如果做错会怎样维度不匹配会直接报forward错误这层是随机初始化的学习率给低了loss基本不动。 实操落地从零跑通拼接模型准备环境与资源下载git clone https://gitcode.com/GitHub_Trending/ha/happy-llm cd happy-llm/Extra-Chapter/vlm-concatenation-finetune pip install -r requirements.txt # transformers4.53.0、accelerate、datasets、num2words bash download_resource.sh # 经魔塔社区自动下载模型与数据集训练对算力要求不低单卡至少40G显存作者用8张64G的沐曦C500。冻结策略与训练超参数冻结视觉与文本模块只训Connector和lm_headdef freeze_model(model): for _, p in model.model.text_model.named_parameters(): p.requires_grad False for _, p in model.model.vision_model.named_parameters(): p.requires_grad False return model # 可训练 12.00M / 662.87M 1.81%training_args TrainingArguments( per_device_train_batch_size1, # VLM序列长每卡只能放1条 gradient_accumulation_steps4, # 8卡时等效batch 32 max_length 相关的截断取2K # 图像占0.8K~1.3K token不能更短 learning_rate1e-4, # connector随机初始化用LoRA量级 lr_scheduler_typecosine, warmup_ratio0.1, bf16True, )数据集用HuggingFace的The Cauldron50个视觉任务、188万条、约169G按参数:token≈1:10采样出6万条训练。启动训练与查看输出swanlab login # SwanLab需先登录 CUDA_VISIBLE_DEVICES0 python train.py ./cocoqa_train.yaml # 单卡冒烟测试约200步 accelerate launch --num_processes 8 train.py ./full_train.yaml # 8卡全量约1000步1.5h训练结束脚本会自动用一张三只狗的图跑一次中文推理结果同步到SwanLab。成功训练后可看到SwanLab链接项目资源完整教程Extra-Chapter/vlm-concatenation-finetune/README.md附加章节索引Extra-Chapter/Readme.md官方教材docs/✅ 效果与边界数字与短板1000步全量训练后训练损失0.61、验证损失约0.581k步后损失不再明显下降可认为收敛充分8×64G卡全程1.5小时单卡冒烟测试约20分钟。此前200步小批量时模型把三只狗答成兔子全量训练后同一张图能准确回答图中有三只狗且Qwen3的思考与函数调用能力原样保留。完整训练与小批量训练损失对比全量训练后三只狗案例答对⚠️ 已知限制训练数据全英文The Cauldron中文图文样本目前靠数据合成补齐步数/数据不能省200步欠训练会把狗认成兔子训练需单卡40G以上显存消费级显卡跑不了本教程测试集仅64条训练/验证损失差距不能直接当过拟合证据okvqa、mimic_cgd等子数据集加载异常需手动处理。❓ 常见问题速答问换了模型后loss飞快降到0.1以下但推理时模型完全看不见图答大概率漏改了嵌套config。把image_token_id/eos_token_id/vocab_size在模型、内层model和config里逐层同步视觉特征才进得了语言模型。问调小max_length后报特征拼接错误答文本截断长度不能小于图像token数0.8K~1.3K。要缩短到1.5K时同步降低图像分辨率否则图像特征会被截断。问为什么用指令版Qwen3-0.6B而不是Qwen3-0.6B-Base答本次微调冻结LLM、直接复用其指令跟随能力。换Base版就得额外做SFT违背拼接的低成本初衷。问上下文里row_1_col_1这类位置标记是什么答SmolVLM2的image splitting同时喂全局低清图和高清局部块防止降采样丢细节。拼接方案沿用了这套图像预处理流程。问显存不足40G怎么降训练成本答降图像分辨率减少视觉token、把max_length压到1.5K左右但无法完全绕开40G这条线建议借云卡跑。拼接是拿来主义坑在嵌套配置与上下文对齐。完整教程见Qwen3-SmVL附加章节。【免费下载链接】happy-llm 从零开始构建大模型项目地址: https://gitcode.com/GitHub_Trending/ha/happy-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考