Skip to content

Commit e523827

Browse files
committed
Merge branch 'develop' into main
2 parents f47c16e + 9e3f3d0 commit e523827

9 files changed

Lines changed: 262 additions & 10 deletions

File tree

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919

2020

2121
## Release
22-
- [10/12] 🔥 Check out the Korean LLaVA (Ko-LLaVA), created by ETRI, who has generously supported our research! [[🤗 Demo](https://huggingface.co/spaces/etri-vilab/Ko-LLaVA)]
22+
- [10/26] 🔥 LLaVA-1.5 with LoRA achieves comparable performance as full-model finetuning, with a reduced GPU RAM requirement ([ckpts](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md#llava-v15), [script](https://github.com/haotian-liu/LLaVA#train)). We also provide a [doc](https://github.com/haotian-liu/LLaVA/blob/main/docs/Finetune_Custom_Data.md) on how to finetune LLaVA-1.5 on your own dataset with LoRA.
23+
- [10/12] Check out the Korean LLaVA (Ko-LLaVA), created by ETRI, who has generously supported our research! [[🤗 Demo](https://huggingface.co/spaces/etri-vilab/Ko-LLaVA)]
2324
- [10/12] LLaVA is now supported in [llama.cpp](https://github.com/ggerganov/llama.cpp/pull/3436) with 4-bit / 5-bit quantization support!
2425
- [10/11] The training data and scripts of LLaVA-1.5 are released [here](https://github.com/haotian-liu/LLaVA#train), and evaluation scripts are released [here](https://github.com/haotian-liu/LLaVA/blob/main/docs/Evaluation.md)!
2526
- [10/5] 🔥 LLaVA-1.5 is out! Achieving SoTA on 11 benchmarks, with just simple modifications to the original LLaVA, utilizes all public data, completes training in ~1 day on a single 8-A100 node, and surpasses methods like Qwen-VL-Chat that use billion-scale data. Check out the [technical report](https://arxiv.org/abs/2310.03744), and explore the [demo](https://llava.hliu.cc/)! Models are available in [Model Zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md).
@@ -237,6 +238,13 @@ Visual instruction tuning takes around 20 hours for LLaVA-v1.5-13B on 8x A100 (8
237238

238239
Training script with DeepSpeed ZeRO-3: [`finetune.sh`](https://github.com/haotian-liu/LLaVA/blob/main/scripts/v1_5/finetune.sh).
239240

241+
If you are do not have enough GPU memory:
242+
243+
- Use LoRA: [`finetune_lora.sh`](https://github.com/haotian-liu/LLaVA/blob/main/scripts/v1_5/finetune_lora.sh). We are able to fit 13B training in 8-A100-40G/8-A6000, and 7B training in 8-RTX3090. Make sure `per_device_train_batch_size*gradient_accumulation_steps` is the same as the provided script for best reproducibility.
244+
- Replace `zero3.json` with `zero3_offload.json` which offloads some parameters to CPU RAM. This slows down the training speed.
245+
246+
If you are interested in finetuning LLaVA model to your own task/data, please check out [`Finetune_Custom_Data.md`](https://github.com/haotian-liu/LLaVA/blob/main/docs/Finetune_Custom_Data.md)
247+
240248
New options to note:
241249

242250
- `--mm_projector_type mlp2x_gelu`: the two-layer MLP vision-language connector.

docs/Finetune_Custom_Data.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Finetune LLaVA on Custom Datasets
2+
3+
## Dataset Format
4+
5+
Convert your data to a JSON file of a List of all samples. Sample metadata should contain `id` (a unique identifier), `image` (the path to the image), and `conversations` (the conversation data between human and AI).
6+
7+
A sample JSON for finetuning LLaVA for generating tag-style captions for Stable Diffusion:
8+
9+
```json
10+
[
11+
{
12+
"id": "997bb945-628d-4724-b370-b84de974a19f",
13+
"image": "part-000001/997bb945-628d-4724-b370-b84de974a19f.jpg",
14+
"conversations": [
15+
{
16+
"from": "human",
17+
"value": "<image>\nWrite a prompt for Stable Diffusion to generate this image."
18+
},
19+
{
20+
"from": "gpt",
21+
"value": "a beautiful painting of chernobyl by nekro, pascal blanche, john harris, greg rutkowski, sin jong hun, moebius, simon stalenhag. in style of cg art. ray tracing. cel shading. hyper detailed. realistic. ue 5. maya. octane render. "
22+
},
23+
]
24+
},
25+
...
26+
]
27+
```
28+
29+
## Command
30+
31+
If you have a limited task-specific data, we recommend finetuning from LLaVA checkpoints with LoRA following this [script](https://github.com/haotian-liu/LLaVA/blob/main/scripts/v1_5/finetune_task_lora.sh).
32+
33+
You may need to adjust the hyperparameters to fit each specific dataset and your hardware constraint.
34+
35+

docs/MODEL_ZOO.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ The model weights below are *merged* weights. You do not need to apply delta. Th
1010

1111
| Version | Size | Schedule | Checkpoint | VQAv2 | GQA | VizWiz | SQA | T-VQA | POPE | MME | MM-Bench | MM-Bench-CN | SEED | LLaVA-Bench-Wild | MM-Vet |
1212
|----------|----------|-----------|-----------|---|---|---|---|---|---|---|---|---|---|---|---|
13-
| LLaVA-1.5 | 7B | full_ft-1e | [liuhaotian/llava-v1.5-7b](https://huggingface.co/liuhaotian/llava-v1.5-7b), [logs](https://api.wandb.ai/links/lht/6orh56wc) | 78.5 | 62.0 | 50.0 | 66.8 | 58.2 | 85.9 | 1510.7 | 64.3 | 58.3 | 58.6 | 65.4 | 31.1 |
14-
| LLaVA-1.5 | 13B | full_ft-1e | [liuhaotian/llava-v1.5-13b](https://huggingface.co/liuhaotian/llava-v1.5-13b), [logs](https://api.wandb.ai/links/lht/6orh56wc) | 80.0 | 63.3 | 53.6 | 71.6 | 61.3 | 85.9 | 1531.3 | 67.7 | 63.6 | 61.6 | 72.5 | 36.1 |
15-
| LLaVA-1.5 | 7B | lora-1e | coming soon |
16-
| LLaVA-1.5 | 13B | lora-1e | coming soon |
13+
| LLaVA-1.5 | 7B | full_ft-1e | [liuhaotian/llava-v1.5-7b](https://huggingface.co/liuhaotian/llava-v1.5-7b) | 78.5 | 62.0 | 50.0 | 66.8 | 58.2 | 85.9 | 1510.7 | 64.3 | 58.3 | 58.6 | 65.4 | 31.1 |
14+
| LLaVA-1.5 | 13B | full_ft-1e | [liuhaotian/llava-v1.5-13b](https://huggingface.co/liuhaotian/llava-v1.5-13b) | 80.0 | 63.3 | 53.6 | 71.6 | 61.3 | 85.9 | 1531.3 | 67.7 | 63.6 | 61.6 | 72.5 | 36.1 |
15+
| LLaVA-1.5 | 7B | lora-1e | [liuhaotian/llava-v1.5-7b-lora](https://huggingface.co/liuhaotian/llava-v1.5-7b-lora) | 79.1 | 63.0 | 47.8 | 68.4 | 58.2 | 86.4 | 1476.9 | 66.1 | 58.9 | 60.1 | 67.9 | 30.2 |
16+
| LLaVA-1.5 | 13B | lora-1e | [liuhaotian/llava-v1.5-13b-lora](https://huggingface.co/liuhaotian/llava-v1.5-13b-lora) | 80.0 | 63.3 | 58.9 | 71.2 | 60.2 | 86.7 | 1541.7 | 68.5 | 61.5 | 61.3 | 69.5 | 38.3 |
17+
18+
Training logs: [wandb](https://api.wandb.ai/links/lht/6orh56wc).
1719

1820
<p align="center">
1921
<img src="../images/llava_v1_5_radar.jpg" width="500px"> <br>

llava/model/llava_arch.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ def initialize_vision_modules(self, model_args, fsdp=None):
6969

7070
if getattr(self, 'mm_projector', None) is None:
7171
self.mm_projector = build_vision_projector(self.config)
72+
else:
73+
# In case it is frozen by LoRA
74+
for p in self.mm_projector.parameters():
75+
p.requires_grad = True
7276

7377
if pretrain_mm_mlp_adapter is not None:
7478
mm_projector_weights = torch.load(pretrain_mm_mlp_adapter, map_location='cpu')

llava/train/llava_trainer.py

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
from transformers import Trainer
77
from transformers.trainer import (
8+
is_sagemaker_mp_enabled,
9+
get_parameter_names,
810
has_length,
11+
ALL_LAYERNORM_LAYERS,
12+
ShardedDDPOption,
13+
logger,
914
)
1015
from typing import List, Optional
1116

@@ -74,12 +79,8 @@ def get_modality_length_grouped_indices(lengths, batch_size, world_size, generat
7479
megabatch_indices = torch.randperm(len(megabatches), generator=generator)
7580
megabatches = [megabatches[i] for i in megabatch_indices]
7681

77-
if len(additional_batch) >= megabatch_size:
78-
megabatches = [additional_batch[:megabatch_size]] + megabatches
79-
additional_batch = additional_batch[megabatch_size:]
80-
8182
if len(additional_batch) > 0:
82-
megabatches.append(additional_batch)
83+
megabatches.append(sorted(additional_batch))
8384

8485
return [i for megabatch in megabatches for i in megabatch]
8586

@@ -146,6 +147,95 @@ def _get_train_sampler(self) -> Optional[torch.utils.data.Sampler]:
146147
else:
147148
return super()._get_train_sampler()
148149

150+
def create_optimizer(self):
151+
"""
152+
Setup the optimizer.
153+
154+
We provide a reasonable default that works well. If you want to use something else, you can pass a tuple in the
155+
Trainer's init through `optimizers`, or subclass and override this method in a subclass.
156+
"""
157+
if is_sagemaker_mp_enabled():
158+
return super().create_optimizer()
159+
if self.sharded_ddp == ShardedDDPOption.SIMPLE:
160+
return super().create_optimizer()
161+
162+
opt_model = self.model
163+
164+
if self.optimizer is None:
165+
decay_parameters = get_parameter_names(opt_model, ALL_LAYERNORM_LAYERS)
166+
decay_parameters = [name for name in decay_parameters if "bias" not in name]
167+
if self.args.mm_projector_lr is not None:
168+
projector_parameters = [name for name, _ in opt_model.named_parameters() if "mm_projector" in name]
169+
optimizer_grouped_parameters = [
170+
{
171+
"params": [
172+
p for n, p in opt_model.named_parameters() if (n in decay_parameters and n not in projector_parameters and p.requires_grad)
173+
],
174+
"weight_decay": self.args.weight_decay,
175+
},
176+
{
177+
"params": [
178+
p for n, p in opt_model.named_parameters() if (n not in decay_parameters and n not in projector_parameters and p.requires_grad)
179+
],
180+
"weight_decay": 0.0,
181+
},
182+
{
183+
"params": [
184+
p for n, p in opt_model.named_parameters() if (n in decay_parameters and n in projector_parameters and p.requires_grad)
185+
],
186+
"weight_decay": self.args.weight_decay,
187+
"lr": self.args.mm_projector_lr,
188+
},
189+
{
190+
"params": [
191+
p for n, p in opt_model.named_parameters() if (n not in decay_parameters and n in projector_parameters and p.requires_grad)
192+
],
193+
"weight_decay": 0.0,
194+
"lr": self.args.mm_projector_lr,
195+
},
196+
]
197+
else:
198+
optimizer_grouped_parameters = [
199+
{
200+
"params": [
201+
p for n, p in opt_model.named_parameters() if (n in decay_parameters and p.requires_grad)
202+
],
203+
"weight_decay": self.args.weight_decay,
204+
},
205+
{
206+
"params": [
207+
p for n, p in opt_model.named_parameters() if (n not in decay_parameters and p.requires_grad)
208+
],
209+
"weight_decay": 0.0,
210+
},
211+
]
212+
213+
optimizer_cls, optimizer_kwargs = Trainer.get_optimizer_cls_and_kwargs(self.args)
214+
215+
if self.sharded_ddp == ShardedDDPOption.SIMPLE:
216+
self.optimizer = OSS(
217+
params=optimizer_grouped_parameters,
218+
optim=optimizer_cls,
219+
**optimizer_kwargs,
220+
)
221+
else:
222+
self.optimizer = optimizer_cls(optimizer_grouped_parameters, **optimizer_kwargs)
223+
if optimizer_cls.__name__ == "Adam8bit":
224+
import bitsandbytes
225+
226+
manager = bitsandbytes.optim.GlobalOptimManager.get_instance()
227+
228+
skipped = 0
229+
for module in opt_model.modules():
230+
if isinstance(module, nn.Embedding):
231+
skipped += sum({p.data_ptr(): p.numel() for p in module.parameters()}.values())
232+
logger.info(f"skipped {module}: {skipped/2**20}M params")
233+
manager.register_module_override(module, "weight", {"optim_bits": 32})
234+
logger.debug(f"bitsandbytes: will optimize {module} in fp32")
235+
logger.info(f"skipped: {skipped/2**20}M params")
236+
237+
return self.optimizer
238+
149239
def _save_checkpoint(self, model, trial, metrics=None):
150240
if getattr(self.args, 'tune_mm_mlp_adapter', False):
151241
from transformers.trainer_utils import PREFIX_CHECKPOINT_DIR

llava/train/train.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class TrainingArguments(transformers.TrainingArguments):
103103
lora_dropout: float = 0.05
104104
lora_weight_path: str = ""
105105
lora_bias: str = "none"
106+
mm_projector_lr: Optional[float] = None
106107
group_by_modality_length: bool = field(default=False)
107108

108109

@@ -900,6 +901,7 @@ def make_inputs_require_grad(module, input, output):
900901
model.get_model().mm_projector.to(dtype=compute_dtype, device=training_args.device)
901902

902903
model.config.mm_use_im_start_end = data_args.mm_use_im_start_end = model_args.mm_use_im_start_end
904+
model.config.mm_projector_lr = training_args.mm_projector_lr
903905
training_args.use_im_start_end = model_args.mm_use_im_start_end
904906
model.config.mm_use_im_patch_token = model_args.mm_use_im_patch_token
905907
model.initialize_vision_tokenizer(model_args, tokenizer=tokenizer)

scripts/v1_5/finetune_lora.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
deepspeed llava/train/train_mem.py \
4+
--lora_enable True --lora_r 128 --lora_alpha 256 --mm_projector_lr 2e-5 \
5+
--deepspeed ./scripts/zero3.json \
6+
--model_name_or_path lmsys/vicuna-13b-v1.5 \
7+
--version v1 \
8+
--data_path ./playground/data/llava_v1_5_mix665k.json \
9+
--image_folder ./playground/data \
10+
--vision_tower openai/clip-vit-large-patch14-336 \
11+
--pretrain_mm_mlp_adapter ./checkpoints/llava-v1.5-13b-pretrain/mm_projector.bin \
12+
--mm_projector_type mlp2x_gelu \
13+
--mm_vision_select_layer -2 \
14+
--mm_use_im_start_end False \
15+
--mm_use_im_patch_token False \
16+
--image_aspect_ratio pad \
17+
--group_by_modality_length True \
18+
--bf16 True \
19+
--output_dir ./checkpoints/llava-v1.5-13b-lora \
20+
--num_train_epochs 1 \
21+
--per_device_train_batch_size 16 \
22+
--per_device_eval_batch_size 4 \
23+
--gradient_accumulation_steps 1 \
24+
--evaluation_strategy "no" \
25+
--save_strategy "steps" \
26+
--save_steps 50000 \
27+
--save_total_limit 1 \
28+
--learning_rate 2e-4 \
29+
--weight_decay 0. \
30+
--warmup_ratio 0.03 \
31+
--lr_scheduler_type "cosine" \
32+
--logging_steps 1 \
33+
--tf32 True \
34+
--model_max_length 2048 \
35+
--gradient_checkpointing True \
36+
--dataloader_num_workers 4 \
37+
--lazy_preprocess True \
38+
--report_to wandb

scripts/v1_5/finetune_task.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
deepspeed llava/train/train_mem.py \
4+
--deepspeed ./scripts/zero3.json \
5+
--model_name_or_path liuhaotian/llava-v1.5-13b \
6+
--version v1 \
7+
--data_path ./playground/data/llava_v1_5_mix665k.json \
8+
--image_folder ./playground/data \
9+
--vision_tower openai/clip-vit-large-patch14-336 \
10+
--mm_projector_type mlp2x_gelu \
11+
--mm_vision_select_layer -2 \
12+
--mm_use_im_start_end False \
13+
--mm_use_im_patch_token False \
14+
--image_aspect_ratio pad \
15+
--group_by_modality_length True \
16+
--bf16 True \
17+
--output_dir ./checkpoints/llava-v1.5-13b-task \
18+
--num_train_epochs 1 \
19+
--per_device_train_batch_size 16 \
20+
--per_device_eval_batch_size 4 \
21+
--gradient_accumulation_steps 1 \
22+
--evaluation_strategy "no" \
23+
--save_strategy "steps" \
24+
--save_steps 50000 \
25+
--save_total_limit 1 \
26+
--learning_rate 2e-5 \
27+
--weight_decay 0. \
28+
--warmup_ratio 0.03 \
29+
--lr_scheduler_type "cosine" \
30+
--logging_steps 1 \
31+
--tf32 True \
32+
--model_max_length 2048 \
33+
--gradient_checkpointing True \
34+
--dataloader_num_workers 4 \
35+
--lazy_preprocess True \
36+
--report_to wandb

scripts/v1_5/finetune_task_lora.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
deepspeed llava/train/train_mem.py \
4+
--lora_enable True --lora_r 128 --lora_alpha 256 --mm_projector_lr 2e-5 \
5+
--deepspeed ./scripts/zero3.json \
6+
--model_name_or_path liuhaotian/llava-v1.5-13b \
7+
--version v1 \
8+
--data_path ./playground/data/llava_v1_5_mix665k.json \
9+
--image_folder ./playground/data \
10+
--vision_tower openai/clip-vit-large-patch14-336 \
11+
--mm_projector_type mlp2x_gelu \
12+
--mm_vision_select_layer -2 \
13+
--mm_use_im_start_end False \
14+
--mm_use_im_patch_token False \
15+
--image_aspect_ratio pad \
16+
--group_by_modality_length True \
17+
--bf16 True \
18+
--output_dir ./checkpoints/llava-v1.5-13b-task-lora \
19+
--num_train_epochs 1 \
20+
--per_device_train_batch_size 16 \
21+
--per_device_eval_batch_size 4 \
22+
--gradient_accumulation_steps 1 \
23+
--evaluation_strategy "no" \
24+
--save_strategy "steps" \
25+
--save_steps 50000 \
26+
--save_total_limit 1 \
27+
--learning_rate 2e-4 \
28+
--weight_decay 0. \
29+
--warmup_ratio 0.03 \
30+
--lr_scheduler_type "cosine" \
31+
--logging_steps 1 \
32+
--tf32 True \
33+
--model_max_length 2048 \
34+
--gradient_checkpointing True \
35+
--dataloader_num_workers 4 \
36+
--lazy_preprocess True \
37+
--report_to wandb

0 commit comments

Comments
 (0)