|
ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-left: none;padding: 1em;border-radius: 8px;color: rgba(0, 0, 0, 0.5);background: rgb(247, 247, 247);margin: 2em 8px;"> 作者:HelloWorl 原文:https://zhuanlan.zhihu.com/p/698218006 整理:青稞AI ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">本文参考官方教程[1]介绍如何训练 LLaVA v1.5 多模态模型。LLaVA 训练包括特征对齐阶段(feature alignment stage)和视觉指令微调阶段(visual instruction tuning stage),其中特征对齐阶段使用 LAION-CC-SBU 数据集的 558K 子集(记为 LLaVA-Pretrain),目的是训练 MLP connector(或称为 projector),而视觉指令微调阶段使用 GPT-4 生成的 150K 条多模态指令跟随数据和来自学术任务的 515K 条 VQA 数据引导 LLaVA 模型遵从多模态指令。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">官方给出的 LLaVA v1.5 使用了 8 个 A100 GPU(80G)进行训练,如果我们没有 8 个 GPU 或者足够的显存(80G),可以减小per_device_train_batch_size的值并增大gradient_accumulation_steps,始终保证全局 batch size 不变,其中 batch size 的大小等于 per_device_train_batch_sizexgradient_accumulation_stepsxnum_gpus 。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">下面以 LLaVA-v1.5-13B 为例介绍 LLaVA 模型的训练。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.2em;font-weight: bold;display: table;margin: 2em auto 1em;padding-right: 1em;padding-left: 1em;border-bottom: 2px solid rgb(250, 81, 81);color: rgb(63, 63, 63);">特征对齐阶段ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.1em;font-weight: bold;margin-top: 2em;margin-right: 8px;margin-bottom: 0.75em;padding-left: 8px;border-left: 3px solid rgb(250, 81, 81);color: rgb(63, 63, 63);">准备数据ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-weight: bold;margin: 2em 8px 0.5em;color: rgb(250, 81, 81);">下载LLaVA-Pretrain[2]数据集ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;overflow-x: auto;border-radius: 8px;margin: 10px 8px;">#将数据下载到./playground/data/LLaVA-Pretrain,否则需要修改启动脚本的data_path参数 huggingface-clidownload--repo-typedatasetliuhaotian/LLaVA-Pretrain--local-dir./playground/data/LLaVA-PretrainingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;margin: 1.5em 8px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">LLaVA-Pretrain 包含 3 个文件:ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;padding-left: 1em;list-style: circle;color: rgb(63, 63, 63);" class="list-paddingleft-1">• blip_laion_cc_sbu_558k.json:此数据的构造过程是将 image-caption 数据添加随机选择的指令(例如:“Describe this image”)转换成多模态对话,下面是数据示例: { 'id':'004539375', 'image':'00453/004539375.jpg', 'conversations':[ { 'from':'human', 'value':'Renderaclearandconcisesummaryofthephoto.\n<image>' }, { 'from':'gpt', 'value':'selectluxuryfurniture3-inchgelmemoryfoammattresstopper' } ] },
{ 'id':'004539375', 'image':'00453/004539375.jpg', 'blip_caption':'selectluxuryfurniture3-inchgelmemoryfoammattresstopper', 'url':'http://ec1.ostkcdn.com/images/products/8111140/P15459545.jpg' }
解压images.zip#解压到./playground/data/LLaVA-Pretrain/images,否则需要修改启动脚本的image_folder参数 unzip./playground/data/LLaVA-Pretrain/images.zip-d./playground/data/LLaVA-Pretrain/images
启动训练在这个阶段,使用 8 个 A100(80G)训练 LLaVA-v1.5-13B 大约需要 5.5 小时。 启动的脚本是scripts/v1_5/pretrain.sh,它的内容如下: #!/bin/bash deepspeedllava/train/train_mem.py\ --deepspeed./scripts/zero2.json\#使用DeepSpeedZeRO-2 --model_name_or_pathlmsys/vicuna-13b-v1.5\#语言模型是lmsys/vicuna-13b-v1.5 --versionplain\ --data_path./playground/data/LLaVA-Pretrain/blip_laion_cc_sbu_558k.json\#训练样本文件 --image_folder./playground/data/LLaVA-Pretrain/images\#存放图像的目录 --vision_toweropenai/clip-vit-large-patch14-336\#视觉编码器 --mm_projector_typemlp2x_gelu\#projector的类型 --tune_mm_mlp_adapterTrue\#是否训练projector --mm_vision_select_layer-2\ --mm_use_im_start_endFalse\ --mm_use_im_patch_tokenFalse\ --bf16True\ --output_dir./checkpoints/llava-v1.5-13b-pretrain\#保存的路径 --num_train_epochs1\ --per_device_train_batch_size32\ --per_device_eval_batch_size4\ --gradient_accumulation_steps1\ --evaluation_strategy'no'\ --save_strategy'steps'\ --save_steps24000\ --save_total_limit1\ --learning_rate1e-3\ --weight_decay0.\ --warmup_ratio0.03\ --lr_scheduler_type'cosine'\ --logging_steps1\ --tf32True\ --model_max_length2048\ --gradient_checkpointingTrue\ --dataloader_num_workers4\ --lazy_preprocessTrue\ --report_towandb
启动脚本: sh./scripts/v1_5/pretrain.sh 启动训练后,会自动下载语言模型视觉编码器的权重,完成权重的下载后会提示是否需要使用 wandb 可视化结果,这里按需选择即可。 接下来就开始了训练,下面是 loss 的部分日志: 训练完成后,权重会保存在./checkpoints/llava-v1.5-13b-pretrain目录。 视觉指令微调阶段完成特征对齐阶段的训练后,我们进入视觉指令微调阶段。注意:如果我们跳过特征对齐阶段的训练,则需要将对应的 projector 下载到./checkpoints目录,下载的命令如下: huggingface-clidownloadliuhaotian/llava-v1.5-mlp2x-336px-pretrain-vicuna-13b-v1.5--local-dir./checkpoints/llava-v1.5-13b-pretrain 准备数据下载数据集#将数据下载到./playground/data/LLaVA-Instruct-150K huggingface-clidownload--repo-typedatasetliuhaotian/LLaVA-Instruct-150K--local-dir./playground/data/LLaVA-Instruct-150K cp./playground/data/LLaVA-Instruct-150K/llava_v1_5_mix665k.json./playground/data/llava_v1_5_mix665k.json
下面是 llava_v1_5_mix665k.json 的示例: { 'id':'000000033471',//样本的唯一id 'image':'coco/train2017/000000033471.jpg',//可以是绝对路径,也可以是相对于image_folder的路径 'conversations':[ { 'from':'human', 'value':'<image>\nWhatarethecolorsofthebusintheimage?' }, { 'from':'gpt', 'value':'Thebusintheimageiswhiteandred.' }, { 'from':'human', 'value':'Whatfeaturecanbeseenonthebackofthebus?' }, { 'from':'gpt', 'value':'Thebackofthebusfeaturesanadvertisement.' }, { 'from':'human', 'value':'Isthebusdrivingdownthestreetorpulledofftotheside?' }, { 'from':'gpt', 'value':'Thebusisdrivingdownthestreet,whichiscrowdedwithpeopleandothervehicles.' } ] },
wgethttp://images.cocodataset.org/zips/train2017.zip-P./playground/data/coco unzip./playground/data/coco/train2017.zip-d./playground/data/coco
wgethttps://downloads.cs.stanford.edu/nlp/data/gqa/images.zip-P./playground/data/gqa unzip./playground/data/gqa/images.zip-d./playground/data/gqa
cd./playground/data/ocr_vqa pythonloadDataset.py #回到LLaVA目录 cd../../../
使用下面的代码处理OCR-VQA 图像的后缀问题[7]: importjson importos
withopen('./playground/data/llava_v1_5_mix665k.json')asf: samples=json.load(f)
forsampleinsamples: if'image'notinsample: continue
img_path=os.path.join('./playground/data',sample['image']) ifnotos.path.exists(img_path): #处理OCR-VQA图像后缀和llava_v1_5_mix665k.json中的后缀不一致问题 img_path_wo_ext=os.path.splitext(img_path)[0] forextin['.png','.gif']: real_path=img_path_wo_ext+ext ifos.path.exists(real_path): #重命名 os.replace(real_path,img_path) break
也可以参考 https://github.com/haotian-liu/LLaVA/pull/1458 给出的路径下载 ORC-VQA 数据。 wgethttps://dl.fbaipublicfiles.com/textvqa/images/train_val_images.zip-P./playground/data/textvqa unzip./playground/data/textvqa/train_val_images.zip-d./playground/data/textvqa
wgethttps://cs.stanford.edu/people/rak248/VG_100K_2/images.zip-P./playground/data/vg wgethttps://cs.stanford.edu/people/rak248/VG_100K_2/images2.zip-P./playground/data/vg unzip./playground/data/vg/images.zip-d./playground/data/vg unzip./playground/data/vg/images2.zip-d./playground/data/vg
数据集结构完成数据集的下载后,检查数据集的目录结构是否和下面的一致: ├──coco │├──train2017 ││├──xxx.jpg ├──gqa │├──images ││├──xxx.jpg ├──llava_v1_5_mix665k.json ├──ocr_vqa │├──dataset.json │├──images ││├──xxx.jpg │└──loadDataset.py ├──textvqa │├──train_images ││├──xxx.jpg │──vg ├──└──VG_100K ││├──xxx.jpg ├──│──VG_100K_2 ││├──xxx.jpg
使用下面的代码检查数据目录结构: importjson importos
withopen('./playground/data/llava_v1_5_mix665k.json')asf: samples=json.load(f)
missing_cnt=0#记录图像路径不存在的个数 forsampleinsamples: if'image'notinsample: continue
img_path=os.path.join('./playground/data',sample['image']) ifnotos.path.exists(img_path): missing_cnt+=1
print(missing_cnt)
如果 missing_cnt 为 0,则说明数据的目录结构是正确的。 启动训练在启动训练前,请查看 https://github.com/haotian-liu/LLaVA/issues/1144 以避免训练结束后权重保存出错。 在这个阶段,使用 8 个 A100(80G)训练 LLaVA-v1.5-13B 大约需要 20 小时。启动的脚本是scripts/v1_5/finetune.sh,它的内容如下: #!/bin/bash
deepspeedllava/train/train_mem.py\ --deepspeed./scripts/zero3.json\#使用DeepSpeedZeRO-3 --model_name_or_pathlmsys/vicuna-13b-v1.5\ --versionv1\ --data_path./playground/data/llava_v1_5_mix665k.json\#训练样本 --image_folder./playground/data\#存放图像的目录 --vision_toweropenai/clip-vit-large-patch14-336\ --pretrain_mm_mlp_adapter./checkpoints/llava-v1.5-13b-pretrain/mm_projector.bin\ --mm_projector_typemlp2x_gelu\#projector的类型 --mm_vision_select_layer-2\ --mm_use_im_start_endFalse\ --mm_use_im_patch_tokenFalse\ --image_aspect_ratiopad\ --group_by_modality_lengthTrue\ --bf16True\ --output_dir./checkpoints/llava-v1.5-13b\ --num_train_epochs1\ --per_device_train_batch_size16\ --per_device_eval_batch_size4\ --gradient_accumulation_steps1\ --evaluation_strategy'no'\ --save_strategy'steps'\ --save_steps50000\ --save_total_limit1\ --learning_rate2e-5\ --weight_decay0.\ --warmup_ratio0.03\ --lr_scheduler_type'cosine'\ --logging_steps1\ --tf32True\ --model_max_length2048\ --gradient_checkpointingTrue\ --dataloader_num_workers4\ --lazy_preprocessTrue\ --report_towandb
启动脚本: sh./scripts/v1_5/finetune.sh 启动训练后,会询问是否需要使用 wandb 可视化结果,这里按需选择即可。 接下来就开始了训练,下面是 loss 的部分日志: 训练完成后,权重会保存在./checkpoints/llava-v1.5-13b目录。注意:如果单卡显存不足 80G,可以使用 LoRA 微调脚本finetune_lora.sh[11]。完成训练后,可以参考LLaVA 评测[12]对模型的性能进行评测。 微调自定义数据集参考Finetune LLaVA on Custom Datasets[13] 将训练样本以列表的形式保存到 json 文件,其中每一个样本是一个字典,它至少包含三个字段: 下面是一个示例: [ { 'id':'997bb945-628d-4724-b370-b84de974a19f', 'image':'part-000001/997bb945-628d-4724-b370-b84de974a19f.jpg', 'conversations':[ { 'from':'human', 'value':'<image>\nWriteapromptforStableDiffusiontogeneratethisimage.' }, { 'from':'gpt', 'value':'abeautifulpaintingofchernobylbynekro,pascalblanche,johnharris,gregrutkowski,sinjonghun,moebius,simonstalenhag.instyleofcgart.raytracing.celshading.hyperdetailed.realistic.ue5.maya.octanerender.' }, ] }, ... ]
完成数据的处理后,修改finetune.sh[14]中的 data_path 参数(必须)以及其他想要调整的参数(可选,例如学习率)。 修改完成后,即可启动训练: sh./scripts/v1_5/finetune.sh 以上就是 LLaVA 的训练流程。 引用链接[1]官方教程:https://github.com/haotian-liu/LLaVA?tab=readme-ov-file#train
[2]LLaVA-Pretrain:https://huggingface.co/datasets/liuhaotian/LLaVA-Pretrain
[3]llava_v1_5_mix665k.json:https://huggingface.co/datasets/liuhaotian/LLaVA-Instruct-150K/blob/main/llava_v1_5_mix665k.json
[4]COCO train2017:http://images.cocodataset.org/zips/train2017.zip
[5]GQA images:https://downloads.cs.stanford.edu/nlp/data/gqa/images.zip
[6]OCR-VQA:https://drive.google.com/drive/folders/1_GYPY5UkUy7HIcR0zq3ZCFgeZN7BAfm_?usp=sharing
[7]OCR-VQA 图像的后缀问题:https://github.com/haotian-liu/LLaVA/issues/601
[8]TextVQA:https://dl.fbaipublicfiles.com/textvqa/images/train_val_images.zip
[9]part1:https://cs.stanford.edu/people/rak248/VG_100K_2/images.zip
[10]part2:https://cs.stanford.edu/people/rak248/VG_100K_2/images2.zip
[11]finetune_lora.sh:https://github.com/haotian-liu/LLaVA/blob/main/scripts/v1_5/finetune_lora.sh
[12]LLaVA 评测:https://github.com/haotian-liu/LLaVA?tab=readme-ov-file#evaluation
[13]Finetune LLaVA on Custom Datasets:https://github.com/haotian-liu/LLaVA/blob/main/docs/Finetune_Custom_Data.md
[14]finetune.sh:https://github.com/haotian-liu/LLaVA/blob/main/scripts/v1_5/finetune.sh
|