104 lines
4.6 KiB
Markdown
104 lines
4.6 KiB
Markdown
---
|
||
license: apache-2.0
|
||
base_model:
|
||
- microsoft/llava-med-v1.5-mistral-7b
|
||
pipeline_tag: visual-question-answering
|
||
language:
|
||
- en
|
||
tags:
|
||
- medical
|
||
- biology
|
||
---
|
||
# llava-med-v1.5-mistral-7b-hf
|
||
|
||
This repository contains a **drop-in, Hugging Face–compatible** checkpoint converted from
|
||
[https://huggingface.co/microsoft/llava-med-v1.5-mistral-7b](https://huggingface.co/microsoft/llava-med-v1.5-mistral-7b).
|
||
You can load it with the **exact same code** you use for the original model—no extra conversion steps required.
|
||
|
||
---
|
||
## ✅ Clarification on Vocab Size Expansion & Weight Integrity
|
||
You can refer to the original conversion code we provided to access the relevant implementation details and code snippets.
|
||
You may wonder if the vocab size mismatch (e.g., 32000 vs. 32064) breaks the original weights by causing dimension mismatches between embed_tokens/lm_head and the original weights.
|
||
|
||
The answer is no. Below are key clarifications:
|
||
|
||
### 1. Does expanding embed_tokens affect the attention mechanism?
|
||
No. The embed_tokens layer is simply an embedding lookup table (nn.Embedding) that maps token IDs to vectors.
|
||
The attention mechanism (e.g., nn.MultiheadAttention or LlamaAttention) does not operate on this lookup table directly. It only cares if the dimension of input hidden states is consistent.
|
||
Thus, even if you add more tokens, as long as the hidden_size remains unchanged, the weight shape of the attention layer is not affected at all.
|
||
|
||
### 2. Which layers actually change after expansion?
|
||
| Module | Weight Shape Change | Affects Attention Calculation? |
|
||
|----------------------|--------------------------------------|---------------------------------|
|
||
| embed_tokens | [vocab_size+2, hidden_size] | ❌ No |
|
||
| lm_head | [vocab_size+2, hidden_size] | ❌ No |
|
||
| All attention layers | No shape change | ✅ Completely unchanged |
|
||
|
||
#### Analogy for easier understanding
|
||
Think of the model as a dictionary:
|
||
- embed_tokens is the "new word list": You add two new words, but the length of each word’s explanation (hidden_size) stays the same.
|
||
- Attention is the "reading rule": It only focuses on how the vectors of each word in a sentence interact with each other, not how many words are in the dictionary.
|
||
|
||
#### The only "change" lies in input distribution
|
||
- The original model never encountered embeddings for tokens like `<image>` or `<pad>`.
|
||
- Now these tokens are initialized, and their new vectors appear during the first forward pass.
|
||
- This is a data-level change, not damage to the model’s parameters.
|
||
|
||
#### Summary
|
||
Expanding the vocab only changes the "dictionary size", not the "reading rules". The weight shape and calculation logic of the attention mechanism remain completely unchanged. The output layer (lm_head) changes in shape but not in functional logic.
|
||
|
||
### 3. What exactly changes in the output layer (lm_head)?
|
||
The line below modifies the weight matrix of lm_head (the language modeling head):
|
||
```python
|
||
model.resize_token_embeddings(config.text_config.vocab_size + 2, pad_shape)
|
||
```
|
||
## Quick Start
|
||
|
||
```python
|
||
from transformers import LlavaForConditionalGeneration, AutoProcessor
|
||
import torch
|
||
|
||
model_path = "chaoyinshe/llava-med-v1.5-mistral-7b-hf"
|
||
|
||
model = LlavaForConditionalGeneration.from_pretrained(
|
||
model_path,
|
||
torch_dtype=torch.bfloat16,
|
||
attn_implementation="flash_attention_2", # requires FA2
|
||
device_map="auto" # multi-GPU ready
|
||
)
|
||
|
||
processor = AutoProcessor.from_pretrained(model_path)
|
||
|
||
# Example inference
|
||
messages = [
|
||
{
|
||
"role": "user",
|
||
"content": [
|
||
{"type": "image"},
|
||
{"type": "text", "text": "What is the main finding in this chest X-ray?"}
|
||
]
|
||
}
|
||
]
|
||
|
||
prompt = processor.tokenizer.apply_chat_template(
|
||
messages, tokenize=False, add_generation_prompt=True
|
||
)
|
||
|
||
inputs = processor(
|
||
images=[image], text=prompt, return_tensors="pt"
|
||
).to(model.device, torch.bfloat16)
|
||
|
||
with torch.inference_mode():
|
||
out = model.generate(**inputs, max_new_tokens=256)
|
||
|
||
print(processor.decode(out[0], skip_special_tokens=True))
|
||
```
|
||
## ✅ Training Screenshot
|
||
(Note: The image below is for illustrative purposes only — actual training metrics may vary.)
|
||
🤗
|
||
|
||

|
||
|
||

|
||
|
||
 |