- GPT-4o tính phí 170 token để xử lý mỗi ô 512x512 được dùng trong chế độ độ phân giải cao. Với tỷ lệ khoảng 0,75 token/từ, điều này có nghĩa là một bức ảnh tương đương khoảng 227 từ
- So với câu nói “một bức ảnh đáng giá hơn ngàn lời nói”, con số này chênh khoảng 4 lần
- Số 170 là một con số đặc biệt đến mức kỳ quặc. OpenAI thường dùng các con số được làm tròn như “20 USD” hoặc “0,50 USD” trong định giá, hay các lũy thừa của 2 và 3 cho số chiều nội bộ
- Vậy tại sao lại chọn con số như 170? Trong lập trình, những con số được ném vào codebase mà không có giải thích thường được gọi là “magic number”, và 170 là một magic number khá nổi bật
- Tại sao chi phí hình ảnh lại được quy đổi sang số token? Nếu chỉ nhằm mục đích tính phí, việc liệt kê giá theo mỗi ô có lẽ sẽ đỡ gây nhầm lẫn hơn
- Nếu việc OpenAI chọn 170 đơn giản là vì đó là sự thật theo nghĩa đen thì sao? Nếu một ô ảnh thực sự được biểu diễn bằng 170 vector embedding liên tiếp thì sao?
Embedding
- Điều đầu tiên cần nhắc lại về mô hình transformer là chúng hoạt động trên vector, không phải token rời rạc
- Đầu vào phải là vector; nếu không, độ tương đồng tích vô hướng, nền tảng cốt lõi của transformer, sẽ không còn ý nghĩa
- Toàn bộ khái niệm token là một bước tiền xử lý: văn bản được chuyển thành token, rồi token được mô hình embedding chuyển thành vector embedding trước khi đến lớp đầu tiên của mô hình transformer
- Ví dụ, Llama 3 nội bộ sử dụng 4.096 chiều đặc trưng
- Xét câu “My very educated mother just served us nine pizzas.”
- Câu này được BPE chuyển thành 10 token số nguyên (bao gồm cả dấu chấm), sau đó mỗi token được mô hình embedding chuyển thành vector 4.096 chiều, tạo thành ma trận 10x4096
- Đây mới là đầu vào “thật sự” cho mô hình transformer
- Tuy nhiên, không có quy luật nào bắt buộc các vector này phải đến từ mô hình embedding văn bản
- Đó là chiến lược hoạt động tốt với dữ liệu văn bản, nhưng nếu muốn đưa vào transformer các dạng dữ liệu khác thì chỉ cần dùng chiến lược embedding khác
- Ta biết OpenAI đã suy nghĩ theo hướng này vì họ công bố mô hình embedding CLIP vào năm 2021
- CLIP nhúng văn bản và hình ảnh vào cùng một không gian vector ngữ nghĩa, nhờ đó có thể dùng độ tương đồng cosine để tìm ảnh liên quan đến một chuỗi văn bản, hoặc tìm ảnh giống nhau về mặt ngữ nghĩa
- Tuy nhiên, CLIP nhúng toàn bộ ảnh thành một vector duy nhất, chứ không phải 170 vector. GPT-4o hẳn phải dùng một chiến lược tiên tiến khác ở bên trong để biểu diễn hình ảnh (và tương tự là video, giọng nói cùng các loại dữ liệu khác). Đó là lý do nó là “omnimodal”
- Cụ thể với dữ liệu hình ảnh, hãy thử suy luận chiến lược đó là gì
Số chiều đặc trưng
- Nếu thử ước lượng số chiều mà GPT-4o dùng nội bộ để biểu diễn vector embedding, ta không thể biết con số thật vì đây là công nghệ độc quyền, nhưng có thể đưa ra giả định hợp lý
- Có vẻ OpenAI thích các lũy thừa của 2, đôi khi trộn thêm một thừa số 3
- Ví dụ, họ dùng 1.536 cho embedding ada-002 và 3.072 cho text-embedding-3-large
- GPT-3 được biết là dùng tổng cộng 12.288 chiều
- GPT-4o có thể đã giữ nguyên hoặc tăng thông số đó
- Có vẻ không hợp lý nếu số embedding lại giảm từ GPT-3 sang GPT-4o, dù vẫn có khả năng
- Các bản phát hành như GPT-4 Turbo thực tế nhanh hơn và rẻ hơn các bản trước; nếu các nhà phát triển có benchmark cho thấy kích thước nhỏ hơn vẫn giữ chất lượng tương đương, thì việc giảm số chiều embedding có thể là một phần lý do
- Số chiều đặc trưng được dùng bên trong GPT-4o nhiều khả năng là một trong các giá trị sau: 1536, 2048, 3072, 4096, 12228, 16384, 24576
- Hãy giả sử GPT-4o dùng 12.228 cho số chiều của vector embedding. Dù có lệch một hệ số 2 hay 4 thì cũng không quá quan trọng. Lập luận tương tự vẫn áp dụng
Embedding hình ảnh
- Vì ô ảnh là hình vuông, rất có thể nó được biểu diễn bằng một lưới token hình vuông
- 170 rất gần với 13x13
- Token bổ sung có thể là một vector embedding đơn lẻ mã hóa ấn tượng gestalt tổng thể của toàn bộ ảnh, tương tự CLIP
- Vậy làm sao đi từ 512x512x3 đến 13x13x12228?
Chiến lược 1: pixel thô
- Một cách rất đơn giản để đưa ảnh vào không gian vector:
- Chia ảnh 512x512 thành lưới 8x8 “ô nhỏ”
- Mỗi ô nhỏ sẽ là 64x64x3, rồi được trải phẳng thành vector 12.228 chiều
- Mỗi ô nhỏ là một vector embedding đơn lẻ
- Toàn bộ ô ảnh sẽ được biểu diễn bằng 64 vector embedding liên tiếp
- Cách tiếp cận này có hai vấn đề:
- 64 ≠ 170
- Nó rất ngớ ngẩn (dùng giá trị RGB thô để nhúng rồi hy vọng transformer tự xử lý là điều không hợp lý)
Chiến lược 2: CNN
- May mắn là đã có một loại mô hình sở hữu các đặc tính này, và đã có hơn 10 năm thành công trong xử lý dữ liệu hình ảnh: mạng nơ-ron tích chập (Convolutional Neural Network)
- CNN có những đặc tính như translation invariance và scale invariance
- AlexNet và YOLO là những ví dụ tiêu biểu của kiến trúc CNN
- CNN giống như một cái phễu nén pixel thô thành vector ngữ nghĩa
- YOLO không rút ảnh xuống một vector phẳng duy nhất mà dừng lại ở 13x13
- Đầu ra của YOLOv3 là 169 vector riêng biệt, mỗi vector có 1.024 chiều, được sắp trong lưới 13x13
- CNN embedding ảnh giả định của GPT-4o được kỳ vọng sẽ có hình thức tương tự các kiến trúc CNN này
- Bài viết đưa ra một cách dùng các lớp CNN chuẩn để đi từ 512x512x3 đến 13x13x12228
- Một thiết kế tương tự AlexNet có thể đạt được điều này một cách thanh nhã (dùng 5 khối lặp giống nhau)
- Cũng có một phương án khác giống YOLO hơn nhưng sẽ ra 12x12 (thay vì 13x13)
- Không thể chứng minh điều này, nhưng các thiết kế suy đoán như vậy cho thấy tồn tại những kiến trúc CNN hợp lý có thể biểu diễn ảnh dưới dạng lưới vector embedding kxk
Kiểm chứng thực nghiệm
- Liệu GPT-4o có thực sự “nhìn thấy” một lưới vector embedding 13x13 hay không?
- Để kiểm tra, tác giả thiết kế một bài toán lấy cảm hứng từ thẻ Zener: nhận diện màu sắc và hình dạng của mọi ký hiệu trong một lưới trên ảnh
- Tác giả dùng một chương trình đơn giản để tạo ảnh lưới thử nghiệm, rồi prompt GPT-4o mô tả hình dạng và màu sắc của từng ô dưới dạng mảng JSON
- Nếu giả thuyết 13x13 là đúng, ta kỳ vọng GPT-4o sẽ hoạt động tốt cho đến kích thước 13x13 rồi sau đó hiệu năng mới giảm
- Nhưng trên thực tế, nó chỉ đạt hiệu năng hoàn hảo ở các lưới 5x5 trở xuống, rồi suy giảm mạnh sau đó
- Ở lưới 7x7, độ chính xác là 76%, còn ở lưới 13x13 thì hiệu năng chỉ ở mức ngẫu nhiên
- Điều này có nghĩa là giả thuyết 169 token tương ứng với lưới 13x13 là sai
- Tuy nhiên, kết quả với lưới 5x5 cho thấy GPT-4o có thể theo dõi 25 đối tượng phân biệt cùng vị trí tuyệt đối của chúng trong ảnh
- Có thể khái niệm cơ bản là đúng nhưng số chiều bị suy đoán sai, và chỉ cần thêm tầng vào CNN để thu nhỏ xuống 5x5 thay vì 13x13
- Nếu giả sử chỉ dùng lưới 5x5 trở xuống, thì cần tiếp tục suy nghĩ cách cấu trúc đầu ra để vẫn đạt tới 170 token
Chiến lược kim tự tháp
- Một cách để thu được các con số gần 85 và 170 là giả định rằng hình ảnh được mã hóa như một chuỗi kim tự tháp ở các mức độ chi tiết tăng dần
- Bắt đầu với một vector embedding để nắm bắt ấn tượng gestalt của toàn bộ hình ảnh, sau đó thêm
3x3 để nắm bắt trái/giữa/phải và trên/giữa/dưới, rồi thêm 5x5, 7x7, v.v.
- Chiến lược này cho kết quả rất gần 85 token cho “thumbnail tổng” nếu dừng ở
7x7
- Nếu thêm lưới
9x9 cuối cùng thì sẽ rất gần 170
- 12+32+52+72+92=1+9+25+49+81=165
- Có thể khớp hoàn hảo nếu dùng một lưới tạm
2x2 cho ô 512x512 và giả định có một token đặc biệt <|image start|> cho mỗi ô
- 1+12+32+52+72=1+1+9+25+49=85
- 1+12+22+32+52+72+92=1+1+4+9+25+49+81=170
- Hệ thống này không có bất kỳ ký hiệu phân cách nào cho đầu và cuối hàng, nhưng có thể xử lý bằng mã hóa vị trí trong 2D, tương tự như cách RoPE được dùng để mã hóa thông tin vị trí của token văn bản
- Nội dung trên không hoàn toàn khớp với bằng chứng rằng hiệu năng trên lưới Zener bắt đầu giảm sau
5x5, vì nó chỉ lấy các kích thước lưới lẻ và bỏ qua 5x5
- Một phương án thay thế là lấy mọi lưới (cả chẵn lẫn lẻ) cho đến
5x5
- Cách tiếp cận này cho ra 55 token: 12+22+32+42+52=55
- Nếu giả định 3 token cho mỗi ô mini và 1 token phân cách giữa mỗi ô, thì có thể đạt 170
- Về mặt số học thì chưa hoàn toàn thỏa đáng, nhưng lại khớp tốt với kết quả thực nghiệm
- Chiến lược kim tự tháp có sức hấp dẫn trực quan rất lớn, và gần như là cách “hiển nhiên” để mã hóa thông tin không gian ở các mức zoom khác nhau
- Điều này có thể giải thích vì sao nó hoạt động tốt với lưới
5x5 trở xuống nhưng rất kém với 6x6 trở lên
- Thật khó chịu khi mọi giả thuyết đều có vẻ gần như giải thích được tất cả, nhưng các con số lại không bao giờ khớp thật gọn gàng
- Dù vậy, chiến lược kim tự tháp như thế này vẫn là lời giải thích tốt nhất mà tôi có thể nghĩ ra
Nhận dạng ký tự quang học (OCR)
- Không giả thuyết nào ở trên giải thích được cách GPT-4o thực hiện OCR
- Về cơ bản CLIP không thể làm OCR quá tốt, ít nhất là với các khối văn bản lớn
- (Dù vậy, bản thân việc GPT-4o có thể làm OCR đã là điều khá đáng kinh ngạc, và là một ví dụ rõ ràng của năng lực xuất hiện)
- Rõ ràng GPT-4o có thể thực hiện OCR chất lượng cao
- Nó có thể chép lại các khối văn bản dài, và đọc được chữ viết tay hoặc văn bản bị di chuyển, xoay, biến dạng phối cảnh hay che khuất một phần
- Các engine OCR hiện đại vốn đã phải làm rất nhiều việc để làm sạch ảnh, tìm hộp bao và dải ký tự, rồi chạy các mô hình nhận dạng ký tự chuyên dụng dọc theo các dải đó, mỗi lần một ký tự hoặc một từ
- Không phải chỉ đơn giản dùng một CNN lớn
- Về lý thuyết, OpenAI có thể thực sự đã xây dựng được một mô hình xuất sắc đến vậy, nhưng điều đó không phù hợp với hiệu năng tương đối yếu trong bài kiểm tra lưới Zener
- Nếu nó không thể đọc 36 ký hiệu trong một lưới
6x6 gọn gàng trong ảnh, thì khó có thể đọc hoàn hảo hàng trăm ký tự văn bản
- Một giả thuyết đơn giản để giải thích sự không nhất quán này:
- Tôi cho rằng OpenAI chạy một công cụ OCR dựng sẵn như Tesseract (hoặc một công cụ độc quyền tối tân), rồi đưa phần văn bản được nhận diện vào transformer cùng với dữ liệu hình ảnh
- Điều này giải thích vì sao các phiên bản đầu dễ bị đánh lừa bởi văn bản ẩn trong ảnh (vì từ góc nhìn của GPT-4o, văn bản đó là một phần của prompt)
- Hiện điều này đã được sửa, và GPT-4o khá thành thạo trong việc bỏ qua các prompt độc hại ẩn bên trong ảnh
- Tuy nhiên, điều này không giải thích được vì sao không có phí tính theo token cho phần văn bản được tìm thấy trong ảnh
- Điều thú vị là gửi văn bản dưới dạng hình ảnh thực ra còn hiệu quả hơn
- Một ảnh
512x512 với phông chữ nhỏ nhưng vẫn đọc được có thể dễ dàng chứa 400-500 token văn bản, nhưng bạn chỉ bị tính phí cho 170 token đầu vào cộng thêm 85 cho “thumbnail tổng”, tổng cộng là 255 token (ít hơn rất nhiều so với số từ trong ảnh)
- Giả thuyết này giải thích vì sao có thêm độ trễ khi xử lý hình ảnh
- CNN về bản chất gần như tức thì, nhưng OCR của bên thứ ba sẽ tốn thêm thời gian
- Mà nói vậy thôi (không phải điều này chứng minh được gì), trong môi trường Python mà OpenAI Code Interpreter sử dụng có cài sẵn PyTesseract
- Bạn có thể yêu cầu nó chạy PyTesseract trên ảnh bạn tải lên để lấy ý kiến thứ hai
Kết luận
- Về cơ bản, tôi đã suy đoán rất nhiều chỉ từ một sự thật chắc chắn duy nhất: OpenAI đã dùng con số ma thuật 170
- Nhưng dường như có một cách tiếp cận hoàn toàn hợp lý, rất phù hợp với các kiến trúc CNN khác như YOLO, đó là ánh xạ các ô ảnh thành các vector embedding
- Vì vậy tôi không cho rằng 170 token chỉ đơn thuần là một giá trị gần đúng dùng để tính phí cho lượng tính toán cần thiết để xử lý ảnh
- Tôi cũng không cho rằng họ chỉ nối các lớp lại với nhau để kết hợp dữ liệu ảnh và văn bản như một số mô hình đa phương thức khác vẫn làm
- Tôi cho rằng GPT-4o dùng một kiến trúc CNN pha trộn giữa CLIP và YOLO để nhúng hình ảnh trực tiếp vào không gian vector ngữ nghĩa của transformer, nhờ đó biểu diễn ảnh
512x512 theo nghĩa đen bằng 170 vector embedding
- Khi bắt đầu viết bài này, tôi đã tin chắc rằng mình đã giải mã hoàn toàn việc 170 token tương ứng với lưới
13x13 và một token bổ sung cho “ấn tượng gestalt”
- Nhưng hiệu năng của bài kiểm tra Zener bắt đầu suy giảm sau
5x5 đã làm giả thuyết đó sụp đổ. Dù nội bộ hệ thống đang làm gì đi nữa, có vẻ nó nhỏ hơn 13x13 rất nhiều
- Dù vậy, phép so sánh với YOLO vẫn rất thuyết phục, và hiệu năng trên bài kiểm tra Zener
5x5 gần như xác nhận rằng nó có thực hiện một dạng lưới nào đó
- Giả thuyết này cũng có sức dự báo khá lớn ở các lĩnh vực khác
- Nó giải thích cách GPT-4o có thể xử lý nhiều hình ảnh và thực hiện các tác vụ như so sánh hai ảnh
- Nó giải thích vì sao mô hình có thể nhìn thấy nhiều đối tượng trong cùng một ảnh, nhưng lại bị quá tải khi cảnh phức tạp có quá nhiều đối tượng
- Nó giải thích vì sao GPT-4o có vẻ rất mơ hồ về vị trí tuyệt đối và tương đối của từng đối tượng trong cảnh, và vì sao nó không thể đếm chính xác các đối tượng trong ảnh (khi một đối tượng trải qua hai ô lưới liền kề, cùng một lớp sẽ được kích hoạt ở cả hai ô, nên không rõ đó là một đối tượng hay hai)
- Trớ trêu thay, điều duy nhất mà giả thuyết này không thể giải thích gọn gàng lại chính là câu hỏi đã khiến tôi viết bài này ngay từ đầu: tại sao lại là 170 token?
- Lý thuyết kim tự tháp (
1x1 + 2x2 + 3x3 + 4x4 + 5x5) là lời giải thích tốt nhất mà tôi nghĩ ra, nhưng nó không thực sự gọn gàng
- Tôi rất muốn nghe ý kiến từ ai đó có một giả thuyết khớp hơn một chút (hoặc kiến thức thực tế, miễn là không vi phạm NDA)
Phần bổ sung: mẹo với kênh alpha
- Trong quá trình thực hiện dự án này, tôi nhận ra GPT-4o bỏ qua kênh alpha và vì thế có hành vi hơi trái với trực giác
- Nói rằng nó "bỏ qua" không có nghĩa là theo cách trình chỉnh sửa ảnh loại bỏ độ trong suốt khi chuyển PNG sang JPG bằng cách ghép ảnh lên nền mặc định
- GPT-4o theo nghĩa đen chỉ lấy các kênh RGB và bỏ qua kênh alpha
- Có thể minh họa điều này bằng 4 hình ảnh được chuẩn bị cẩn thận
- Để thuận tiện, tác giả dùng HTML và CSS để hiển thị hình trên nền caro, còn bản thân hình ảnh có nền phẳng và trong suốt
- Tuy nhiên, một nửa có nền đen trong suốt, còn nửa kia có nền trắng trong suốt
- "Đen trong suốt" hoặc "trắng trong suốt" nghĩa là gì?
- Khi biểu diễn màu RGBA bằng 4 byte, ngay cả khi alpha là 100%, các byte RGB vẫn tồn tại
- Vì vậy
(0, 0, 0, 255) và (255, 255, 255, 255) theo một nghĩa nào đó là hai màu khác nhau, nhưng vì cả hai đều trong suốt 100% nên sẽ không có tình huống nào mà một trình kết xuất đúng đắn lại hiển thị chúng khác nhau
- Nếu hỏi GPT-4o nó "nhìn thấy" gì trong 4 hình này:
- Chữ đen trên nền đen trong suốt: GPT-4o đọc là
""
- Chữ đen trên nền trắng trong suốt: GPT-4o đọc là
"ENORMOUS"
- Chữ trắng trên nền đen trong suốt: GPT-4o đọc là
"SCINTILLA"
- Chữ trắng trên nền trắng trong suốt: GPT-4o đọc là
""
- Vậy ở đây đang xảy ra chuyện gì?
- Có một mẫu hình cho thấy GPT-4o chỉ có thể đọc văn bản khi màu chữ khác với "màu" của nền trong suốt
- Điều này cho thấy GPT-4o bỏ qua kênh alpha và chỉ nhìn các kênh RGB. Với GPT-4o, đen trong suốt là màu đen, còn trắng trong suốt là màu trắng
- Có thể thấy rõ hơn bằng cách chỉnh sửa ảnh sao cho vẫn giữ nguyên 3 kênh RGB nhưng đặt kênh alpha thành 100%
- Tác giả đã dùng hàm Pillow để làm việc này
- Dùng cách đó để tạo hai hình bên dưới, trong đó dữ liệu RGB giống hệt nhau và chỉ khác ở kênh alpha
- Kênh alpha = 255: GPT-4o có thể dễ dàng nhìn thấy con thú mỏ vịt được giấu bên trong
- Kênh alpha = 0: GPT-4o thấy đó là một hình hoàn toàn trong suốt
- Bạn có thể tải xuống hình
hidden_platypus.png và chèn trực tiếp vào ChatGPT để kiểm tra, nó sẽ mô tả chính xác
- Bạn có thể thấy kích thước ảnh là 39.3KB, giống như
platypus.png; nếu đó là một hình hoàn toàn rỗng và trong suốt thì nhờ nén PNG nó đáng lẽ phải nhỏ hơn rất nhiều
- Hoặc bạn có thể dùng hàm ở trên để đặt lại kênh alpha về 255 và khôi phục ảnh gốc
- Không chắc đây có phải là lỗi hay không, nhưng chắc chắn là một hành vi đáng ngạc nhiên, và có cảm giác như người dùng ác ý có thể lợi dụng nó để lén chuyển thông tin trực tiếp cho GPT-4o mà con người không nhận ra
- Tuy nhiên, GPT-4o giỏi hơn GPT-4v rất nhiều trong việc phát hiện và bỏ qua các prompt độc hại được giấu trong ảnh
- Trong thư viện ảnh kiểm thử GPT-4o do tiện ích
image_tagger tạo ra, bạn có thể tìm thấy các ví dụ khác mà GPT-4o phát hiện và bỏ qua thành công các prompt độc hại ẩn trong ảnh
- Vì vậy, ngay cả nếu đây là một lỗi thì cũng chưa rõ liệu nó có thể bị khai thác hay không
- Dù vậy, sẽ bớt ngạc nhiên hơn nếu GPT-4o "nhìn thấy" đúng những gì con người nhìn thấy trong trình duyệt
2 bình luận
Vì vậy,
(0, 0, 0, 255)và(255, 255, 255, 255)theo một nghĩa nào đó là các màu khác nhau, nhưng vì cả hai đều trong suốt 100% nên sẽ không có tình huống nào mà một trình kết xuất đúng lại hiển thị chúng khác nhau.Để trong suốt thì alpha phải là 0, tức là
(0, 0, 0, 0)và(255, 255, 255, 0), nên có vẻ trong phần nội dung chính đã bị lỗi gõ nhầm.Ý kiến Hacker News