- GPT-4o facture 170 tokens pour traiter chaque tuile de 512x512 utilisée en mode haute résolution. Avec un ratio d’environ 0,75 token/mot, cela signifie qu’une image équivaut à environ 227 mots
- Comparé à l’expression « une image vaut mille mots », cela représente un écart d’environ 4x
- Le nombre 170 est étrangement spécifique. OpenAI utilise généralement des nombres arrondis dans sa tarification, comme « 20 dollars » ou « 0,50 dollar », ou des puissances de 2 et de 3 pour les dimensions internes
- Pourquoi avoir choisi un nombre comme 170 ? En programmation, un nombre jeté dans une base de code sans explication est appelé un « magic number », et 170 est un magic number particulièrement voyant
- Pourquoi convertir le coût des images en nombre de tokens ? Si c’était uniquement à des fins de facturation, il serait moins déroutant d’indiquer simplement un coût par tuile
- Et si OpenAI avait choisi 170 simplement parce que c’est littéralement vrai ? Et si une tuile d’image était réellement représentée par 170 vecteurs d’embedding consécutifs ?
Embeddings
- La première chose à se rappeler à propos des modèles Transformer est qu’ils travaillent sur des vecteurs, et non sur des tokens discrets
- L’entrée doit être vectorielle ; sinon, la similarité par produit scalaire, qui est au cœur du Transformer, n’aurait aucun sens
- Toute la notion de token relève du prétraitement : le texte est converti en tokens, puis les tokens sont transformés en vecteurs d’embedding par un modèle d’embedding avant d’atteindre la première couche du modèle Transformer
- Par exemple, Llama 3 utilise en interne 4 096 dimensions de caractéristiques
- Si l’on prend la phrase « My very educated mother just served us nine pizzas. »
- Elle est convertie par BPE en 10 tokens entiers (point compris), puis chacun est transformé par le modèle d’embedding en un vecteur de 4 096 dimensions, ce qui donne une matrice 10x4096
- C’est cela, la « vraie » entrée du modèle Transformer
- Mais rien n’impose que ces vecteurs proviennent d’un modèle d’embedding de texte
- C’est une stratégie qui fonctionne bien pour les données textuelles, mais si l’on veut alimenter le Transformer avec d’autres formes de données, on peut simplement utiliser une autre stratégie d’embedding
- On sait qu’OpenAI réfléchit dans cette direction, puisqu’il a publié le modèle d’embedding CLIP en 2021
- CLIP embarque le texte et les images dans le même espace vectoriel sémantique, ce qui permet, avec la similarité cosinus, de retrouver des images liées à une chaîne de texte ou des images sémantiquement proches d’une autre image
- Mais CLIP embarque l’image entière dans un seul vecteur, pas dans 170. GPT-4o doit utiliser en interne une autre stratégie plus avancée pour représenter les images — et, de la même manière, la vidéo, la voix et d’autres types de données. C’est pour cela qu’il est « omnimodal »
- L’idée est donc d’inférer quelle pourrait être cette stratégie, en particulier pour les données d’image
Nombre de dimensions de caractéristiques
- Si l’on essaie d’estimer le nombre de dimensions qu’utilise GPT-4o en interne pour représenter les vecteurs d’embedding, le nombre réel reste inconnu car il est propriétaire, mais on peut faire des hypothèses raisonnables
- OpenAI semble aimer les puissances de 2, en y mélangeant parfois un unique facteur 3
- Par exemple, ada-002 utilise 1 536, et text-embedding-3-large 3 072
- GPT-3 est connu pour utiliser 12 288 dimensions au total
- GPT-4o a probablement conservé ou augmenté ce paramètre
- Il paraît peu probable que le nombre d’embeddings ait diminué entre GPT-3 et GPT-4o, mais cela reste possible
- Des versions comme GPT-4 Turbo étaient en réalité plus rapides et moins chères que leurs prédécesseurs, et si les développeurs disposaient de benchmarks montrant qu’une taille plus petite donnait une qualité équivalente, réduire la dimension des embeddings a pu en faire partie
- Le nombre de dimensions de caractéristiques utilisé à l’intérieur de GPT-4o est probablement l’un des suivants : 1536, 2048, 3072, 4096, 12228, 16384, 24576
- Supposons que GPT-4o utilise 12 228 pour la dimension des vecteurs d’embedding. Même si l’on se trompe d’un facteur 2 ou 4, cela n’a pas beaucoup d’importance. Le même raisonnement s’appliquerait
Embedding d’image
- Comme les tuiles d’image sont carrées, elles sont probablement représentées par une grille carrée de tokens
- 170 est très proche de 13x13
- Le token supplémentaire pourrait être un unique vecteur d’embedding encodant une impression gestalt globale de l’image entière, à la manière de CLIP
- Comment passer alors de 512x512x3 à 13x13x12228 ?
Stratégie 1 : pixels bruts
- Une manière très simple de projeter une image dans un espace vectoriel :
- Diviser une image 512x512 en une grille de 8x8 « mini-tuiles »
- Chaque mini-tuile fait 64x64x3 et est aplatie en un vecteur de 12 228 dimensions
- Chaque mini-tuile devient un unique vecteur d’embedding
- La tuile d’image entière est représentée par 64 vecteurs d’embedding consécutifs
- Cette approche a deux problèmes :
- 64 ≠ 170
- C’est très stupide (encoder à partir de valeurs RGB brutes en espérant que le Transformer se débrouille n’a pas beaucoup de sens)
Stratégie 2 : CNN
- Heureusement, il existe déjà un type de modèle présentant ces propriétés, avec plus de dix ans de succès dans le traitement des données d’image : les réseaux de neurones convolutifs (Convolutional Neural Network)
- Les CNN possèdent des propriétés comme l’invariance à la translation et à l’échelle
- AlexNet et YOLO sont des exemples représentatifs d’architectures CNN
- Les CNN agissent comme un entonnoir qui compresse les raw pixels en vecteurs sémantiques
- YOLO ne réduit pas l’image à un unique vecteur plat, mais s’arrête à 13x13
- La sortie de YOLOv3 est constituée de 169 vecteurs distincts disposés sur une grille 13x13, chacun de 1 024 dimensions
- On peut s’attendre à ce que le CNN hypothétique d’embedding d’image de GPT-4o ressemble, dans sa forme, à ces architectures CNN
- Une méthode est proposée pour passer de 512x512x3 à 13x13x12228 à l’aide de couches CNN standard
- Un design proche d’AlexNet permettrait d’y parvenir élégamment (avec 5 blocs répétés identiques)
- Une alternative plus proche de YOLO existe aussi, mais elle aboutit à 12x12 (au lieu de 13x13)
- On ne peut pas le prouver, mais cette conception spéculative montre qu’il existe des architectures CNN plausibles capables de représenter une image sous la forme d’une grille kxk de vecteurs d’embedding
Vérification expérimentale
- GPT-4o voit-il vraiment une grille 13x13 de vecteurs d’embedding ?
- Pour le tester, une tâche inspirée des cartes de Zener a été conçue : identifier la couleur et la forme de tous les symboles présents dans une grille d’image
- Un programme simple a servi à générer des images de grille de test, puis GPT-4o a reçu comme prompt de décrire la forme et la couleur de chaque cellule au format de tableau JSON
- Si l’hypothèse 13x13 est correcte, GPT-4o devrait bien se comporter jusqu’à une taille de 13x13, puis voir ses performances se dégrader au-delà
- Mais en pratique, ses performances sont parfaites jusqu’aux grilles de 5x5, puis chutent fortement
- Sur une grille 7x7, il a montré 76 % de précision, et sur une grille 13x13, des performances proches du hasard
- Cela signifie que l’hypothèse selon laquelle 169 tokens représenteraient une grille 13x13 est fausse
- En revanche, le résultat sur les grilles 5x5 suggère que GPT-4o peut suivre 25 objets distincts dans une image ainsi que leur position absolue
- Le concept de base est peut-être correct, mais avec une mauvaise estimation des dimensions ; on pourrait ajouter davantage de couches au CNN pour réduire à 5x5 au lieu de 13x13
- En supposant que seules des grilles jusqu’à 5x5 soient utilisées, il faut alors réfléchir à la manière de structurer la sortie pour atteindre 170 tokens
Stratégie pyramidale
- Une façon d’obtenir des nombres proches de 85 et 170 est de supposer que l’image est encodée comme une série de pyramides à des niveaux de granularité de plus en plus fins
- On commence par un vecteur d’embedding unique pour capturer l’impression gestalt de l’image entière, puis on ajoute un
3x3 pour capturer la gauche/le centre/la droite et le haut/le milieu/le bas, puis un 5x5, 7x7, etc.
- Cette stratégie se rapproche beaucoup des 85 tokens pour la « master thumbnail » si l’on s’arrête à
7x7
- L’ajout de la grille finale
9x9 se rapproche beaucoup de 170
- 12+32+52+72+92=1+9+25+49+81=165
- On peut obtenir une correspondance parfaite en utilisant une grille provisoire
2x2 pour les tuiles 512x512 et en supposant un token spécial <|image start|> pour chacune
- 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
- Ce schéma n’a pas de délimiteurs pour marquer le début et la fin des lignes, mais cela pourrait être géré par un encodage positionnel en 2D, d’une manière analogue à l’usage de RoPE pour encoder les informations de position des tokens textuels
- Ce qui précède ne correspond pas parfaitement aux preuves selon lesquelles les performances sur la grille de Zener commencent à décliner après
5x5, puisque cela ne retient que des tailles de grille impaires et saute 5x5
- Une autre possibilité consiste à prendre toutes les grilles (paires et impaires) jusqu’à
5x5
- Cette approche donne 55 tokens : 12+22+32+42+52=55
- En supposant 3 tokens par mini-tuile et 1 token délimiteur entre chaque tuile, on peut atteindre 170
- Ce n’est pas totalement satisfaisant sur le plan numérique, mais cela colle bien aux résultats empiriques
- La stratégie pyramidale est intuitivement très séduisante et ressemble presque à une manière « évidente » d’encoder l’information spatiale à différents niveaux de zoom
- Cela pourrait expliquer pourquoi le modèle se comporte bien jusqu’à une grille
5x5, puis très mal à partir de 6x6
- Toutes les hypothèses semblent fascinamment proches d’expliquer l’ensemble, mais c’est frustrant de voir que les chiffres ne tombent jamais parfaitement juste
- Malgré cela, ce type de stratégie pyramidale reste la meilleure explication que j’aie pu imaginer
Reconnaissance optique de caractères (OCR)
- Aucune des hypothèses ci-dessus n’explique comment GPT-4o effectue l’OCR
- CLIP n’est fondamentalement pas très bon en OCR, du moins pas pour de gros blocs de texte
- (Cela dit, le simple fait que GPT-4o puisse faire de l’OCR est déjà assez étonnant, et constitue un exemple clair de capacité émergente)
- GPT-4o est manifestement capable d’un OCR de haute qualité
- Il peut transcrire de longs blocs de texte et lire du texte manuscrit, ou du texte déplacé, tourné, projeté ou partiellement occulté
- Les moteurs OCR modernes effectuent déjà beaucoup de travail pour nettoyer les images, trouver les boîtes englobantes et les bandes de caractères, puis exécuter des modèles spécialisés de reconnaissance des caractères, un caractère ou un mot à la fois, le long de ces bandes
- Il ne s’agit pas simplement d’utiliser un gros CNN
- En théorie, OpenAI a peut-être réellement construit un modèle à ce point performant, mais cela ne cadre pas avec ses performances relativement faibles sur la tâche des grilles de Zener
- S’il ne peut pas lire les 36 symboles d’une grille
6x6 propre dans une image, il ne devrait pas pouvoir lire parfaitement des centaines de caractères de texte
- Une théorie simple pour expliquer cette incohérence :
- Je pense qu’OpenAI exécute un outil OCR prêt à l’emploi comme Tesseract (ou un outil propriétaire de pointe), puis alimente le transformeur avec le texte identifié en plus des données d’image
- Cela expliquerait pourquoi les premières versions se laissaient facilement tromper par du texte caché dans les images (du point de vue de GPT-4o, ce texte faisait partie du prompt)
- Cela a maintenant été corrigé, et GPT-4o sait bien ignorer les prompts malveillants dissimulés dans une image
- En revanche, cela n’explique pas pourquoi il n’y a pas de facturation par token pour le texte trouvé dans l’image
- Fait intéressant, envoyer du texte sous forme d’image est en réalité plus efficace
- Une image
512x512 avec une police petite mais lisible peut facilement contenir 400 à 500 tokens de texte, mais seuls 170 tokens en entrée sont facturés, plus les 85 de la « master thumbnail », soit un total de 255 tokens (bien moins que le nombre de mots dans l’image)
- Cette théorie explique pourquoi le traitement d’image introduit une latence supplémentaire
- Un CNN est intrinsèquement quasi instantané, mais un OCR tiers prendrait un peu plus de temps
- D’ailleurs (sans prétendre que cela prouve quoi que ce soit), l’environnement Python utilisé dans l’interpréteur de code d’OpenAI a PyTesseract installé
- On peut lui demander d’exécuter PyTesseract sur une image téléversée afin d’obtenir un deuxième avis
Conclusion
- J’ai essentiellement beaucoup extrapolé à partir d’un seul fait solide : OpenAI a utilisé le nombre magique 170
- Mais il semble exister une approche tout à fait plausible, très cohérente avec d’autres architectures CNN comme YOLO, consistant à mapper des tuiles d’image vers des vecteurs d’embedding
- Je ne pense donc pas que les 170 tokens soient simplement une approximation utilisée pour facturer la quantité approximative de calcul nécessaire au traitement de l’image
- Je ne pense pas non plus qu’il s’agisse d’empiler des couches pour fusionner les données image et texte, comme le font certains autres modèles multimodaux
- Je pense que GPT-4o utilise une architecture CNN hybride entre CLIP et YOLO, en intégrant directement les images dans l’espace des vecteurs sémantiques du transformeur, de sorte qu’une image
512x512 est littéralement représentée par 170 vecteurs d’embedding
- Quand j’ai commencé cet article, j’étais convaincu d’avoir entièrement décodé le fait que les 170 tokens correspondaient à une grille
13x13 et à un token supplémentaire d’« impression gestalt »
- Mais les performances sur la tâche de Zener commencent à se dégrader après
5x5, ce qui a fait s’effondrer cette hypothèse. Quoi qu’il se passe en interne, cela semble bien plus petit que 13x13
- Malgré cela, l’analogie avec YOLO est convaincante, et les performances sur la tâche de Zener en
5x5 confirment presque qu’il y a bien une forme de grille
- Cette théorie a aussi un fort pouvoir prédictif dans d’autres domaines
- Elle explique comment GPT-4o peut traiter plusieurs images et effectuer des tâches comme la comparaison de deux images
- Elle explique pourquoi il peut voir plusieurs objets dans une même image, mais se trouve dépassé lorsqu’une scène complexe contient trop d’objets
- Elle explique pourquoi GPT-4o semble très flou sur les positions absolues et relatives des objets dans une scène, et pourquoi il ne peut pas compter précisément les objets dans une image (lorsqu’un objet chevauche deux cellules adjacentes de la grille, la même classe est activée dans les deux, si bien qu’on ne sait pas avec certitude s’il s’agit d’un seul objet ou de deux)
- Ironiquement, la seule chose que cette théorie n’arrive pas à expliquer proprement est précisément la question qui m’a poussé à écrire cet article au départ : pourquoi 170 tokens, et pas un autre nombre ?
- La théorie pyramidale (
1x1 + 2x2 + 3x3 + 4x4 + 5x5) est la meilleure que j’aie trouvée, mais elle n’a rien de particulièrement élégant
- J’aimerais entendre l’avis de quelqu’un qui aurait une théorie un peu meilleure (ou une connaissance réelle, à supposer que cela ne viole pas un NDA)
Postface : l’astuce du canal alpha
- En menant ce projet, j’ai découvert que GPT-4o ignore le canal alpha, ce qui entraîne un comportement quelque peu contre-intuitif
- Par « ignore », je ne veux pas dire qu’il supprime la transparence comme le ferait un éditeur d’images en convertissant un PNG en JPG en le compositant sur un arrière-plan par défaut
- GPT-4o prend littéralement uniquement les canaux RGB et ignore le canal alpha
- On peut l’illustrer avec 4 images soigneusement préparées
- Pour plus de commodité, j’ai utilisé HTML et CSS pour afficher les images sur un motif en damier, tandis que les images elles-mêmes ont un fond plat et transparent
- Cependant, la moitié a un fond noir transparent, et l’autre moitié un fond blanc transparent
- Qu’est-ce qu’un « noir transparent » ou un « blanc transparent » ?
- Lorsqu’une couleur RGBA est représentée sur 4 octets, les octets RGB existent toujours même si l’alpha est à 100 %
- Ainsi,
(0, 0, 0, 255) et (255, 255, 255, 255) sont, d’une certaine manière, des couleurs différentes, mais comme elles sont toutes deux 100 % transparentes, un moteur de rendu correct n’a aucune raison de les afficher différemment
- Si l’on demande à GPT-4o ce qu’il « voit » dans ces 4 images :
- texte noir sur fond noir transparent : GPT-4o lit
""
- texte noir sur fond blanc transparent : GPT-4o lit
"ENORMOUS"
- texte blanc sur fond noir transparent : GPT-4o lit
"SCINTILLA"
- texte blanc sur fond blanc transparent : GPT-4o lit
""
- Que se passe-t-il ici ?
- Un schéma apparaît : GPT-4o ne peut lire le texte que lorsque la couleur du texte diffère de la « couleur » du fond transparent
- Cela montre que GPT-4o ignore le canal alpha et ne regarde que les canaux RGB. Pour GPT-4o, le noir transparent est noir, et le blanc transparent est blanc
- On peut le voir encore plus clairement en manipulant une image pour conserver les trois canaux RGB tout en réglant le canal alpha à 100 %
- J’ai utilisé une fonction Pillow pour faire cela
- Je m’en suis servi pour créer les deux images ci-dessous, dont les données RGB sont identiques et seul le canal alpha diffère
- canal alpha = 255 : GPT-4o peut facilement voir l’ornithorynque caché
- canal alpha = 0 : GPT-4o le perçoit comme une image entièrement transparente
- Vous pouvez télécharger l’image
hidden_platypus.png et l’insérer directement dans ChatGPT : il la décrira correctement
- Vous remarquerez que l’image pèse 39,3 Ko, comme
platypus.png ; si elle était parfaitement vide et transparente, la compression PNG l’aurait rendue bien plus petite
- Ou bien vous pouvez utiliser la fonction ci-dessus pour remettre le canal alpha à 255 et restaurer l’image d’origine
- Je ne sais pas avec certitude si c’est un bug, mais c’est clairement un comportement surprenant, et on a l’impression qu’un utilisateur malveillant pourrait s’en servir pour faire passer directement des informations à GPT-4o en contournant les humains
- Cependant, GPT-4o est bien plus performant que GPT-4v pour détecter et ignorer les prompts malveillants cachés dans les images
- Dans la galerie d’images de test GPT-4o générée avec l’utilitaire
image_tagger, vous pouvez trouver d’autres exemples où GPT-4o détecte et ignore avec succès des prompts malveillants cachés dans l’image
- Ainsi, même si c’est un bug, il n’est pas évident qu’il puisse être exploité
- Malgré tout, cela serait moins surprenant si GPT-4o « voyait » la même chose qu’un humain dans un navigateur
2 commentaires
Ainsi,
(0, 0, 0, 255)et(255, 255, 255, 255)sont, dans un certain sens, des couleurs différentes, mais comme elles sont toutes deux transparentes à 100 %, il n’y a aucune situation où un moteur de rendu correct les afficherait différemment.Pour être transparent, il faut un alpha à 0, comme
(0, 0, 0, 0)et(255, 255, 255, 0); il semble donc y avoir une faute de frappe dans le corps du texte.Avis sur Hacker News