1. 项目概述
最近在参与一个公式识别比赛时,我尝试使用MS-Swift框架对Intern-S1-mini和InternVL3_5-1B两个视觉语言模型进行微调。这个过程中遇到了不少坑,也积累了一些实战经验,今天就来分享一下完整的微调流程和注意事项。
公式识别任务的核心是将图片中的数学公式转换为LaTeX代码。这在学术论文数字化、在线教育等领域都有广泛应用。相比通用OCR,公式识别需要模型具备更强的视觉-语言对齐能力,这也是为什么选择Intern系列这种视觉语言模型进行微调。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备
2.1 基础环境配置
首先需要搭建Python环境,我推荐使用conda管理环境:
bash复制conda create -n ms-swift11 python=3.10 -y
conda activate ms-swift11
这里有几个注意事项:
- Python版本建议3.8-3.10,3.11可能会有兼容性问题
- 环境命名最好包含Swift版本号,方便后续管理多版本
- 建议在Linux环境下运行,Windows可能会有路径问题
2.2 依赖安装
接下来安装必要的依赖包:
bash复制cd /root
git clone https://gh.llkk.cc/https://github.com/fak111/VLM-formula-recognition-dataset.git
cd VLM-formula-recognition-dataset
pip install -r requirements.txt
pip install transformers -U
这里容易踩的坑:
- 网络问题可能导致克隆失败,可以尝试多次或更换镜像源
- transformers建议升级到最新版,否则可能不兼容InternVL模型
- 如果遇到权限问题,可以添加--user参数
2.3 MS-Swift安装
MS-Swift是ModelScope提供的模型微调框架,安装时需要指定commit:
bash复制git clone https://gh.llkk.cc/https://github.com/modelscope/ms-swift.git
cd ms-swift
git checkout cab4aa59
pip install -e .
pip install timm==1.0.9 msgspec==0.19.0
安装注意事项:
- 必须checkout指定commit,新版本可能有兼容性问题
- 使用-e参数以可编辑模式安装,方便调试
- timm和msgspec版本需要严格匹配
3. Intern-S1-mini微调实战
3.1 训练配置
Intern-S1-mini是一个轻量级的视觉语言模型,适合作为入门尝试。训练脚本通常放在swift_config目录下,主要参数包括:
bash复制# 示例训练脚本内容
nohup swift sft \
--model '/path/to/Intern-S1-mini' \
--dataset '/path/to/train.jsonl' \
--train_type lora \
--lora_rank 4 \
--lora_alpha 8 \
--learning_rate 1e-4 \
--num_train_epochs 5 \
--output_dir ./output \
> train.log 2>&1 &
关键参数说明:
- lora_rank: LoRA矩阵的秩,影响模型参数量和效果
- lora_alpha: LoRA缩放系数,一般设为rank的2倍
- batch_size: 根据GPU显存调整,公式识别任务建议从1开始
3.2 训练监控
训练启动后,可以通过以下命令实时查看日志:
bash复制tail -f train.log
监控要点:
- 关注loss下降曲线,正常应该平稳下降
- 检查GPU利用率,理想应在80%以上
- 注意内存泄漏问题,可通过nvidia-smi观察
3.3 模型合并
训练完成后需要合并LoRA权重:
bash复制swift export --adapters ./output --merge_lora True
合并后常见问题:
- 部分文件缺失:需要从原始模型目录补全
bash复制rsync -ah --ignore-existing --exclude='/proc' "$SRC"/ "$DST"/
- 模型体积异常:检查是否成功合并
- 加载失败:确认torch版本兼容性
4. InternVL3_5-1B微调进阶
4.1 大模型训练技巧
InternVL3_5-1B参数量较大,训练时需要特别注意:
- 使用gradient_checkpointing节省显存
- 设置gradient_accumulation_steps增加有效batch_size
- 启用bfloat16减少显存占用
示例训练脚本:
bash复制nohup swift sft \
--model 'InternVL3_5-1B' \
--train_type lora \
--torch_dtype bfloat16 \
--gradient_accumulation_steps 4 \
--gradient_checkpointing_kwargs '{"use_reentrant": false}' \
> vl_train.log 2>&1 &
4.2 大模型调试经验
- 学习率设置:大模型需要更小的学习率,建议从1e-5开始尝试
- 冻结视觉编码器:设置--freeze_vit true可以加速训练
- 日志管理:建议为每个实验创建独立的日志目录
4.3 性能优化
- 数据预处理:使用dataset_num_proc并行处理数据
- 数据加载:设置dataloader_num_workers提高IO效率
- 混合精度:bfloat16相比float16更适合大模型
5. 模型提交与评测
5.1 模型上传
使用ModelScope API上传模型:
python复制from modelscope.hub.api import HubApi
api = HubApi()
api.login('your_token')
api.create_model('your_model_name', license='APACHE_V2')
api.upload_folder('your_model_name', folder_path='output')
上传注意事项:
- 提前申请API token
- 模型名称需要唯一
- 首次上传可能需要验证邮箱
5.2 Prompt优化
公式识别的prompt设计很关键,我的经验是:
- 明确输出格式要求
- 提供示例减少歧义
- 禁止模型添加解释文字
优化后的prompt示例:
code复制请根据图片中的公式生成对应的latex公式文本,不要任何解释。
输出必须使用 ```latex 代码块包裹,仅包含LaTeX代码。
确保语法正确,下标用{}括起来。
5.3 评测技巧
- 本地验证:先在小批量数据上测试
- 错误分析:统计常见错误类型
- 迭代优化:根据错误反馈调整prompt
6. 常见问题排查
6.1 训练失败
可能原因:
- CUDA内存不足:减小batch_size或使用梯度累积
- 数据格式错误:检查jsonl文件是否合法
- 路径问题:确保所有路径都是绝对路径
6.2 模型加载失败
解决方案:
- 检查模型文件完整性
- 确认torch版本匹配
- 尝试重新合并权重
6.3 识别准确率低
优化方向:
- 增加训练epoch
- 调整LoRA超参数
- 优化数据质量
7. 实战经验分享
经过多次实验,我总结了以下提升公式识别效果的关键点:
- 数据质量比数量更重要:1000个清洗过的样本比1万个噪声数据效果好
- LoRA rank不是越大越好:4-8之间通常性价比最高
- 学习率需要耐心调:建议用学习率扫描找出最优值
- 早停很关键:监控验证集loss防止过拟合
在比赛中的一个小技巧是:对复杂公式可以先用大模型生成伪标签,再用小模型蒸馏,这样既能保证效果又能控制推理速度。
