|
--- |
|
library_name: transformers |
|
license: mit |
|
datasets: |
|
- 5CD-AI/LLaVA-CoT-o1-Instruct |
|
language: |
|
- vi |
|
- en |
|
- zh |
|
pipeline_tag: image-text-to-text |
|
--- |
|
|
|
|
|
 |
|
|
|
## This is our basic reasoning model before enhanced by Reinforcement Learning. |
|
|
|
Multimodal LLM x Reasoning Model 👀 🧠 🔍 |
|
|
|
After more than six months since creating the [5CD-AI/LLaVA-CoT-o1-Instruct](https://huggingface.co/datasets/5CD-AI/LLaVA-CoT-o1-Instruct) dataset—one of Hugging Face’s most liked datasets of 2024 🎉—we have just completed the "base" version of the Vintern Reasoning Model! |
|
- This model can perform long and complex reasoning based on images, breaking down each reasoning step into multiple sub-steps while keeping hallucinations under control. |
|
- Despite the difficulty of balancing multiple tasks alongside reasoning, Vintern-3B-R-beta has outperformed all previous versions across various benchmarks! |
|
|
|
When should you choose [Vintern-1B-v3_5](https://huggingface.co/5CD-AI/Vintern-1B-v3_5) vs Vintern-3B-R-beta? 🤔 |
|
|
|
- **Vintern-1B-v3_5**: Fast ⚡ and good for Vietnamese OCR with simple text formatting. 📝 Highly reliable. ✅ |
|
- **Vintern-3B-R-beta**: Better for complex questions and complex structured doc image. 🔍📚 OCR performance on blurred or unclear text may be slightly affected due to our training focus on reasoning. 🔍🤖 |
|
|
|
🚀 The next step? Training and enhancing its reasoning ability by Reinforcement Learning! |
|
|
|
## Benchmarks 📈 |
|
|
|
 |
|
|
|
## Example 1: |
|
|
|
``` |
|
|
|
<SUMMARY>Đề bài toán yêu cầu xác định món ăn có giá cao nhất trong danh sách các món ăn được liệt kê trên menu của một quán ăn. |
|
Để giải quyết vấn đề này, cần phân tích giá của từng món ăn từ menu và so sánh để tìm ra món có giá cao nhất.</SUMMARY> |
|
|
|
<CAPTION>Ảnh chụp một phần menu của quán ăn, hiển thị danh sách các món ăn kèm theo giá tiền. |
|
Menu được chia thành hai cột, mỗi cột liệt kê các món ăn khác nhau với giá tiền tương ứng.</CAPTION> |
|
|
|
<FIND_CANDIDATES_REASONING>Để tìm ra món ăn có giá cao nhất, chúng ta cần thực hiện các bước sau: |
|
|
|
1. **Xác định danh sách các món ăn:** Menu cung cấp danh sách đầy đủ các món ăn, bao gồm: ếch xào sả ớt, ếch chiên mắm, gà nướng ớt, gà chiên mắm, ốc bươu xào sả ớt, ốc cà na xào sả ớt, ốc cà na xào bơ tỏi, ốc hương xào sả ớt, ốc hương xào bơ tỏi, chả cua mồng tơi, bao tử cá ba sa xào nghệ, ba chỉ nướng ớt, thịt đà điểu xào sả ớt, thịt đà điểu xào thơm cà, thịt nai xào sả ớt, thịt nai xào thơm cà, cá bả trầu nướng cuốn cải (2 con), cá bả trầu nướng ớt xanh (2 con), lẩu gà lá giang, lẩu ếch lá giang, lẩu mực, lẩu bò. |
|
|
|
2. **Xác định giá của từng món ăn:** Mỗi món ăn đều có giá tiền được ghi rõ ràng bên cạnh tên món ăn. Ví dụ, ếch xào sả ớt có giá 55k, ếch chiên mắm có giá 55k, gà nướng ớt có giá 50k, v.v. |
|
|
|
3. **So sánh giá của các món ăn:** So sánh giá của từng món ăn để tìm ra món có giá cao nhất. Quá trình này đòi hỏi sự cẩn thận để đảm bảo không bỏ sót bất kỳ món nào.</FIND_CANDIDATES_REASONING> |
|
|
|
<TOP3_CANDIDATES> |
|
1. Cá bả trầu nướng cuốn cải (2 con) 65k |
|
2. Cá bả trầu nướng ớt xanh (2 con) 65k |
|
3. Lẩu bò 69k |
|
</TOP3_CANDIDATES> |
|
|
|
<REASONING>Để xác định món ăn có giá cao nhất, chúng ta cần so sánh giá của tất cả các món ăn trên menu. Dựa trên thông tin trong ảnh, chúng ta có thể lập bảng giá như sau: |
|
|
|
| Món ăn | Giá (VNĐ) | |
|
|-------------------------------|--------| |
|
| Ếch xào sả ớt | 55k | |
|
| Ếch chiên mắm | 55k | |
|
| Gà nướng ớt | 50k | |
|
| Gà chiên mắm | 50k | |
|
| Ốc bươu xào sả ớt | 45k | |
|
| Ốc cà na xào sả ớt | 49k | |
|
| Ốc cà na xào bơ tỏi | 49k | |
|
| Ốc hương xào sả ớt | 59k | |
|
| Ốc hương xào bơ tỏi | 59k | |
|
| Chả cua mồng tơi | 55k | |
|
| Bao tử cá ba sa xào nghệ | 55k | |
|
| Ba chỉ nướng ớt | 50k | |
|
| Thịt đà điểu xào sả ớt | 55k | |
|
| Thịt đà điểu xào thơm cà | 55k | |
|
| Thịt nai xào sả ớt | 55k | |
|
| Thịt nai xào thơm cà | 55k | |
|
| Cá bả trầu nướng cuốn cải (2 con) | 65k | |
|
| Cá bả trầu nướng ớt xanh (2 con) | 65k | |
|
| Lẩu gà lá giang | 59k | |
|
| Lẩu ếch lá giang | 65k | |
|
| Lẩu mực | 65k | |
|
| Lẩu bò | 69k | |
|
|
|
Sau khi so sánh, món ăn có giá cao nhất là Lẩu bò với giá 69k.</REASONING> |
|
|
|
<COUNTER_ARGUMENTS>Những người phản đối có thể đưa ra các lập luận như sau: |
|
|
|
- **Một số món ăn có giá thấp hơn:** Một số món ăn có giá thấp hơn, ví dụ như ếch xào sả ớt, ếch chiên mắm, gà nướng ớt, gà chiên mắm, ốc bươu xào sả ớt, ốc cà na xào sả ớt, ốc cà na xào bơ tỏi, ốc hương xào sả ớt, ốc hương xào bơ tỏi, chả cua mồng tơi, bao tử cá ba sa xào nghệ, ba chỉ nướng ớt, thịt đà điểu xào sả ớt, thịt đà điểu xào thơm cà, thịt nai xào sả ớt, thịt nai xào thơm cà, cá bả trầu nướng cuốn cải (2 con), cá bả trầu nướng ớt xanh (2 con), lẩu gà lá giang, lẩu ếch lá giang, lẩu mực. |
|
|
|
- **Giá có thể thay đổi:** Giá của các món ăn có thể thay đổi tùy thuộc vào thời điểm và địa điểm. Việc so sánh giá dựa trên thông tin trong ảnh có thể không phản ánh chính xác giá thực tế.</COUNTER_ARGUMENTS> |
|
|
|
<REASONING>Những lập luận phản đối tập trung vào việc so sánh giá của các món ăn có giá thấp hơn. Tuy nhiên, mục đích của bài toán là xác định món ăn có giá cao nhất, không phải so sánh giá của tất cả các món ăn. Chúng ta đã so sánh giá của tất cả các món ăn và kết luận món ăn có giá cao nhất là Lẩu bò với giá 69k.</REASONING> |
|
|
|
<CONCLUSION>Lẩu bò</CONCLUSION> |
|
``` |
|
|
|
|
|
<div align="center"> |
|
<img src="https://cdn-uploads.huggingface.co/production/uploads/6336b5c831efcb5647f00170/p-pG8lJu3_RUHrOIUsZeH.png" width="300"/> |
|
</div> |
|
|
|
|
|
## Example 2: |
|
|
|
<div align="center"> |
|
<img src="https://cdn-uploads.huggingface.co/production/uploads/6336b5c831efcb5647f00170/msklqHxFL0JTRw_Yf7LhQ.jpeg" width="300"/> |
|
</div> |
|
|
|
|
|
``` |
|
User: <image> |
|
Liệt kê toàn bộ văn bản. |
|
Assistant: CHÍNH PHỦ |
|
Số: 626/QĐ-TTg |
|
CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM |
|
Độc lập - Tự do - Hạnh phúc |
|
Hà Nội, ngày 29 tháng 7 năm 2002 |
|
QUYẾT ĐỊNH CỦA THỦ TƯỚNG CHÍNH PHỦ |
|
Phê duyệt Báo cáo nghiên cứu khả thi dự án đầu tư |
|
Nhà máy sản xuất phân bón diamôn phốt phát (DAP) tại khu |
|
Kinh tế Đình Vũ, thành phố Hải Phòng |
|
THỦ TƯỚNG (CHÍNH PHỦ) |
|
Căn cứ Luật Tổ chức Chính phủ ngày 25 tháng 12 năm 2001; |
|
Căn cứ Nghị định số 52/1999/NĐ-CP ngày 8 tháng 7 năm 1999 của Chính phủ |
|
ban hành (Quy chế quản lý đầu tư và xây dựng và Ngành dịch số 12/2000/ND-CP |
|
ngày 05 tháng 5 năm 2000) của Chính phủ quy định sửa đổi, bổ sung một số |
|
điều của Quy chế quản lý đầu tư và xây dựng. |
|
Xét đề nghị của Tổng công ty Hoá chất Việt Nam (công văn số 916/ CV-HĐQT |
|
ngày 01 tháng 11 năm 2001), ý kiến thẩm định của Bộ Kế hoạch và Đầu tư tại |
|
công văn số 1944 BKH/VPTD ngày 01 tháng 4 năm 2002, về việc phê duyệt |
|
Báo cáo nghiên cứu khả thi dự án đầu tư Nhà máy sản xuất phân bón diamôn |
|
phốt phát tại khu kinh tế Đình Vũ, thành phố Hải Phòng và ý kiến của các Bộ, |
|
ngành tại cuộc họp ngày 19 tháng 6 năm 2002, |
|
QUYẾT ĐỊNH: |
|
Điều 1. Phê duyệt Báo cáo nghiên cứu khả thi dự án đầu tư Nhà máy sản |
|
xuất phân bón DAP tại khu kinh tế Đình Vũ, thành phố Hải Phòng với các nội |
|
dung chính sau : |
|
1. Tên dự án : Nhà máy sản xuất phân bón DAP tại khu kinh tế Đình Vũ, |
|
thành phố Hải Phòng. |
|
2. Mục tiêu đầu tư: góp phần đảm bảo ổn định và chủ động trong việc cung |
|
cấp phân bón DAP cho phát triển nông nghiệp, hạn chế nhập khẩu, sử dụng có |
|
hiệu quả hơn nguồn tài nguyên quặng apatit trong nước. |
|
3. Chủ đầu tư : Tổng công ty Hoá chất Việt Nam. |
|
``` |
|
|
|
## Quickstart |
|
|
|
Here provides a code snippet to show you how to load the tokenizer and model and how to generate contents. |
|
To run inference using the model, follow the steps outlined in our Colab inference notebook |
|
[](https://colab.research.google.com/drive/1ZD1oB56PF0lF66RCuTVJYLTEV0tM3CFf?usp=sharing) |
|
|
|
```python |
|
import numpy as np |
|
import torch |
|
import torchvision.transforms as T |
|
# from decord import VideoReader, cpu |
|
from PIL import Image |
|
from torchvision.transforms.functional import InterpolationMode |
|
from transformers import AutoModel, AutoTokenizer |
|
|
|
IMAGENET_MEAN = (0.485, 0.456, 0.406) |
|
IMAGENET_STD = (0.229, 0.224, 0.225) |
|
|
|
def build_transform(input_size): |
|
MEAN, STD = IMAGENET_MEAN, IMAGENET_STD |
|
transform = T.Compose([ |
|
T.Lambda(lambda img: img.convert('RGB') if img.mode != 'RGB' else img), |
|
T.Resize((input_size, input_size), interpolation=InterpolationMode.BICUBIC), |
|
T.ToTensor(), |
|
T.Normalize(mean=MEAN, std=STD) |
|
]) |
|
return transform |
|
|
|
def find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, image_size): |
|
best_ratio_diff = float('inf') |
|
best_ratio = (1, 1) |
|
area = width * height |
|
for ratio in target_ratios: |
|
target_aspect_ratio = ratio[0] / ratio[1] |
|
ratio_diff = abs(aspect_ratio - target_aspect_ratio) |
|
if ratio_diff < best_ratio_diff: |
|
best_ratio_diff = ratio_diff |
|
best_ratio = ratio |
|
elif ratio_diff == best_ratio_diff: |
|
if area > 0.5 * image_size * image_size * ratio[0] * ratio[1]: |
|
best_ratio = ratio |
|
return best_ratio |
|
|
|
def dynamic_preprocess(image, min_num=1, max_num=12, image_size=448, use_thumbnail=False): |
|
orig_width, orig_height = image.size |
|
aspect_ratio = orig_width / orig_height |
|
|
|
# calculate the existing image aspect ratio |
|
target_ratios = set( |
|
(i, j) for n in range(min_num, max_num + 1) for i in range(1, n + 1) for j in range(1, n + 1) if |
|
i * j <= max_num and i * j >= min_num) |
|
target_ratios = sorted(target_ratios, key=lambda x: x[0] * x[1]) |
|
|
|
# find the closest aspect ratio to the target |
|
target_aspect_ratio = find_closest_aspect_ratio( |
|
aspect_ratio, target_ratios, orig_width, orig_height, image_size) |
|
|
|
# calculate the target width and height |
|
target_width = image_size * target_aspect_ratio[0] |
|
target_height = image_size * target_aspect_ratio[1] |
|
blocks = target_aspect_ratio[0] * target_aspect_ratio[1] |
|
|
|
# resize the image |
|
resized_img = image.resize((target_width, target_height)) |
|
processed_images = [] |
|
for i in range(blocks): |
|
box = ( |
|
(i % (target_width // image_size)) * image_size, |
|
(i // (target_width // image_size)) * image_size, |
|
((i % (target_width // image_size)) + 1) * image_size, |
|
((i // (target_width // image_size)) + 1) * image_size |
|
) |
|
# split the image |
|
split_img = resized_img.crop(box) |
|
processed_images.append(split_img) |
|
assert len(processed_images) == blocks |
|
if use_thumbnail and len(processed_images) != 1: |
|
thumbnail_img = image.resize((image_size, image_size)) |
|
processed_images.append(thumbnail_img) |
|
return processed_images |
|
|
|
def load_image(image_file, input_size=448, max_num=12): |
|
image = Image.open(image_file).convert('RGB') |
|
transform = build_transform(input_size=input_size) |
|
images = dynamic_preprocess(image, image_size=input_size, use_thumbnail=True, max_num=max_num) |
|
pixel_values = [transform(image) for image in images] |
|
pixel_values = torch.stack(pixel_values) |
|
return pixel_values |
|
|
|
model = AutoModel.from_pretrained( |
|
"5CD-AI/Vintern-3B-R-beta", |
|
torch_dtype=torch.bfloat16, |
|
low_cpu_mem_usage=True, |
|
trust_remote_code=True, |
|
use_flash_attn=False, |
|
).eval().cuda() |
|
|
|
tokenizer = AutoTokenizer.from_pretrained("5CD-AI/Vintern-3B-R-beta", trust_remote_code=True, use_fast=False) |
|
|
|
test_image = 'test-image.jpg' |
|
|
|
think_prompt_format = """<image>\nBạn là người rất cẩn thận và đa nghi, vui lòng trả lời câu hỏi dưới đây bằng tiếng Việt. Khi suy luận bạn thường liệt kê ra các bằng chứng để chỉ ra các đáp án khả thi, suy luận và giải thích tại sao lại lựa chọn và loại bỏ trước khi đưa ra câu trả lời cuối cùng. |
|
Câu hỏi: |
|
{question_input} |
|
Hãy trả lời rất dài theo định dạng sau: |
|
<SUMMARY>...</SUMMARY> |
|
<CAPTION>...</CAPTION> |
|
<INFORMATION_EXTRACT>...</INFORMATION_EXTRACT> |
|
<EXTERNAL_KNOWLEDGE_EXPANSION>...</EXTERNAL_KNOWLEDGE_EXPANSION> |
|
<FIND_CANDIDATES_REASONING>...</FIND_CANDIDATES_REASONING> |
|
<TOP3_CANDIDATES>...</TOP3_CANDIDATES> |
|
<REASONING_PLAN>...</REASONING_PLAN> |
|
<REASONING>...</REASONING> |
|
<COUNTER_ARGUMENTS>...</COUNTER_ARGUMENTS> |
|
<VALIDATION_REASONING>...</VALIDATION_REASONING> |
|
<CONCLUSION>...</CONCLUSION> |
|
""" |
|
|
|
pixel_values = load_image(test_image, max_num=6).to(torch.bfloat16).cuda() |
|
generation_config = dict(max_new_tokens= 1024, do_sample=False, num_beams = 3, repetition_penalty=2.5) |
|
|
|
question = '<image>\nTrích xuất thông tin chính trong ảnh và trả về dạng markdown.' |
|
|
|
response, history = model.chat(tokenizer, pixel_values, question, generation_config, history=None, return_history=True) |
|
print(f'User: {question}\nAssistant: {response}') |
|
|
|
#question = "Câu hỏi khác ......" |
|
#response, history = model.chat(tokenizer, pixel_values, question, generation_config, history=history, return_history=True) |
|
#print(f'User: {question}\nAssistant: {response}') |
|
``` |
|
|
|
## Citation |
|
|
|
``` |
|
@misc{doan2024vintern1befficientmultimodallarge, |
|
title={Vintern-1B: An Efficient Multimodal Large Language Model for Vietnamese}, |
|
author={Khang T. Doan and Bao G. Huynh and Dung T. Hoang and Thuc D. Pham and Nhat H. Pham and Quan T. M. Nguyen and Bang Q. Vo and Suong N. Hoang}, |
|
year={2024}, |
|
eprint={2408.12480}, |
|
archivePrefix={arXiv}, |
|
primaryClass={cs.LG}, |
|
url={https://arxiv.org/abs/2408.12480}, |
|
} |
|
``` |
|
|
|
## Reference |
|
|
|
[1] Z. Chen et al., ‘Expanding performance boundaries of open-source multimodal models with model, data, and test-time scaling’, arXiv preprint arXiv:2412. 05271, 2024. |