Flash pour itérer, Pro pour livrer
Une équipe marketing qui génère tout avec le modèle le plus cher paie deux fois plus et attend deux fois plus longtemps pour des images dont 80 % finiront à la corbeille. Une équipe qui livre tout avec le modèle rapide publie des visuels un cran en dessous de ce qu'elle pourrait obtenir pour 7 centimes de plus. La bonne répartition se décide sur des mesures, pas sur la page marketing des modèles.
Le mécanisme : deux modèles, un même appel
Les modèles d'image Gemini (famille « Nano Banana » dans la documentation) sont des modèles multimodaux : ils reçoivent du texte et des images, réfléchissent (des tokens de « réflexion » facturés comme du texte), puis renvoient une image. Le code est identique pour les deux ; seul le nom change.
gemini-3.1-flash-image | gemini-3-pro-image | |
|---|---|---|
| Positionnement (documentation) | rapide, volume, références multiples | tâches complexes, rendu de marque, texte, contrôle fin |
| Tailles | 512 px, 1K, 2K, 4K | 1K, 2K, 4K |
| Prix par image (API, 2026-10-15) | 0,045 (1K) ; 0,101 (4K) | 0,134 (4K) |
| Images de référence | jusqu'à 10 objets et 4 personnages | jusqu'à 6 objets et 5 personnages, 14 au total |
| Texte et réflexion | 3 $ par million de tokens | 12 $ par million de tokens |
Deux autres modèles existent : gemini-3.1-flash-lite-image (0,034 $ l'image, 1K seulement, « non optimisé » selon la documentation pour les références multiples et la retouche multi-tours) et gemini-2.5-flash-image, l'ancienne génération. Le mode Batch divise les prix par deux pour des travaux qui peuvent attendre jusqu'à 24 heures.
flowchart TB
Q{"L'image sera-t-elle publiée telle quelle ?"} -->|"non : recherche, variantes, validation d'idée"| F["Flash 1K<br/>0,067 $, ~9 s"]
Q -->|"oui"| R{"Texte dans l'image, marque exigeante,<br/>scène complexe, grand format ?"}
R -->|"non"| F2["Flash 1K ou 2K"]
R -->|"oui"| P["Pro 2K<br/>0,134 $, ~24 s"]
F --> S["Sélection humaine"] --> P
La mesure : mêmes prompts, deux modèles
Trois prompts, identiques au caractère près, ont été envoyés aux deux modèles le 2026-10-15 avec la clé d'API, en 1K, une seule fois chacun. Le coût est calculé depuis usage_metadata par couts.py ; la durée est mesurée autour de l'appel.
| Prompt | Flash : durée, coût | Pro : durée, coût | Observation |
|---|---|---|---|
| Packshot (lampe sur bureau) | 9,4 s, 0,0686 $ | 16,1 s, 0,1377 $ | Pro : moins d'accessoires, lumière rasante plus nette ; aucun des deux ne reproduit le vrai produit |
| Atelier RH (quatre mains, un outil) | 10,4 s, 0,0686 $ | 17,4 s, 0,1371 $ | mains correctes des deux côtés ; pince déformée chez Flash |
| Affiche avec texte français | 8,6 s, 0,0685 $ | 16,4 s, 0,1387 $ | les deux écrivent le texte exact, accents compris |
Et dans la campagne complète (make run, même jour) : Flash 1K entre 8,0 et 9,7 s, Pro 2K à 22,9 et 25,6 s pour 0,141 .
Trois constats sortent de ces mesures, sur un échantillon volontairement petit (une image par case) :
- Le Pro coûte 2 fois plus et prend 1,7 à 1,9 fois plus de temps à 1K. À 2K, le Pro coûte le même prix qu'à 1K : demandez toujours 2K pour un rendu final Pro.
- La structure du prompt compte plus que le modèle pour la composition. Aucun des deux ne connaît votre produit sans image de référence.
- Le texte court ne casse plus sur ces deux modèles. Le texte long, les petits corps et les polices de marque restent un risque (leçon 6).
La mise en œuvre : le modèle vient du brief
Le brief fixe le modèle d'itération, le modèle final et leurs tailles ; chaque visuel marqué final: true passe en Pro 2K. Deux options de ligne de commande servent à comparer sans modifier le brief : --final (tout en Pro) et --modele (un modèle imposé à tous les visuels).
modele_iteration: gemini-3.1-flash-image
modele_final: gemini-3-pro-image
taille: "1K"
taille_finale: "2K"
budget_usd: 2.0TARIFS: dict[str, Tarif] = {
"gemini-3.1-flash-image": Tarif(0.50, 3.0, 60.0, {"512": 747, "1K": 1120, "2K": 1680, "4K": 2520}),
"gemini-3-pro-image": Tarif(2.00, 12.0, 120.0, {"1K": 1120, "2K": 1120, "4K": 2000}),
...
}
def cout_reel(modele: str, usage) -> dict:
t = tarif(modele)
entree = usage.prompt_token_count or 0
sortie = usage.candidates_token_count or 0
image = sum(d.token_count or 0 for d in (usage.candidates_tokens_details or [])
if str(getattr(d.modality, "value", d.modality)) == "IMAGE")
texte = sortie - image + (usage.thoughts_token_count or 0)
usd = (entree * t.entree + texte * t.sortie_texte + image * t.sortie_image) / 1e6Le détail compte : une réponse Flash 1K a facturé 1 496 tokens de sortie, dont 1 120 d'image (60 le million). Ignorer ces derniers sous-estime peu chez Flash (0,1 centime) mais davantage chez Pro (12 $ le million).
Résultat obtenu
L'estimation se lit sans aucun appel :
$ .venv/bin/python -m campagne brief.yaml --dry-run | grep -E "^---|^Estimation"
--- orbe-hero gemini-3-pro-image 2K 16:9 ~0.141 $
--- orbe-salon gemini-3.1-flash-image 1K 4:5 ~0.138 $
--- rh-atelier gemini-3.1-flash-image 1K 16:9 ~0.069 $
--- edito-sobriete gemini-3.1-flash-image 1K 4:3 ~0.069 $
--- flyer-salon gemini-3-pro-image 2K 2:3 ~0.141 $
Estimation totale : 0.557 $ pour 5 visuels
$ .venv/bin/python -m campagne brief.yaml --dry-run --final | tail -1
Estimation totale : 0.844 $ pour 5 visuelsLe coût réel de make run, mesuré ensuite, a été de 0,557 $ : l'estimation tombe juste à quelques dixièmes de centime près parce que le prix d'une image est fixe par taille ; seuls les tokens de texte varient.
Ce qui casse en production
| Symptôme | Cause | Parade |
|---|---|---|
400 INVALID_ARGUMENT sur image_size="512" | le Pro ne produit pas de 512 px | pipeline.py remonte à 1K si la taille n'existe pas pour le modèle |
| Facture deux fois plus haute que prévu | tout le monde génère en Pro « pour être sûr » | modèle par défaut = Flash dans le brief ; Pro réservé aux visuels final: true |
| Latence de 86 s sur un appel habituel de 7 s | longue traîne côté service (observée sur Vertex AI le 2026-10-15) | délai HTTP explicite (TIMEOUT_S, 180 s par défaut), jamais d'appel synchrone dans une requête web |
429 RESOURCE_EXHAUSTED en lot | quota de requêtes par minute | reprises avec attente exponentielle (generateur.py), ou API Batch pour les gros volumes |
| Prix faux après une mise à jour tarifaire | tarifs codés en dur | date de relevé en tête de couts.py, KeyError explicite pour un modèle inconnu |
La règle de décision
Itérez en Flash 1K, ou en 512 px pour explorer des compositions. Passez en Pro 2K pour les visuels validés qui seront publiés, et d'emblée pour les affiches avec texte et les scènes à plusieurs personnages. Surveillez le ratio coût réel / estimation sur la planche : un écart de plus de 10 % signale des retouches non prévues ou un tarif à mettre à jour.
Pratique
Une campagne de 40 visuels prévoit 4 essais Flash 1K par visuel, puis un rendu final. Quel choix pour le rendu final minimise le coût sans perdre en qualité ?
Le Pro facture 1 120 tokens d'image en 1K comme en 2K (0,134 $). Choisir 1K revient à payer le même prix pour moins de pixels. Flash 4K (0,151 $) coûte plus cher que Pro 2K. Pro 4K (0,24 $) ne se justifie que pour le grand format imprimé.
Votre comparaison montre que le Pro rend le texte de l'affiche un peu mieux, mais votre titre sera de toute façon composé en post-production. Les visuels sont des photos produit sur fond simple. Que décidez-vous ?
L'avantage mesuré du Pro (le texte) ne sert pas ici. Doubler le coût sans écart visible sur votre cas n'a pas de justification. Flash Lite est tentant mais la documentation le dit non optimisé pour les images de référence et les retouches multi-tours, que la photo produit exige.
Exercice. Avec le tableau de prix, calculez le coût de la campagne suivante : 25 visuels, 3 essais Flash 1K chacun, puis un rendu Pro 2K pour 10 d'entre eux et une retouche Flash pour 8 autres. Vérifiez ensuite votre calcul avec --dry-run sur un brief équivalent.
Voir la solution
- essais : 25 × 3 × 0,067 ;
- rendus Pro : 10 × 0,134 ;
- retouches Flash : 8 × 0,067 ;
- total images : 6,91 en Flash, 0,0048 .
--dry-run donne un chiffre légèrement supérieur parce qu'il compte aussi les images de référence en entrée (560 tokens chacune).
- Je connais le prix par image des deux modèles et l'effet de la taille
- Je demande 2K pour tout rendu final Pro
- Je calcule le coût réel depuis
usage_metadata, réflexion comprise - J'ai estimé une campagne avec
--dry-runavant de lancer