[Vintern-1B-v3.5] Mô hình kết hợp OCR và xử lý văn bản nhỏ nhẹ dành cho tiếng Việt

0 0 0

Người đăng: Nguyễn Văn Mạnh

Theo Viblo Asia

1. Giới thiệu

Vintern-1B-v3.5 là phiên bản mô hình ngôn ngữ lớn đa phương thức (MLLM) trong dòng mô hình Vintern được phát triển bởi nhóm nghiên cứu Fifth Civil Defender (5CD) dựa trên nền tảng của các mô hình InternVL từ OpenGVLab. Đây là một mô hình 1 tỷ tham số tối ưu cho tiếng Việt, với khả năng tinh chỉnh tham số, vượt trội trong việc nhận dạng ký tự quang học (OCR), xử lý văn bản và hiểu tài liệu chuyên biệt.

Đây có thể nói là một lựa chọn sáng giá có thể quyết nhanh các bài toán OCR tiếng Việt nhưng vẫn khả dụng trên phần cứng phổ thông.


2. Đặt vấn đề

2.1 Quá Trình Phát Triển

  • Mô hình cơ sở

Bắt đầu từ InternVL2.5-1B, một mô hình đa phương thức từ OpenGVLab, nổi tiếng với hiệu suất mạnh mẽ trong các tác vụ kết hợp thị giác và ngôn ngữ.

  • Tinh chỉnh trên dữ liệu tiếng Việt

Mô hình được tinh chỉnh thêm trên tập dữ liệu Viet-ShareGPT-4o-Text-VQA, bao gồm các cặp câu hỏi-đáp dựa trên hình ảnh, được thiết kế đặc biệt cho tiếng Việt.

  • Các phiên bản trước:

    • ColVintern-1B-v1: phiên bản đầu tiên dòng 1B, tập trung vào truy xuất thông tin từ cả văn bản và hình ảnh bằng cách tích hợp pipeline Colpali. Colpali sử dụng mô hình PaliGemma để tạo embedding đa vector trực tiếp từ hình ảnh tài liệu, giúp loại bỏ OCR phức tạp và cải thiện độ chính xác truy xuất. Mô hình này hỗ trợ RAG, ưu tiên tiếng Việt, và đạt hiệu suất cao với chỉ 1 tỷ tham số, hướng tới sự nhẹ và hiệu quả hơn so với các phiên bản trước.
    • Vintern-1B-v2: là phiên bản nâng cấp của ColVintern-1B-v1, cải thiện đáng kể hiệu suất trên các benchmark, nâng cao khả năng xử lý đa phương thức bằng tiếng Việt. Mô hình này kết hợp Qwen2-0.5B-InstructInternViT-300M-448px, với 1 tỷ tham số và độ dài ngữ cảnh (context length) 4096, được tinh chỉnh trên hơn 3 triệu cặp câu hỏi-trả lời cho OCR, VQA và trích xuất tài liệu. Những cải tiến này giúp Vintern-1B-v2 vượt xa nhiệm vụ truy xuất tài liệu, mở rộng khả năng hiểu thông tin thị giác và ngôn ngữ.
    • Vintern-1B-v3.5: là phiên bản tiên tiến nhất của dòng Vintern, vượt trội so với v2 nhờ tinh chỉnh từ InternVL2.5-1B và sử dụng dữ liệu Viet-ShareGPT-4o-Text-VQA. Mô hình này cải thiện đáng kể khả năng xử lý tài liệu tiếng Việt, bao gồm hóa đơn, văn bản pháp lý, chữ viết tay và bảng biểu, đồng thời hiểu prompt phức tạp hơn. Với khả năng chạy trên GPU phổ thông như T4 và dễ dàng tinh chỉnh, Vintern-1B-v3_5 là lựa chọn tối ưu cho các tác vụ ngôn ngữ tiếng Việt.

2.2. Cấu trúc Mô hình

Vintern-1B-v3.5 áp dụng kiến trúc "ViT-MLP-LLM", một thiết kế phổ biến và hiệu quả cho các MLLM. Kiến trúc này tương tự như nhiều MLLM nổi tiếng khác. ViT-MLP-LLM của Vintern-1B-v3.5 sẽ gồm 3 phần như sau:

  • Mô hình thị giác InternViT-300M-448px đóng vai trò là thành phần xử lý đầu vào hình ảnh. Mô hình này được huấn luyện chắt lọc kiến thức từ mô hình InternViT-6B-448px-V1-5 mạnh mẽ và có khả năng xử lý hình ảnh với độ phân giải 448x448 pixel (thông tin này khá quan trọng để các bạn có thể chuẩn bị dữ liệu hình ảnh phù hợp).
  • Mô hình ngôn ngữ Qwen2-0.5B-Instruct chịu trách nhiệm xử lý và tạo ra đầu ra văn bản. Các mô hình Qwen2 được biết đến với khả năng đa ngôn ngữ mạnh mẽ, bao gồm cả tiếng Việt. Phiên bản 0.5 tỷ tham số này góp phần tăng hiệu suất của Vintern 1B 3.5.
  • Một thành phần quan trọng khác là MLP (Multi-Layer Perceptron) projector, có vai trò kết nối mô hình thị giác và mô hình ngôn ngữ. MLP projector hoạt động như một cơ chế để điều chỉnh các biểu diễn đặc trưng từ InternViTQwen2, cho phép chúng tương tác hiệu quả với nhau. Thành phần này rất quan trọng để kích hoạt chức năng đa phương thức, cho phép mô hình hiểu mối quan hệ giữa thông tin thị giác và văn bản.

Hình 1: Kiến trúc tổng thể

Hình ảnh đầu vào được xử lý bởi mô-đun Độ phân giải Cao Động (Dynamic High Resolution), trong đó hình ảnh được chia thành các phần nhỏ có kích thước 448x448 pixel cùng với một ảnh thu nhỏ (thumbnail). Các phần hình ảnh này sau đó được đưa vào mô hình InternViT-300M-448px để trích xuất đặc trưng thị giác. Một bước xáo trộn điểm ảnh (Pixel Shuffle) cũng được áp dụng trước khi truyền dữ liệu vào bộ chiếu MLP (MLP projector) nhằm căn chỉnh với các embedding của mô hình ngôn ngữ lớn Qwen2-0.5B-Instruct. Mô hình này tiếp nhận các token thị giác đã được căn chỉnh cùng với câu hỏi liên quan và tạo ra câu trả lời tương ứng.

Hình 2: Single Model Training Pipeline

Pipeline huấn luyện được thiết kế thành ba giai đoạn nhằm nâng cao khả năng nhận thức hình ảnh và xử lý đa phương thức:

  • Giai đoạn 1: Khởi động MLP (MLP Warmup). Trong giai đoạn này, chỉ bộ phận MLP (Multi-Layer Perceptron) được huấn luyện, trong khi bộ mã hóa hình ảnh (vision encoder) và mô hình ngôn ngữ được đóng băng. Chiến lược huấn luyện độ phân giải cao động được áp dụng để cải thiện hiệu suất, mặc dù chi phí tăng lên. Mục tiêu của giai đoạn này là đảm bảo sự liên kết chặt chẽ giữa các mô thức và chuẩn bị cho quá trình huấn luyện đa phương thức ổn định.

  • Giai đoạn 1.5: Học tăng cường ViT (ViT Incremental Learning) (Tùy chọn). Giai đoạn này cho phép huấn luyện bổ sung bộ mã hóa hình ảnh (ViT - Vision Transformer) cùng với bộ phận MLP bằng cách sử dụng cùng dữ liệu như ở Giai đoạn 1. Mục tiêu là cải thiện khả năng trích xuất đặc trưng hình ảnh, giúp mô hình nắm bắt thông tin toàn diện hơn, đặc biệt trong các lĩnh vực dữ liệu ít được đại diện như OCR đa ngôn ngữ và biểu đồ toán học. Sau khi được huấn luyện, bộ mã hóa này có thể được tái sử dụng với các mô hình ngôn ngữ lớn khác mà không cần huấn luyện lại, làm cho giai đoạn này trở thành tùy chọn trừ khi có sự giới thiệu các lĩnh vực mới.

  • Giai đoạn 2: Huấn luyện đa phương thức (Multimodal Training). Ở giai đoạn cuối cùng, toàn bộ mô hình được huấn luyện trên các tập dữ liệu hướng dẫn đa phương thức chất lượng cao. Việc kiểm soát chất lượng dữ liệu nghiêm ngặt được thực hiện để ngăn chặn sự suy giảm của mô hình ngôn ngữ lớn, vì dữ liệu nhiễu có thể gây ra các vấn đề như đầu ra lặp lại hoặc không chính xác. Sau giai đoạn này, quá trình huấn luyện hoàn tất.


3. Các bước cài đặt và triển khai mô hình

Mình sẽ hướng dẫn nhanh triển khai trên môi trường colab sử dụng GPU T4

3.1. Cài đặt môi trường

Đầu tiên, bạn cần cài đặt các thư viện cần thiết:

# Cài đặt thư viện Python
!pip install torch torchvision timm transformers

3.2. Phần code chính

Tiền xử lý ảnh động cho mô hình thị giác

import os
import numpy as np
import torch
import torchvision.transforms as T
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

Tải và khởi tạo mô hình

model_name = "5CD-AI/Vintern-1B-v2"
model_name = "5CD-AI/Vintern-1B-v3_5" try: model = AutoModel.from_pretrained( model_name, torch_dtype=torch.bfloat16, low_cpu_mem_usage=True, trust_remote_code=True, use_flash_attn=False, ).eval().cuda()
except: model = AutoModel.from_pretrained( model_name, torch_dtype=torch.bfloat16, low_cpu_mem_usage=True, trust_remote_code=True ).eval().cuda() tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True, use_fast=False)

Chạy chương trình trích xuất thông tin hình ảnh

import matplotlib.pyplot as plt
test_image = "/content/Hóa đơn.jpg"
plt.figure(figsize=(10,10))
plt.imshow(Image.open(test_image))
plt.show()
pixel_values = load_image(test_image, max_num=6).to(torch.bfloat16).cuda()
generation_config = dict(max_new_tokens= 512, do_sample=False, num_beams = 3, repetition_penalty=3.5) question = '<image>\nMô tả hình ảnh một cách chi tiết trả về dạng markdown.' response = model.chat(tokenizer, pixel_values, question, generation_config)
print(f'User: {question}\nAssistant: {response}')
Hình 3: Đầu ra mẫu

4. Kết luận

Với những cải tiến và khả năng ấn tượng trên, Vintern-1B-v3.5 hứa hẹn là một công cụ mạnh mẽ và hữu ích, mở ra nhiều tiềm năng ứng dụng trong việc tự động hóa xử lý tài liệu, trích xuất thông tin và khai thác dữ liệu đa phương thức bằng tiếng Việt. Đây là một lựa chọn đáng cân nhắc cho bất kỳ ai đang tìm kiếm một giải pháp OCR và xử lý văn bản hiệu quả, tối ưu cho ngôn ngữ và bối cảnh Việt Nam.

5. Nguồn tham khảo

https://huggingface.co/5CD-AI/Vintern-1B-v3_5

https://github.com/OpenGVLab/InternVL

https://arxiv.org/pdf/2408.12480

https://arxiv.org/pdf/2312.14238)

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tấn công và phòng thủ bậc nhất cực mạnh cho các mô hình học máy

tấn công bậc nhất cực mạnh = universal first-order adversary. Update: Bleeding edge của CleverHans đã lên từ 3.1.0 đến 4.

0 0 42

- vừa được xem lúc

[Deep Learning] Key Information Extraction from document using Graph Convolution Network - Bài toán trích rút thông tin từ hóa đơn với Graph Convolution Network

Các nội dung sẽ được đề cập trong bài blog lần này. . Tổng quan về GNN, GCN. Bài toán Key Information Extraction, trích rút thông tin trong văn bản từ ảnh.

0 0 223

- vừa được xem lúc

Trích xuất thông tin bảng biểu cực đơn giản với OpenCV

Trong thời điểm nhà nước đang thúc đẩy mạnh mẽ quá trình chuyển đổi số như hiện nay, Document Understanding nói chung cũng như Table Extraction nói riêng đang trở thành một trong những lĩnh vực được quan tâm phát triển và chú trọng hàng đầu. Vậy Table Extraction là gì? Document Understanding là cái

0 0 232

- vừa được xem lúc

Con đường AI của tôi

Gần đây, khá nhiều bạn nhắn tin hỏi mình những câu hỏi đại loại như: có nên học AI, bắt đầu học AI như nào, làm sao tự học cho đúng, cho nhanh, học không bị nản, lộ trình học AI như nào... Sau nhiều lần trả lời, mình nghĩ rằng nên viết hẳn một bài để trả lời chi tiết hơn, cũng như để các bạn sau này

0 0 159

- vừa được xem lúc

[B5'] Smooth Adversarial Training

Đây là một bài trong series Báo khoa học trong vòng 5 phút. Được viết bởi Xie et. al, John Hopkins University, trong khi đang intern tại Google. Hiện vẫn là preprint do bị reject tại ICLR 2021.

0 0 46

- vừa được xem lúc

Deep Learning với Java - Tại sao không?

Muốn tìm hiểu về Machine Learning / Deep Learning nhưng với background là Java thì sẽ như thế nào và bắt đầu từ đâu? Để tìm được câu trả lời, hãy đọc bài viết này - có thể kỹ năng Java vốn có sẽ giúp bạn có những chuyến phiêu lưu thú vị. DJL là tên viết tắt của Deep Java Library - một thư viện mã ng

0 0 141