Multimodal
This content is not available in your language yet.
Mục tiêu
Phần tiêu đề “Mục tiêu”Sau bài này, bạn sẽ:
- Hiểu cách Vision Transformer biến ảnh thành dãy token: cắt thành patch (ô ảnh), chiếu tuyến tính, thêm vị trí. Tính được số token ảnh .
- Mô tả được mẫu chung của LLM đa phương thức (multimodal): bộ mã hóa ảnh (vision encoder) → lớp chiếu (projector) → LLM, và hai giai đoạn huấn luyện của LLaVA: phần nào đóng băng (freeze, giữ nguyên trọng số), phần nào học.
- So sánh được ba cách ghép ảnh với LLM: nối vào chuỗi (LLaVA), cross-attention (Llama 3.2 Vision), token chung từ đầu (Chameleon).
- Cài được phép cắt patch bằng NumPy, patch embedding và projector bằng PyTorch, rồi kiểm số token.
Cần biết trước
Phần tiêu đề “Cần biết trước”- The LLaMA Family: RoPE and Parallel Training, in Large Language Models(Not translated yet) (Learned)
- Vision and Language (2): LLaVA and Its Variants, in Computer Vision(Not translated yet) (Learned)
Trực giác
Phần tiêu đề “Trực giác”LLM chỉ đọc dãy vectơ
Phần tiêu đề “LLM chỉ đọc dãy vectơ”Ở bài API cho hình ảnh và video, bạn gửi một tấm ảnh kèm câu hỏi, và mô hình trả lời đại ý “có một hình vuông đỏ ở giữa”. Bài đó nói nhà cung cấp biến ảnh thành token ảnh. Bài này mở chiếc hộp đó.
Mỗi loại dữ liệu (chữ, ảnh, âm thanh, video) gọi là một phương thức (modality); mô hình nhận nhiều phương thức gọi là mô hình đa phương thức.
Điểm mấu chốt: khối Transformer không quan tâm vectơ đến từ đâu. Nó nhận một dãy vectơ cùng số chiều và trả ra một dãy vectơ. Nếu làm ra được một dãy vectơ “kể” nội dung tấm ảnh, Transformer xử lý được ngay.
Hình dung một bức tranh ghép. Cắt ảnh thành lưới ô vuông, đọc các ô từ trái sang phải, từ trên xuống dưới, như đọc chữ trên trang sách. Mỗi ô là một “từ”, tấm ảnh thành một “câu”: ảnh cắt ô cho câu dài 196 từ. Đó chính là ViT.
Hai việc, và một người phiên dịch
Phần tiêu đề “Hai việc, và một người phiên dịch”Thứ nhất, vectơ của các ô phải có nghĩa: ô có con mèo thì vectơ phải mang ý “mèo”, không chỉ là màu điểm ảnh. Đó là việc của bộ mã hóa ảnh, thường lấy từ CLIP.
Thứ hai, bộ mã hóa ảnh và LLM được huấn luyện riêng, nên “nói hai thứ tiếng”: vectơ ảnh có chiều theo cách hiểu của bộ mã hóa, embedding chữ có chiều theo cách hiểu của LLM. Cần một người phiên dịch nhỏ đứng giữa: projector.
Còn đưa ảnh cho LLM thế nào? Hãy nghĩ tới cách đưa ảnh cho người đọc sách:
- Dán ảnh vào sách, xen giữa các trang chữ: ảnh chiếm trang. Đây là cách nối chuỗi của LLaVA.
- Đặt ảnh ở bàn bên cạnh, cứ vài đoạn người đọc liếc sang: sách không dày thêm, nhưng cần thêm “mắt” để liếc. Đây là cross-attention của Llama 3.2 Vision.
- Viết lại ảnh bằng chính bảng chữ cái của sách, để một người vừa đọc vừa viết được cả hai. Đây là Chameleon.
Bài toán của bài này là: làm sao biến một tấm ảnh thành dãy vectơ cùng “ngôn ngữ” với embedding của LLM, ghép dãy đó vào đâu, và huấn luyện phần nào để LLM trả lời được về ảnh mà không quên cách đọc chữ?
Lý thuyết
Phần tiêu đề “Lý thuyết”Ký hiệu
Phần tiêu đề “Ký hiệu”Ảnh có chiều cao , chiều rộng (tính bằng điểm ảnh) và kênh màu ( với ảnh RGB). Ở bài này là chiều cao ảnh, không phải số đầu attention như bài Họ LLaMA. Chữ nghiêng (chiều rộng) khác ma trận đậm của projector ở Bước 4, và khác ma trận . Cỡ patch là , số patch là . Vectơ ra khỏi bộ mã hóa ảnh có chiều, embedding của LLM có chiều, độ dài chuỗi LLM đọc là .
Bước 1: cắt ảnh thành patch
Phần tiêu đề “Bước 1: cắt ảnh thành patch”Chia ảnh thành các ô không chồng nhau. Theo chiều cao có hàng ô, theo chiều rộng có cột ô, nên số ô là tích của hai số đó:
Công thức cần và chia hết cho ; nếu không, ảnh được co giãn, cắt hoặc đệm trước. Mỗi patch có điểm ảnh, mỗi điểm số, nên trải phẳng thành vectơ .
nằm ở mẫu số và bị bình phương: giảm nửa cỡ patch, hay gấp đôi mỗi cạnh ảnh, thì số token gấp 4.
Bước 2: patch embedding
Phần tiêu đề “Bước 2: patch embedding”Mỗi patch được nhân với một ma trận học được , rồi cộng thêm một vectơ vị trí:
Ở đây là vectơ hàng của patch thứ , là token ảnh, là embedding vị trí (position embedding, chính là vectơ vị trí ở bài Xây dựng LLM đầu tiên) học được của ô thứ .
Vì sao một chung cho mọi patch? Giống bảng embedding từ dùng chung cho mọi vị trí trong câu: “mèo” ở đầu hay cuối câu vẫn là một vectơ. Hệ quả là hai patch giống hệt nhau cho cùng một dù nằm ở hai góc ảnh (ô NumPy kiểm điều này), nên cần để biết ô nằm ở đâu. ViT đánh số ô theo thứ tự đọc và dùng embedding vị trí một chiều; tác giả thử loại hai chiều và không thấy lợi đáng kể. ViT thêm một token lớp (class token) học được ở đầu dãy (giống token [CLS] của BERT), rồi cho cả dãy qua các khối Transformer encoder chuẩn. Ngoài bước cắt patch, ViT gần như không dùng hiểu biết riêng nào về ảnh: quan hệ không gian giữa các ô do mô hình tự học từ dữ liệu.
Về cài đặt, “cắt patch rồi nhân ” chính là một phép tích chập (convolution) có kernel và bước nhảy (stride) , nên thư viện thường viết bằng Conv2d. Ra khỏi bộ mã hóa, ta có : mỗi hàng là đặc trưng của một ô, đã “nhìn” các ô khác qua self-attention.
Bước 3: vì sao lấy bộ mã hóa của CLIP
Phần tiêu đề “Bước 3: vì sao lấy bộ mã hóa của CLIP”CLIP (Radford và cộng sự, 2021) học trên 400 triệu cặp ảnh và chú thích từ Internet. Với một lô cặp, nó tính độ giống cosine giữa mọi ảnh và mọi chú thích, được bảng mà đường chéo là các cặp đúng, rồi dùng cross-entropy theo cả hàng lẫn cột để điểm trên đường chéo cao hơn hẳn phần còn lại. Nhờ vậy đặc trưng ảnh của CLIP đã gần với ngôn ngữ: điểm xuất phát tốt cho LLM. LLaVA dùng bộ mã hóa ViT-L/14 của CLIP (patch ). Nhưng CLIP chỉ ghép ảnh với chữ, không sinh câu nào.
Bước 4: projector và chuỗi cho LLM
Phần tiêu đề “Bước 4: projector và chuỗi cho LLM”LLaVA (Liu và cộng sự, 2023) nối đặc trưng ảnh vào LLM bằng một lớp tuyến tính:
Mỗi hàng số của thành một hàng số, đúng số chiều embedding từ của LLM. Bài báo viết theo cột; ở đây viết theo hàng cho khớp với code. Tác giả cố ý chọn lớp đơn giản để thử nghiệm nhanh. LLaVA-1.5 (Liu và cộng sự, 2023) thay nó bằng một MLP hai lớp và báo cáo kết quả tốt hơn:
là hàm kích hoạt (activation function). Bài báo chỉ nói “MLP hai lớp”; code của bài dùng GELU, trùng với code chính thức của LLaVA-1.5 (mlp2x_gelu: Linear → GELU → Linear).
Ở dạng đơn giản nhất (và trong code của bài), token ảnh đứng trước embedding của token chữ, thành một chuỗi:
có hàng, mỗi hàng là embedding của một token chữ trong câu hỏi. Khi huấn luyện, LLaVA còn đổi ngẫu nhiên thứ tự ảnh và câu hỏi ở lượt đầu. Từ đây LLM làm việc như thường: dự đoán token kế tiếp. Khi huấn luyện, hàm mất mát chỉ tính trên các token của câu trả lời.
Số token ảnh là chi phí thật. Self-attention chấm điểm mọi cặp vị trí, nên số cặp tỉ lệ với . Câu hỏi 50 token kèm 576 token ảnh cho nghìn cặp, so với nếu chỉ có chữ (tự tính). Token ảnh còn chiếm cửa sổ ngữ cảnh và KV cache như token chữ.
| Ảnh | Gặp ở đâu | ||
|---|---|---|---|
| 16 | 196 | ViT-B/16 trong bài báo ViT (tự tính) | |
| 14 | 256 | ViT-L/14 của CLIP ở cỡ ảnh 224 (tự tính); báo cáo Llama 3 ghi đúng 256 patch cho bộ mã hóa của họ | |
| 14 | 576 | CLIP ViT-L 336px của LLaVA-1.5 (tự tính) | |
| 14 | 1 024 | Tự tính: cạnh gấp đôi dòng 256 |
Huấn luyện hai giai đoạn của LLaVA
Phần tiêu đề “Huấn luyện hai giai đoạn của LLaVA”| Giai đoạn | Dữ liệu | Bộ mã hóa ảnh | Projector | LLM |
|---|---|---|---|---|
| 1. Căn chỉnh đặc trưng | 595K cặp ảnh và chú thích, lọc từ CC3M (Conceptual Captions, khoảng 3 triệu cặp) | Đóng băng | Học | Đóng băng |
| 2. Tinh chỉnh toàn bộ | LLaVA-Instruct-158K: hội thoại, mô tả chi tiết, suy luận | Đóng băng | Học | Học |
Giai đoạn 1. Mỗi cặp thành một hội thoại một lượt: câu hỏi kiểu “hãy mô tả ngắn ảnh này”, đáp án là chú thích gốc. Chỉ được cập nhật. Tác giả gọi đây là huấn luyện một “bộ tách từ cho ảnh” tương thích với LLM đóng băng: dạy người phiên dịch trong khi hai bên giữ nguyên.
Giai đoạn 2. Bộ mã hóa ảnh vẫn đóng băng; projector và cả LLM (Vicuna) được cập nhật trên dữ liệu làm theo chỉ dẫn có ảnh. Đây là instruction tuning của bài Họ GPT và fine-tune đa nhiệm, giờ có thêm ảnh. 158K mẫu này do GPT-4 chỉ đọc chữ sinh ra từ chú thích và khung tọa độ đối tượng của ảnh, không phải do người viết.
LLaVA-1.5 giữ khung này, dùng projector MLP, ảnh và thêm dữ liệu hỏi đáp về ảnh từ các bộ học thuật.
Cross-attention: Llama 3.2 Vision
Phần tiêu đề “Cross-attention: Llama 3.2 Vision”Cách nối chuỗi đặt token ảnh vào trong chuỗi; cross-attention để ảnh ở ngoài. Gọi là biểu diễn của các token chữ ở một lớp của LLM, là đặc trưng ảnh. Một lớp cross-attention tính:
Truy vấn (query) đến từ chữ, khóa và giá trị (key, value) đến từ ảnh; là số chiều mỗi đầu. Bảng điểm có cỡ : mỗi token chữ “liếc” sang mọi ô ảnh. Kết quả có hàng, đúng bằng số token chữ, nên chuỗi không dài thêm token nào.
Ba nguồn cần tách bạch:
- Báo cáo Llama 3, mục 7 (Llama Team, 2024) mô tả các thí nghiệm, và ghi rõ các mô hình này khi đó chưa sẵn sàng phát hành. Bộ mã hóa là ViT-H/14 (630 triệu tham số, học kiểu đối chiếu trên 2.5 tỉ cặp ảnh và chữ), được pre-train trên ảnh , chia thành 256 patch; khi huấn luyện adapter, ảnh được đưa vào ở độ phân giải cao hơn, tối đa bốn mảnh . Lớp cross-attention được chèn sau mỗi lớp self-attention thứ tư của LLM; riêng bản 405B, chúng thêm khoảng 100 tỉ tham số. Khi huấn luyện bộ adapter này, nhóm tác giả cập nhật cả bộ mã hóa ảnh nhưng cố ý không cập nhật LLM (mục 1 và 7).
- Model card Llama 3.2 Vision (Meta, phát hành 25/9/2024): hai cỡ 11B và 90B, dựng trên Llama 3.1 chỉ có chữ, thêm một bộ adapter ảnh huấn luyện riêng gồm các lớp cross-attention đưa biểu diễn của bộ mã hóa ảnh vào LLM; pre-train trên 6 tỉ cặp ảnh và chữ.
- Bài giới thiệu Llama 3.2 trên blog của Meta (25/9/2024) xác nhận cho bản phát hành: khi huấn luyện adapter, Meta cập nhật bộ mã hóa ảnh nhưng cố ý giữ nguyên tham số của LLM, nên khả năng xử lý chữ không đổi và bản Vision thay thẳng được cho Llama 3.1 (“drop-in replacement”).
Báo cáo Llama 3 nêu bốn lý do: phát triển phần nhìn và phần ngôn ngữ song song được; tránh rắc rối của việc huấn luyện chung ảnh và chữ; khả năng xử lý chữ không bị ảnh hưởng vì LLM giữ nguyên; và ảnh độ phân giải đầy đủ không phải đi qua các mạng truyền thẳng của LLM, nên suy luận hiệu quả hơn.
Fusion sớm: Chameleon
Phần tiêu đề “Fusion sớm: Chameleon”Chameleon (Chameleon Team, 2024) đi hướng ngược lại: không có bộ mã hóa ảnh riêng. Một bộ tách từ cho ảnh lượng tử hóa (quantization) ảnh thành 1 024 token rời rạc (khác với lượng tử hóa trọng số ở bài PEFT): mỗi token là số thứ tự trong một sổ mã (codebook) 8 192 mục, nằm luôn trong từ vựng chung 65 536 token cùng token chữ. Một Transformer duy nhất, huấn luyện từ đầu bằng dự đoán token kế tiếp, đọc và sinh được cả chữ lẫn ảnh xen kẽ. Bài báo gọi đây là fusion sớm (early fusion, trộn sớm), đối lập với fusion muộn (late fusion): các mô hình giữ bộ mã hóa riêng cho từng phương thức, như Flamingo (Alayrac và cộng sự, 2022) hay LLaVA. Cái giá, theo chính tác giả: huấn luyện khó giữ ổn định, và bộ tách từ ảnh yếu với ảnh chứa nhiều chữ.
Giới hạn
Phần tiêu đề “Giới hạn”- Bài chỉ nói về ảnh vào, chữ ra. Sinh ảnh chỉ có ở đoạn Chameleon; gọi API sinh ảnh và video thuộc bài API cho hình ảnh và video.
- Phục vụ mô hình đa phương thức (token ảnh làm KV cache lớn thêm) thuộc bài Deploy LLM: nhiều GPU, phân tán.
- Projector là phần nhỏ được huấn luyện, cùng tinh thần với LoRA ở bài Đánh giá mô hình và PEFT.
Minh họa
Phần tiêu đề “Minh họa”Hình dưới vẽ cách nối chuỗi của LLaVA, cũng là cách ô PyTorch làm lại. Hãy nhìn chỗ token ảnh và token chữ gặp nhau: sau projector, chúng chỉ là các vectơ cùng số chiều, xếp chung một hàng.
Bảng dưới đặt ba cách cạnh nhau. Cột “Huấn luyện gì” là cấu hình trong bài báo của từng mô hình.
| Tiêu chí | LLaVA (nối chuỗi) | Llama 3.2 Vision (cross-attention) | Chameleon (fusion sớm) |
|---|---|---|---|
| Ảnh thành gì | Đặc trưng CLIP, qua projector | Đặc trưng của bộ mã hóa ảnh | Token rời rạc từ sổ mã |
| Ảnh nằm ở đâu | Trong chuỗi, chiếm vị trí | Ngoài chuỗi, chữ nhìn sang qua cross-attention | Trong chuỗi, 1 024 token mỗi ảnh |
| Huấn luyện gì | Projector, rồi thêm LLM; bộ mã hóa đóng băng | Adapter và bộ mã hóa; LLM đóng băng | Cả mô hình, từ đầu |
| Sinh ảnh | Không | Không | Có |
| Điểm mạnh | Đơn giản, rẻ, dựng trên LLM có sẵn | Khả năng xử lý chữ giữ nguyên, chuỗi không dài thêm | Đọc và viết xen kẽ chữ, ảnh |
| Cái giá | Token ảnh tốn ngữ cảnh và tính toán | Nhiều tham số mới cho cross-attention | Huấn luyện khó ổn định, tốn kém |
Ví dụ code
Phần tiêu đề “Ví dụ code”Code trong bài chạy thử lần cuối tháng 10/2026: ô NumPy với Python 3.14 và NumPy 2.4 (bản có trong Pyodide), ô PyTorch với Python 3.14 và PyTorch 2.14 trên CPU. Ô NumPy chạy ngay trên trang, ô PyTorch chạy trên máy bạn. Hai ô độc lập, không dùng biến của nhau.
Cắt patch bằng NumPy
Phần tiêu đề “Cắt patch bằng NumPy”Ô dưới đây lấy một ảnh ngẫu nhiên (hạt giống 0), cắt thành patch , chiếu mỗi patch bằng một ma trận thành vectơ chiều, rồi đếm số token cho vài cỡ ảnh. Mẹo reshape rồi transpose tách mỗi trục ảnh thành “số thứ tự ô” và “vị trí trong ô”.
Cắt ảnh thành patch, chiếu thành token
# Cắt một ảnh nhỏ thành patch rồi chiếu tuyến tính thành token, như ViTimport numpy as np
rng = np.random.default_rng(0)H, W, C = 32, 32, 3 # ảnh 32x32, 3 kênh màuP, D_v = 8, 64 # cỡ patch, số chiều của token ảnhimg = rng.random((H, W, C))
def to_patches(x): # Chia lưới (H/P) x (W/P) ô, đọc từ trái sang phải, trên xuống dưới, # rồi trải phẳng mỗi ô thành P*P*C số grid = x.reshape(H // P, P, W // P, P, C).transpose(0, 2, 1, 3, 4) return grid.reshape(-1, P * P * C)
patches = to_patches(img)print("patches:", patches.shape)print("patch 0 = top-left:", np.array_equal(patches[0], img[:P, :P].ravel()))print("patch 1 = next right:", np.array_equal(patches[1], img[:P, P:2 * P].ravel()))
# Một ma trận E dùng chung cho mọi patch: P*P*C số -> vectơ D_v chiềuE = rng.normal(0, 0.02, (P * P * C, D_v))tokens = patches @ Eprint("tokens:", tokens.shape, "E params:", E.size)
# Chép ô trên trái xuống góc dưới phải: hai ô giống nhau, hai chỗ khác nhauimg2 = img.copy()img2[-P:, -P:] = img[:P, :P]tokens2 = to_patches(img2) @ Eprint("same token at two places:", np.allclose(tokens2[0], tokens2[-1]))
# Số token N = (H/P)(W/P) với vài cỡ ảnh hay gặpfor h, p in [(224, 16), (224, 8), (224, 14), (336, 14), (448, 14)]: print(f"{h}x{h}, P={p}: N = {(h // p) ** 2}")The first run downloads Python, about 10 MB.
Đọc kết quả:
patches: (16, 192): patch, mỗi patch số.- Hai dòng
Truetiếp theo: patch 0 là ô góc trên trái, patch 1 là ô ngay bên phải nó: đọc hết một hàng rồi mới xuống hàng. tokens: (16, 64): có tham số, dùng chung cho cả 16 patch.same token at two places: True: chép ô trên trái xuống góc dưới phải thì hai ô ở hai đầu ảnh cho cùng một vectơ. Thiếu embedding vị trí, mô hình không phân biệt được chúng.- Bảng cuối: khớp bảng ở mục Lý thuyết, thêm dòng : 784 token, gấp đúng 4 lần 196 của .
Patch embedding và projector bằng PyTorch
Phần tiêu đề “Patch embedding và projector bằng PyTorch”File dưới đây dựng lại mẫu chung ở cỡ nhỏ: một Conv2d đóng vai bộ mã hóa ảnh (chỉ có bước patch embedding), một nn.Embedding đóng vai bảng embedding của LLM, cả hai đóng băng như giai đoạn 1 của LLaVA. Ở giữa là projector MLP hai lớp . File kiểm Conv2d bằng “cắt patch rồi nhân ma trận”, ghép token ảnh với 10 token chữ, rồi lan truyền ngược một hàm mất mát giả để xem gradient đi tới đâu. Cách cài PyTorch bản CPU có ở bài Xây dựng LLM đầu tiên.
Run on your machine
Token ảnh, projector và chuỗi cho LLM
- Install
pip install torch- Hardware
- CPU là đủ. Vài giây trên máy phát triển, phần lớn là thời gian nạp PyTorch
# Patch embedding, projector và chuỗi cho LLM kiểu LLaVA, cỡ nhỏ chạy CPUimport torchfrom torch import nn
torch.manual_seed(0)B, C, H, W, P = 2, 3, 224, 224, 14 # 2 ảnh, 3 kênh, 224x224, patch 14x14D_v, D, L_text = 64, 128, 10 # chiều token ảnh, chiều LLM, số token chữ
# Hai phần "đã huấn luyện sẵn", đóng băng như giai đoạn 1 của LLaVApatch_embed = nn.Conv2d(C, D_v, kernel_size=P, stride=P) # thay bộ mã hóatext_embed = nn.Embedding(1000, D) # thay bảng embedding của LLMpatch_embed.requires_grad_(False)text_embed.requires_grad_(False)
# 1. Patch embedding: Conv2d với kernel = stride = Pimg = torch.randn(B, C, H, W)z = patch_embed(img).flatten(2).transpose(1, 2) # (B, N, D_v)print("image tokens:", tuple(z.shape))
# Cùng kết quả khi cắt patch (unfold) rồi nhân một ma trận Ecols = nn.functional.unfold(img, kernel_size=P, stride=P).transpose(1, 2)E = patch_embed.weight.flatten(1) # (D_v, C*P*P)same = cols @ E.T + patch_embed.biasprint("conv == unfold + matmul:", torch.allclose(z, same, atol=1e-4))
# 2. Projector: MLP hai lớp D_v -> D -> D (GELU là lựa chọn của bài)projector = nn.Sequential(nn.Linear(D_v, D), nn.GELU(), nn.Linear(D, D))h_v = projector(z) # (B, N, D)
# 3. Token ảnh đứng trước embedding của token chữ: một chuỗi cho LLMids = torch.randint(0, 1000, (B, L_text))seq = torch.cat([h_v, text_embed(ids)], dim=1)print("sequence for the LLM:", tuple(seq.shape))
# Loss giả, chỉ để xem gradient đi tới đâuseq.pow(2).mean().backward()print("grad in projector:", projector[0].weight.grad is not None)print("grad in patch_embed:", patch_embed.weight.grad is not None)for name, m in [("patch_embed", patch_embed), ("projector", projector), ("text_embed", text_embed)]: n = sum(p.numel() for p in m.parameters()) k = sum(p.numel() for p in m.parameters() if p.requires_grad) print(f"{name}: {n} params, {k} trainable")Sample output
From one real run.
image tokens: (2, 256, 64)conv == unfold + matmul: Truesequence for the LLM: (2, 266, 128)grad in projector: Truegrad in patch_embed: Falsepatch_embed: 37696 params, 0 trainableprojector: 24832 params, 24832 trainabletext_embed: 128000 params, 0 trainableĐọc kết quả:
(2, 256, 64): mỗi ảnh , patch 14, cho token chiều.conv == unfold + matmul: True:Conv2dvới kernel bằng stride đúng là “cắt patch, trải phẳng, nhân ” của Bước 2.(2, 266, 128): sau projector, token ảnh có chiều như token chữ; là độ dài của chuỗi LLM đọc.- Gradient và tham số: chỉ projector có gradient và có tham số được học: . Đúng cấu hình giai đoạn 1 của LLaVA.
Ở mô hình thật, lên tới hàng nghìn (Llama 3 8B có ), LLM có hàng tỉ tham số, và projector chỉ là một phần rất nhỏ.
Lỗi hay gặp
Phần tiêu đề “Lỗi hay gặp”Kiểm tra nhanh
Phần tiêu đề “Kiểm tra nhanh”Tóm tắt và đọc thêm
Phần tiêu đề “Tóm tắt và đọc thêm”Ý chính:
- LLM chỉ đọc dãy vectơ. ViT cắt ảnh thành patch, chiếu mỗi patch bằng một ma trận chung và cộng embedding vị trí. Số token ảnh là chi phí thật: tốn ngữ cảnh, và số cặp attention tăng theo bình phương độ dài chuỗi.
- Mẫu chung: bộ mã hóa ảnh (thường từ CLIP, đã học ghép ảnh với chữ) → projector () → LLM. LLaVA nối token ảnh vào chuỗi, , và huấn luyện hai giai đoạn: chỉ projector, rồi projector cùng LLM; bộ mã hóa luôn đóng băng.
- Llama 3.2 Vision dùng cross-attention: truy vấn từ chữ, khóa và giá trị từ ảnh, chuỗi không dài thêm. LLM giữ nguyên (thí nghiệm Llama 3 và bài giới thiệu Llama 3.2), nên khả năng xử lý chữ không đổi.
- Chameleon lượng tử hóa ảnh thành token rời rạc trong cùng từ vựng với chữ (1 024 token mỗi ảnh ), nên đọc và sinh được cả hai, đổi lại huấn luyện khó hơn.
Đọc thêm:
- Dosovitskiy, A. và cộng sự (2021). An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale, arXiv:2010.11929, mục 3.1. Ngắn, đủ cách cắt patch và embedding vị trí.
- Radford, A. và cộng sự (2021). Learning Transferable Visual Models From Natural Language Supervision, arXiv:2103.00020, mục 2.3 và hình 3. Giả mã hàm mất mát của CLIP chỉ khoảng mười dòng.
- Liu, H., Li, C., Wu, Q., Lee, Y. J. (2023). Visual Instruction Tuning, arXiv:2304.08485, mục 3 và 4; và Liu, H., Li, C., Li, Y., Lee, Y. J. (2023). Improved Baselines with Visual Instruction Tuning, arXiv:2310.03744, mục 3. Kiến trúc, dữ liệu và hai giai đoạn huấn luyện của LLaVA; projector MLP của LLaVA-1.5.
- Grattafiori, A., Dubey, A., Jauhri, A. và cộng sự (2024). The Llama 3 Herd of Models, arXiv:2407.21783, mục 7 “Vision Experiments”. Lý do chọn cross-attention và kiến trúc của thí nghiệm.
- Meta (2024). Llama 3.2 Vision: model card; và Meta (25/9/2024). Llama 3.2: Revolutionizing edge AI and vision with open, customizable models, blog của Meta AI. Thông tin bản phát hành Llama 3.2: hai cỡ, dữ liệu, adapter cross-attention, LLM giữ nguyên.
- Chameleon Team (2024). Chameleon: Mixed-Modal Early-Fusion Foundation Models, arXiv:2405.09818, mục 2.1. Cách Chameleon tách ảnh thành token.
Your browser is blocking storage. Your progress will be lost when you reload the page.
Content licensed under CC BY-NC-SA 4.0. Code under the MIT license.About