diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5b3f4e8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+__pycache__
+
+.ipynb_checkpoints
+
+output/*
+!output/.gitkeep
+
+data/*
+!data/.gitkeep
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e613aeb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,97 @@
+# Heron - A Library for Vision/Video and Language models
+
+
+
+
+
+Welcome to "heron" repository. Heron is a library that seamlessly integrates multiple Vision and Language models, as well as Video and Language models. One of its standout features is its support for Japanese V&L models. Additionally, we provide pretrained weights trained on various datasets.
+
+
+# Installation
+1. Clone this repository
+```bash
+git clone https://github.com/turingmotors/heron
+cd heron
+```
+
+2. Install Packages
+```bash
+conda create -n git_llm python=3.10 -y
+conda activate git_llm
+pip install --upgrade pip # enable PEP 660 support
+
+pip install -r requirements.txt
+pip install -e .
+```
+
+## For Llama 2
+First, you request access to the llama-2 models, in [huggingface page](https://huggingface.co/meta-llama/Llama-2-7b) and [facebook website](https://ai.meta.com/resources/models-and-libraries/llama-downloads/)
+
+Please sign-in the huggingface account
+```bash
+huggingface-cli login
+```
+
+# Training
+
+Now we support LLaMA, MPT, and OPT as a LLM module.
+
+```bash
+./scripts/run.sh
+```
+
+# Evaluation
+
+You can get the pretrained weight form HuggingFace Hub: [Inoichan/GIT-Llama-2-7B](https://huggingface.co/Inoichan/GIT-Llama-2-7B)
+See also [notebooks](./notebooks).
+
+```python
+import requests
+from transformers import AutoProcessor
+from git_llm.git_llama import GitLlamaForCausalLM
+
+device_id = 0
+
+# prepare a pretrained model
+model = GitLlamaForCausalLM.from_pretrained('Inoichan/GIT-Llama-2-7B')
+model.eval()
+model.to(f"cuda:{device_id}")
+
+# prepare a processor
+processor = AutoProcessor.from_pretrained('Inoichan/GIT-Llama-2-7B')
+
+# prepare inputs
+url = "https://www.barnorama.com/wp-content/uploads/2016/12/03-Confusing-Pictures.jpg"
+image = Image.open(requests.get(url, stream=True).raw)
+
+text = f"##Instruction: Please answer the following question concletely. ##Question: What is unusual about this image? Explain precisely and concletely what he is doing? ##Answer: "
+
+# do preprocessing
+inputs = processor(
+ text,
+ image,
+ return_tensors="pt",
+ truncation=True,
+)
+inputs = {k: v.to(f"cuda:{device_id}") for k, v in inputs.items()}
+
+# set eos token
+eos_token_id_list = [
+ processor.tokenizer.pad_token_id,
+ processor.tokenizer.eos_token_id,
+]
+
+# do inference
+with torch.no_grad():
+ out = model.generate(**inputs, max_length=256, do_sample=False, temperature=0., eos_token_id=eos_token_id_list)
+
+# print result
+print(processor.tokenizer.batch_decode(out))
+```
+
+# Acknoledge
+
+- [GenerativeImage2Text](https://github.com/microsoft/GenerativeImage2Text): The main idia of the model is based on original GIT.
+- [Llava](https://github.com/haotian-liu/LLaVA): This project is learned a lot from the great Llava project.
+- [GIT-LLM](https://github.com/Ino-Ichan/GIT-LLM)
+- [video_blip](https://github.com/kotarotanahashi/video_blip)
diff --git a/configs/datasets/m3it.yaml b/configs/datasets/m3it.yaml
new file mode 100644
index 0000000..acba611
--- /dev/null
+++ b/configs/datasets/m3it.yaml
@@ -0,0 +1,3 @@
+dataset_type: coco
+
+tarain_val: true
diff --git a/configs/deepspeed/ds_config_zero1.json b/configs/deepspeed/ds_config_zero1.json
new file mode 100644
index 0000000..e9200a5
--- /dev/null
+++ b/configs/deepspeed/ds_config_zero1.json
@@ -0,0 +1,48 @@
+{
+ "fp16": {
+ "enabled": "auto",
+ "loss_scale": 0,
+ "loss_scale_window": 1000,
+ "initial_scale_power": 16,
+ "hysteresis": 2,
+ "min_loss_scale": 1
+ },
+ "bf16": {
+ "enabled": "auto"
+ },
+ "optimizer": {
+ "type": "AdamW",
+ "params": {
+ "lr": "auto",
+ "betas": "auto",
+ "eps": "auto",
+ "weight_decay": "auto"
+ }
+ },
+ "scheduler": {
+ "type": "WarmupLR",
+ "params": {
+ "warmup_min_lr": "auto",
+ "warmup_max_lr": "auto",
+ "warmup_num_steps": "auto"
+ }
+ },
+ "zero_optimization": {
+ "stage": 1,
+ "overlap_comm": true,
+ "contiguous_gradients": true,
+ "sub_group_size": 1e9,
+ "reduce_bucket_size": 1e7,
+ "stage3_prefetch_bucket_size": 1e7,
+ "stage3_param_persistence_threshold": 10240,
+ "stage3_max_live_parameters": 1e9,
+ "stage3_max_reuse_distance": 1e9,
+ "stage3_gather_16bit_weights_on_model_save": true
+ },
+ "gradient_accumulation_steps": "auto",
+ "gradient_clipping": "auto",
+ "steps_per_print": 100,
+ "train_batch_size": "auto",
+ "train_micro_batch_size_per_gpu": "auto",
+ "wall_clock_breakdown": false
+}
\ No newline at end of file
diff --git a/configs/deepspeed/ds_config_zero2.json b/configs/deepspeed/ds_config_zero2.json
new file mode 100644
index 0000000..79a93e1
--- /dev/null
+++ b/configs/deepspeed/ds_config_zero2.json
@@ -0,0 +1,48 @@
+{
+ "fp16": {
+ "enabled": "auto",
+ "loss_scale": 0,
+ "loss_scale_window": 1000,
+ "initial_scale_power": 16,
+ "hysteresis": 2,
+ "min_loss_scale": 1
+ },
+ "bf16": {
+ "enabled": "auto"
+ },
+ "optimizer": {
+ "type": "AdamW",
+ "params": {
+ "lr": "auto",
+ "betas": "auto",
+ "eps": "auto",
+ "weight_decay": "auto"
+ }
+ },
+ "scheduler": {
+ "type": "WarmupLR",
+ "params": {
+ "warmup_min_lr": "auto",
+ "warmup_max_lr": "auto",
+ "warmup_num_steps": "auto"
+ }
+ },
+ "zero_optimization": {
+ "stage": 2,
+ "overlap_comm": true,
+ "contiguous_gradients": true,
+ "sub_group_size": 1e9,
+ "reduce_bucket_size": 1e7,
+ "stage3_prefetch_bucket_size": 1e7,
+ "stage3_param_persistence_threshold": 10240,
+ "stage3_max_live_parameters": 1e9,
+ "stage3_max_reuse_distance": 1e9,
+ "stage3_gather_16bit_weights_on_model_save": true
+ },
+ "gradient_accumulation_steps": "auto",
+ "gradient_clipping": "auto",
+ "steps_per_print": 100,
+ "train_batch_size": "auto",
+ "train_micro_batch_size_per_gpu": "auto",
+ "wall_clock_breakdown": false
+}
\ No newline at end of file
diff --git a/configs/deepspeed/ds_config_zero3.json b/configs/deepspeed/ds_config_zero3.json
new file mode 100644
index 0000000..a778176
--- /dev/null
+++ b/configs/deepspeed/ds_config_zero3.json
@@ -0,0 +1,56 @@
+{
+ "fp16": {
+ "enabled": "auto",
+ "loss_scale": 0,
+ "loss_scale_window": 1000,
+ "initial_scale_power": 16,
+ "hysteresis": 2,
+ "min_loss_scale": 1
+ },
+ "bf16": {
+ "enabled": "auto"
+ },
+ "optimizer": {
+ "type": "AdamW",
+ "params": {
+ "lr": "auto",
+ "betas": "auto",
+ "eps": "auto",
+ "weight_decay": "auto"
+ }
+ },
+ "scheduler": {
+ "type": "WarmupLR",
+ "params": {
+ "warmup_min_lr": "auto",
+ "warmup_max_lr": "auto",
+ "warmup_num_steps": "auto"
+ }
+ },
+ "zero_optimization": {
+ "stage": 3,
+ "offload_optimizer": {
+ "device": "cpu",
+ "pin_memory": true
+ },
+ "offload_param": {
+ "device": "cpu",
+ "pin_memory": true
+ },
+ "overlap_comm": true,
+ "contiguous_gradients": true,
+ "sub_group_size": 1e9,
+ "reduce_bucket_size": 1e7,
+ "stage3_prefetch_bucket_size": 1e7,
+ "stage3_param_persistence_threshold": 10240,
+ "stage3_max_live_parameters": 1e9,
+ "stage3_max_reuse_distance": 1e9,
+ "stage3_gather_16bit_weights_on_model_save": true
+ },
+ "gradient_accumulation_steps": "auto",
+ "gradient_clipping": "auto",
+ "steps_per_print": 100,
+ "train_batch_size": "auto",
+ "train_micro_batch_size_per_gpu": "auto",
+ "wall_clock_breakdown": false
+}
\ No newline at end of file
diff --git a/configs/llama/training_config_exp050_llama.yml b/configs/llama/training_config_exp050_llama.yml
new file mode 100644
index 0000000..4b8e692
--- /dev/null
+++ b/configs/llama/training_config_exp050_llama.yml
@@ -0,0 +1,64 @@
+training:
+ per_device_train_batch_size: 2
+ gradient_accumulation_steps: 4
+ num_train_epochs: 1
+ dataloader_num_workers: 16
+ fp16: true
+ optim: "adamw_torch"
+ learning_rate: 5.0e-5
+ logging_steps: 100
+ evaluation_strategy: "steps"
+ save_strategy: "steps"
+ eval_steps: 4000
+ save_steps: 4000
+ save_total_limit: 1
+ deepspeed: configs/ds_config_zero1.json
+ output_dir: ./output/
+ report_to: "wandb"
+
+settings:
+ model_name: meta-llama/Llama-2-7b-chat-hf
+ vision_model_name: openai/clip-vit-base-patch16
+ num_image_with_embedding: # None or video sequence num
+ max_length: 512
+ keys_finetune:
+ - visual_projection
+ - num_image_with_embedding
+
+use_lora: true
+lora:
+ r: 8
+ lora_alpha: 32
+ target_modules:
+ - q_proj
+ - v_proj
+ lora_dropout: 0.01
+ bias: none
+ task_type: CAUSAL_LM
+
+dataset_type: path/to/config
+ - coco
+ - textcap
+ - image-paragraph-captioning
+ - coco-goi
+ - coco-text
+ - imagenet
+ - coco-itm
+ - snli-ve
+ - mocheg
+ - iqa
+ - vqa-v2
+ - shapes
+ - docvqa
+ - ocr-vqa
+ - st-vqa
+ - text-vqa
+ - gqa
+ - okvqa
+ - a-okvqa
+ - viquae
+ - clevr
+ - vcr
+ - visual-mrc
+ - visual-dialog
+ - multi30k
diff --git a/heron/__init__.py b/heron/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/heron/datasets/README.md b/heron/datasets/README.md
new file mode 100644
index 0000000..64f9c00
--- /dev/null
+++ b/heron/datasets/README.md
@@ -0,0 +1,17 @@
+# Datasets Description
+
+# Supported Datasets
+
+## English
+- [M3IT](https://huggingface.co/datasets/MMInstruction/M3IT)
+
+## Japanese
+- [STAIR](http://captions.stair.center/)
+- [Japanese Visual Genome VQA dataset](https://github.com/yahoojapan/ja-vg-vqa)
+
+### Preparing CSV files for Japanese STAIR/Visual Genome
+
+Download [data](../../data/) at data directory.
+For using Japanese dataset, please generate preprocessed csv files. See notebooks in [preprocess](./preprocess/).
+
+
diff --git a/heron/datasets/__init__.py b/heron/datasets/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/heron/datasets/base_datasets.py b/heron/datasets/base_datasets.py
new file mode 100644
index 0000000..41da241
--- /dev/null
+++ b/heron/datasets/base_datasets.py
@@ -0,0 +1,30 @@
+import abc
+
+from torch.utils.data import Dataset
+
+
+class BaseDataset(Dataset):
+
+ def __init__(self, is_inference: bool = False):
+ super(BaseDataset, self).__init__()
+ self.is_inference = is_inference
+
+ @abc.abstractmethod
+ @classmethod
+ def create(cls, *args, **kwargs):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def __getitem__(self, index):
+ if self.is_inference:
+ return self._get_item_inference(index)
+ else:
+ return self._get_item_train(index)
+
+ @abc.abstractmethod
+ def _get_item_train(self, index):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def _get_item_inference(self, index):
+ raise NotImplementedError
diff --git a/heron/datasets/ja_csv_datasets.py b/heron/datasets/ja_csv_datasets.py
new file mode 100644
index 0000000..dc8a831
--- /dev/null
+++ b/heron/datasets/ja_csv_datasets.py
@@ -0,0 +1,106 @@
+import cv2
+import datasets
+import numpy as np
+from PIL import Image
+from torch.utils.data import Dataset
+from transformers import (
+ AutoProcessor,
+ AutoTokenizer,
+ CLIPImageProcessor,
+ LlamaTokenizer,
+)
+
+
+class JapaneseCSVDataset(Dataset):
+ """Dataset for Custom Japanese CSV V&L Dataset learning
+ """
+
+ def __init__(
+ self,
+ model_name: str,
+ vision_model_name: str,
+ loaded_dataset: datasets.GeneratorBasedBuilder,
+ max_length: int = 128,
+ ):
+ super(JapaneseCSVDataset, self).__init__()
+ self.loaded_dataset = loaded_dataset
+ self.unique_img_path = loaded_dataset.img_path.unique()
+
+ self.max_length = max_length
+
+ self.processor = AutoProcessor.from_pretrained("microsoft/git-base")
+ self.processor.image_processor = CLIPImageProcessor.from_pretrained(vision_model_name)
+ if "japanese-stablelm" in model_name:
+ self.processor.tokenizer = LlamaTokenizer.from_pretrained(
+ "novelai/nerdstash-tokenizer-v1",
+ padding_side="right",
+ additional_special_tokens=["▁▁"],
+ )
+ elif (
+ "mpt" in model_name
+ or "matsuo-lab/weblab" in model_name
+ or "cyberagent/open-calm-7b" in model_name
+ ):
+ self.processor.tokenizer = AutoTokenizer.from_pretrained(
+ model_name, padding_side="right", use_fast=True
+ )
+ else:
+ self.processor.tokenizer = AutoTokenizer.from_pretrained(
+ model_name, padding_side="right", use_fast=False
+ )
+ if "llama" in model_name:
+ self.processor.tokenizer.pad_token = self.processor.tokenizer.eos_token
+ elif "mpt" in model_name:
+ self.processor.tokenizer.pad_token = self.processor.tokenizer.eos_token
+ elif "matsuo-lab/weblab" in model_name:
+ self.processor.tokenizer.add_special_tokens(
+ {
+ "bos_token": "<|endoftext|>",
+ "eos_token": "<|endoftext|>",
+ "pad_token": "<|padding|>",
+ "unk_token": "<|endoftext|>",
+ }
+ )
+
+ def __len__(self) -> int:
+ return len(self.unique_img_path)
+
+ def __getitem__(self, index) -> dict:
+ # cf: https://huggingface.co/datasets/MMInstruction/M3IT#data-instances
+ img_path = self.unique_img_path[index]
+
+ df_interest = self.loaded_dataset[self.loaded_dataset.img_path == img_path].reset_index(
+ drop=True
+ )
+ text = ""
+
+ # concatenate text data
+ for i in np.random.randint(0, len(df_interest), len(df_interest)):
+ row = df_interest.iloc[i]
+ # some of nlvr data were broken
+ question = row["question"] # str
+ answer = row["caption"] # str
+ text += f"##問: {question} ##答: {answer}。"
+
+ # remove final space
+ text = text[: len(text) - 1]
+
+ # imageのロード
+ img = Image.open(img_path).convert("RGB")
+ img = np.array(img)
+ if img.shape[2] != 3:
+ img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
+
+ inputs = self.processor(
+ text,
+ img,
+ return_tensors="pt",
+ max_length=self.max_length,
+ padding="max_length",
+ truncation=True,
+ )
+
+ # batch size 1 -> unbatch
+ inputs = {k: v[0] for k, v in inputs.items()}
+ inputs["labels"] = inputs["input_ids"]
+ return inputs
diff --git a/heron/datasets/m3it_datasets.py b/heron/datasets/m3it_datasets.py
new file mode 100644
index 0000000..9f1b355
--- /dev/null
+++ b/heron/datasets/m3it_datasets.py
@@ -0,0 +1,97 @@
+from base64 import b64decode
+from io import BytesIO
+
+import cv2
+import datasets
+import numpy as np
+from PIL import Image
+from torch.utils.data import Dataset
+from transformers import (
+ AutoProcessor,
+ AutoTokenizer,
+ CLIPImageProcessor,
+ LlamaTokenizer,
+)
+
+
+class M3ITDataset(Dataset):
+ """Dataset for M3IT Dataset learning
+ """
+ def __init__(
+ self,
+ model_name: str,
+ vision_model_name: str,
+ loaded_dataset: datasets.GeneratorBasedBuilder,
+ max_length: int = 128,
+ ):
+ super(M3ITDataset, self).__init__()
+ self.loaded_dataset = loaded_dataset
+ self.max_length = max_length
+
+ self.processor = AutoProcessor.from_pretrained("microsoft/git-base")
+ self.processor.image_processor = CLIPImageProcessor.from_pretrained(vision_model_name)
+ if "japanese-stablelm" in model_name:
+ self.processor.tokenizer = LlamaTokenizer.from_pretrained(
+ "novelai/nerdstash-tokenizer-v1",
+ padding_side="right",
+ additional_special_tokens=["▁▁"],
+ )
+ elif (
+ "mpt" in model_name
+ or "matsuo-lab/weblab" in model_name
+ or "cyberagent/open-calm-7b" in model_name
+ ):
+ self.processor.tokenizer = AutoTokenizer.from_pretrained(
+ model_name, padding_side="right", use_fast=True
+ )
+ else:
+ self.processor.tokenizer = AutoTokenizer.from_pretrained(
+ model_name, padding_side="right", use_fast=False
+ )
+ if "llama" in model_name:
+ self.processor.tokenizer.pad_token = self.processor.tokenizer.eos_token
+ elif "mpt" in model_name:
+ self.processor.tokenizer.pad_token = self.processor.tokenizer.eos_token
+ elif "matsuo-lab/weblab" in model_name:
+ self.processor.tokenizer.add_special_tokens(
+ {
+ "bos_token": "<|endoftext|>",
+ "eos_token": "<|endoftext|>",
+ "pad_token": "<|padding|>",
+ "unk_token": "<|endoftext|>",
+ }
+ )
+
+ def __len__(self) -> int:
+ return len(self.loaded_dataset)
+
+ def __getitem__(self, index) -> dict:
+ # cf: https://huggingface.co/datasets/MMInstruction/M3IT#data-instances
+ row = self.loaded_dataset[index]
+
+ # some of nlvr data were broken
+ instruction = row["instruction"] # str
+ question = row["inputs"] # str
+ answer = row["outputs"] # str
+ text = f"##Instruction: {instruction} ##Question: {question} ##Answer: {answer}"
+
+ # imageのロード
+ image_base64_str_list = row["image_base64_str"] # str (base64)
+ img = Image.open(BytesIO(b64decode(image_base64_str_list[0]))).convert("RGB")
+ img = np.array(img)
+ if img.shape[2] != 3:
+ img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
+
+ inputs = self.processor(
+ text,
+ img,
+ return_tensors="pt",
+ max_length=self.max_length,
+ padding="max_length",
+ truncation=True,
+ )
+ # batch size 1 -> unbatch
+ inputs = {k: v[0] for k, v in inputs.items()}
+ inputs["labels"] = inputs["input_ids"]
+ return inputs
+
diff --git a/heron/datasets/preprocess/make_STAIR_csv.ipynb b/heron/datasets/preprocess/make_STAIR_csv.ipynb
new file mode 100644
index 0000000..e5ecced
--- /dev/null
+++ b/heron/datasets/preprocess/make_STAIR_csv.ipynb
@@ -0,0 +1,245 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "8a82402e-eea9-4227-8d08-4e4178895602",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import glob\n",
+ "import json\n",
+ "import os\n",
+ "\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import tqdm"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "4cf98eff-c7b9-4f6e-8c7f-781c52cf4378",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Set path to STAIR data\n",
+ "# Images are download from here: https://cocodataset.org/#download\n",
+ "# Text data are download from here: https://github.com/STAIR-Lab-CIT/STAIR-captions\n",
+ "# Download data at data/coco\n",
+ "\n",
+ "PATH_TO_COCO = os.path.abspath(\"../../../../data/coco\") + \"/\"\n",
+ "PATH_TO_TRAIN_JSON = PATH_TO_COCO + \"stair_captions_v1.2_train.json\"\n",
+ "PATH_TO_VAL_JSON = PATH_TO_COCO + \"stair_captions_v1.2_val.json\"\n",
+ "\n",
+ "# Add some pseudo question's text\n",
+ "random_question_list = [\n",
+ " \"画像の内容を教えてください。\",\n",
+ " \"この画像を説明できますか?\",\n",
+ " \"画像に何が写っていますか?\",\n",
+ " \"画像の詳細を話してください。\",\n",
+ " \"画像に関する情報を共有して。\",\n",
+ " \"画像を解説してもらえますか?\",\n",
+ " \"この画像の主題は何ですか?\",\n",
+ " \"画像を簡潔に説明してください。\",\n",
+ " \"画像についての概要を教えて。\",\n",
+ " \"この画像に関する基本情報を話してください。\",\n",
+ " \"これは何の写真ですか?\",\n",
+ " \"写真には何が写っていますか?\",\n",
+ " \"写真について説明してください。\",\n",
+ " \"この写真はどういう状況ですか?説明してください。\",\n",
+ "]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2578a80-db4a-4be4-b1ee-43f2c718ab7d",
+ "metadata": {},
+ "source": [
+ "# STAIR / COCO"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "d3243048-4846-4ff2-8687-b6c80fc4796d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with open(PATH_TO_TRAIN_JSON, 'r') as f:\n",
+ " coco_train = json.load(f)\n",
+ "\n",
+ "with open(PATH_TO_VAL_JSON, 'r') as f:\n",
+ " coco_val = json.load(f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "f6a23770-495b-4444-9665-825747b4d7c4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# annotations to pandas DataFrame\n",
+ "df_coco_train = pd.DataFrame(coco_train[\"annotations\"])\n",
+ "df_coco_val = pd.DataFrame(coco_val[\"annotations\"])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "7625e256-4cf0-44d7-9035-a70aef61525e",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 413915/413915 [00:35<00:00, 11705.96it/s]\n",
+ "100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 202520/202520 [00:17<00:00, 11630.47it/s]\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " img_path | \n",
+ " caption | \n",
+ " question | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " /home/y_inoue/coco/val2014/COCO_val2014_000000... | \n",
+ " 踏切の近くにワイナリーが開店している | \n",
+ " 写真について説明してください。 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " /home/y_inoue/coco/val2014/COCO_val2014_000000... | \n",
+ " 渋滞の中2人乗りのバイクが走っている | \n",
+ " 画像の内容を教えてください。 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " /home/y_inoue/coco/val2014/COCO_val2014_000000... | \n",
+ " 部屋の中に白い自転車が置いてある | \n",
+ " 画像の詳細を話してください。 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " /home/y_inoue/coco/val2014/COCO_val2014_000000... | \n",
+ " 街の道を白い馬車が走っている | \n",
+ " これは何の写真ですか? | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " /home/y_inoue/coco/val2014/COCO_val2014_000000... | \n",
+ " ビーチ近くの水際に鳥が羽を広げて停まっている | \n",
+ " 画像を解説してもらえますか? | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " img_path caption \\\n",
+ "0 /home/y_inoue/coco/val2014/COCO_val2014_000000... 踏切の近くにワイナリーが開店している \n",
+ "1 /home/y_inoue/coco/val2014/COCO_val2014_000000... 渋滞の中2人乗りのバイクが走っている \n",
+ "2 /home/y_inoue/coco/val2014/COCO_val2014_000000... 部屋の中に白い自転車が置いてある \n",
+ "3 /home/y_inoue/coco/val2014/COCO_val2014_000000... 街の道を白い馬車が走っている \n",
+ "4 /home/y_inoue/coco/val2014/COCO_val2014_000000... ビーチ近くの水際に鳥が羽を広げて停まっている \n",
+ "\n",
+ " question \n",
+ "0 写真について説明してください。 \n",
+ "1 画像の内容を教えてください。 \n",
+ "2 画像の詳細を話してください。 \n",
+ "3 これは何の写真ですか? \n",
+ "4 画像を解説してもらえますか? "
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "for target, df_coco in [\n",
+ " [\"train\", df_coco_train],\n",
+ " [\"val\", df_coco_val]\n",
+ "]:\n",
+ " img_path_list = []\n",
+ " caption_list = []\n",
+ " question_list = []\n",
+ "\n",
+ " for i in tqdm.tqdm(range(len(df_coco))):\n",
+ " row = df_coco.iloc[i]\n",
+ " image_id = row.image_id\n",
+ " img_path = PATH_TO_COCO + f\"{target}2014/COCO_{target}2014_{image_id:012}.jpg\"\n",
+ " if os.path.exists(img_path):\n",
+ " img_path_list.append(img_path)\n",
+ " caption_list.append(row.caption)\n",
+ " q_index = np.random.randint(len(random_question_list))\n",
+ " question_list.append(random_question_list[q_index])\n",
+ " else:\n",
+ " print(f\"Fail path: {img_path}\")\n",
+ " \n",
+ " df = pd.DataFrame({\n",
+ " \"img_path\": img_path_list,\n",
+ " \"caption\": caption_list,\n",
+ " \"question\": question_list,\n",
+ " })\n",
+ " \n",
+ " df.to_csv(PATH_TO_COCO + f\"df_{target}.csv\", index=False)\n",
+ "df.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c8657132-6913-4a16-baa8-b34cfe49f8ec",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/heron/datasets/preprocess/make_japanese_visual_genome_csv.ipynb b/heron/datasets/preprocess/make_japanese_visual_genome_csv.ipynb
new file mode 100644
index 0000000..958dcd0
--- /dev/null
+++ b/heron/datasets/preprocess/make_japanese_visual_genome_csv.ipynb
@@ -0,0 +1,220 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "8a82402e-eea9-4227-8d08-4e4178895602",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import glob\n",
+ "import json\n",
+ "import os\n",
+ "\n",
+ "import pandas as pd\n",
+ "import tqdm"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "4cf98eff-c7b9-4f6e-8c7f-781c52cf4378",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Set path to visual genome data\n",
+ "# Images are download from here: https://homes.cs.washington.edu/~ranjay/visualgenome/api.html\n",
+ "# Text data are download from here: https://github.com/yahoojapan/ja-vg-vqa\n",
+ "# Download data at data/visual_genome_ja\n",
+ "\n",
+ "PATH_TO_VISUAL_GENOME = os.path.abspath(\"../../../../data/visual_genome_ja\") + \"/\""
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "889eb7b5-d60d-4502-8603-56465ca7de0b",
+ "metadata": {},
+ "source": [
+ "# Japanese Visual Genome"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "5b017be4-2400-4fbc-b275-bd5032922a5e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with open(PATH_TO_VISUAL_GENOME + 'question_answers.json', 'r') as f:\n",
+ " v_g = json.load(f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "f9160aaf-bc19-4aea-8e32-76aafeb422f8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Extract question/answer pairs\n",
+ "qas_list = []\n",
+ "for data in v_g:\n",
+ " qas_list.extend(data[\"qas\"])\n",
+ "d_vg = pd.DataFrame(qas_list)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "6235d3e0-df32-4836-a6dd-75e0ad8e4535",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 793664/793664 [01:01<00:00, 12947.91it/s]\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " img_path | \n",
+ " caption | \n",
+ " question | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " /home/y_inoue/visual_genome_ja/VG_100K/2395966... | \n",
+ " オレンジ色 | \n",
+ " バイクの車体の色はどんな色をしていますか? | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " /home/y_inoue/visual_genome_ja/VG_100K/2395966... | \n",
+ " 白色 | \n",
+ " バイクを固定している器具の色はどんな色をしていますか? | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " /home/y_inoue/visual_genome_ja/VG_100K/2395966... | \n",
+ " 黒色 | \n",
+ " バイクが置かれている床は何色ですか? | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " /home/y_inoue/visual_genome_ja/VG_100K/2395966... | \n",
+ " 緑色 | \n",
+ " バイクの右側の通路の床は何色ですか? | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " /home/y_inoue/visual_genome_ja/VG_100K/2395966... | \n",
+ " 5つ | \n",
+ " バイクの左に落ちている箱側面に書かれたメニューはいくつですか? | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " img_path caption \\\n",
+ "0 /home/y_inoue/visual_genome_ja/VG_100K/2395966... オレンジ色 \n",
+ "1 /home/y_inoue/visual_genome_ja/VG_100K/2395966... 白色 \n",
+ "2 /home/y_inoue/visual_genome_ja/VG_100K/2395966... 黒色 \n",
+ "3 /home/y_inoue/visual_genome_ja/VG_100K/2395966... 緑色 \n",
+ "4 /home/y_inoue/visual_genome_ja/VG_100K/2395966... 5つ \n",
+ "\n",
+ " question \n",
+ "0 バイクの車体の色はどんな色をしていますか? \n",
+ "1 バイクを固定している器具の色はどんな色をしていますか? \n",
+ "2 バイクが置かれている床は何色ですか? \n",
+ "3 バイクの右側の通路の床は何色ですか? \n",
+ "4 バイクの左に落ちている箱側面に書かれたメニューはいくつですか? "
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "img_path_list = []\n",
+ "caption_list = []\n",
+ "question_list = []\n",
+ "\n",
+ "for i in tqdm.tqdm(range(len(d_vg))):\n",
+ " row = d_vg.iloc[i]\n",
+ "\n",
+ " image_id = row.image_id\n",
+ " img_path = PATH_TO_VISUAL_GENOME + f\"VG_100K/{image_id}.jpg\"\n",
+ "\n",
+ " if os.path.exists(img_path):\n",
+ " img_path_list.append(img_path)\n",
+ " caption_list.append(row.answer)\n",
+ " question_list.append(row.question)\n",
+ " else:\n",
+ " print(f\"Fail path: {img_path}\")\n",
+ "\n",
+ "df = pd.DataFrame({\n",
+ " \"img_path\": img_path_list,\n",
+ " \"caption\": caption_list,\n",
+ " \"question\": question_list,\n",
+ "})\n",
+ "\n",
+ "df.to_csv(PATH_TO_VISUAL_GENOME + f\"df_vg.csv\", index=False)\n",
+ "df.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5cb70772-220c-4cd8-a4a0-866eab65f987",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/heron/datasets/utils.py b/heron/datasets/utils.py
new file mode 100644
index 0000000..fd4e187
--- /dev/null
+++ b/heron/datasets/utils.py
@@ -0,0 +1,40 @@
+from typing import Union, Optional
+
+import datasets
+import pandas as pd
+from torch.utils.data import ConcatDataset, Dataset
+
+from .ja_csv_datasets import JapaneseCSVDataset
+from .m3it_datasets import M3ITDataset
+
+def get_dataset(config: dict, model_name: str, vision_model_name: str, max_length: int) -> Union[Dataset, Dataset]:
+ if config.get("dataset_type") == "m3it":
+ dataset_list = [
+ datasets.load_dataset("MMInstruction/M3IT", i) for i in config["dataset_names"]
+ ]
+ train_dataframe = ConcatDataset([d["train"] for d in dataset_list])
+ train_dataset = M3ITDataset(model_name, vision_model_name, train_dataframe, max_length)
+
+ # some dataset have no validation
+ val_dataset_list = []
+ for d in dataset_list:
+ try:
+ val_dataset_list.append(d["validation"])
+ except:
+ print(f"{d['train']._info.config_name} has no validation set.")
+ val_dataframe = ConcatDataset(val_dataset_list)
+ val_dataset = M3ITDataset(model_name, vision_model_name, val_dataframe, max_length)
+ elif config.get("dataset_type") == "japanese_csv":
+ df_train = pd.read_csv("./data/coco/df_train.csv")
+ df_val = pd.read_csv("./data/coco/df_val.csv")
+ df_vg = pd.read_csv("./data/visual_genome_ja/df_vg.csv")
+
+ train_dataframe = pd.concat([df_train, df_vg], axis=0, ignore_index=True)
+ train_dataset = JapaneseCSVDataset(model_name, vision_model_name, train_dataframe, max_length)
+
+ val_dataframe = df_val
+ val_dataset = JapaneseCSVDataset(model_name, vision_model_name, val_dataframe, max_length)
+ else:
+ raise ValueError(f"dataset_type: {config.get('dataset_type')} is not supported.")
+
+ return train_dataset, val_dataset
diff --git a/heron/models/__init__.py b/heron/models/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/heron/models/git_llm/__init__.py b/heron/models/git_llm/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/heron/models/git_llm/git_gpt_neox/__init__.py b/heron/models/git_llm/git_gpt_neox/__init__.py
new file mode 100644
index 0000000..4f669d9
--- /dev/null
+++ b/heron/models/git_llm/git_gpt_neox/__init__.py
@@ -0,0 +1 @@
+from .modeling_git_gpt_neox import GitGPTNeoXConfig, GitGPTNeoXForCausalLM, GitGPTNeoXModel
diff --git a/heron/models/git_llm/git_gpt_neox/modeling_git_gpt_neox.py b/heron/models/git_llm/git_gpt_neox/modeling_git_gpt_neox.py
new file mode 100644
index 0000000..bcace8e
--- /dev/null
+++ b/heron/models/git_llm/git_gpt_neox/modeling_git_gpt_neox.py
@@ -0,0 +1,527 @@
+"""PyTorch GIT GPTneoX model."""
+import copy
+from typing import List, Optional, Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torch.nn import CrossEntropyLoss
+from transformers import (
+ CLIPVisionConfig,
+ CLIPVisionModel,
+ GPTNeoXConfig,
+ GPTNeoXForCausalLM,
+ GPTNeoXModel,
+)
+from transformers.modeling_outputs import (
+ BaseModelOutputWithPast,
+ BaseModelOutputWithPooling,
+ CausalLMOutputWithPast,
+)
+from transformers.models.git.modeling_git import GitProjection
+
+
+class GitGPTNeoXConfig(GPTNeoXConfig):
+ model_type = "git_gpt_neox"
+
+ def __init__(
+ self,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.vision_config = CLIPVisionConfig()
+ self.num_image_with_embedding = None
+
+ def set_vision_configs(
+ self,
+ num_image_with_embedding: Union[int, None] = None,
+ vision_model_name: Union[str, None] = None,
+ ):
+ self.num_image_with_embedding = num_image_with_embedding
+ self.vision_model_name = vision_model_name
+ self.vision_config = CLIPVisionConfig.from_pretrained(vision_model_name)
+
+ def to_dict(self):
+ """
+ Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns:
+ `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
+ """
+ output = copy.deepcopy(self.__dict__)
+ output["vision_config"] = self.vision_config.to_dict()
+ output["model_type"] = self.__class__.model_type
+ return output
+
+
+# Copied from transformers.models.bart.modeling_bart._expand_mask
+def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
+ """
+ Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`.
+ """
+ bsz, src_len = mask.size()
+ tgt_len = tgt_len if tgt_len is not None else src_len
+
+ expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype)
+
+ inverted_mask = 1.0 - expanded_mask
+
+ return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min)
+
+
+class GitGPTNeoXModel(GPTNeoXModel):
+ config_class = GitGPTNeoXConfig
+
+ def __init__(self, config: GPTNeoXConfig):
+ super(GitGPTNeoXModel, self).__init__(config)
+
+ # Git modules
+ self.image_encoder = CLIPVisionModel.from_pretrained(config.vision_model_name)
+ self.visual_projection = GitProjection(config)
+
+ if config.num_image_with_embedding is not None:
+ self.img_temporal_embedding = nn.ParameterList(
+ nn.Parameter(torch.zeros(1, 1, config.vision_config.hidden_size))
+ for _ in range(config.num_image_with_embedding)
+ )
+
+ self.image_patch_tokens = int(
+ (config.vision_config.image_size / config.vision_config.patch_size) ** 2 + 1
+ )
+ if config.num_image_with_embedding is not None:
+ self.image_patch_tokens *= config.num_image_with_embedding
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ # def get_input_embeddings(self):
+ # return self.decoder.embed_in
+
+ # def set_input_embeddings(self, value):
+ # self.decoder.embed_in = value
+
+ def _prune_heads(self, heads_to_prune):
+ """
+ Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base
+ class PreTrainedModel
+ """
+ for layer, heads in heads_to_prune.items():
+ self.encoder.layer[layer].attention.prune_heads(heads)
+
+ def _generate_future_mask(
+ self, size: int, dtype: torch.dtype, device: torch.device
+ ) -> torch.Tensor:
+ # Default mask is for forward direction. Flip for backward direction.
+ mask = torch.triu(torch.ones(size, size, device=device, dtype=dtype), diagonal=1)
+ mask = mask.masked_fill(mask == 1, float("-inf"))
+ return mask
+
+ def create_attention_mask(
+ self,
+ tgt,
+ memory,
+ tgt_mask,
+ past_key_values_length,
+ memory_key_padding_mask=None,
+ ):
+ num_tgt = tgt.shape[1]
+ num_memory = memory.shape[1]
+ device = tgt.device
+ dtype = tgt.dtype
+ top_left = torch.zeros((num_memory, num_memory), device=device, dtype=dtype)
+ top_right = torch.full(
+ (num_memory, num_tgt + past_key_values_length),
+ float("-inf"),
+ device=tgt.device,
+ dtype=dtype,
+ )
+ bottom_left = torch.zeros(
+ (num_tgt, num_memory),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ if past_key_values_length > 0:
+ tgt_mask = torch.zeros(
+ (tgt_mask.shape[0], tgt_mask.shape[0] + past_key_values_length),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ left = torch.cat((top_left, bottom_left), dim=0)
+ right = torch.cat((top_right, tgt_mask.to(dtype)), dim=0)
+
+ full_attention_mask = torch.cat((left, right), dim=1)[None, :]
+
+ if memory_key_padding_mask is None:
+ memory_key_padding_mask = torch.full(
+ (memory.shape[0], memory.shape[1]), fill_value=False, device=device
+ )
+ # if it is False, it means valid. That is, it is not a padding
+ if memory_key_padding_mask.dtype != torch.bool:
+ raise ValueError("Memory key padding mask must be a boolean tensor.")
+ zero_negative_infinity = torch.zeros_like(memory_key_padding_mask, dtype=tgt.dtype)
+ zero_negative_infinity[memory_key_padding_mask] = float("-inf")
+ full_attention_mask = full_attention_mask.expand(
+ (
+ memory_key_padding_mask.shape[0],
+ num_memory + num_tgt,
+ num_memory + past_key_values_length + num_tgt,
+ )
+ )
+ full_attention_mask = full_attention_mask.clone()
+ origin_left = full_attention_mask[:, :, :num_memory]
+ update = zero_negative_infinity[:, None, :]
+ full_attention_mask[:, :, :num_memory] = origin_left + update
+
+ # add axis for multi-head
+ full_attention_mask = full_attention_mask[:, None, :, :]
+
+ return full_attention_mask
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ head_mask: Optional[torch.FloatTensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPooling]:
+ r"""
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:"""
+ output_attentions = (
+ output_attentions
+ if output_attentions is not None
+ else self.config.output_hidden_states
+ )
+ output_hidden_states = (
+ output_hidden_states
+ if output_hidden_states is not None
+ else self.config.output_hidden_states
+ )
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError(
+ "You cannot specify both input_ids and inputs_embeds at the same time"
+ )
+ elif input_ids is not None:
+ input_shape = input_ids.size()
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
+
+ batch_size, seq_length = input_shape
+ seq_length_with_past = seq_length
+
+ past_key_values_length = 0
+
+ if past_key_values is not None:
+ past_key_values_length = past_key_values[0][0].shape[2]
+ seq_length_with_past = seq_length_with_past + past_key_values_length
+
+ # GIT Vision Encoder part
+ projected_visual_features = None
+ if pixel_values is not None and past_key_values is None:
+ if pixel_values.ndim == 4:
+ # here we assume pixel_values is of shape (batch_size, num_channels, height, width)
+ visual_features = self.image_encoder(pixel_values).last_hidden_state
+
+ elif pixel_values.ndim == 5:
+ # here we assume pixel_values is of shape (batch_size, num_frames, num_channels, height, width)
+ visual_features = []
+ for frame_idx in range(pixel_values.shape[1]):
+ visual_features_frame = self.image_encoder(
+ pixel_values[:, frame_idx, :, :]
+ ).last_hidden_state
+ visual_features_frame += self.img_temporal_embedding[frame_idx]
+ visual_features.append(visual_features_frame)
+
+ # finally, concatenate all features along sequence dimension
+ visual_features = torch.cat(visual_features, dim=1)
+ else:
+ raise ValueError("pixel_values must be of rank 4 or 5")
+
+ projected_visual_features = self.visual_projection(visual_features)
+
+ if inputs_embeds is None:
+ inputs_embeds = self.embed_in(input_ids)
+
+ # embed positions
+ if attention_mask is None:
+ attention_mask = torch.ones(
+ (batch_size, seq_length_with_past), dtype=torch.bool, device=inputs_embeds.device
+ )
+
+ embedding_output = self.emb_dropout(inputs_embeds)
+
+ if projected_visual_features is None:
+ projected_visual_features = torch.zeros(
+ (embedding_output.shape[0], 0, embedding_output.shape[2]),
+ dtype=embedding_output.dtype,
+ device=embedding_output.device,
+ )
+
+ # Repeat visual features to match embedding batch size.
+ projected_visual_features = projected_visual_features.repeat(
+ embedding_output.size(0) // projected_visual_features.size(0), 1, 1
+ )
+
+ # concatenate patch token and text token embeddings
+ hidden_states = torch.cat((projected_visual_features, embedding_output), dim=1)
+
+ if position_ids is None:
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
+ position_ids = torch.arange(
+ past_key_values_length,
+ seq_length + projected_visual_features.shape[1] + past_key_values_length,
+ dtype=torch.long,
+ device=device,
+ )
+ position_ids = position_ids.unsqueeze(0).view(
+ -1, seq_length + projected_visual_features.shape[1]
+ )
+ else:
+ position_ids = position_ids.view(
+ -1, seq_length + projected_visual_features.shape[1]
+ ).long()
+
+ # Prepare head mask if needed
+ # 1.0 in head_mask indicate we keep the head
+ # attention_probs has shape bsz x n_heads x N x N
+ # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
+ # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
+ head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)
+
+ if self.gradient_checkpointing and self.training:
+ if use_cache:
+ logger.warning_once(
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
+ )
+ use_cache = False
+
+ # By default, an additive causal mask is created
+ # for masking the future (one direction).
+ tgt_mask = self._generate_future_mask(
+ seq_length, embedding_output.dtype, embedding_output.device
+ )
+
+ # Create an attention mask of shape (batch_size, 1, tgt_seq_len, src_seq_len)
+ combined_attention_mask = self.create_attention_mask(
+ tgt=embedding_output,
+ memory=projected_visual_features,
+ tgt_mask=tgt_mask,
+ past_key_values_length=past_key_values_length,
+ )
+
+ if attention_mask is not None:
+ # if the user provides an attention mask, we add it to the default one
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ expanded_attn_mask = _expand_mask(
+ attention_mask, embedding_output.dtype, tgt_len=input_shape[-1]
+ ).to(embedding_output.device)
+ if past_key_values_length > 0:
+ expanded_attn_mask = expanded_attn_mask[:, :, -past_key_values_length:, :]
+ else:
+ combined_attention_mask[
+ :, :, -input_shape[1] :, -input_shape[1] :
+ ] += expanded_attn_mask
+
+ if past_key_values is None:
+ past_key_values = tuple([None] * self.config.num_hidden_layers)
+
+ # decoder layers
+ presents = () if use_cache else None
+ all_attentions = () if output_attentions else None
+ all_hidden_states = () if output_hidden_states else None
+ for i, (layer, layer_past) in enumerate(zip(self.layers, past_key_values)):
+ if output_hidden_states:
+ all_hidden_states = all_hidden_states + (hidden_states,)
+
+ if self.gradient_checkpointing and self.training:
+
+ def create_custom_forward(module):
+ def custom_forward(*inputs):
+ # None for layer_past
+ return module(*inputs, use_cache, None, output_attentions)
+
+ return custom_forward
+
+ outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(layer),
+ hidden_states,
+ combined_attention_mask,
+ position_ids,
+ head_mask[i],
+ )
+ else:
+ outputs = layer(
+ hidden_states,
+ attention_mask=combined_attention_mask,
+ position_ids=position_ids,
+ head_mask=head_mask[i],
+ layer_past=layer_past,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ )
+ hidden_states = outputs[0]
+ if use_cache is True:
+ presents = presents + (outputs[1],)
+ if output_attentions:
+ all_attentions = all_attentions + (outputs[2 if use_cache else 1],)
+
+ hidden_states = self.final_layer_norm(hidden_states)
+ # Add last hidden state
+ if output_hidden_states:
+ all_hidden_states = all_hidden_states + (hidden_states,)
+
+ if not return_dict:
+ return tuple(
+ v
+ for v in [hidden_states, presents, all_hidden_states, all_attentions]
+ if v is not None
+ )
+
+ return BaseModelOutputWithPast(
+ last_hidden_state=hidden_states,
+ past_key_values=presents,
+ hidden_states=all_hidden_states,
+ attentions=all_attentions,
+ )
+
+
+class GitGPTNeoXForCausalLM(GPTNeoXForCausalLM):
+ config_class = GitGPTNeoXConfig
+
+ def __init__(
+ self,
+ config,
+ ):
+ super(GitGPTNeoXForCausalLM, self).__init__(config)
+ self.gpt_neox = GitGPTNeoXModel(config)
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ head_mask: Optional[torch.FloatTensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ labels: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.Tensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithPast]:
+ r"""
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
+ Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
+ `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
+ ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:
+ """
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+ if labels is not None:
+ use_cache = False
+
+ outputs = self.gpt_neox(
+ input_ids,
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ head_mask=head_mask,
+ pixel_values=pixel_values,
+ inputs_embeds=inputs_embeds,
+ past_key_values=past_key_values,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+
+ sequence_output = outputs[0]
+ logits = self.embed_out(sequence_output)
+
+ loss = None
+ if labels is not None:
+ # we are doing next-token prediction; shift prediction scores and input ids by one
+ num_image_tokens = self.gpt_neox.image_patch_tokens
+ shifted_logits = logits[:, num_image_tokens:-1, :].contiguous()
+ labels = labels[:, 1:].contiguous()
+ loss_fct = CrossEntropyLoss()
+ loss = loss_fct(shifted_logits.view(-1, self.config.vocab_size), labels.view(-1))
+
+ if not return_dict:
+ output = (logits,) + outputs[1:]
+ return ((loss,) + output) if loss is not None else output
+
+ return CausalLMOutputWithPast(
+ loss=loss,
+ logits=logits,
+ past_key_values=outputs.past_key_values,
+ hidden_states=outputs.hidden_states,
+ attentions=outputs.attentions,
+ )
+
+ def prepare_inputs_for_generation(
+ self,
+ input_ids,
+ past_key_values=None,
+ attention_mask=None,
+ use_cache=None,
+ **kwargs,
+ ):
+ # cut decoder_input_ids if past_key_values is used
+ if past_key_values is not None:
+ input_ids = input_ids[:, -1:]
+
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
+ input_shape = input_ids.shape
+ if attention_mask is None:
+ attention_mask = input_ids.new_ones(input_shape)
+
+ return {
+ "input_ids": input_ids,
+ "attention_mask": attention_mask,
+ "pixel_values": kwargs.get("pixel_values", None),
+ "past_key_values": past_key_values,
+ "use_cache": use_cache,
+ }
+
+ def _reorder_cache(self, past_key_values, beam_idx):
+ reordered_past = ()
+ for layer_past in past_key_values:
+ reordered_past += (
+ tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),
+ )
+ return reordered_past
diff --git a/heron/models/git_llm/git_japanese_stablelm_alpha/__init__.py b/heron/models/git_llm/git_japanese_stablelm_alpha/__init__.py
new file mode 100644
index 0000000..6d293ae
--- /dev/null
+++ b/heron/models/git_llm/git_japanese_stablelm_alpha/__init__.py
@@ -0,0 +1,10 @@
+from .configuration_japanese_stablelm_alpha import JapaneseStableLMAlphaConfig
+from .modeling_git_japanese_stablelm_alpha import (
+ GitJapaneseStableLMAlphaConfig,
+ GitJapaneseStableLMAlphaForCausalLM,
+ GitJapaneseStableLMAlphaModel,
+)
+from .modeling_japanese_stablelm_alpha import (
+ JapaneseStableLMAlphaForCausalLM,
+ JapaneseStableLMAlphaModel,
+)
diff --git a/heron/models/git_llm/git_japanese_stablelm_alpha/configuration_japanese_stablelm_alpha.py b/heron/models/git_llm/git_japanese_stablelm_alpha/configuration_japanese_stablelm_alpha.py
new file mode 100644
index 0000000..79f17e1
--- /dev/null
+++ b/heron/models/git_llm/git_japanese_stablelm_alpha/configuration_japanese_stablelm_alpha.py
@@ -0,0 +1,120 @@
+# coding=utf-8
+# Copyright 2023 Stability and The HuggingFace Inc. team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+""" JapaneseStableLMAlpha model configuration"""
+
+from transformers import PretrainedConfig
+from transformers.utils import logging
+
+logger = logging.get_logger(__name__)
+
+STABLE_LM_PRETRAINED_CONFIG_ARCHIVE_MAP = {}
+
+
+class JapaneseStableLMAlphaConfig(PretrainedConfig):
+ r"""
+ Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
+ documentation from [`PretrainedConfig`] for more information.
+
+ Args:
+ vocab_size (`int`, *optional*, defaults to 65536):
+ Vocabulary size of the JapaneseStableLMAlphaModel. Defines the number of different tokens that
+ can be represented by the `inputs_ids` passed when calling [`JapaneseStableLMAlphaModel`].
+ hidden_size (`int`, *optional*, defaults to 4096):
+ Dimension of the decoder layers and the pooler layer.
+ num_hidden_layers (`int`, *optional*, defaults to 32):
+ Number of hidden layers in the Transformer decoder.
+ num_attention_heads (`int`, *optional*, defaults to 32):
+ Number of attention heads for each attention layer in the Transformer decoder.
+ intermediate_size (`int`, *optional*, defaults to 16384):
+ Dimension of the "intermediate" (i.e., feed-forward) layer in the Transformer decoder.
+ hidden_act (`str` or `function`, *optional*, defaults to `"silu"`):
+ The non-linear activation function (function or string).
+ rotary_pct (`float`, *optional*, defaults to 0.25):
+ Percentage of hidden dimensions to allocate to rotary embeddings.
+ rotary_emb_base (`int`, *optional*, defaults to 10000)
+ Base for computing rotary embeddings frequency.
+ rotary_scale_base (`int`, *optional*, defaults to 512)
+ Base `scale` for computing XPos rotary embeddings scale.
+ classifier_dropout (`float`, *optional*, defaults to 0.1):
+ Argument used when doing token classification, used in the model
+ [`StableLMForTokenClassification`]. The dropout ratio for the hidden layer.
+ max_position_embeddings (`int`, *optional*, defaults to 2048):
+ The maximum sequence length that this model might ever be used with.
+ Typically set this to something large just in case (e.g., 512 or 1024 or 2048).
+ initializer_range (`float`, *optional*, defaults to 1e-5):
+ The standard deviation of the truncated_normal_initializer for initializing
+ all weight matrices.
+ layer_norm_eps (`float`, *optional*, defaults to 1e-12):
+ The epsilon used by the layer normalization layers.
+ use_cache (`bool`, *optional*, defaults to `True`):
+ Whether or not the model should return the last key/values attentions
+ (not used by all models). Only relevant if `config.is_decoder=True`.
+ use_parallel_residual (`bool`, *optional*, defaults to `True`):
+ Whether to use a "parallel" formulation in each Transformer layer,
+ which can provide a slight training speedup at large scales.
+ Example:
+
+ ```python
+ >>> from transformers import JapaneseStableLMAlphaConfig, JapaneseStableLMAlphaModel
+
+ >>> # Initializing a JapaneseStableLMAlpha style configuration
+ >>> configuration = JapaneseStableLMAlphaConfig()
+
+ >>> # Initializing a model (with random weights) from the style configuration
+ >>> model = JapaneseStableLMAlphaModel(configuration) # doctest: +SKIP
+
+ >>> # Accessing the model configuration
+ >>> configuration = model.config # doctest: +SKIP
+ ```"""
+
+ def __init__(
+ self,
+ vocab_size=65536,
+ hidden_size=4096,
+ num_hidden_layers=32,
+ num_attention_heads=32,
+ hidden_act="silu",
+ rotary_pct=0.25,
+ rotary_emb_base=10000,
+ rotary_scale_base=512,
+ classifier_dropout=0.1,
+ max_position_embeddings=2048,
+ initializer_range=0.02,
+ layer_norm_eps=1e-5,
+ use_cache=True,
+ bos_token_id=3,
+ eos_token_id=3,
+ tie_word_embeddings=False,
+ use_parallel_residual=True,
+ use_bias_in_mlp=True,
+ **kwargs,
+ ):
+ super().__init__(bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs)
+ self.vocab_size = vocab_size
+ self.max_position_embeddings = max_position_embeddings
+ self.hidden_size = hidden_size
+ self.num_hidden_layers = num_hidden_layers
+ self.num_attention_heads = num_attention_heads
+ self.hidden_act = hidden_act
+ self.rotary_pct = rotary_pct
+ self.rotary_emb_base = rotary_emb_base
+ self.rotary_scale_base = rotary_scale_base
+ self.classifier_dropout = classifier_dropout
+ self.initializer_range = initializer_range
+ self.layer_norm_eps = layer_norm_eps
+ self.use_cache = use_cache
+ self.tie_word_embeddings = tie_word_embeddings
+ self.use_parallel_residual = use_parallel_residual
+ self.use_bias_in_mlp = use_bias_in_mlp
diff --git a/heron/models/git_llm/git_japanese_stablelm_alpha/modeling_git_japanese_stablelm_alpha.py b/heron/models/git_llm/git_japanese_stablelm_alpha/modeling_git_japanese_stablelm_alpha.py
new file mode 100644
index 0000000..8852390
--- /dev/null
+++ b/heron/models/git_llm/git_japanese_stablelm_alpha/modeling_git_japanese_stablelm_alpha.py
@@ -0,0 +1,527 @@
+"""PyTorch GIT Jpanese StableLM alpha model."""
+import copy
+from typing import List, Optional, Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torch.nn import CrossEntropyLoss
+from transformers import CLIPVisionConfig, CLIPVisionModel
+from transformers.modeling_outputs import (
+ BaseModelOutputWithPast,
+ BaseModelOutputWithPooling,
+ CausalLMOutputWithPast,
+)
+from transformers.models.git.modeling_git import GitProjection
+
+from .configuration_japanese_stablelm_alpha import JapaneseStableLMAlphaConfig
+from .modeling_japanese_stablelm_alpha import (
+ JapaneseStableLMAlphaForCausalLM,
+ JapaneseStableLMAlphaModel,
+)
+
+
+class GitJapaneseStableLMAlphaConfig(JapaneseStableLMAlphaConfig):
+ model_type = "git_japanese_stablelm_alpha"
+
+ def __init__(
+ self,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.vision_config = CLIPVisionConfig()
+ self.num_image_with_embedding = None
+
+ def set_vision_configs(
+ self,
+ num_image_with_embedding: Union[int, None] = None,
+ vision_model_name: Union[str, None] = None,
+ ):
+ self.num_image_with_embedding = num_image_with_embedding
+ self.vision_model_name = vision_model_name
+ self.vision_config = CLIPVisionConfig.from_pretrained(vision_model_name)
+
+ def to_dict(self):
+ """
+ Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns:
+ `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
+ """
+ output = copy.deepcopy(self.__dict__)
+ output["vision_config"] = self.vision_config.to_dict()
+ output["model_type"] = self.__class__.model_type
+ return output
+
+
+# Copied from transformers.models.bart.modeling_bart._expand_mask
+def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
+ """
+ Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`.
+ """
+ bsz, src_len = mask.size()
+ tgt_len = tgt_len if tgt_len is not None else src_len
+
+ expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype)
+
+ inverted_mask = 1.0 - expanded_mask
+
+ return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min)
+
+
+class GitJapaneseStableLMAlphaModel(JapaneseStableLMAlphaModel):
+ config_class = GitJapaneseStableLMAlphaConfig
+
+ def __init__(self, config: JapaneseStableLMAlphaConfig):
+ super(GitJapaneseStableLMAlphaModel, self).__init__(config)
+
+ # Git modules
+ self.image_encoder = CLIPVisionModel.from_pretrained(config.vision_model_name)
+ self.visual_projection = GitProjection(config)
+
+ if config.num_image_with_embedding is not None:
+ self.img_temporal_embedding = nn.ParameterList(
+ nn.Parameter(torch.zeros(1, 1, config.vision_config.hidden_size))
+ for _ in range(config.num_image_with_embedding)
+ )
+
+ self.image_patch_tokens = int(
+ (config.vision_config.image_size / config.vision_config.patch_size) ** 2 + 1
+ )
+ if config.num_image_with_embedding is not None:
+ self.image_patch_tokens *= config.num_image_with_embedding
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ # def get_input_embeddings(self):
+ # return self.decoder.embed_in
+
+ # def set_input_embeddings(self, value):
+ # self.decoder.embed_in = value
+
+ def _prune_heads(self, heads_to_prune):
+ """
+ Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base
+ class PreTrainedModel
+ """
+ for layer, heads in heads_to_prune.items():
+ self.encoder.layer[layer].attention.prune_heads(heads)
+
+ def _generate_future_mask(
+ self, size: int, dtype: torch.dtype, device: torch.device
+ ) -> torch.Tensor:
+ # Default mask is for forward direction. Flip for backward direction.
+ mask = torch.triu(torch.ones(size, size, device=device, dtype=dtype), diagonal=1)
+ mask = mask.masked_fill(mask == 1, float("-inf"))
+ return mask
+
+ def create_attention_mask(
+ self,
+ tgt,
+ memory,
+ tgt_mask,
+ past_key_values_length,
+ memory_key_padding_mask=None,
+ ):
+ num_tgt = tgt.shape[1]
+ num_memory = memory.shape[1]
+ device = tgt.device
+ dtype = tgt.dtype
+ top_left = torch.zeros((num_memory, num_memory), device=device, dtype=dtype)
+ top_right = torch.full(
+ (num_memory, num_tgt + past_key_values_length),
+ float("-inf"),
+ device=tgt.device,
+ dtype=dtype,
+ )
+ bottom_left = torch.zeros(
+ (num_tgt, num_memory),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ if past_key_values_length > 0:
+ tgt_mask = torch.zeros(
+ (tgt_mask.shape[0], tgt_mask.shape[0] + past_key_values_length),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ left = torch.cat((top_left, bottom_left), dim=0)
+ right = torch.cat((top_right, tgt_mask.to(dtype)), dim=0)
+
+ full_attention_mask = torch.cat((left, right), dim=1)[None, :]
+
+ if memory_key_padding_mask is None:
+ memory_key_padding_mask = torch.full(
+ (memory.shape[0], memory.shape[1]), fill_value=False, device=device
+ )
+ # if it is False, it means valid. That is, it is not a padding
+ if memory_key_padding_mask.dtype != torch.bool:
+ raise ValueError("Memory key padding mask must be a boolean tensor.")
+ zero_negative_infinity = torch.zeros_like(memory_key_padding_mask, dtype=tgt.dtype)
+ zero_negative_infinity[memory_key_padding_mask] = float("-inf")
+ full_attention_mask = full_attention_mask.expand(
+ (
+ memory_key_padding_mask.shape[0],
+ num_memory + num_tgt,
+ num_memory + past_key_values_length + num_tgt,
+ )
+ )
+ full_attention_mask = full_attention_mask.clone()
+ origin_left = full_attention_mask[:, :, :num_memory]
+ update = zero_negative_infinity[:, None, :]
+ full_attention_mask[:, :, :num_memory] = origin_left + update
+
+ # add axis for multi-head
+ full_attention_mask = full_attention_mask[:, None, :, :]
+
+ return full_attention_mask
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ head_mask: Optional[torch.FloatTensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPooling]:
+ r"""
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:"""
+ output_attentions = (
+ output_attentions
+ if output_attentions is not None
+ else self.config.output_hidden_states
+ )
+ output_hidden_states = (
+ output_hidden_states
+ if output_hidden_states is not None
+ else self.config.output_hidden_states
+ )
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError(
+ "You cannot specify both input_ids and inputs_embeds at the same time"
+ )
+ elif input_ids is not None:
+ input_shape = input_ids.size()
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
+
+ batch_size, seq_length = input_shape
+ seq_length_with_past = seq_length
+
+ past_key_values_length = 0
+
+ if past_key_values is not None:
+ past_key_values_length = past_key_values[0][0].shape[2]
+ seq_length_with_past = seq_length_with_past + past_key_values_length
+
+ # GIT Vision Encoder part
+ projected_visual_features = None
+ if pixel_values is not None and past_key_values is None:
+ if pixel_values.ndim == 4:
+ # here we assume pixel_values is of shape (batch_size, num_channels, height, width)
+ visual_features = self.image_encoder(pixel_values).last_hidden_state
+
+ elif pixel_values.ndim == 5:
+ # here we assume pixel_values is of shape (batch_size, num_frames, num_channels, height, width)
+ visual_features = []
+ for frame_idx in range(pixel_values.shape[1]):
+ visual_features_frame = self.image_encoder(
+ pixel_values[:, frame_idx, :, :]
+ ).last_hidden_state
+ visual_features_frame += self.img_temporal_embedding[frame_idx]
+ visual_features.append(visual_features_frame)
+
+ # finally, concatenate all features along sequence dimension
+ visual_features = torch.cat(visual_features, dim=1)
+ else:
+ raise ValueError("pixel_values must be of rank 4 or 5")
+
+ projected_visual_features = self.visual_projection(visual_features)
+
+ if inputs_embeds is None:
+ inputs_embeds = self.embed_in(input_ids)
+
+ # embed positions
+ if attention_mask is None:
+ attention_mask = torch.ones(
+ (batch_size, seq_length_with_past), dtype=torch.bool, device=inputs_embeds.device
+ )
+
+ embedding_output = inputs_embeds
+
+ if projected_visual_features is None:
+ projected_visual_features = torch.zeros(
+ (embedding_output.shape[0], 0, embedding_output.shape[2]),
+ dtype=embedding_output.dtype,
+ device=embedding_output.device,
+ )
+
+ # Repeat visual features to match embedding batch size.
+ projected_visual_features = projected_visual_features.repeat(
+ embedding_output.size(0) // projected_visual_features.size(0), 1, 1
+ )
+
+ # concatenate patch token and text token embeddings
+ hidden_states = torch.cat((projected_visual_features, embedding_output), dim=1)
+
+ if position_ids is None:
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
+ position_ids = torch.arange(
+ past_key_values_length,
+ seq_length + projected_visual_features.shape[1] + past_key_values_length,
+ dtype=torch.long,
+ device=device,
+ )
+ position_ids = position_ids.unsqueeze(0).view(
+ -1, seq_length + projected_visual_features.shape[1]
+ )
+ else:
+ position_ids = position_ids.view(
+ -1, seq_length + projected_visual_features.shape[1]
+ ).long()
+
+ # Prepare head mask if needed
+ # 1.0 in head_mask indicate we keep the head
+ # attention_probs has shape bsz x n_heads x N x N
+ # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
+ # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
+ head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)
+
+ if self.gradient_checkpointing and self.training:
+ if use_cache:
+ logger.warning_once(
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
+ )
+ use_cache = False
+
+ # By default, an additive causal mask is created
+ # for masking the future (one direction).
+ tgt_mask = self._generate_future_mask(
+ seq_length, embedding_output.dtype, embedding_output.device
+ )
+
+ # Create an attention mask of shape (batch_size, 1, tgt_seq_len, src_seq_len)
+ combined_attention_mask = self.create_attention_mask(
+ tgt=embedding_output,
+ memory=projected_visual_features,
+ tgt_mask=tgt_mask,
+ past_key_values_length=past_key_values_length,
+ )
+
+ if attention_mask is not None:
+ # if the user provides an attention mask, we add it to the default one
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ expanded_attn_mask = _expand_mask(
+ attention_mask, embedding_output.dtype, tgt_len=input_shape[-1]
+ ).to(embedding_output.device)
+ if past_key_values_length > 0:
+ expanded_attn_mask = expanded_attn_mask[:, :, -past_key_values_length:, :]
+ else:
+ combined_attention_mask[
+ :, :, -input_shape[1] :, -input_shape[1] :
+ ] += expanded_attn_mask
+
+ if past_key_values is None:
+ past_key_values = tuple([None] * self.config.num_hidden_layers)
+
+ # decoder layers
+ presents = () if use_cache else None
+ all_attentions = () if output_attentions else None
+ all_hidden_states = () if output_hidden_states else None
+ for i, (layer, layer_past) in enumerate(zip(self.layers, past_key_values)):
+ if output_hidden_states:
+ all_hidden_states = all_hidden_states + (hidden_states,)
+
+ if self.gradient_checkpointing and self.training:
+
+ def create_custom_forward(module):
+ def custom_forward(*inputs):
+ # None for layer_past
+ return module(*inputs, use_cache, None, output_attentions)
+
+ return custom_forward
+
+ outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(layer),
+ hidden_states,
+ combined_attention_mask,
+ position_ids,
+ head_mask[i],
+ )
+ else:
+ outputs = layer(
+ hidden_states,
+ attention_mask=combined_attention_mask,
+ position_ids=position_ids,
+ head_mask=head_mask[i],
+ layer_past=layer_past,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ )
+ hidden_states = outputs[0]
+ if use_cache is True:
+ presents = presents + (outputs[1],)
+ if output_attentions:
+ all_attentions = all_attentions + (outputs[2 if use_cache else 1],)
+
+ hidden_states = self.final_layer_norm(hidden_states)
+ # Add last hidden state
+ if output_hidden_states:
+ all_hidden_states = all_hidden_states + (hidden_states,)
+
+ if not return_dict:
+ return tuple(
+ v
+ for v in [hidden_states, presents, all_hidden_states, all_attentions]
+ if v is not None
+ )
+
+ return BaseModelOutputWithPast(
+ last_hidden_state=hidden_states,
+ past_key_values=presents,
+ hidden_states=all_hidden_states,
+ attentions=all_attentions,
+ )
+
+
+class GitJapaneseStableLMAlphaForCausalLM(JapaneseStableLMAlphaForCausalLM):
+ config_class = GitJapaneseStableLMAlphaConfig
+
+ def __init__(
+ self,
+ config,
+ ):
+ super(GitJapaneseStableLMAlphaForCausalLM, self).__init__(config)
+ self.transformer = GitJapaneseStableLMAlphaModel(config)
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ head_mask: Optional[torch.FloatTensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ labels: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.Tensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithPast]:
+ r"""
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
+ Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
+ `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
+ ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:
+ """
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+ if labels is not None:
+ use_cache = False
+
+ outputs = self.transformer(
+ input_ids,
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ head_mask=head_mask,
+ pixel_values=pixel_values,
+ inputs_embeds=inputs_embeds,
+ past_key_values=past_key_values,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+
+ sequence_output = outputs[0]
+ logits = self.embed_out(sequence_output)
+
+ loss = None
+ if labels is not None:
+ # we are doing next-token prediction; shift prediction scores and input ids by one
+ num_image_tokens = self.transformer.image_patch_tokens
+ shifted_logits = logits[:, num_image_tokens:-1, :].contiguous()
+ labels = labels[:, 1:].contiguous()
+ loss_fct = CrossEntropyLoss()
+ loss = loss_fct(shifted_logits.view(-1, self.config.vocab_size), labels.view(-1))
+
+ if not return_dict:
+ output = (logits,) + outputs[1:]
+ return ((loss,) + output) if loss is not None else output
+
+ return CausalLMOutputWithPast(
+ loss=loss,
+ logits=logits,
+ past_key_values=outputs.past_key_values,
+ hidden_states=outputs.hidden_states,
+ attentions=outputs.attentions,
+ )
+
+ def prepare_inputs_for_generation(
+ self,
+ input_ids,
+ past_key_values=None,
+ attention_mask=None,
+ use_cache=None,
+ **kwargs,
+ ):
+ # cut decoder_input_ids if past_key_values is used
+ if past_key_values is not None:
+ input_ids = input_ids[:, -1:]
+
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
+ input_shape = input_ids.shape
+ if attention_mask is None:
+ attention_mask = input_ids.new_ones(input_shape)
+
+ return {
+ "input_ids": input_ids,
+ "attention_mask": attention_mask,
+ "pixel_values": kwargs.get("pixel_values", None),
+ "past_key_values": past_key_values,
+ "use_cache": use_cache,
+ }
+
+ def _reorder_cache(self, past_key_values, beam_idx):
+ reordered_past = ()
+ for layer_past in past_key_values:
+ reordered_past += (
+ tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),
+ )
+ return reordered_past
diff --git a/heron/models/git_llm/git_japanese_stablelm_alpha/modeling_japanese_stablelm_alpha.py b/heron/models/git_llm/git_japanese_stablelm_alpha/modeling_japanese_stablelm_alpha.py
new file mode 100644
index 0000000..a9a042e
--- /dev/null
+++ b/heron/models/git_llm/git_japanese_stablelm_alpha/modeling_japanese_stablelm_alpha.py
@@ -0,0 +1,712 @@
+# coding=utf-8
+# Copyright 2023 Stability and The HuggingFace Inc. team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+""" PyTorch JapaneseStableLMAlpha model. """
+from typing import Optional, Tuple, Union
+
+import torch
+import torch.utils.checkpoint
+from torch import nn
+from torch.nn import CrossEntropyLoss
+from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
+from transformers.modeling_utils import PreTrainedModel
+from transformers.utils import logging
+
+from .configuration_japanese_stablelm_alpha import JapaneseStableLMAlphaConfig
+
+logger = logging.get_logger(__name__)
+
+
+class JapaneseStableLMAlphaPreTrainedModel(PreTrainedModel):
+ """
+ An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
+ models.
+ """
+
+ config_class = JapaneseStableLMAlphaConfig
+ base_model_prefix = "transformer"
+ supports_gradient_checkpointing = True
+ _no_split_modules = ["DecoderLayer"]
+ _skip_keys_device_placement = "past_key_values"
+
+ def _init_weights(self, module):
+ """Initialize the weights"""
+ if isinstance(module, nn.Linear):
+ module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)
+ if module.bias is not None:
+ module.bias.data.zero_()
+ elif isinstance(module, nn.Embedding):
+ module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)
+ if module.padding_idx is not None:
+ module.weight.data[module.padding_idx].zero_()
+ elif isinstance(module, nn.LayerNorm):
+ if module.bias is not None:
+ module.bias.data.zero_()
+ if module.weight is not None:
+ module.weight.data.fill_(1.0)
+
+ def _set_gradient_checkpointing(self, module, value=False):
+ if isinstance(module, JapaneseStableLMAlphaModel):
+ module.gradient_checkpointing = value
+
+
+class JapaneseStableLMAlphaModel(JapaneseStableLMAlphaPreTrainedModel):
+ def __init__(self, config):
+ super().__init__(config)
+ self.config = config
+
+ self.embed_in = nn.Embedding(config.vocab_size, config.hidden_size)
+ self.layers = nn.ModuleList(
+ [DecoderLayer(config) for _ in range(config.num_hidden_layers)]
+ )
+ self.final_layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
+
+ self.gradient_checkpointing = False
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def get_input_embeddings(self):
+ return self.embed_in
+
+ def set_input_embeddings(self, value):
+ self.embed_in = value
+
+ def forward(
+ self,
+ input_ids: Optional[torch.LongTensor] = None,
+ attention_mask: Optional[torch.FloatTensor] = None,
+ position_ids: Optional[torch.LongTensor] = None,
+ head_mask: Optional[torch.FloatTensor] = None,
+ inputs_embeds: Optional[torch.FloatTensor] = None,
+ past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple, BaseModelOutputWithPast]:
+ r"""
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+ """
+ output_attentions = (
+ output_attentions if output_attentions is not None else self.config.output_attentions
+ )
+ output_hidden_states = (
+ output_hidden_states
+ if output_hidden_states is not None
+ else self.config.output_hidden_states
+ )
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError(
+ "You cannot specify both input_ids and inputs_embeds at the same time"
+ )
+ elif input_ids is not None:
+ input_shape = input_ids.size()
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
+
+ batch_size, seq_length = input_shape
+
+ if past_key_values is None:
+ past_length = 0
+ past_key_values = tuple([None] * self.config.num_hidden_layers)
+ else:
+ past_length = past_key_values[0][0].size(-2)
+
+ if position_ids is None:
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
+ position_ids = torch.arange(
+ past_length, seq_length + past_length, dtype=torch.long, device=device
+ )
+ position_ids = position_ids.unsqueeze(0).view(-1, seq_length)
+ else:
+ position_ids = position_ids.view(-1, seq_length).long()
+
+ # Attention mask.
+ if attention_mask is not None:
+ assert batch_size > 0, "batch_size has to be defined and > 0"
+ attention_mask = attention_mask.view(batch_size, -1)
+ # We create a 3D attention mask from a 2D tensor mask.
+ # Sizes are [batch_size, 1, 1, to_seq_length]
+ # So we can broadcast to [batch_size, num_heads, from_seq_length, to_seq_length]
+ # this attention mask is more simple than the triangular masking of causal attention
+ # used in OpenAI GPT, we just need to prepare the broadcast dimension here.
+ attention_mask = attention_mask[:, None, None, :]
+
+ # Since attention_mask is 1.0 for positions we want to attend and 0.0 for
+ # masked positions, this operation will create a tensor which is 0.0 for
+ # positions we want to attend and the dtype's smallest value for masked positions.
+ # Since we are adding it to the raw scores before the softmax, this is
+ # effectively the same as removing these entirely.
+ attention_mask = attention_mask.to(dtype=self.dtype) # fp16 compatibility
+ attention_mask = (1.0 - attention_mask) * torch.finfo(self.dtype).min
+
+ # Prepare head mask if needed
+ # 1.0 in head_mask indicate we keep the head
+ # attention_probs has shape bsz x n_heads x N x N
+ # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
+ # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
+ head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)
+
+ if inputs_embeds is None:
+ inputs_embeds = self.embed_in(input_ids)
+
+ hidden_states = inputs_embeds
+
+ if self.gradient_checkpointing and self.training:
+ if use_cache:
+ logger.warning(
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
+ )
+ use_cache = False
+
+ presents = () if use_cache else None
+ all_attentions = () if output_attentions else None
+ all_hidden_states = () if output_hidden_states else None
+ for i, (layer, layer_past) in enumerate(zip(self.layers, past_key_values)):
+ if output_hidden_states:
+ all_hidden_states = all_hidden_states + (hidden_states,)
+
+ if self.gradient_checkpointing and self.training:
+
+ def create_custom_forward(module):
+ def custom_forward(*inputs):
+ # None for layer_past
+ return module(*inputs, use_cache, None, output_attentions)
+
+ return custom_forward
+
+ outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(layer),
+ hidden_states,
+ attention_mask,
+ position_ids,
+ head_mask[i],
+ )
+ else:
+ outputs = layer(
+ hidden_states,
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ head_mask=head_mask[i],
+ layer_past=layer_past,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ )
+ hidden_states = outputs[0]
+ if use_cache is True:
+ presents = presents + (outputs[1],)
+ if output_attentions:
+ all_attentions = all_attentions + (outputs[2 if use_cache else 1],)
+
+ hidden_states = self.final_layer_norm(hidden_states)
+ # Add last hidden state
+ if output_hidden_states:
+ all_hidden_states = all_hidden_states + (hidden_states,)
+
+ if not return_dict:
+ return tuple(
+ v
+ for v in [hidden_states, presents, all_hidden_states, all_attentions]
+ if v is not None
+ )
+
+ return BaseModelOutputWithPast(
+ last_hidden_state=hidden_states,
+ past_key_values=presents,
+ hidden_states=all_hidden_states,
+ attentions=all_attentions,
+ )
+
+
+class DecoderLayer(nn.Module):
+ def __init__(self, config):
+ super().__init__()
+ self.use_parallel_residual = config.use_parallel_residual
+ self.input_layernorm = nn.LayerNorm(
+ config.hidden_size,
+ eps=config.layer_norm_eps,
+ elementwise_affine=False,
+ )
+ self.post_attention_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
+ self.attention = Attention(config)
+ self.mlp = MLP(config)
+
+ def forward(
+ self,
+ hidden_states: Optional[torch.FloatTensor],
+ attention_mask: Optional[torch.FloatTensor] = None,
+ position_ids: Optional[torch.LongTensor] = None,
+ head_mask: Optional[torch.FloatTensor] = None,
+ use_cache: Optional[bool] = False,
+ layer_past: Optional[Tuple[torch.Tensor]] = None,
+ output_attentions: Optional[bool] = False,
+ ):
+ attention_layer_outputs = self.attention(
+ self.input_layernorm(hidden_states),
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ layer_past=layer_past,
+ head_mask=head_mask,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ )
+ attn_output = attention_layer_outputs[
+ 0
+ ] # output_attn: attn_output, present, (attn_weights)
+ outputs = attention_layer_outputs[1:]
+
+ mlp_output = self.mlp(self.post_attention_layernorm(hidden_states))
+ hidden_states = hidden_states + mlp_output + attn_output
+
+ if use_cache:
+ outputs = (hidden_states,) + outputs # hidden_states, present, (attn_weights)
+ else:
+ outputs = (hidden_states,) + outputs[1:] # hidden_states, (attn_weights)
+
+ return outputs
+
+
+class MLP(nn.Module):
+ def __init__(self, config: JapaneseStableLMAlphaConfig):
+ super().__init__()
+ hidden_size = config.hidden_size
+ multiple_of = 256
+ ff_dim = int(8 * hidden_size / 3)
+ intermediate_size = multiple_of * ((ff_dim + multiple_of - 1) // multiple_of)
+
+ self.packed_input_proj = torch.nn.Linear(hidden_size, 2 * intermediate_size, bias=False)
+ self.out_proj = nn.Linear(intermediate_size, hidden_size, bias=False)
+ self.act = nn.SiLU()
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ ff, ff_gate = self.packed_input_proj(x).chunk(2, dim=-1)
+ return self.out_proj(ff * self.act(ff_gate))
+
+
+class RotaryEmbedding(torch.nn.Module):
+ """Based on Tri Dao's XPos: https://github.com/HazyResearch/flash-attention/blob/main/flash_attn/layers/rotary.py"""
+
+ def __init__(
+ self,
+ dim: int,
+ max_position_embeddings: int,
+ base: int = 10_000,
+ scale_base: int = 512,
+ device: str = None,
+ ):
+ super().__init__()
+ self.dim = dim
+ self.seq_len_cached = max_position_embeddings
+
+ # Set up `inv_freq` term
+ inv_freq = 1.0 / (
+ base ** (torch.arange(0, dim, 2, device=device, dtype=torch.float32) / dim)
+ )
+ self.register_buffer("inv_freq", inv_freq)
+
+ # Set up `scale` term
+ self.scale_base = scale_base
+ scale = (
+ (torch.arange(0, dim, 2, device=device, dtype=torch.float32) + 0.4 * dim) / (1.4 * dim)
+ if scale_base is not None
+ else None
+ )
+ self.register_buffer("scale", scale)
+
+ # Seet up `cos..` and `sin...` cache terms
+ t = torch.arange(self.seq_len_cached, device=device, dtype=torch.float32)
+ freqs = torch.outer(t, self.inv_freq)
+ # freqs = torch.cat((freqs, freqs), dim=-1)
+ seq_range = torch.arange(
+ self.seq_len_cached, dtype=self.scale.dtype, device=self.scale.device
+ )
+ power = (seq_range - self.seq_len_cached // 2) / self.scale_base
+ scale_cached = self.scale.to(device=power.device) ** power.unsqueeze(-1)
+ # scale_cached = torch.cat((scale_cached, scale_cached), dim=-1)
+ self.register_buffer("cos_cached", torch.cos(freqs) * scale_cached, persistent=False)
+ self.register_buffer("sin_cached", torch.sin(freqs) * scale_cached, persistent=False)
+ self.register_buffer("cos_k_cached", torch.cos(freqs) / scale_cached, persistent=False)
+ self.register_buffer("sin_k_cached", torch.sin(freqs) / scale_cached, persistent=False)
+
+ def forward(self, x, seq_len=None):
+ if seq_len > self.seq_len_cached:
+ self.seq_len_cached = seq_len
+ t = torch.arange(seq_len, device=x.device, dtype=torch.float32)
+ freqs = torch.outer(t, self.inv_freq)
+ freqs = torch.cat((freqs, freqs), dim=-1)
+ seq_range = torch.arange(
+ self.seq_len_cached, dtype=self.scale.dtype, device=self.scale.device
+ )
+ power = (seq_range - self.seq_len_cached // 2) / self.scale_base
+ scale_cached = self.scale.to(device=power.device) ** power.unsqueeze(-1)
+ scale_cached = torch.cat((scale_cached, scale_cached), dim=-1)
+ self.register_buffer("cos_cached", torch.cos(freqs) * scale_cached, persistent=False)
+ self.register_buffer("sin_cached", torch.sin(freqs) * scale_cached, persistent=False)
+ self.register_buffer("cos_k_cached", torch.cos(freqs) / scale_cached, persistent=False)
+ self.register_buffer("sin_k_cached", torch.sin(freqs) / scale_cached, persistent=False)
+ return (
+ self.cos_cached[:seq_len, ...],
+ self.sin_cached[:seq_len, ...],
+ self.cos_k_cached[:seq_len, ...],
+ self.sin_k_cached[:seq_len, ...],
+ )
+
+
+def rotate_half(x):
+ x1, x2 = x.chunk(2, dim=-1)
+ return torch.cat((-x2, x1), dim=-1)
+
+
+def apply_rotary_pos_emb(q, k, cos, sin, position_ids, cos_k=None, sin_k=None):
+ """
+ q, k: [bs, num_heads, seq_len, rot_dim]
+ cos, sin: [seq_len, rot_dim / 2]
+ position_ids: [bs, seq_len]
+ """
+ # print(f"q: {q.shape}, k: {k.shape}, cos: {cos.shape}, sin: {sin.shape}, position_ids: {position_ids.shape}")
+ import einops
+
+ cos = einops.repeat(cos, "s r -> s (2 r)")
+ sin = einops.repeat(sin, "s r -> s (2 r)")
+ cos_k = einops.repeat(cos_k, "s r -> s (2 r)")
+ sin_k = einops.repeat(sin_k, "s r -> s (2 r)")
+ cos = cos[position_ids].unsqueeze(1) # [bs, 1, seq_len, rot_dim]
+ sin = sin[position_ids].unsqueeze(1) # [bs, 1, seq_len, rot_dim]
+ cos_k = cos_k[position_ids].unsqueeze(1) # [bs, 1, seq_len, rot_dim]
+ sin_k = sin_k[position_ids].unsqueeze(1) # [bs, 1, seq_len, rot_dim]
+
+ q_embed = (q * cos) + (rotate_half(q) * sin)
+ k_embed = (k * cos_k) + (rotate_half(k) * sin_k)
+ return q_embed, k_embed
+
+
+class Attention(nn.Module):
+ def __init__(self, config):
+ super().__init__()
+ self.num_attention_heads = config.num_attention_heads
+ self.hidden_size = config.hidden_size
+ if self.hidden_size % self.num_attention_heads != 0:
+ raise ValueError(
+ "The hidden size is not divisble by the number of attention heads! Make sure to update them"
+ )
+ self.head_size = self.hidden_size // self.num_attention_heads
+
+ max_positions = config.max_position_embeddings
+ self.register_buffer(
+ "bias",
+ torch.tril(torch.ones((max_positions, max_positions), dtype=torch.bool)).view(
+ 1, 1, max_positions, max_positions
+ ),
+ persistent=False,
+ )
+ self.register_buffer("masked_bias", torch.tensor(-1e9), persistent=False)
+
+ self.rotary_ndims = int(self.head_size * config.rotary_pct)
+ self.rotary_emb = RotaryEmbedding(
+ self.rotary_ndims,
+ max_position_embeddings=config.max_position_embeddings,
+ base=config.rotary_emb_base,
+ scale_base=config.rotary_scale_base,
+ )
+
+ self.register_buffer(
+ "norm_factor",
+ torch.sqrt(torch.tensor(self.head_size, dtype=torch.float32)).to(
+ torch.get_default_dtype()
+ ),
+ persistent=False,
+ )
+
+ self.query_key_value = nn.Linear(self.hidden_size, 3 * self.hidden_size, bias=False)
+ self.dense = nn.Linear(self.hidden_size, self.hidden_size, bias=False)
+
+ def forward(
+ self,
+ hidden_states: torch.FloatTensor,
+ attention_mask: torch.FloatTensor,
+ position_ids: torch.LongTensor,
+ head_mask: Optional[torch.FloatTensor] = None,
+ layer_past: Optional[Tuple[torch.Tensor]] = None,
+ use_cache: Optional[bool] = False,
+ output_attentions: Optional[bool] = False,
+ ):
+ has_layer_past = layer_past is not None
+
+ # Compute QKV
+ # Attention heads [batch, seq_len, hidden_size]
+ # --> [batch, seq_len, (np * 3 * head_size)]
+ qkv = self.query_key_value(hidden_states)
+
+ # [batch, seq_len, (num_heads * 3 * head_size)]
+ # --> [batch, seq_len, num_heads, 3 * head_size]
+ new_qkv_shape = qkv.size()[:-1] + (self.num_attention_heads, 3 * self.head_size)
+ qkv = qkv.view(*new_qkv_shape)
+
+ # [batch, seq_len, num_attention_heads, 3 * head_size] --> 3 [batch, num_attention_heads, seq_len, head_size]
+ query = qkv[..., : self.head_size].permute(0, 2, 1, 3)
+ key = qkv[..., self.head_size : 2 * self.head_size].permute(0, 2, 1, 3)
+ value = qkv[..., 2 * self.head_size :].permute(0, 2, 1, 3)
+
+ # Compute rotary embeddings on rotary_ndims
+ query_rot = query[..., : self.rotary_ndims]
+ query_pass = query[..., self.rotary_ndims :]
+ key_rot = key[..., : self.rotary_ndims]
+ key_pass = key[..., self.rotary_ndims :]
+
+ # Compute token offset for rotary embeddings (when decoding)
+ kv_seq_len = key.shape[-2]
+ if has_layer_past:
+ kv_seq_len += layer_past[0].shape[-2]
+
+ # Add rotary embeddings to query and key
+ # TODO: Check if using xpos
+ cos, sin, cos_k, sin_k = self.rotary_emb(value, seq_len=kv_seq_len)
+ query, key = apply_rotary_pos_emb(
+ query_rot, key_rot, cos, sin, position_ids, cos_k=cos_k, sin_k=sin_k
+ )
+
+ query = torch.cat((query, query_pass), dim=-1)
+ key = torch.cat((key, key_pass), dim=-1)
+
+ # Cache QKV values
+ if has_layer_past:
+ past_key = layer_past[0]
+ past_value = layer_past[1]
+ key = torch.cat((past_key, key), dim=-2)
+ value = torch.cat((past_value, value), dim=-2)
+ present = (key, value) if use_cache else None
+
+ # Compute attention
+ attn_output, attn_weights = self._attn(query, key, value, attention_mask, head_mask)
+
+ # Merge attn_head_size dim and num_attn_heads dim into hidden dim
+ # [bs, seq_len, num_attention_heads, attn_head_size]
+ attn_output = attn_output.permute(0, 2, 1, 3).contiguous()
+ attn_output = attn_output.view(
+ attn_output.size(0), attn_output.size(1), self.num_attention_heads * self.head_size
+ )
+
+ attn_output = self.dense(attn_output)
+
+ outputs = (attn_output, present)
+ if output_attentions:
+ outputs += (attn_weights,)
+
+ return outputs
+
+ def _attn(self, query, key, value, attention_mask=None, head_mask=None):
+ # q, k, v: [bs, num_attention_heads, seq_len, attn_head_size]
+ # compute causal mask from causal mask buffer
+
+ batch_size, num_attention_heads, query_length, attn_head_size = query.size()
+ key_length = key.size(-2)
+
+ causal_mask = self.bias[:, :, key_length - query_length : key_length, :key_length]
+
+ query = query.view(batch_size * num_attention_heads, query_length, attn_head_size)
+ key = key.view(batch_size * num_attention_heads, key_length, attn_head_size)
+ attn_scores = torch.zeros(
+ batch_size * num_attention_heads,
+ query_length,
+ key_length,
+ dtype=query.dtype,
+ device=key.device,
+ )
+ attn_scores = torch.baddbmm(
+ attn_scores,
+ query,
+ key.transpose(1, 2),
+ beta=1.0,
+ alpha=(
+ torch.tensor(1.0, dtype=self.norm_factor.dtype, device=self.norm_factor.device)
+ / self.norm_factor
+ ),
+ )
+ attn_scores = attn_scores.view(batch_size, num_attention_heads, query_length, key_length)
+
+ mask_value = torch.finfo(attn_scores.dtype).min
+ # Need to be a tensor, otherwise we get error: `RuntimeError: expected scalar type float but found double`.
+ # Need to be on the same device, otherwise `RuntimeError: ..., x and y to be on the same device`
+ mask_value = torch.tensor(mask_value, dtype=attn_scores.dtype, device=attn_scores.device)
+ attn_scores = torch.where(causal_mask, attn_scores, mask_value)
+
+ if attention_mask is not None:
+ # Apply the attention mask
+ attn_scores = attn_scores + attention_mask
+
+ # NOTE: Upcast to float32
+ attn_weights = nn.functional.softmax(attn_scores, dim=-1, dtype=torch.float32).type_as(
+ value
+ )
+
+ # Mask heads if we want to
+ if head_mask is not None:
+ attn_weights = attn_weights * head_mask
+
+ attn_output = torch.matmul(attn_weights, value)
+ return attn_output, attn_weights
+
+
+def attention_mask_func(attention_scores, ltor_mask):
+ attention_scores.masked_fill_(~ltor_mask, torch.finfo(attention_scores.dtype).min)
+ return attention_scores
+
+
+class JapaneseStableLMAlphaForCausalLM(JapaneseStableLMAlphaPreTrainedModel):
+ _tied_weights_keys = ["embed_out.weight"]
+
+ def __init__(self, config):
+ super().__init__(config)
+
+ self.transformer = JapaneseStableLMAlphaModel(config)
+ self.embed_out = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def get_output_embeddings(self):
+ return self.embed_out
+
+ def set_output_embeddings(self, new_embeddings):
+ self.embed_out = new_embeddings
+
+ def forward(
+ self,
+ input_ids: Optional[torch.LongTensor] = None,
+ attention_mask: Optional[torch.FloatTensor] = None,
+ position_ids: Optional[torch.LongTensor] = None,
+ inputs_embeds: Optional[torch.FloatTensor] = None,
+ head_mask: Optional[torch.FloatTensor] = None,
+ past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None,
+ labels: Optional[torch.LongTensor] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
+ r"""
+ Example:
+
+ ```python
+ >>> import torch
+ >>> from transformers import LlamaTokenizer, JapaneseStableLMAlphaForCausalLM, JapaneseStableLMAlphaConfig
+
+ >>> tokenizer = LlamaTokenizer.from_pretrained("novelai/nerdstash-tokenizer-v1")
+ >>> config = JapaneseStableLMAlphaConfig.from_pretrained("stabilityai/stablelm-ja-base-alpha-7b")
+ >>> config.is_decoder = True
+ >>> model = JapaneseStableLMAlphaForCausalLM.from_pretrained("stabilityai/stablelm-ja-base-alpha-7b", config=config, trust_remote_code=True)
+
+ >>> inputs = tokenizer("日本語の美しいところは、", return_tensors="pt")
+ >>> outputs = model(**inputs)
+
+ >>> prediction_logits = outputs.logits
+ ```"""
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ outputs = self.transformer(
+ input_ids,
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ head_mask=head_mask,
+ inputs_embeds=inputs_embeds,
+ past_key_values=past_key_values,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+
+ hidden_states = outputs[0]
+ lm_logits = self.embed_out(hidden_states)
+
+ lm_loss = None
+ if labels is not None:
+ # move labels to correct device to enable model parallelism
+ labels = labels.to(lm_logits.device)
+ # we are doing next-token prediction; shift prediction scores and input ids by one
+ shift_logits = lm_logits[:, :-1, :].contiguous()
+ labels = labels[:, 1:].contiguous()
+ loss_fct = CrossEntropyLoss()
+ lm_loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), labels.view(-1))
+
+ if not return_dict:
+ output = (lm_logits,) + outputs[1:]
+ return ((lm_loss,) + output) if lm_loss is not None else output
+
+ return CausalLMOutputWithPast(
+ loss=lm_loss,
+ logits=lm_logits,
+ past_key_values=outputs.past_key_values,
+ hidden_states=outputs.hidden_states,
+ attentions=outputs.attentions,
+ )
+
+ def prepare_inputs_for_generation(
+ self, input_ids, past_key_values=None, attention_mask=None, inputs_embeds=None, **kwargs
+ ):
+ input_shape = input_ids.shape
+
+ # cut decoder_input_ids if past is used
+ if past_key_values and past_key_values[0] is not None:
+ input_ids = input_ids[:, -1:]
+
+ position_ids = kwargs.get("position_ids", None)
+ if attention_mask is not None and position_ids is None:
+ # create position_ids on the fly for batch generation
+ position_ids = attention_mask.long().cumsum(-1) - 1
+ position_ids.masked_fill_(attention_mask == 0, 1)
+ if past_key_values:
+ position_ids = position_ids[:, -1].unsqueeze(-1)
+
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
+ if attention_mask is None:
+ attention_mask = input_ids.new_ones(input_shape)
+
+ # if `inputs_embeds` are passed, we only want to use them in the 1st generation step
+ if inputs_embeds is not None and past_key_values is None:
+ model_inputs = {"inputs_embeds": inputs_embeds}
+ else:
+ model_inputs = {"input_ids": input_ids}
+
+ model_inputs.update(
+ {
+ "attention_mask": attention_mask,
+ "past_key_values": past_key_values,
+ "position_ids": position_ids,
+ }
+ )
+
+ return model_inputs
+
+ def _reorder_cache(self, past_key_values, beam_idx):
+ reordered_past = ()
+ for layer_past in past_key_values:
+ reordered_past += (
+ tuple(past_state.index_select(0, beam_idx) for past_state in layer_past[:2])
+ + layer_past[2:],
+ )
+ return reordered_past
diff --git a/heron/models/git_llm/git_llama/__init__.py b/heron/models/git_llm/git_llama/__init__.py
new file mode 100644
index 0000000..68c23ef
--- /dev/null
+++ b/heron/models/git_llm/git_llama/__init__.py
@@ -0,0 +1 @@
+from .modeling_git_llama import GitLlamaConfig, GitLlamaForCausalLM, GitLlamaModel
diff --git a/heron/models/git_llm/git_llama/modeling_git_llama.py b/heron/models/git_llm/git_llama/modeling_git_llama.py
new file mode 100644
index 0000000..955717a
--- /dev/null
+++ b/heron/models/git_llm/git_llama/modeling_git_llama.py
@@ -0,0 +1,519 @@
+"""PyTorch GIT OPT model."""
+import copy
+from typing import List, Optional, Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torch.nn import CrossEntropyLoss
+from transformers import (
+ CLIPVisionConfig,
+ CLIPVisionModel,
+ LlamaConfig,
+ LlamaForCausalLM,
+ LlamaModel,
+)
+from transformers.modeling_outputs import (
+ BaseModelOutputWithPast,
+ BaseModelOutputWithPooling,
+ CausalLMOutputWithPast,
+)
+from transformers.models.git.modeling_git import GitProjection
+
+
+class GitLlamaConfig(LlamaConfig):
+ model_type = "git_llama"
+
+ def __init__(
+ self,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.vision_config = CLIPVisionConfig()
+ self.num_image_with_embedding = None
+
+ def set_vision_configs(
+ self,
+ num_image_with_embedding: Union[int, None] = None,
+ vision_model_name: Union[str, None] = None,
+ ):
+ self.num_image_with_embedding = num_image_with_embedding
+ self.vision_model_name = vision_model_name
+ self.vision_config = CLIPVisionConfig.from_pretrained(vision_model_name)
+
+ def to_dict(self):
+ """
+ Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns:
+ `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
+ """
+ output = copy.deepcopy(self.__dict__)
+ output["vision_config"] = self.vision_config.to_dict()
+ output["model_type"] = self.__class__.model_type
+ return output
+
+
+# Copied from transformers.models.bart.modeling_bart._expand_mask
+def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
+ """
+ Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`.
+ """
+ bsz, src_len = mask.size()
+ tgt_len = tgt_len if tgt_len is not None else src_len
+
+ expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype)
+
+ inverted_mask = 1.0 - expanded_mask
+
+ return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min)
+
+
+class GitLlamaModel(LlamaModel):
+ config_class = GitLlamaConfig
+
+ def __init__(self, config: LlamaConfig):
+ super(GitLlamaModel, self).__init__(config)
+
+ # Git modules
+ self.image_encoder = CLIPVisionModel.from_pretrained(config.vision_model_name)
+ self.visual_projection = GitProjection(config)
+
+ if config.num_image_with_embedding is not None:
+ self.img_temporal_embedding = nn.ParameterList(
+ nn.Parameter(torch.zeros(1, 1, config.vision_config.hidden_size))
+ for _ in range(config.num_image_with_embedding)
+ )
+
+ self.image_patch_tokens = int(
+ (config.vision_config.image_size / config.vision_config.patch_size) ** 2 + 1
+ )
+ if config.num_image_with_embedding is not None:
+ self.image_patch_tokens *= config.num_image_with_embedding
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def get_input_embeddings(self):
+ return self.decoder.embed_tokens
+
+ def set_input_embeddings(self, value):
+ self.decoder.embed_tokens = value
+
+ def _prune_heads(self, heads_to_prune):
+ """
+ Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base
+ class PreTrainedModel
+ """
+ for layer, heads in heads_to_prune.items():
+ self.encoder.layer[layer].attention.prune_heads(heads)
+
+ def _generate_future_mask(
+ self, size: int, dtype: torch.dtype, device: torch.device
+ ) -> torch.Tensor:
+ # Default mask is for forward direction. Flip for backward direction.
+ mask = torch.triu(torch.ones(size, size, device=device, dtype=dtype), diagonal=1)
+ mask = mask.masked_fill(mask == 1, float("-inf"))
+ return mask
+
+ def create_attention_mask(
+ self,
+ tgt,
+ memory,
+ tgt_mask,
+ past_key_values_length,
+ memory_key_padding_mask=None,
+ ):
+ num_tgt = tgt.shape[1]
+ num_memory = memory.shape[1]
+ device = tgt.device
+ dtype = tgt.dtype
+ top_left = torch.zeros((num_memory, num_memory), device=device, dtype=dtype)
+ top_right = torch.full(
+ (num_memory, num_tgt + past_key_values_length),
+ float("-inf"),
+ device=tgt.device,
+ dtype=dtype,
+ )
+ bottom_left = torch.zeros(
+ (num_tgt, num_memory),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ if past_key_values_length > 0:
+ tgt_mask = torch.zeros(
+ (tgt_mask.shape[0], tgt_mask.shape[0] + past_key_values_length),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ left = torch.cat((top_left, bottom_left), dim=0)
+ right = torch.cat((top_right, tgt_mask.to(dtype)), dim=0)
+
+ full_attention_mask = torch.cat((left, right), dim=1)[None, :]
+
+ if memory_key_padding_mask is None:
+ memory_key_padding_mask = torch.full(
+ (memory.shape[0], memory.shape[1]), fill_value=False, device=device
+ )
+ # if it is False, it means valid. That is, it is not a padding
+ if memory_key_padding_mask.dtype != torch.bool:
+ raise ValueError("Memory key padding mask must be a boolean tensor.")
+ zero_negative_infinity = torch.zeros_like(memory_key_padding_mask, dtype=tgt.dtype)
+ zero_negative_infinity[memory_key_padding_mask] = float("-inf")
+ full_attention_mask = full_attention_mask.expand(
+ (
+ memory_key_padding_mask.shape[0],
+ num_memory + num_tgt,
+ num_memory + past_key_values_length + num_tgt,
+ )
+ )
+ full_attention_mask = full_attention_mask.clone()
+ origin_left = full_attention_mask[:, :, :num_memory]
+ update = zero_negative_infinity[:, None, :]
+ full_attention_mask[:, :, :num_memory] = origin_left + update
+
+ # add axis for multi-head
+ full_attention_mask = full_attention_mask[:, None, :, :]
+
+ return full_attention_mask
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPooling]:
+ r"""
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:"""
+ output_attentions = (
+ output_attentions
+ if output_attentions is not None
+ else self.config.output_hidden_states
+ )
+ output_hidden_states = (
+ output_hidden_states
+ if output_hidden_states is not None
+ else self.config.output_hidden_states
+ )
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError(
+ "You cannot specify both input_ids and inputs_embeds at the same time"
+ )
+ elif input_ids is not None:
+ input_shape = input_ids.size()
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
+
+ batch_size, seq_length = input_shape
+ seq_length_with_past = seq_length
+
+ past_key_values_length = 0
+
+ if past_key_values is not None:
+ past_key_values_length = past_key_values[0][0].shape[2]
+ seq_length_with_past = seq_length_with_past + past_key_values_length
+
+ # GIT Vision Encoder part
+ projected_visual_features = None
+ if pixel_values is not None and past_key_values is None:
+ if pixel_values.ndim == 4:
+ # here we assume pixel_values is of shape (batch_size, num_channels, height, width)
+ visual_features = self.image_encoder(pixel_values).last_hidden_state
+
+ elif pixel_values.ndim == 5:
+ # here we assume pixel_values is of shape (batch_size, num_frames, num_channels, height, width)
+ visual_features = []
+ for frame_idx in range(pixel_values.shape[1]):
+ visual_features_frame = self.image_encoder(
+ pixel_values[:, frame_idx, :, :]
+ ).last_hidden_state
+ visual_features_frame += self.img_temporal_embedding[frame_idx]
+ visual_features.append(visual_features_frame)
+
+ # finally, concatenate all features along sequence dimension
+ visual_features = torch.cat(visual_features, dim=1)
+ else:
+ raise ValueError("pixel_values must be of rank 4 or 5")
+
+ projected_visual_features = self.visual_projection(visual_features)
+
+ if inputs_embeds is None:
+ inputs_embeds = self.embed_tokens(input_ids)
+
+ # embed positions
+ if attention_mask is None:
+ attention_mask = torch.ones(
+ (batch_size, seq_length_with_past), dtype=torch.bool, device=inputs_embeds.device
+ )
+
+ embedding_output = inputs_embeds
+
+ if projected_visual_features is None:
+ projected_visual_features = torch.zeros(
+ (embedding_output.shape[0], 0, embedding_output.shape[2]),
+ dtype=embedding_output.dtype,
+ device=embedding_output.device,
+ )
+
+ # Repeat visual features to match embedding batch size.
+ projected_visual_features = projected_visual_features.repeat(
+ embedding_output.size(0) // projected_visual_features.size(0), 1, 1
+ )
+
+ # concatenate patch token and text token embeddings
+ hidden_states = torch.cat((projected_visual_features, embedding_output), dim=1)
+
+ if position_ids is None:
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
+ position_ids = torch.arange(
+ past_key_values_length,
+ seq_length + projected_visual_features.shape[1] + past_key_values_length,
+ dtype=torch.long,
+ device=device,
+ )
+ position_ids = position_ids.unsqueeze(0).view(
+ -1, seq_length + projected_visual_features.shape[1]
+ )
+ else:
+ position_ids = position_ids.view(
+ -1, seq_length + projected_visual_features.shape[1]
+ ).long()
+
+ if self.gradient_checkpointing and self.training:
+ if use_cache:
+ logger.warning_once(
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
+ )
+ use_cache = False
+
+ # By default, an additive causal mask is created
+ # for masking the future (one direction).
+ tgt_mask = self._generate_future_mask(
+ seq_length, embedding_output.dtype, embedding_output.device
+ )
+
+ # Create an attention mask of shape (batch_size, 1, tgt_seq_len, src_seq_len)
+ combined_attention_mask = self.create_attention_mask(
+ tgt=embedding_output,
+ memory=projected_visual_features,
+ tgt_mask=tgt_mask,
+ past_key_values_length=past_key_values_length,
+ )
+
+ if attention_mask is not None:
+ # if the user provides an attention mask, we add it to the default one
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ expanded_attn_mask = _expand_mask(
+ attention_mask, embedding_output.dtype, tgt_len=input_shape[-1]
+ ).to(embedding_output.device)
+ if past_key_values_length > 0:
+ expanded_attn_mask = expanded_attn_mask[:, :, -past_key_values_length:, :]
+ else:
+ combined_attention_mask[
+ :, :, -input_shape[1] :, -input_shape[1] :
+ ] += expanded_attn_mask
+
+ # decoder layers
+ all_hidden_states = () if output_hidden_states else None
+ all_self_attns = () if output_attentions else None
+ next_decoder_cache = () if use_cache else None
+ for idx, decoder_layer in enumerate(self.layers):
+ if output_hidden_states:
+ all_hidden_states += (hidden_states,)
+
+ past_key_value = past_key_values[idx] if past_key_values is not None else None
+
+ if self.gradient_checkpointing and self.training:
+
+ def create_custom_forward(module):
+ def custom_forward(*inputs):
+ # None for past_key_value
+ return module(*inputs, output_attentions, None)
+
+ return custom_forward
+
+ layer_outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(decoder_layer),
+ hidden_states,
+ combined_attention_mask,
+ position_ids,
+ None,
+ )
+ else:
+ layer_outputs = decoder_layer(
+ hidden_states,
+ attention_mask=combined_attention_mask,
+ position_ids=position_ids,
+ past_key_value=past_key_value,
+ output_attentions=output_attentions,
+ use_cache=use_cache,
+ )
+
+ hidden_states = layer_outputs[0]
+
+ if use_cache:
+ next_decoder_cache += (layer_outputs[2 if output_attentions else 1],)
+
+ if output_attentions:
+ all_self_attns += (layer_outputs[1],)
+
+ hidden_states = self.norm(hidden_states)
+
+ # add hidden states from the last decoder layer
+ if output_hidden_states:
+ all_hidden_states += (hidden_states,)
+
+ next_cache = next_decoder_cache if use_cache else None
+ if not return_dict:
+ return tuple(
+ v
+ for v in [hidden_states, next_cache, all_hidden_states, all_self_attns]
+ if v is not None
+ )
+ return BaseModelOutputWithPast(
+ last_hidden_state=hidden_states,
+ past_key_values=next_cache,
+ hidden_states=all_hidden_states,
+ attentions=all_self_attns,
+ )
+
+
+class GitLlamaForCausalLM(LlamaForCausalLM):
+ config_class = GitLlamaConfig
+
+ def __init__(
+ self,
+ config,
+ ):
+ super(GitLlamaForCausalLM, self).__init__(config)
+ self.model = GitLlamaModel(config)
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ labels: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.Tensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithPast]:
+ r"""
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
+ Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
+ `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
+ ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:
+ """
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+ if labels is not None:
+ use_cache = False
+
+ outputs = self.model(
+ input_ids,
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ pixel_values=pixel_values,
+ inputs_embeds=inputs_embeds,
+ past_key_values=past_key_values,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+
+ sequence_output = outputs[0]
+ logits = self.lm_head(sequence_output)
+
+ loss = None
+ if labels is not None:
+ # we are doing next-token prediction; shift prediction scores and input ids by one
+ num_image_tokens = self.model.image_patch_tokens
+ shifted_logits = logits[:, num_image_tokens:-1, :].contiguous()
+ labels = labels[:, 1:].contiguous()
+ loss_fct = CrossEntropyLoss()
+ loss = loss_fct(shifted_logits.view(-1, self.config.vocab_size), labels.view(-1))
+
+ if not return_dict:
+ output = (logits,) + outputs[1:]
+ return ((loss,) + output) if loss is not None else output
+
+ return CausalLMOutputWithPast(
+ loss=loss,
+ logits=logits,
+ past_key_values=outputs.past_key_values,
+ hidden_states=outputs.hidden_states,
+ attentions=outputs.attentions,
+ )
+
+ def prepare_inputs_for_generation(
+ self,
+ input_ids,
+ past_key_values=None,
+ attention_mask=None,
+ use_cache=None,
+ **kwargs,
+ ):
+ # cut decoder_input_ids if past_key_values is used
+ if past_key_values is not None:
+ input_ids = input_ids[:, -1:]
+
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
+ input_shape = input_ids.shape
+ if attention_mask is None:
+ attention_mask = input_ids.new_ones(input_shape)
+
+ return {
+ "input_ids": input_ids,
+ "attention_mask": attention_mask,
+ "pixel_values": kwargs.get("pixel_values", None),
+ "past_key_values": past_key_values,
+ "use_cache": use_cache,
+ }
+
+ def _reorder_cache(self, past_key_values, beam_idx):
+ reordered_past = ()
+ for layer_past in past_key_values:
+ reordered_past += (
+ tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),
+ )
+ return reordered_past
diff --git a/heron/models/git_llm/git_mpt/__init__.py b/heron/models/git_llm/git_mpt/__init__.py
new file mode 100644
index 0000000..9a36f12
--- /dev/null
+++ b/heron/models/git_llm/git_mpt/__init__.py
@@ -0,0 +1,2 @@
+# from .git_opt_trainer import GitOPTTrainer
+from .modeling_git_mpt import GitMptConfig, GitMptForCausalLM, GitMptModel
diff --git a/heron/models/git_llm/git_mpt/modeling_git_mpt.py b/heron/models/git_llm/git_mpt/modeling_git_mpt.py
new file mode 100644
index 0000000..8c1fdc7
--- /dev/null
+++ b/heron/models/git_llm/git_mpt/modeling_git_mpt.py
@@ -0,0 +1,533 @@
+"""PyTorch GIT MPT model.
+This codes is based on modeling_mpt.py in transformers.
+See: https://github.com/huggingface/transformers/blob/main/src/transformers/models/mpt/modeling_mpt.py
+"""
+import copy
+from typing import List, Optional, Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torch.nn import CrossEntropyLoss
+from transformers import CLIPVisionConfig, CLIPVisionModel, MptConfig, MptForCausalLM, MptModel
+from transformers.modeling_outputs import (
+ BaseModelOutputWithPast,
+ BaseModelOutputWithPastAndCrossAttentions,
+ BaseModelOutputWithPooling,
+ CausalLMOutputWithPast,
+)
+from transformers.models.git.modeling_git import GitProjection
+
+
+class GitMptConfig(MptConfig):
+ model_type = "git_mpt"
+
+ def __init__(
+ self,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.vision_config = CLIPVisionConfig()
+ self.num_image_with_embedding = None
+
+ def set_vision_configs(
+ self,
+ num_image_with_embedding: Union[int, None] = None,
+ vision_model_name: Union[str, None] = None,
+ ):
+ self.num_image_with_embedding = num_image_with_embedding
+ self.vision_model_name = vision_model_name
+ self.vision_config = CLIPVisionConfig.from_pretrained(vision_model_name)
+
+ def to_dict(self):
+ """
+ Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns:
+ `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
+ """
+ output = copy.deepcopy(self.__dict__)
+ output["attn_config"] = output["attn_config"].to_dict()
+ output["vision_config"] = self.vision_config.to_dict()
+ output["model_type"] = self.__class__.model_type
+ return output
+
+
+# Copied from transformers.models.bart.modeling_bart._expand_mask
+def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
+ """
+ Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`.
+ """
+ bsz, src_len = mask.size()
+ tgt_len = tgt_len if tgt_len is not None else src_len
+
+ expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype)
+
+ inverted_mask = 1.0 - expanded_mask
+
+ return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min)
+
+
+class GitMptModel(MptModel):
+ config_class = GitMptConfig
+
+ def __init__(self, config: MptConfig):
+ super(GitMptModel, self).__init__(config)
+
+ # Git modules
+ self.image_encoder = CLIPVisionModel.from_pretrained(config.vision_model_name)
+ self.visual_projection = GitProjection(config)
+
+ if config.num_image_with_embedding is not None:
+ self.img_temporal_embedding = nn.ParameterList(
+ nn.Parameter(torch.zeros(1, 1, config.vision_config.hidden_size))
+ for _ in range(config.num_image_with_embedding)
+ )
+
+ self.image_patch_tokens = int(
+ (config.vision_config.image_size / config.vision_config.patch_size) ** 2 + 1
+ )
+ if config.num_image_with_embedding is not None:
+ self.image_patch_tokens *= config.num_image_with_embedding
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def get_input_embeddings(self):
+ return self.wte
+
+ def set_input_embeddings(self, value):
+ self.wte = value
+
+ def _generate_future_mask(
+ self, size: int, dtype: torch.dtype, device: torch.device
+ ) -> torch.Tensor:
+ # Default mask is for forward direction. Flip for backward direction.
+ mask = torch.triu(torch.ones(size, size, device=device, dtype=dtype), diagonal=1)
+ mask = mask.masked_fill(mask == 1, float("-inf"))
+ return mask
+
+ def create_attention_mask(
+ self,
+ tgt,
+ memory,
+ tgt_mask,
+ past_key_values_length,
+ memory_key_padding_mask=None,
+ ):
+ num_tgt = tgt.shape[1]
+ num_memory = memory.shape[1]
+ device = tgt.device
+ dtype = tgt.dtype
+ top_left = torch.zeros((num_memory, num_memory), device=device, dtype=dtype)
+ top_right = torch.full(
+ (num_memory, num_tgt + past_key_values_length),
+ float("-inf"),
+ device=tgt.device,
+ dtype=dtype,
+ )
+ bottom_left = torch.zeros(
+ (num_tgt, num_memory),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ if past_key_values_length > 0:
+ tgt_mask = torch.zeros(
+ (tgt_mask.shape[0], tgt_mask.shape[0] + past_key_values_length),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ left = torch.cat((top_left, bottom_left), dim=0)
+ right = torch.cat((top_right, tgt_mask.to(dtype)), dim=0)
+
+ full_attention_mask = torch.cat((left, right), dim=1)[None, :]
+
+ if memory_key_padding_mask is None:
+ memory_key_padding_mask = torch.full(
+ (memory.shape[0], memory.shape[1]), fill_value=False, device=device
+ )
+ # if it is False, it means valid. That is, it is not a padding
+ if memory_key_padding_mask.dtype != torch.bool:
+ raise ValueError("Memory key padding mask must be a boolean tensor.")
+ zero_negative_infinity = torch.zeros_like(memory_key_padding_mask, dtype=tgt.dtype)
+ zero_negative_infinity[memory_key_padding_mask] = float("-inf")
+ full_attention_mask = full_attention_mask.expand(
+ (
+ memory_key_padding_mask.shape[0],
+ num_memory + num_tgt,
+ num_memory + past_key_values_length + num_tgt,
+ )
+ )
+ full_attention_mask = full_attention_mask.clone()
+ origin_left = full_attention_mask[:, :, :num_memory]
+ update = zero_negative_infinity[:, None, :]
+ full_attention_mask[:, :, :num_memory] = origin_left + update
+
+ # add axis for multi-head
+ full_attention_mask = full_attention_mask[:, None, :, :]
+
+ return full_attention_mask
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPooling]:
+ r"""
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:"""
+ output_attentions = (
+ output_attentions
+ if output_attentions is not None
+ else self.config.output_hidden_states
+ )
+ output_hidden_states = (
+ output_hidden_states
+ if output_hidden_states is not None
+ else self.config.output_hidden_states
+ )
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError(
+ "You cannot specify both input_ids and inputs_embeds at the same time"
+ )
+ elif input_ids is not None:
+ input_shape = input_ids.size()
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
+
+ batch_size, seq_length = input_shape
+ seq_length_with_past = seq_length
+
+ past_key_values_length = 0
+
+ if past_key_values is not None:
+ past_key_values_length = past_key_values[0][0].shape[2]
+ seq_length_with_past = seq_length_with_past + past_key_values_length
+
+ # GIT Vision Encoder part
+ projected_visual_features = None
+ if pixel_values is not None and past_key_values is None:
+ if pixel_values.ndim == 4:
+ # here we assume pixel_values is of shape (batch_size, num_channels, height, width)
+ visual_features = self.image_encoder(pixel_values).last_hidden_state
+
+ elif pixel_values.ndim == 5:
+ # here we assume pixel_values is of shape (batch_size, num_frames, num_channels, height, width)
+ visual_features = []
+ for frame_idx in range(pixel_values.shape[1]):
+ visual_features_frame = self.image_encoder(
+ pixel_values[:, frame_idx, :, :]
+ ).last_hidden_state
+ visual_features_frame += self.img_temporal_embedding[frame_idx]
+ visual_features.append(visual_features_frame)
+
+ # finally, concatenate all features along sequence dimension
+ visual_features = torch.cat(visual_features, dim=1)
+ else:
+ raise ValueError("pixel_values must be of rank 4 or 5")
+
+ projected_visual_features = self.visual_projection(visual_features)
+
+ if inputs_embeds is None:
+ inputs_embeds = self.wte(input_ids)
+
+ # embed positions
+ if attention_mask is None:
+ attention_mask = torch.ones(
+ (batch_size, seq_length_with_past), dtype=torch.bool, device=inputs_embeds.device
+ )
+
+ embedding_output = inputs_embeds
+
+ if projected_visual_features is None:
+ projected_visual_features = torch.zeros(
+ (embedding_output.shape[0], 0, embedding_output.shape[2]),
+ dtype=embedding_output.dtype,
+ device=embedding_output.device,
+ )
+
+ # Repeat visual features to match embedding batch size.
+ projected_visual_features = projected_visual_features.repeat(
+ embedding_output.size(0) // projected_visual_features.size(0), 1, 1
+ )
+
+ # concatenate patch token and text token embeddings
+ hidden_states = torch.cat((projected_visual_features, embedding_output), dim=1)
+
+ if self.gradient_checkpointing and self.training:
+ if use_cache:
+ logger.warning_once(
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
+ )
+ use_cache = False
+
+ # By default, an additive causal mask is created
+ # for masking the future (one direction).
+ tgt_mask = self._generate_future_mask(
+ seq_length, embedding_output.dtype, embedding_output.device
+ )
+
+ # Create an attention mask of shape (batch_size, 1, tgt_seq_len, src_seq_len)
+ combined_attention_mask = self.create_attention_mask(
+ tgt=embedding_output,
+ memory=projected_visual_features,
+ tgt_mask=tgt_mask,
+ past_key_values_length=past_key_values_length,
+ )
+
+ if attention_mask is not None:
+ # if the user provides an attention mask, we add it to the default one
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ expanded_attn_mask = _expand_mask(
+ attention_mask, embedding_output.dtype, tgt_len=input_shape[-1]
+ ).to(embedding_output.device)
+ if past_key_values_length > 0:
+ expanded_attn_mask = expanded_attn_mask[:, :, -past_key_values_length:, :]
+ else:
+ combined_attention_mask[
+ :, :, -input_shape[1] :, -input_shape[1] :
+ ] += expanded_attn_mask
+
+ # MPT mask should be bool, mask pos is True, un-mask pos is False
+ # See: https://github.com/huggingface/transformers/blob/main/src/transformers/models/mpt/modeling_mpt.py#L59
+ combined_attention_mask = torch.where(combined_attention_mask == 0, False, True)
+
+ all_hidden_states = () if output_hidden_states else None
+ all_self_attentions = () if output_attentions else None
+ presents = () if use_cache else None
+
+ if self.gradient_checkpointing and self.training:
+ if use_cache:
+ logger.warning_once(
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
+ )
+ use_cache = False
+
+ # Compute alibi tensor: check build_alibi_tensor documentation
+ alibi = self.build_mpt_alibi_tensor(
+ self.num_heads, self.config.max_seq_len, device=hidden_states.device
+ )
+
+ for idx, block in enumerate(self.blocks):
+ if output_hidden_states:
+ all_hidden_states += (hidden_states,)
+
+ layer_past = past_key_values[idx] if past_key_values is not None else None
+
+ if self.gradient_checkpointing and self.training:
+
+ def create_custom_forward(module):
+ def custom_forward(*inputs):
+ # None for past_key_value
+ return module(
+ *inputs, use_cache=use_cache, output_attentions=output_attentions
+ )
+
+ return custom_forward
+
+ outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(block),
+ hidden_states,
+ alibi,
+ combined_attention_mask,
+ layer_past,
+ )
+ else:
+ outputs = block(
+ hidden_states,
+ layer_past=layer_past,
+ attention_mask=combined_attention_mask,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ position_bias=alibi,
+ )
+
+ hidden_states = outputs[0]
+
+ if use_cache:
+ presents = presents + (outputs[1],)
+
+ if output_attentions:
+ all_self_attentions = all_self_attentions + (outputs[2 if use_cache else 1],)
+
+ # Add last hidden state
+ hidden_states = self.norm_f(hidden_states)
+
+ # add hidden states from the last decoder layer
+ if output_hidden_states:
+ all_hidden_states = all_hidden_states + (hidden_states,)
+
+ if not return_dict:
+ return tuple(
+ v
+ for v in [hidden_states, presents, all_hidden_states, all_self_attentions]
+ if v is not None
+ )
+
+ return BaseModelOutputWithPastAndCrossAttentions(
+ last_hidden_state=hidden_states,
+ past_key_values=presents,
+ hidden_states=all_hidden_states,
+ attentions=all_self_attentions,
+ )
+
+
+class GitMptForCausalLM(MptForCausalLM):
+ config_class = GitMptConfig
+
+ def __init__(
+ self,
+ config,
+ ):
+ super(GitMptForCausalLM, self).__init__(config)
+ self.transformer = GitMptModel(config)
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def get_output_embeddings(self):
+ return self.lm_head
+
+ def set_output_embeddings(self, new_embeddings):
+ self.lm_head = new_embeddings
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ labels: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.Tensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithPast]:
+ r"""
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
+ Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
+ `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
+ ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:
+ """
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+ if labels is not None:
+ use_cache = False
+
+ outputs = self.transformer(
+ input_ids,
+ attention_mask=attention_mask,
+ pixel_values=pixel_values,
+ inputs_embeds=inputs_embeds,
+ past_key_values=past_key_values,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+
+ sequence_output = outputs[0]
+ logits = self.lm_head(sequence_output)
+
+ loss = None
+ if labels is not None:
+ # we are doing next-token prediction; shift prediction scores and input ids by one
+ num_image_tokens = self.transformer.image_patch_tokens
+ shifted_logits = logits[:, num_image_tokens:-1, :].contiguous()
+ labels = labels[:, 1:].contiguous()
+ loss_fct = CrossEntropyLoss()
+ loss = loss_fct(shifted_logits.view(-1, self.config.vocab_size), labels.view(-1))
+
+ if not return_dict:
+ output = (logits,) + outputs[1:]
+ return ((loss,) + output) if loss is not None else output
+
+ return CausalLMOutputWithPast(
+ loss=loss,
+ logits=logits,
+ past_key_values=outputs.past_key_values,
+ hidden_states=outputs.hidden_states,
+ attentions=outputs.attentions,
+ )
+
+ def prepare_inputs_for_generation(
+ self,
+ input_ids,
+ past_key_values=None,
+ attention_mask=None,
+ use_cache=None,
+ **kwargs,
+ ):
+ # cut decoder_input_ids if past_key_values is used
+ if past_key_values is not None:
+ input_ids = input_ids[:, -1:]
+
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
+ input_shape = input_ids.shape
+ if attention_mask is None:
+ attention_mask = input_ids.new_ones(input_shape)
+
+ return {
+ "input_ids": input_ids,
+ "attention_mask": attention_mask,
+ "pixel_values": kwargs.get("pixel_values", None),
+ "past_key_values": past_key_values,
+ "use_cache": use_cache,
+ }
+
+ def _reorder_cache(
+ self, past: Tuple[Tuple[torch.Tensor, torch.Tensor], ...], beam_idx: torch.LongTensor
+ ) -> Tuple[Tuple[torch.Tensor, torch.Tensor], ...]:
+ """
+ This function is used to re-order the `past_key_values` cache if [`~PreTrainedModel.beam_search`] or
+ [`~PreTrainedModel.beam_sample`] is called. This is required to match `past_key_values` with the correct
+ beam_idx at every generation step.
+
+ Output shares the same memory storage as `past`.
+ """
+ # Get a copy of `beam_idx` on all the devices where we need those indices.
+ device_to_beam_idx = {
+ past_state.device: beam_idx.to(past_state.device)
+ for layer_past in past
+ for past_state in layer_past
+ }
+ reordered_past = tuple(
+ (
+ layer_past[0].index_select(0, device_to_beam_idx[layer_past[0].device]),
+ layer_past[1].index_select(0, device_to_beam_idx[layer_past[0].device]),
+ )
+ for layer_past in past
+ )
+ return reordered_past
diff --git a/heron/models/git_llm/git_opt/__init__.py b/heron/models/git_llm/git_opt/__init__.py
new file mode 100644
index 0000000..9c96f44
--- /dev/null
+++ b/heron/models/git_llm/git_opt/__init__.py
@@ -0,0 +1,2 @@
+# from .git_opt_trainer import GitOPTTrainer
+from .modeling_git_opt import GitOPTConfig, GitOPTForCausalLM, GitOPTModel
diff --git a/heron/models/git_llm/git_opt/modeling_git_opt.py b/heron/models/git_llm/git_opt/modeling_git_opt.py
new file mode 100644
index 0000000..e7d6710
--- /dev/null
+++ b/heron/models/git_llm/git_opt/modeling_git_opt.py
@@ -0,0 +1,535 @@
+"""PyTorch GIT OPT model."""
+import copy
+from typing import List, Optional, Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torch.nn import CrossEntropyLoss
+from transformers import CLIPVisionConfig, CLIPVisionModel, OPTConfig, OPTForCausalLM, OPTModel
+from transformers.modeling_outputs import (
+ BaseModelOutputWithPast,
+ BaseModelOutputWithPooling,
+ CausalLMOutputWithPast,
+)
+from transformers.models.git.modeling_git import GitProjection
+from transformers.models.opt.modeling_opt import OPTLearnedPositionalEmbedding
+
+
+class GitOPTConfig(OPTConfig):
+ model_type = "git_opt"
+
+ def __init__(
+ self,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.vision_config = CLIPVisionConfig()
+ self.num_image_with_embedding = None
+
+ def set_vision_configs(
+ self,
+ num_image_with_embedding: Union[int, None] = None,
+ vision_model_name: Union[str, None] = None,
+ ):
+ self.num_image_with_embedding = num_image_with_embedding
+ self.vision_model_name = vision_model_name
+ self.vision_config = CLIPVisionConfig.from_pretrained(vision_model_name)
+
+ def to_dict(self):
+ """
+ Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`]. Returns:
+ `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
+ """
+ output = copy.deepcopy(self.__dict__)
+ output["vision_config"] = self.vision_config.to_dict()
+ output["model_type"] = self.__class__.model_type
+ return output
+
+
+# Copied from transformers.models.bart.modeling_bart._expand_mask
+def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
+ """
+ Expands attention_mask from `[bsz, seq_len]` to `[bsz, 1, tgt_seq_len, src_seq_len]`.
+ """
+ bsz, src_len = mask.size()
+ tgt_len = tgt_len if tgt_len is not None else src_len
+
+ expanded_mask = mask[:, None, None, :].expand(bsz, 1, tgt_len, src_len).to(dtype)
+
+ inverted_mask = 1.0 - expanded_mask
+
+ return inverted_mask.masked_fill(inverted_mask.to(torch.bool), torch.finfo(dtype).min)
+
+
+class GitOPTModel(OPTModel):
+ config_class = GitOPTConfig
+
+ def __init__(self, config: OPTConfig):
+ super(GitOPTModel, self).__init__(config)
+
+ # Git modules
+ self.image_encoder = CLIPVisionModel.from_pretrained(config.vision_model_name)
+ self.visual_projection = GitProjection(config)
+
+ if config.num_image_with_embedding is not None:
+ self.img_temporal_embedding = nn.ParameterList(
+ nn.Parameter(torch.zeros(1, 1, config.vision_config.hidden_size))
+ for _ in range(config.num_image_with_embedding)
+ )
+
+ self.image_patch_tokens = int(
+ (config.vision_config.image_size / config.vision_config.patch_size) ** 2 + 1
+ )
+ if config.num_image_with_embedding is not None:
+ self.image_patch_tokens *= config.num_image_with_embedding
+
+ self.embed_positions = OPTLearnedPositionalEmbedding(
+ config.max_position_embeddings, config.hidden_size
+ )
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def get_input_embeddings(self):
+ return self.decoder.embed_tokens
+
+ def set_input_embeddings(self, value):
+ self.decoder.embed_tokens = value
+
+ def _prune_heads(self, heads_to_prune):
+ """
+ Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base
+ class PreTrainedModel
+ """
+ for layer, heads in heads_to_prune.items():
+ self.encoder.layer[layer].attention.prune_heads(heads)
+
+ def _generate_future_mask(
+ self, size: int, dtype: torch.dtype, device: torch.device
+ ) -> torch.Tensor:
+ # Default mask is for forward direction. Flip for backward direction.
+ mask = torch.triu(torch.ones(size, size, device=device, dtype=dtype), diagonal=1)
+ mask = mask.masked_fill(mask == 1, float("-inf"))
+ return mask
+
+ def create_attention_mask(
+ self,
+ tgt,
+ memory,
+ tgt_mask,
+ past_key_values_length,
+ memory_key_padding_mask=None,
+ ):
+ num_tgt = tgt.shape[1]
+ num_memory = memory.shape[1]
+ device = tgt.device
+ dtype = tgt.dtype
+ top_left = torch.zeros((num_memory, num_memory), device=device, dtype=dtype)
+ top_right = torch.full(
+ (num_memory, num_tgt + past_key_values_length),
+ float("-inf"),
+ device=tgt.device,
+ dtype=dtype,
+ )
+ bottom_left = torch.zeros(
+ (num_tgt, num_memory),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ if past_key_values_length > 0:
+ tgt_mask = torch.zeros(
+ (tgt_mask.shape[0], tgt_mask.shape[0] + past_key_values_length),
+ dtype=dtype,
+ device=tgt_mask.device,
+ )
+
+ left = torch.cat((top_left, bottom_left), dim=0)
+ right = torch.cat((top_right, tgt_mask.to(dtype)), dim=0)
+
+ full_attention_mask = torch.cat((left, right), dim=1)[None, :]
+
+ if memory_key_padding_mask is None:
+ memory_key_padding_mask = torch.full(
+ (memory.shape[0], memory.shape[1]), fill_value=False, device=device
+ )
+ # if it is False, it means valid. That is, it is not a padding
+ if memory_key_padding_mask.dtype != torch.bool:
+ raise ValueError("Memory key padding mask must be a boolean tensor.")
+ zero_negative_infinity = torch.zeros_like(memory_key_padding_mask, dtype=tgt.dtype)
+ zero_negative_infinity[memory_key_padding_mask] = float("-inf")
+ full_attention_mask = full_attention_mask.expand(
+ (
+ memory_key_padding_mask.shape[0],
+ num_memory + num_tgt,
+ num_memory + past_key_values_length + num_tgt,
+ )
+ )
+ full_attention_mask = full_attention_mask.clone()
+ origin_left = full_attention_mask[:, :, :num_memory]
+ update = zero_negative_infinity[:, None, :]
+ full_attention_mask[:, :, :num_memory] = origin_left + update
+
+ # add axis for multi-head
+ full_attention_mask = full_attention_mask[:, None, :, :]
+
+ return full_attention_mask
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ head_mask: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPooling]:
+ r"""
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:"""
+ output_attentions = (
+ output_attentions
+ if output_attentions is not None
+ else self.config.output_hidden_states
+ )
+ output_hidden_states = (
+ output_hidden_states
+ if output_hidden_states is not None
+ else self.config.output_hidden_states
+ )
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+ if input_ids is not None and inputs_embeds is not None:
+ raise ValueError(
+ "You cannot specify both input_ids and inputs_embeds at the same time"
+ )
+ elif input_ids is not None:
+ input_shape = input_ids.size()
+ elif inputs_embeds is not None:
+ input_shape = inputs_embeds.size()[:-1]
+ else:
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
+
+ batch_size, seq_length = input_shape
+
+ # past_key_values_length
+ past_key_values_length = (
+ past_key_values[0][0].shape[2] if past_key_values is not None else 0
+ )
+
+ # Prepare head mask if needed
+ # 1.0 in head_mask indicate we keep the head
+ # attention_probs has shape bsz x n_heads x N x N
+ # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]
+ # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]
+ head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)
+
+ projected_visual_features = None
+ if pixel_values is not None and past_key_values is None:
+ if pixel_values.ndim == 4:
+ # here we assume pixel_values is of shape (batch_size, num_channels, height, width)
+ visual_features = self.image_encoder(pixel_values).last_hidden_state
+
+ elif pixel_values.ndim == 5:
+ # here we assume pixel_values is of shape (batch_size, num_frames, num_channels, height, width)
+ visual_features = []
+ for frame_idx in range(pixel_values.shape[1]):
+ visual_features_frame = self.image_encoder(
+ pixel_values[:, frame_idx, :, :]
+ ).last_hidden_state
+ visual_features_frame += self.img_temporal_embedding[frame_idx]
+ visual_features.append(visual_features_frame)
+
+ # finally, concatenate all features along sequence dimension
+ visual_features = torch.cat(visual_features, dim=1)
+ else:
+ raise ValueError("pixel_values must be of rank 4 or 5")
+
+ projected_visual_features = self.visual_projection(visual_features)
+
+ # https://github.com/huggingface/transformers/blob/main/src/transformers/models/opt/modeling_opt.py#L634-L658
+ inputs_embeds = self.decoder.embed_tokens(input_ids)
+
+ # required mask seq length can be calculated via length of past
+ mask_seq_length = past_key_values_length + seq_length
+ if past_key_values is not None:
+ mask_seq_length = mask_seq_length - self.image_patch_tokens
+ past_key_values_length = past_key_values_length - self.image_patch_tokens
+
+ # embed positions
+ if attention_mask is None:
+ attention_mask = torch.ones(batch_size, mask_seq_length, device=inputs_embeds.device)
+ elif attention_mask.shape[1] != mask_seq_length:
+ raise ValueError(
+ f"The provided attention mask has length {attention_mask.shape[1]}, but its length should be "
+ f"{mask_seq_length} (sum of the lengths of current and past inputs)"
+ )
+ pos_embeds = self.embed_positions(attention_mask, past_key_values_length)
+
+ if self.decoder.project_in is not None:
+ inputs_embeds = self.decoder.project_in(inputs_embeds)
+
+ embedding_output = inputs_embeds + pos_embeds
+
+ if projected_visual_features is None:
+ projected_visual_features = torch.zeros(
+ (embedding_output.shape[0], 0, embedding_output.shape[2]),
+ dtype=embedding_output.dtype,
+ device=embedding_output.device,
+ )
+
+ # Repeat visual features to match embedding batch size.
+ projected_visual_features = projected_visual_features.repeat(
+ embedding_output.size(0) // projected_visual_features.size(0), 1, 1
+ )
+
+ # concatenate patch token and text token embeddings
+ hidden_states = torch.cat((projected_visual_features, embedding_output), dim=1)
+
+ # By default, an additive causal mask is created
+ # for masking the future (one direction).
+ tgt_mask = self._generate_future_mask(
+ seq_length, embedding_output.dtype, embedding_output.device
+ )
+
+ # for full sequence (w/ image patch tokens)
+ if past_key_values is not None:
+ past_key_values_length = past_key_values_length + self.image_patch_tokens
+
+ # Create an attention mask of shape (batch_size, 1, tgt_seq_len, src_seq_len)
+ combined_attention_mask = self.create_attention_mask(
+ tgt=embedding_output,
+ memory=projected_visual_features,
+ tgt_mask=tgt_mask,
+ past_key_values_length=past_key_values_length,
+ )
+
+ if attention_mask is not None:
+ # if the user provides an attention mask, we add it to the default one
+ # [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
+ expanded_attn_mask = _expand_mask(
+ attention_mask, embedding_output.dtype, tgt_len=input_shape[-1]
+ ).to(embedding_output.device)
+ if past_key_values_length > 0:
+ expanded_attn_mask = expanded_attn_mask[:, :, -past_key_values_length:, :]
+ else:
+ combined_attention_mask[
+ :, :, -input_shape[1] :, -input_shape[1] :
+ ] += expanded_attn_mask
+
+ # decoder layers
+ all_hidden_states = () if output_hidden_states else None
+ all_self_attns = () if output_attentions else None
+ next_decoder_cache = () if use_cache else None
+
+ for idx, decoder_layer in enumerate(self.decoder.layers):
+ # add LayerDrop (see https://arxiv.org/abs/1909.11556 for description)
+ if output_hidden_states:
+ all_hidden_states += (hidden_states,)
+
+ # dropout_probability = random.uniform(0, 1)
+ # if self.training and (dropout_probability < self.layerdrop):
+ # continue
+
+ past_key_value = past_key_values[idx] if past_key_values is not None else None
+
+ if self.decoder.gradient_checkpointing and self.decoder.training:
+
+ def create_custom_forward(module):
+ def custom_forward(*inputs):
+ # None for past_key_value
+ return module(*inputs, output_attentions, None)
+
+ return custom_forward
+
+ layer_outputs = torch.utils.checkpoint.checkpoint(
+ create_custom_forward(decoder_layer),
+ hidden_states,
+ combined_attention_mask,
+ head_mask[idx] if head_mask is not None else None,
+ None,
+ )
+ else:
+ layer_outputs = decoder_layer(
+ hidden_states,
+ attention_mask=combined_attention_mask,
+ layer_head_mask=(head_mask[idx] if head_mask is not None else None),
+ past_key_value=past_key_value,
+ output_attentions=output_attentions,
+ use_cache=use_cache,
+ )
+
+ hidden_states = layer_outputs[0]
+
+ if use_cache:
+ next_decoder_cache += (layer_outputs[2 if output_attentions else 1],)
+
+ if output_attentions:
+ all_self_attns += (layer_outputs[1],)
+
+ if self.decoder.final_layer_norm is not None:
+ hidden_states = self.decoder.final_layer_norm(hidden_states)
+
+ if self.decoder.project_out is not None:
+ hidden_states = self.decoder.project_out(hidden_states)
+
+ # add hidden states from the last decoder layer
+ if output_hidden_states:
+ all_hidden_states += (hidden_states,)
+
+ next_cache = next_decoder_cache if use_cache else None
+ if not return_dict:
+ return tuple(
+ v
+ for v in [hidden_states, next_cache, all_hidden_states, all_self_attns]
+ if v is not None
+ )
+ return BaseModelOutputWithPast(
+ last_hidden_state=hidden_states,
+ past_key_values=next_cache,
+ hidden_states=all_hidden_states,
+ attentions=all_self_attns,
+ )
+
+
+class GitOPTForCausalLM(OPTForCausalLM):
+ config_class = GitOPTConfig
+
+ def __init__(
+ self,
+ config,
+ ):
+ super(GitOPTForCausalLM, self).__init__(config)
+ self.model = GitOPTModel(config)
+
+ # Initialize weights and apply final processing
+ self.post_init()
+
+ def get_output_embeddings(self):
+ return self.lm_head
+
+ def set_output_embeddings(self, new_embeddings):
+ self.lm_head = new_embeddings
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ pixel_values: Optional[torch.Tensor] = None,
+ head_mask: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ labels: Optional[torch.Tensor] = None,
+ past_key_values: Optional[List[torch.Tensor]] = None,
+ use_cache: Optional[bool] = None,
+ output_attentions: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ ) -> Union[Tuple[torch.Tensor], CausalLMOutputWithPast]:
+ r"""
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
+ Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
+ `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
+ ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`
+ past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
+ Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
+
+ If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
+ don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
+ `decoder_input_ids` of shape `(batch_size, sequence_length)`.
+ use_cache (`bool`, *optional*):
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
+ `past_key_values`).
+
+ Returns:
+ """
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+ if labels is not None:
+ use_cache = False
+
+ outputs = self.model(
+ input_ids,
+ attention_mask=attention_mask,
+ position_ids=position_ids,
+ pixel_values=pixel_values,
+ head_mask=head_mask,
+ inputs_embeds=inputs_embeds,
+ past_key_values=past_key_values,
+ use_cache=use_cache,
+ output_attentions=output_attentions,
+ output_hidden_states=output_hidden_states,
+ return_dict=return_dict,
+ )
+
+ sequence_output = outputs[0]
+ logits = self.lm_head(sequence_output)
+
+ loss = None
+ if labels is not None:
+ # we are doing next-token prediction; shift prediction scores and input ids by one
+ num_image_tokens = self.model.image_patch_tokens
+ shifted_logits = logits[:, num_image_tokens:-1, :].contiguous()
+ labels = labels[:, 1:].contiguous()
+ loss_fct = CrossEntropyLoss()
+ loss = loss_fct(shifted_logits.view(-1, self.config.vocab_size), labels.view(-1))
+
+ if not return_dict:
+ output = (logits,) + outputs[1:]
+ return ((loss,) + output) if loss is not None else output
+
+ return CausalLMOutputWithPast(
+ loss=loss,
+ logits=logits,
+ past_key_values=outputs.past_key_values,
+ hidden_states=outputs.hidden_states,
+ attentions=outputs.attentions,
+ )
+
+ def prepare_inputs_for_generation(
+ self,
+ input_ids,
+ past_key_values=None,
+ attention_mask=None,
+ use_cache=None,
+ **kwargs,
+ ):
+ # cut decoder_input_ids if past_key_values is used
+ if past_key_values is not None:
+ input_ids = input_ids[:, -1:]
+
+ # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
+ input_shape = input_ids.shape
+ if attention_mask is None:
+ attention_mask = input_ids.new_ones(input_shape)
+
+ return {
+ "input_ids": input_ids,
+ "attention_mask": attention_mask,
+ "pixel_values": kwargs.get("pixel_values", None),
+ "past_key_values": past_key_values,
+ "use_cache": use_cache,
+ }
+
+ def _reorder_cache(self, past_key_values, beam_idx):
+ reordered_past = ()
+ for layer_past in past_key_values:
+ reordered_past += (
+ tuple(past_state.index_select(0, beam_idx) for past_state in layer_past),
+ )
+ return reordered_past
diff --git a/heron/models/prepare_processors.py b/heron/models/prepare_processors.py
new file mode 100644
index 0000000..e69de29
diff --git a/heron/models/utils.py b/heron/models/utils.py
new file mode 100644
index 0000000..33680b9
--- /dev/null
+++ b/heron/models/utils.py
@@ -0,0 +1,135 @@
+import glob
+from typing import Any, Optional
+
+import numpy as np
+import torch
+from peft import LoraConfig, get_peft_config, get_peft_model
+
+from .git_llm.git_japanese_stablelm_alpha import (
+ GitJapaneseStableLMAlphaConfig,
+ GitJapaneseStableLMAlphaForCausalLM,
+)
+from .git_llm.git_llama import GitLlamaConfig, GitLlamaForCausalLM
+from .git_llm.git_mpt import GitMptConfig, GitMptForCausalLM
+from .git_llm.git_opt import GitOPTConfig, GitOPTForCausalLM
+from .git_llm.git_gpt_neox import GitGPTNeoXConfig, GitGPTNeoXForCausalLM
+
+GitLLMForCausalLM = Any
+
+
+def load_model(
+ model_name: str,
+ vision_model_name: str,
+ num_image_with_embedding: Optional[int],
+ is_fp16: bool,
+) -> GitLLMForCausalLM:
+ """Loading a GIT-LLM depending on configs"""
+ # set dtype
+ if is_fp16:
+ torch_dtype = torch.float16
+ else:
+ torch_dtype = torch.float32
+
+ if "opt" in model_name:
+ git_config = GitOPTConfig.from_pretrained(model_name)
+ git_config.set_vision_configs(
+ num_image_with_embedding=num_image_with_embedding, vision_model_name=vision_model_name
+ )
+ model = GitOPTForCausalLM.from_pretrained(
+ model_name, config=git_config, torch_dtype=torch_dtype
+ )
+ elif "llama" in model_name:
+ git_config = GitLlamaConfig.from_pretrained(model_name)
+ git_config.set_vision_configs(
+ num_image_with_embedding=num_image_with_embedding, vision_model_name=vision_model_name
+ )
+ model = GitLlamaForCausalLM.from_pretrained(
+ model_name, config=git_config, torch_dtype=torch_dtype
+ )
+ elif "mpt" in model_name:
+ git_config = GitMptConfig.from_pretrained(model_name)
+ git_config.set_vision_configs(
+ num_image_with_embedding=num_image_with_embedding, vision_model_name=vision_model_name
+ )
+ model = GitMptForCausalLM.from_pretrained(
+ model_name, config=git_config, torch_dtype=torch_dtype
+ )
+ elif "japanese-stablelm" in model_name:
+ git_config = GitJapaneseStableLMAlphaConfig.from_pretrained(model_name)
+ git_config.set_vision_configs(
+ num_image_with_embedding=num_image_with_embedding, vision_model_name=vision_model_name
+ )
+ model = GitJapaneseStableLMAlphaForCausalLM.from_pretrained(
+ model_name, config=git_config, torch_dtype=torch_dtype
+ )
+ elif (
+ "line-corporation/japanese-large-lm" in model_name
+ or "matsuo-lab/weblab" in model_name
+ or "cyberagent/open-calm-7b" in model_name
+ ):
+ git_config = GitGPTNeoXConfig.from_pretrained(model_name)
+ git_config.set_vision_configs(
+ num_image_with_embedding=num_image_with_embedding, vision_model_name=vision_model_name
+ )
+ model = GitGPTNeoXForCausalLM.from_pretrained(
+ model_name, config=git_config, torch_dtype=torch_dtype
+ )
+ return model
+
+
+def load_pretrained_weight(model: GitLLMForCausalLM, weight_path: str):
+
+ weight = {}
+ weight_path = glob.glob(f"{weight_path}/pytorch*.bin")
+ for w in weight_path:
+ weight_temp = torch.load(w, map_location="cpu")
+ weight.update(weight_temp)
+ model.load_state_dict(weight, strict=False)
+
+
+def apply_lora_model(model: GitLLMForCausalLM, model_name: str, config: dict) -> GitLLMForCausalLM:
+ """Apply LoRA"""
+ peft_config = LoraConfig(**config["lora"])
+ # apply lora only to LLM
+ if "opt" in model_name:
+ model.model.decoder = get_peft_model(model.model.decoder, peft_config)
+ elif "llama" in model_name:
+ target_modules = []
+ for m in peft_config.target_modules:
+ target_modules += [
+ f"model.layers.{i}.self_attn.{m}" for i in range(len(model.model.layers))
+ ]
+
+ peft_config.target_modules = target_modules
+ model = get_peft_model(model, peft_config)
+ model.base_model.model.lm_head = model.lm_head
+ # remove peft wrapper
+ model = model.base_model.model
+ elif "mpt" in model_name:
+ model = get_peft_model(model, peft_config)
+ model.base_model.model.lm_head = model.lm_head
+ # remove peft wrapper
+ model = model.base_model.model
+ elif (
+ "japanese-stablelm" in model_name
+ or "line-corporation/japanese-large-lm" in model_name
+ or "matsuo-lab/weblab" in model_name
+ or "cyberagent/open-calm-7b" in model_name
+ ):
+ model = get_peft_model(model, peft_config)
+ model.base_model.model.embed_out = model.embed_out
+ # remove peft wrapper
+ model = model.base_model.model
+ return model
+
+
+def set_trainable_params(model: GitLLMForCausalLM, model_name: str, keys_finetune: list) -> None:
+ trainable_list = []
+ untrainable_list = []
+ for name, p in model.named_parameters():
+ if np.any([k in name for k in keys_finetune]):
+ p.requires_grad = True
+ trainable_list.append(name)
+ else:
+ p.requires_grad = False
+ untrainable_list.append(name)
diff --git a/images/heron_image.png b/images/heron_image.png
new file mode 100644
index 0000000..9e8cc18
Binary files /dev/null and b/images/heron_image.png differ
diff --git a/notebooks/inference.ipynb b/notebooks/inference.ipynb
new file mode 100644
index 0000000..f65eab3
--- /dev/null
+++ b/notebooks/inference.ipynb
@@ -0,0 +1,1423 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "0b513f29-6f5f-4524-82f7-04177b835c3b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "exp = \"exp050_llama\"\n",
+ "device_id = 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "3b156306-373d-41a9-82b6-4f0e85c737e7",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2023-08-09 03:11:29,783] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n"
+ ]
+ }
+ ],
+ "source": [
+ "import glob\n",
+ "import os\n",
+ "import sys\n",
+ "from base64 import b64decode\n",
+ "from io import BytesIO\n",
+ "from PIL import Image\n",
+ "\n",
+ "from transformers import (\n",
+ " AutoTokenizer,\n",
+ " CLIPImageProcessor,\n",
+ " AutoProcessor,\n",
+ " TrainingArguments,\n",
+ " Trainer,\n",
+ " AutoModelForCausalLM\n",
+ ")\n",
+ "import datasets\n",
+ "import torch\n",
+ "from torch.utils.data import Dataset\n",
+ "import yaml\n",
+ "import deepspeed\n",
+ "import fire\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import japanize_matplotlib\n",
+ "from peft import LoraConfig, get_peft_config, get_peft_model\n",
+ "\n",
+ "\n",
+ "from git_llm.git_opt import GitOPTForCausalLM, GitOPTConfig\n",
+ "from git_llm.git_llama import GitLlamaForCausalLM, GitLlamaConfig"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "7b5cb602-f80d-4881-9408-6b6be3369a33",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sys.path.append('..')\n",
+ "from train import load_model, apply_lora_model"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "87dd43fe-0005-4db2-a3f5-744f6be7fc2c",
+ "metadata": {},
+ "source": [
+ "# Functions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "535b178f-f679-434a-872b-5e53a0236b6f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def generate_text(model, data):\n",
+ " eos_token_id_list = [\n",
+ " supervised_test_dataset.processor.tokenizer.pad_token_id,\n",
+ " supervised_test_dataset.processor.tokenizer.eos_token_id,\n",
+ " ]\n",
+ " with torch.no_grad():\n",
+ " out = model.generate(**data, max_length=256, do_sample=False, temperature=0., eos_token_id=eos_token_id_list)\n",
+ " return supervised_test_dataset.processor.tokenizer.batch_decode(out)\n",
+ "\n",
+ "# SupervisedDataset\n",
+ "class SupervisedDataset(Dataset):\n",
+ " \"\"\"Dataset for supervised learning\"\"\"\n",
+ "\n",
+ " def __init__(\n",
+ " self,\n",
+ " model_name: str,\n",
+ " vision_model_name: str,\n",
+ " loaded_dataset: datasets.GeneratorBasedBuilder,\n",
+ " max_length: int = 128,\n",
+ " ):\n",
+ " super(SupervisedDataset, self).__init__()\n",
+ " self.loaded_dataset = loaded_dataset\n",
+ " self.max_length = max_length\n",
+ "\n",
+ " self.processor = AutoProcessor.from_pretrained(\"microsoft/git-base\")\n",
+ " self.processor.image_processor = CLIPImageProcessor.from_pretrained(vision_model_name)\n",
+ " self.processor.tokenizer = AutoTokenizer.from_pretrained(\n",
+ " model_name, padding_side=\"right\", use_fast=False\n",
+ " )\n",
+ " if \"llama\" in model_name:\n",
+ " self.processor.tokenizer.pad_token = self.processor.tokenizer.eos_token\n",
+ "\n",
+ " def __len__(self) -> int:\n",
+ " return len(self.loaded_dataset)\n",
+ "\n",
+ " def __getitem__(self, index) -> dict:\n",
+ " # cf: https://huggingface.co/datasets/MMInstruction/M3IT#data-instances\n",
+ " row = self.loaded_dataset[index]\n",
+ "\n",
+ " instruction = row[\"instruction\"] # str\n",
+ " question = row[\"inputs\"] # str\n",
+ " answer = row[\"outputs\"] # str\n",
+ " full_text = f\"##Instruction: {instruction} ##Question: {question} ##Answer: {answer}\"\n",
+ " text = f\"##Instruction: {instruction} ##Question: {question} ##Answer:\"\n",
+ "\n",
+ " # imageのロード\n",
+ " image_base64_str_list = row[\"image_base64_str\"] # str (base64)\n",
+ " img = Image.open(BytesIO(b64decode(image_base64_str_list[0])))\n",
+ "\n",
+ " inputs = self.process_data(text, img)\n",
+ "\n",
+ " return inputs, img, text, full_text\n",
+ "\n",
+ " def process_data(self, text, img):\n",
+ " inputs = self.processor(\n",
+ " text,\n",
+ " img,\n",
+ " return_tensors=\"pt\",\n",
+ " # max_length=self.max_length,\n",
+ " # padding=\"max_length\",\n",
+ " truncation=True,\n",
+ " )\n",
+ " inputs = {k: v.to(f\"cuda:{device_id}\") for k, v in inputs.items()}\n",
+ " inputs[\"pixel_values\"] = inputs[\"pixel_values\"].to(torch.float16)\n",
+ " inputs[\"labels\"] = None\n",
+ " return inputs"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "974b1a15-0574-4d61-b167-05e74aadad09",
+ "metadata": {},
+ "source": [
+ "# Load configs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "d85d3447-cb64-4ee1-83b9-32ea808c323c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "config_file = f\"../configs/training_config_{exp}.yml\"\n",
+ "\n",
+ "# get config\n",
+ "with open(config_file, \"r\") as i_:\n",
+ " config = yaml.safe_load(i_)\n",
+ "\n",
+ "\n",
+ "# model\n",
+ "model_name = config[\"settings\"][\"model_name\"]\n",
+ "vision_model_name = config[\"settings\"][\"vision_model_name\"]\n",
+ "num_image_with_embedding = config[\"settings\"][\"num_image_with_embedding\"]\n",
+ "\n",
+ "keys_finetune = config[\"settings\"][\"keys_finetune\"]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2b9a7fb1-1594-472c-8ead-116b4924a0f3",
+ "metadata": {},
+ "source": [
+ "# Load a pretrained model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "3fc3a60d-f92e-4e74-a504-114ab42ac1df",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "You are using a model of type llama to instantiate a model of type git_llama. This is not supported for all configurations of models and can yield errors.\n"
+ ]
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "adf8224c06d14ca6b89975b5669018f2",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Loading checkpoint shards: 0%| | 0/2 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Some weights of GitLlamaForCausalLM were not initialized from the model checkpoint at meta-llama/Llama-2-7b-chat-hf and are newly initialized: ['model.image_encoder.vision_model.encoder.layers.9.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.1.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.4.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.3.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.2.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.9.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.3.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.7.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.1.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.9.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.6.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.v_proj.bias', 'model.image_encoder.vision_model.embeddings.patch_embedding.weight', 'model.image_encoder.vision_model.encoder.layers.11.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.4.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.10.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.0.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.10.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.11.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.9.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.7.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.q_proj.weight', 'model.image_encoder.vision_model.pre_layrnorm.bias', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.9.layer_norm2.bias', 'model.image_encoder.vision_model.embeddings.position_embedding.weight', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.k_proj.bias', 'model.image_encoder.vision_model.embeddings.class_embedding', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.1.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.5.mlp.fc1.weight', 'model.visual_projection.visual_projection.1.weight', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.7.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.9.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.8.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.3.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.6.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.7.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.4.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.11.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.k_proj.bias', 'model.visual_projection.visual_projection.0.weight', 'model.image_encoder.vision_model.encoder.layers.7.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.5.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.11.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.0.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.3.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.6.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.0.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.11.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.q_proj.weight', 'model.visual_projection.visual_projection.1.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.2.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.3.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.11.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.8.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.2.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.out_proj.weight', 'model.image_encoder.vision_model.post_layernorm.weight', 'model.image_encoder.vision_model.encoder.layers.8.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.10.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.0.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.2.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.1.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.2.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.6.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.6.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.5.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.9.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.1.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.4.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.4.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.5.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.5.mlp.fc2.bias', 'model.image_encoder.vision_model.pre_layrnorm.weight', 'model.image_encoder.vision_model.encoder.layers.8.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.10.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.7.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.10.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.3.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.8.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.0.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.9.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.5.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.7.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.2.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.0.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.10.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.4.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.8.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.0.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.8.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.10.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.4.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.6.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.1.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.5.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.1.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.5.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.5.mlp.fc2.weight', 'model.image_encoder.vision_model.encoder.layers.0.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.8.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.2.layer_norm2.bias', 'model.visual_projection.visual_projection.0.bias', 'model.image_encoder.vision_model.encoder.layers.6.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.9.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.2.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.4.mlp.fc2.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.k_proj.weight', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.q_proj.weight', 'model.image_encoder.vision_model.encoder.layers.8.layer_norm1.weight', 'model.image_encoder.vision_model.encoder.layers.11.mlp.fc1.bias', 'model.image_encoder.vision_model.post_layernorm.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.6.layer_norm2.weight', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.v_proj.bias', 'model.image_encoder.vision_model.encoder.layers.3.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.6.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.10.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.4.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.1.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.2.mlp.fc1.weight', 'model.image_encoder.vision_model.encoder.layers.3.mlp.fc1.bias', 'model.image_encoder.vision_model.encoder.layers.10.layer_norm2.bias', 'model.image_encoder.vision_model.encoder.layers.11.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.v_proj.weight', 'model.image_encoder.vision_model.encoder.layers.1.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.q_proj.bias', 'model.image_encoder.vision_model.encoder.layers.0.self_attn.k_proj.bias', 'model.image_encoder.vision_model.encoder.layers.7.self_attn.out_proj.weight', 'model.image_encoder.vision_model.encoder.layers.11.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.out_proj.bias', 'model.image_encoder.vision_model.encoder.layers.7.layer_norm1.bias', 'model.image_encoder.vision_model.encoder.layers.3.self_attn.k_proj.bias']\n",
+ "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Complete preparing an eval model\n"
+ ]
+ }
+ ],
+ "source": [
+ "model = load_model(model_name, vision_model_name, num_image_with_embedding)\n",
+ "\n",
+ "# lora\n",
+ "if config[\"use_lora\"]:\n",
+ " keys_finetune.append(\"lora\")\n",
+ " model = apply_lora_model(model, model_name, config)\n",
+ "\n",
+ "weight = {}\n",
+ "weight_path = glob.glob(f'../output/{exp}/checkpoint*/pytorch*.bin')\n",
+ "for w in weight_path:\n",
+ " weight_temp = torch.load(w, map_location=\"cpu\")\n",
+ " weight.update(weight_temp)\n",
+ "model.load_state_dict(weight, strict=False)\n",
+ "\n",
+ "model.eval()\n",
+ "model.to(f\"cuda:{device_id}\")\n",
+ "print(\"Complete preparing an eval model\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "70c5259a-b26c-45ef-b941-86b74fbd6d75",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a17c3b9c-724f-4d38-9d36-19823ea3ddc6",
+ "metadata": {},
+ "source": [
+ "# Inference"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "ca00dcf9-6334-4b3f-a7cc-da0f4150dd55",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Found cached dataset m3_it (/home/y_inoue/.cache/huggingface/datasets/MMInstruction___m3_it/coco/1.0.0/631dfd20153e0fbacb50b0239d4a71727503813fa0e821ba5ab399bed706034e)\n"
+ ]
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3269a01d9ed14a96a3b00384b9c75e37",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/3 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Asking to truncate to max_length but no maximum length is provided and the model has no predefined maximum length. Default to no truncation.\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "--------------------\n",
+ "[' ##Instruction: Write a succinct description of the image, capturing its main components, the relationships between them, and any notable details. ##Question: ##Answer: A street sign with a street name and a parking sign.']\n",
+ "##Instruction: Write a succinct description of the image, capturing its main components, the relationships between them, and any notable details. ##Question: ##Answer: A large wooden pole with a green street sign hanging from it.\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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la985dBva2mcRISHH34Y733ve/GkJz0Jf/d3f4drrrkG1to1M07nHN72trfhfe97Hz7wgQ/gO9/5Dl7ykpfg8ccfxzvf+c4TYpwnlcQUc3g0vUP27NmDnTt3Ho8urSrs2rVraGxAfXzTlDlR4K677sLll1+On/qpn8JXv/pVXHrppeVva22sALB582bcdNNN2LNnD9773veumTF+/vOfxx/90R/hgx/8YOvva2WcAHDrrbfiT//0T3HOOeeAiHD55Zfjda97HW699dY1M86zzjoLr371q3HllVeCiHDBBRfghhtuwEc+8hEAJ8h6HrGV6hjDpZdeyu9+97trz37u536OX//61x+nHq0cms4PDz/8MGdZxl/72tfKZ0VR8Pbt2/lP/uRPmJn5U5/6FG/dupWLoijLfOMb3+BOp8MPP/zwMev7JPjhD3/IW7du5Y9//OOtv6+FsTrn+LOf/ezQ86uvvppf97rXrYkxMjO/7nWvK5Mtt30+/vGPr4lxMovXYRN+93d/l5/xjGesmfX8lV/5Ff4P/+E/1J597GMf4507dzLziXE2TzrC9NGPfpR37tzJd999NzPLBG3cuJG/+93vHueezQ5NwsTM/OpXv5r/5b/8l7x//3621vKv//qv80UXXVRugKIo+KKLLuLrr7+erbW8b98+ftaznsW/+qu/ehxGMBqe97zn8Vvf+taxZU72sT700EO8bds2futb31p65t1+++3c6XT485//PDOf/GMcBalXHvPaGecLXvACfsMb3sBLS0vMzPy3f/u3vHXrVv7Qhz7EzGtjnPfccw/v2LGD//Iv/5KZmX/wgx/whRdeyDfccENZ5niP86QjTMzMv//7v89PfvKTefv27fz0pz+dv/SlLx3vLq0I2ghTv9/n17/+9bxz504+44wz+EUvehHff//9tTL3338/v+hFL+Lt27fzzp07+fWvf/2Qy/LxBgC8detW3rlz59AnwloY6/e//32+9tpreceOHbx9+3Z+2tOeVnOTXwtjbIMmYVor43zggQf4l37pl3jXrl28detWfvKTn8zvfe97y9/Xyjj/8i//kq+44go+/fTT+dxzz+WbbrqpJv0c73HOo4vPYQ5zmMMcTig4qZwf5jCHOcxhDmsf5oRpDnOYwxzmcELBnDDNYQ5zmMMcTiiYE6Y5zGEOc5jDCQVzwjSHOcxhDnM4oWBOmOYwhznMYQ4nFMwJ0xzmMIc5zOGEgjlhmsMc5jCHOZxQMCdMc5jDHOYwhxMK5oRpDnOYwxzmcELBnDDNYQ5zmMMcTiiYE6Y5zGEOc5jDCQX/P9K19fndC32mAAAAAElFTkSuQmCC",
+ "text/plain": [
+ "