ConvLLaVAを日本語LLMで学習してみた

## はじめに
Image EncoderにCNN系のモデルであるConvNeXtを使用した、ConvLLaVAが提案されました。

本記事はConvLLaVAを使って768x768の画像が入力可能な日本語VLMを学習してみました。

また、学習したモデルを日本語ベンチマークを使用して他のモデルとの比較も行いました。

モデルの重みは以下で公開しています。

https://huggingface.co/toshi456/ConvLLaVA-JP-1.3b-768

## ConvLLaVAについて
ConvLLaVAは[ConvLLaVA: Hierarchical Backbones as Visual Encoder for Large Multimodal Models](https://arxiv.org/abs/2405.15738)で提案された手法です。

前述したとおりImage EncoderにConvNeXtを使用しているのが特徴ですが他にも以下の2つの工夫点があります。

### 工夫点1
ConvNeXtにStage 5を追加することで解像度が高い画像を入力しても画像トークンが少なくなるようにしている。

ConvNeXtは通常4つのStageからできているモデルですが、ConvLLaVAでは以下のようにStage 5を追加しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571964/3a26da5a-0317-9fe1-ad07-1e13d3fdce40.png)
> ConvLLaVA: Hierarchical Backbones as Visual Encoder for Large Multimodal Models, Ge, C. et al.(2024)

ConvNeXtはStage 1では最初の層にストライドが4の4x4の畳み込み層があり、それ以降のStageの最初の層ではストライドが2の2x2の畳み込み層があります。

そのためStageを追加することで特徴マップの解像度が圧縮されて画像トークン数を減らすことができます。

ConvLLaVAの解像度ごとの画像トークン数は以下のとおりです。

|解像度|画像トークン数|
|-|-|
|768x768|144|
|1024x1024|256|
|1280x1280|400|
|1536x1536|576|

### 工夫点2
高解像度に対応するためImage Encoderも発火させている。

ConvLLaVAでは以下の図のように学習が3段階で行われています。2段階目では高解像度の画像にも対応できるように、Image Encoderの学習を行っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571964/d4420e9d-e50d-12c2-8474-ff8905c5c6ce.png)
> ConvLLaVA: Hierarchical Backbones as Visual Encoder for Large Multimodal Models, Ge, C. et al.(2024)

## ConvLLaVAの学習
今回学習を行うにあたり入力画像の解像度は768x768にリサイズし、Image EncoderとLLMは以下のものを使用しました。

||モデル名|
|-|-|
|Image Encoder|[laion/CLIP-convnext_large_d_320.laion2B-s29B-b131K-ft](https://huggingface.co/laion/CLIP-convnext_large_d_320.laion2B-s29B-b131K-ft)|
|LLM|[llm-jp/llm-jp-1.3b-v1.0](https://huggingface.co/llm-jp/llm-jp-1.3b-v1.0)|

### 学習データ
学習データは過去に私が学習させた[llava-jp-1.3b-v1.1](https://huggingface.co/toshi456/llava-jp-1.3b-v1.1)と比較したかったこともあり以下を使用しました。

|学習フェーズ|データセット名|
|-|-|
|Stage1|[LLaVA-Pretrain-JA](https://huggingface.co/datasets/turing-motors/LLaVA-Pretrain-JA)|
|Stage2|[LLaVA-Pretrain-JA](https://huggingface.co/datasets/turing-motors/LLaVA-Pretrain-JA)|
|Stage3|[LLaVA-v1.5-Instruct-620K-JA](https://huggingface.co/datasets/turing-motors/LLaVA-v1.5-Instruct-620K-JA)|

### 学習パラメータ
学習パラメータは論文に合わせて以下のものを使用しました。

|学習フェーズ|lr|batch size|warmup ratio|epoch|optimizer|
|-|-|-|-|-|-|
|Stage1|3e-4|32|0.03|1|AdamW|
|Stage2|2e-5|32|0.03|1|adamw_bnb_8bit|
|Stage3|2e-5|32|0.03|1|adamw_bnb_8bit|


### 学習戦略
論文に合わせて学習段階ごとに発火させる層を変更しています。✓がついているのが発火させている層です。

Staeg 5はConvNeXtに追加したStage 5のことです。

|学習フェーズ|ConvNeXt|Stage 5|Projector|LLM|
|-|-|-|-|-|
|Stage1||✓|✓||
|Stage2|✓|✓|✓|✓|
|Stage3|||✓|✓|

## 評価
### 評価データ
評価データとしてRouge-Lで評価するJA-VG-VQA-500とJA-VLM-Bench-In-the-Wild、GPT4で評価を行うHeron-Benchを使用します。

|評価データ|評価手法|
|-|-|
|[JA-VG-VQA-500](https://huggingface.co/datasets/SakanaAI/JA-VG-VQA-500)|Rouge-L|
|[JA-VLM-Bench-In-the-Wild](https://huggingface.co/datasets/SakanaAI/JA-VLM-Bench-In-the-Wild)|Rouge-L|
|[Heron-Bench](https://huggingface.co/datasets/turing-motors/Japanese-Heron-Bench)|GPT4|

### 結果

今回学習させたConvLLaVAと既存の日本語VLMのベンチマークスコアは以下のとおりです。

|モデル|パラメータ数|JA-VG-VQA-500|JA-VLM-Bench-In-the-Wild|Heron-Bench(Detail)|Heron-Bench(Conv)|Heron-Bench(Complex)|Heron-Bench(Average)|
|-|-|-|-|-|-|-|-|
|[Japanese Stable VLM](https://huggingface.co/stabilityai/japanese-stable-vlm)|7.57B|-|40.50|25.15|51.23|37.84|38.07|
|[EvoVLM-JP-v1-7B](https://huggingface.co/SakanaAI/EvoVLM-JP-v1-7B)|7.57B|<font color="Red">**19.70**</font>|<font color="Red">**51.25**</font>|<font color="Blue">50.31</font>|44.42|40.47|45.07|
|[Heron BLIP-7B](https://huggingface.co/turing-motors/heron-chat-blip-ja-stablelm-base-7b-v1-llava-620k)|8.15B|14.51|33.26|49.09|41.51|45.72|45.44|
|[Heron GIT-7B](https://huggingface.co/turing-motors/heron-chat-git-ja-stablelm-base-7b-v1)|7.32B|<font color="Blue">15.18</font>|37.82|42.77|<font color="Red">**54.20**</font>|43.53|<font color="Blue">46.83</font>|
|[llava-jp-1.3b-v1.0-620k](https://huggingface.co/toshi456/llava-jp-1.3b-v1.0-620k)|1.86B|12.69|<font color="Blue">44.58</font>|<font color="Red">**51.21**</font>|41.05|45.95|44.84|
|[llava-jp-1.3b-v1.1](https://huggingface.co/toshi456/llava-jp-1.3b-v1.1)|1.86B|13.33|44.40|50.00|<font color="Blue">51.83</font>|<font color="Red">**48.98**</font>|<font color="Red">**50.39**</font>|
|[ConvLLaVA-JP-1.3b-768](https://huggingface.co/toshi456/ConvLLaVA-JP-1.3b-768)|2.10B|12.05|42.80|44.24|40.00|<font color="Blue">48.16</font>|44.96|
|[ConvLLaVA-JP-1.3b-1280](https://huggingface.co/toshi456/ConvLLaVA-JP-1.3b-1280)|11.88|43.64|38.95|44.79|41.24|42.31|

- ※ <font color="Red">**赤字**</font>は1番スコアが高いもの、<font color="Blue">青字</font>は2番目にスコアが高いもの

768x768の画像で学習させたConvLLaVAの性能はSigLIPを画像エンコーダとして使用し、384x384の画像で学習させたllava-jp-1.3b-v1.0-620kと近い性能でした。

解像度をあげたにも関わらず性能が低いのは画像トークン数が少ないことが原因だと考えられます。

ただ、画像トークン数が少なく画像エンコーダも1回しか通さないため、推論速度が早いのは良いなと思いました(速度は正確に測定したわけではなく体感ですが)。

## 出力例
今回学習させたConvLLaVA-JPのHeron-Benchの出力をいくつか紹介します。

### 例1 「鳥の羽の色は何色でしょうか？」

![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571964/49d02a9f-a949-04b6-4fb6-d17a0c73ab53.jpeg)

|モデル名|出力|
|-|-|
|ConvLLaVA-JP-1.3b-768|鳥の羽の色は茶色です。|

### 例2 「力士たちは何を行っているか説明してください。」

![009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571964/f877526b-0c24-5beb-9612-6b471f983d52.jpeg)

|モデル名|出力|
|-|-|
|ConvLLaVA-JP-1.3b-768|画像の中の力士たちは、おそらく日本の伝統的な儀式や祭りの一環として、大きな丸い丸いお札を使ってパフォーマンスを披露しています。彼らは、おそらく儀式の一部として、またはパフォーマンスの一部として、丸いお札を使ってパフォーマンスを行います。|

### 例3 「あなたは車を運転しており、交差点で右折しようと思っています。このまま交差点に向かってよいでしょうか？」

![020.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571964/4861e356-f861-e7dd-b610-56c48adff748.jpeg)

|モデル名|出力|
|-|-|
|ConvLLaVA-JP-1.3b-768|いいえ、画像の交差点で右折しようとする車を運転している人は、交差点で右折しようとする車を運転している人に注意し、注意を払う必要があります。交差点での右折は、交通の流れを乱し、事故のリスクを高める可能性があるため、慎重に行う必要があります。ドライバーは、交差点での右折を試みる前に、交通信号や標識に注意を払い、交通ルールを守り、他の車と安全な距離を保つ必要があります。|

## まとめ
本記事ではConvLLaVAを日本語LLMで学習させてみました。

768x768では性能が微妙でしたので、今後もう少し解像度をあげて学習してみようと思います。

1280x1280で学習してみましたが768x768よりベンチマーク結果が悪かったです。(2024/6/14 追記)

また、ConvLLaVAではアスペクト比を保つことでDocVQAの精度が向上したことも報告されています。そのため今後JDocQAの学習も試してみたいと考えています。

学習にしようしたコードは以下で公開しています。RTX4090が1枚あれば学習できるので気になる方は学習してみてください。

https://github.com/tosiyuki/LLaVA-JP

## TODO
- [x] 1280x1280の解像度でモデルを学習させる
- [ ] JDocQAで微調整してみる