nanoVLM- Kho lưu trữ đơn giản nhất để huấn luyện VLM của bạn bằng PyTorch thuần túy

Bài viết giới thiệu nanoVLM, một kho lưu trữ đơn giản để huấn luyện các mô hình ngôn ngữ thị giác (VLM) bằng PyTorch thuần túy.

  • 11 min read
nanoVLM- Kho lưu trữ đơn giản nhất để huấn luyện VLM của bạn bằng PyTorch thuần túy
Bài viết giới thiệu nanoVLM, một kho lưu trữ đơn giản để huấn luyện các mô hình ngôn ngữ thị giác (VLM) bằng PyTorch thuần túy.

nanoVLM: Kho lưu trữ đơn giản nhất để đào tạo VLM của bạn bằng PyTorch thuần túy

nanoVLM là cách đơn giản nhất để bắt đầu đào tạo Mô hình Ngôn ngữ Tầm nhìn (VLM) của riêng bạn bằng PyTorch thuần túy. Đây là bộ công cụ nhẹ cho phép bạn khởi chạy quá trình đào tạo VLM trên một sổ tay colab cấp miễn phí.

Chúng tôi được truyền cảm hứng từ Andrej Karpathy’s nanoGPT và cung cấp một dự án tương tự cho lĩnh vực thị giác.

Về cốt lõi, nanoVLM là một bộ công cụ giúp bạn xây dựng và đào tạo một mô hình có thể hiểu cả hình ảnh và văn bản, sau đó tạo văn bản dựa trên đó. Vẻ đẹp của nanoVLM nằm ở sự đơn giản của nó. Toàn bộ cơ sở mã được giữ tối thiểudễ đọc một cách có chủ ý, khiến nó trở nên hoàn hảo cho người mới bắt đầu hoặc bất kỳ ai muốn nhìn lướt qua bên trong VLMs mà không bị choáng ngợp.

Trong bài đăng trên blog này, chúng tôi đề cập đến các ý tưởng cốt lõi đằng sau dự án và cung cấp một cách đơn giản để tương tác với kho lưu trữ. Chúng tôi không chỉ đi sâu vào chi tiết của dự án mà còn gói gọn tất cả để bạn có thể nhanh chóng bắt đầu.

Mục lục:

TL;DR

Bạn có thể bắt đầu đào tạo Mô hình Ngôn ngữ Tầm nhìn bằng bộ công cụ nanoVLM của chúng tôi bằng cách làm theo các bước sau:

# Sao chép repo
git clone https://github.com/huggingface/nanoVLM.git

# Thực thi tập lệnh đào tạo
python train.py

Đây là sổ tay Colab sẽ giúp bạn khởi chạy quá trình đào tạo mà không cần thiết lập cục bộ!

Mô hình Ngôn ngữ Tầm nhìn là gì?

Như tên cho thấy, Mô hình Ngôn ngữ Tầm nhìn (VLM) là một mô hình đa phương thức xử lý hai phương thức: thị giác và văn bản. Các mô hình này thường lấy hình ảnh và/hoặc văn bản làm đầu vào và tạo văn bản làm đầu ra.

Việc tạo văn bản (đầu ra) có điều kiện dựa trên sự hiểu biết về hình ảnh và văn bản (đầu vào) là một mô hình mạnh mẽ. Nó cho phép một loạt các ứng dụng, từ chú thích hình ảnh và phát hiện đối tượng đến trả lời các câu hỏi về nội dung trực quan (như trong bảng dưới đây). Một điều cần lưu ý là nanoVLM chỉ tập trung vào Trả lời Câu hỏi Trực quan làm mục tiêu đào tạo.

Chú thích cho hình ảnh Hai con mèo nằm trên giường với điều khiển từ xa gần chúng Chú thích
Phát hiện các đối tượng trong hình ảnh <locxx><locxx><locxx><locxx> Phát hiện đối tượng
Phân đoạn các đối tượng trong hình ảnh <segxx><segxx><segxx> Phân đoạn ngữ nghĩa
Có bao nhiêu con mèo trong hình ảnh? 2 Trả lời câu hỏi trực quan

Nếu bạn quan tâm đến việc tìm hiểu thêm về VLMs, chúng tôi đặc biệt khuyên bạn nên đọc blog mới nhất của chúng tôi về chủ đề này: Mô hình Ngôn ngữ Tầm nhìn (Tốt hơn, Nhanh hơn, Mạnh hơn)

Làm việc với kho lưu trữ

“Nói thì dễ, hãy cho tôi xem mã” - Linus Torvalds

Trong phần này, chúng tôi sẽ hướng dẫn bạn qua cơ sở mã. Sẽ rất hữu ích nếu bạn mở một tab để tham khảo khi bạn theo dõi.

Dưới đây là cấu trúc thư mục của kho lưu trữ của chúng tôi. Chúng tôi đã xóa các tệp trợ giúp để ngắn gọn.

.
├── data
│   ├── collators.py
│   ├── datasets.py
│   └── processors.py
├── generate.py
├── models
│   ├── config.py
│   ├── language_model.py
│   ├── modality_projector.py
│   ├── utils.py
│   ├── vision_language_model.py
│   └── vision_transformer.py
└── train.py

Kiến trúc

.
├── data
│   └── ...
├── models      # 👈 Bạn đang ở đây
│   └── ...
└── train.py

Chúng tôi mô hình hóa nanoVLM theo hai kiến trúc nổi tiếng và được sử dụng rộng rãi. Vision backbone của chúng tôi (models/vision_transformer.py) là vision transformer tiêu chuẩn, cụ thể hơn là SigLIP vision encoder của Google. Language backbone của chúng tôi tuân theo kiến trúc Llama 3.

Các phương thức thị giác và văn bản được căn chỉnh bằng mô-đun Modality Projection. Mô-đun này lấy các embedding hình ảnh được tạo bởi vision backbone làm đầu vào và chuyển đổi chúng thành các embedding tương thích với các embedding văn bản từ lớp embedding của mô hình ngôn ngữ. Sau đó, các embedding này được nối và đưa vào bộ giải mã ngôn ngữ. Mô-đun Modality Projection bao gồm một hoạt động pixel shuffle theo sau là một lớp tuyến tính.

Kiến trúc của mô hình (Nguồn: Tác giả)

Pixel shuffle làm giảm số lượng token hình ảnh, giúp giảm chi phí tính toán và tăng tốc độ đào tạo, đặc biệt đối với bộ giải mã ngôn ngữ dựa trên transformer, vốn nhạy cảm với độ dài đầu vào. Hình dưới đây minh họa khái niệm này.

Pixel Shuffle được hình dung (Nguồn: Tác giả)

Tất cả các tệp đều rất nhẹ và được ghi lại đầy đủ. Chúng tôi đặc biệt khuyến khích bạn kiểm tra chúng riêng lẻ để hiểu rõ hơn về các chi tiết triển khai (models/xxx.py)

Trong khi đào tạo, chúng tôi sử dụng các trọng số backbone được đào tạo trước sau:

  1. Vision backbone: google/siglip-base-patch16-224
  2. Language backbone: HuggingFaceTB/SmolLM2-135M

Người ta cũng có thể thay thế các backbones bằng các biến thể khác của SigLIP/SigLIP 2 (cho vision backbone) và SmolLM2 (cho language backbone).

Đào tạo VLM của riêng bạn

Bây giờ chúng ta đã quen thuộc với kiến trúc, hãy chuyển sang cách đào tạo Mô hình Ngôn ngữ Tầm nhìn của riêng bạn bằng train.py.

.
├── data
│   └── ...
├── models
│   └── ...
└── train.py     # 👈 Bạn đang ở đây

Bạn có thể bắt đầu đào tạo bằng:

python train.py

Tập lệnh này là cửa hàng một cửa của bạn cho toàn bộ quy trình đào tạo, bao gồm:

  • Tải và tiền xử lý bộ dữ liệu
  • Khởi tạo mô hình
  • Tối ưu hóa và ghi nhật ký

Cấu hình

Trước bất cứ điều gì khác, tập lệnh sẽ tải hai lớp cấu hình từ models/config.py:

  • TrainConfig: Các tham số cấu hình hữu ích cho việc đào tạo, như tốc độ học tập, đường dẫn checkpoint, v.v.
  • VLMConfig: Các tham số cấu hình được sử dụng để khởi tạo VLM, như kích thước ẩn, số lượng đầu chú ý, v.v.

Tải dữ liệu

Trung tâm của quy trình dữ liệu là hàm get_dataloaders. Nó:

  • Tải bộ dữ liệu thông qua API load_dataset của Hugging Face.
  • Kết hợp và trộn nhiều bộ dữ liệu (nếu được cung cấp).
  • Áp dụng phân chia train/val thông qua lập chỉ mục.
  • Gói chúng trong các bộ dữ liệu tùy chỉnh (VQADataset, MMStarDataset) và collators (VQACollator, MMStarCollator).

Một flag hữu ích ở đây là data_cutoff_idx, hữu ích cho việc gỡ lỗi trên các tập con nhỏ.

Khởi tạo mô hình

Mô hình được xây dựng thông qua lớp VisionLanguageModel. Nếu bạn đang tiếp tục từ một checkpoint, thì việc này rất dễ dàng:

from models.vision_language_model import VisionLanguageModel

model = VisionLanguageModel.from_pretrained(model_path)

Nếu không, bạn sẽ nhận được một mô hình được khởi tạo mới với các backbones được tải trước tùy chọn cho cả thị giác và ngôn ngữ.

Thiết lập trình tối ưu hóa: Hai LRs

Vì modality projector (MP) được khởi tạo mới trong khi các backbones được đào tạo trước, nên trình tối ưu hóa được chia thành hai nhóm tham số, mỗi nhóm có tốc độ học tập riêng:

  • LR cao hơn cho MP
  • LR nhỏ hơn cho ngăn xếp bộ mã hóa/giải mã

Sự cân bằng này đảm bảo MP học nhanh chóng trong khi vẫn giữ được kiến thức trong vision và language backbones.

Vòng lặp đào tạo

Phần này khá tiêu chuẩn nhưng được cấu trúc chu đáo:

  • Độ chính xác hỗn hợp được sử dụng với torch.autocast để cải thiện hiệu suất.
  • Lịch trình tốc độ học tập cosine với khởi động tuyến tính được triển khai thông qua get_lr.
  • Thông lượng token (token/giây) được ghi lại trên mỗi lô để theo dõi hiệu suất.

Cứ sau 250 bước (có thể định cấu hình), mô hình sẽ được đánh giá trên bộ dữ liệu thử nghiệm validation và MMStar. Nếu độ chính xác được cải thiện, mô hình sẽ được checkpoint.

Ghi nhật ký & Giám sát

Nếu log_wandb được bật, các thống kê đào tạo như batch_loss, val_loss, accuracytokens_per_second sẽ được ghi vào Weights & Biases để theo dõi theo thời gian thực.

Các lần chạy được tự động đặt tên bằng siêu dữ liệu như kích thước mẫu, kích thước lô, số lượng epoch, tốc độ học tập và ngày tháng, tất cả đều được xử lý bởi trợ giúp get_run_name.

Đẩy lên Hub

Sử dụng những điều sau để đẩy mô hình đã đào tạo lên Hub để người khác tìm và kiểm tra:

model.save_pretrained(save_path)

Bạn có thể dễ dàng đẩy chúng bằng cách sử dụng:

model.push_to_hub("hub/id")

Chạy suy luận trên mô hình được đào tạo trước

Sử dụng nanoVLM làm bộ công cụ, chúng tôi đã đào tạo một mô hình và xuất bản nó lên Hub. Chúng tôi đã sử dụng google/siglip-base-patch16-224HuggingFaceTB/SmolLM2-135M làm backbones. Mô hình này đã được đào tạo trong ~6 giờ trên một GPU H100 trên ~1,7 triệu mẫu của cauldron.

Mô hình này không nhằm mục đích cạnh tranh với các mô hình SoTA, mà là để làm sáng tỏ các thành phần và quy trình đào tạo của VLMs.

.
├── data
│   └── ...
├── generate.py     # 👈 Bạn đang ở đây
├── models
│   └── ...
└── ...

Hãy chạy suy luận trên mô hình đã đào tạo bằng tập lệnh generate.py. Bạn có thể chạy tập lệnh tạo bằng lệnh sau:

python generate.py

Điều này sẽ sử dụng các đối số mặc định và chạy truy vấn “Đây là gì?” trên hình ảnh assets/image.png. Bạn có thể sử dụng tập lệnh này trên hình ảnh và lời nhắc của riêng mình như sau:

python generate.py --image path/to/image.png --prompt "Bạn nhắc ở đây"

Nếu bạn muốn hình dung trái tim của tập lệnh, nó chỉ là những dòng này:

model = VisionLanguageModel.from_pretrained(source).to(device)
model.eval()

tokenizer = get_tokenizer(model.cfg.lm_tokenizer)
image_processor = get_image_processor(model.cfg.vit_img_size)

template = f"Question: {args.prompt} Answer:"
encoded = tokenizer.batch_encode_plus([template], return_tensors="pt")
tokens = encoded["input_ids"].to(device)

img = Image.open(args.image).convert("RGB")
img_t = image_processor(img).unsqueeze(0).to(device)

print("\nInput:\n ", args.prompt, "\n\nOutputs:")
for i in range(args.generations):
    gen = model.generate(tokens, img_t, max_new_tokens=args.max_new_tokens)
    out = tokenizer.batch_decode(gen, skip_special_tokens=True)[0]
    print(f"  >> Generation {i+1}: {out}")

Chúng tôi tạo mô hình và đặt nó thành eval. Khởi tạo tokenizer, cái mà token hóa lời nhắc văn bản, và trình xử lý hình ảnh, cái mà được sử dụng để xử lý hình ảnh. Bước tiếp theo là xử lý các đầu vào và chạy model.generate để tạo văn bản đầu ra. Cuối cùng, giải mã đầu ra bằng batch_decode.

Hình ảnh Lời nhắc Tạo
Đây là gì? Trong bức ảnh, tôi có thể thấy tấm ga trải giường màu hồng. Tôi có thể thấy hai con mèo nằm trên tấm ga trải giường.
Người phụ nữ đang làm gì? Ở đây ở giữa, cô ấy đang thực hiện yoga

Nếu bạn muốn chạy suy luận trên mô hình đã đào tạo trong giao diện UI, đây là Hugging Face Space để bạn tương tác với mô hình.

Kết luận

Trong bài đăng trên blog này, chúng tôi đã đi qua VLMs là gì, khám phá các lựa chọn kiến trúc cung cấp năng lượng cho nanoVLM và giải nén chi tiết các quy trình làm việc đào tạo và suy luận.

Bằng cách giữ cho cơ sở mã nhẹ và dễ đọc, nanoVLM nhằm mục đích phục vụ cả như một công cụ học tập và một nền tảng mà bạn có thể xây dựng. Cho dù bạn đang tìm cách hiểu cách các đầu vào đa phương thức được căn chỉnh hay bạn muốn đào tạo VLM trên bộ dữ liệu của riêng mình, kho lưu trữ này sẽ giúp bạn có một khởi đầu thuận lợi.

Nếu bạn dùng thử, xây dựng trên nó hoặc chỉ có câu hỏi, chúng tôi rất muốn nghe từ bạn. Chúc bạn có một ngày vui vẻ!

Tài liệu tham khảo

  1. GitHub - huggingface/nanoVLM: Kho lưu trữ đơn giản nhất, nhanh nhất để đào tạo/tinh chỉnh VLMs cỡ nhỏ.
  2. Mô hình ngôn ngữ tầm nhìn (Tốt hơn, nhanh hơn, mạnh hơn)
  3. Các mô hình ngôn ngữ tầm nhìn được giải thích
  4. Đi sâu vào các mô hình ngôn ngữ tầm nhìn
  5. SmolVLM: Định nghĩa lại các mô hình đa phương thức nhỏ và hiệu quả

Recommended for You

Khám phá các backend lượng tử hóa trong Diffusers

Khám phá các backend lượng tử hóa trong Diffusers

Bài viết khám phá các backend lượng tử hóa khác nhau có sẵn trong Diffusers.

Giới thiệu Chương trình Khởi nghiệp Llama

Giới thiệu Chương trình Khởi nghiệp Llama

Chúng tôi vui mừng thông báo Chương trình Khởi nghiệp Llama, một sáng kiến mới để trao quyền cho các công ty khởi nghiệp giai đoạn đầu đổi mới và xây dựng các ứng dụng AI tạo sinh bằng Llama.