Multimodal Pricing: What Images, Audio and Video Really Bill
Three models given the same 500 photographs disagree by a factor of 5.5, and which one is cheapest flips the moment somebody resizes them.
On this page
Here is one task, priced three ways: describe five hundred product photographs, one short caption each. Same photographs, same instruction, same length of answer. The only thing that changes is which model reads them.
| photograph | gpt-5.6-luna | gemini-3.1-flash-lite | claude-haiku-4.5 |
|---|---|---|---|
| 800 × 600 | $0.0848 | $0.1638 | $0.4380 |
| 1024 × 768 | $0.1200 | $0.1638 | $0.6370 |
| 1280 × 960 | $0.1718 | $0.1638 | $0.9010 |
| 1600 × 1200 | $0.2558 | $0.1638 | $0.9010 |
| 4000 × 3000 | $0.3220 | $0.1638 | $0.9010 |
Three things in that table are worth stopping on.
The cheapest model changes between the third row and the fourth, on the same task, because somebody resized the photographs. Ask for a paragraph instead of a caption and the crossing point moves again: at 1280 × 960 the winner is Gemini for a forty-token caption and OpenAI for a four-hundred-token paragraph.
The Gemini column does not move at all, in any row: a 4000 \u00d7 3000 photograph costs it exactly what a 640 \u00d7 480 one costs. A 4000 × 3000 photograph costs it exactly what a 640 × 480 photograph costs. That is not a cap. It is a consequence of how it counts, and it means the most common cost optimisation in this business — downsample before you upload — pays like this:
| image tokens, 4000 × 3000 → 800 × 600 | cost of the run | saved | |
|---|---|---|---|
gpt-5.6-luna | 2,942 → 570 | $0.3220 → $0.0848 | 73.7 % |
claude-haiku-4.5 | 1,564 → 638 | $0.9010 → $0.4380 | 51.4 % |
gemini-3.1-flash-lite | 1,032 → 1,032 | $0.1638 → $0.1638 | 0.0 % |
None of those numbers is a price the vendor publishes. All three had to be computed, from three different rules, because a photograph is not a billable unit anywhere: it is converted into tokens first, by an arithmetic written down in three incompatible places.
Chapter 16 built the bill for text and stopped where text stops. This chapter is the rest of the invoice: images, speech, transcription, video and raw compute, which between them are billed in eight different units, and the method for comparing things that are not sold by the same measure.
Show details
What this chapter needs from the earlier ones.
- Chapter 7 built the tokenizer and the unit. Everything here is an attempt to turn something that is not text into that unit.
- Chapter 8 established what a model consumes: not symbols, but vectors in an embedding space. That is why an image can be priced in tokens at all.
- Chapter 16 built
computeCost, its price tiers and its five token buckets. This chapter extends that function rather than replacing it. - Chapter 11 introduced LoRA as a fine-tuning technique and Chapter 20 priced it as a budget decision. Here it turns up on a model that is not a language model.
No tensors, by the rule from Chapter 14: this is tariffs, conversions and accounting, so it is TypeScript.
Why a photograph has a token price
Link to the section: Why a photograph has a token priceA transformer takes a sequence of vectors. It has no opinion about where they came from. Chapter 8 fed it embeddings looked up from a token id; nothing in the architecture requires the lookup.
So: cut the picture into fixed squares, flatten each square into a list of numbers, and push each list through one learned linear layer to get a vector of the model's width. A 32 × 32 patch of colour pixels is numbers; the projection turns it into one -dimensional vector, exactly the shape a text token arrives in. That is the whole of it, and it is the paper whose title says it: an image is worth 16 × 16 words.1 Add a positional encoding so the model knows which square was where, interleave the results with the text embeddings, and the sequence the model reads is part picture and part sentence.
Three papers made it a product. CLIP trained an image encoder and a text encoder to agree, on four hundred million scraped pairs, which is where the idea that pixels and words can share a space stopped being a hypothesis.2 Flamingo bolted a frozen vision encoder onto a frozen language model with a few trained bridging layers.3 LLaVA showed the bridge could be a single linear projection and the instruction-following could be taught with generated data, which is why every open vision-language model since looks roughly the same.4
The consequence for your invoice is immediate and unglamorous: the patches are positions in the sequence, so they are input tokens, so you pay for them at the input rate. How many is arithmetic, and each provider does it differently.
Three rules, all published, none the same
Link to the section: Three rules, all published, none the sameEvery rule below is implemented from the provider's own documentation and checked against the worked examples in that same documentation.
OpenAI covers the image with 32 × 32 patches and multiplies the count by a per-model factor. If the patch count exceeds the budget for that model and detail level, the image is scaled down until it fits:
Anthropic covers it with 28 × 28 patches, one visual token each, and caps both the long edge and the token count — 1,568 pixels and 1,568 tokens on standard-tier models, 2,576 and 4,784 on the high-resolution tier. Oversized images are scaled to the largest size that fits both.5
Google does not count pixels at all. An image with both sides at or below 384 pixels costs a flat 258 tokens. Anything larger is cut into tiles of 258 tokens each, and the tile grid comes from a crop unit of .6
export function openaiImageTokens(
w: number, h: number,
{ maxDim, patchBudget, multiplier }: { maxDim: number; patchBudget: number; multiplier: number },
) {
const fit = Math.min(1, maxDim / Math.max(w, h)); // never enlarges
w = Math.floor(w * fit); h = Math.floor(h * fit);
let patches = Math.ceil(w / 32) * Math.ceil(h / 32);
if (patches > patchBudget) {
const s = Math.sqrt((32 * 32 * patchBudget) / (w * h));
const adj = s * Math.min(
Math.floor((w * s) / 32) / ((w * s) / 32),
Math.floor((h * s) / 32) / ((h * s) / 32));
patches = Math.ceil(Math.floor(w * adj) / 32) * Math.ceil(Math.floor(h * adj) / 32);
}
return Math.ceil(patches * multiplier);
}
export function anthropicVisualTokens(
w: number, h: number,
{ maxLongEdge, maxTokens }: { maxLongEdge: number; maxTokens: number },
) {
const tok = (a: number, b: number) => Math.ceil(a / 28) * Math.ceil(b / 28);
const long = Math.max(w, h), short = Math.min(w, h);
for (let L = Math.min(long, maxLongEdge); L >= 1; L--) {
const t = tok(L, Math.round((short * L) / long));
if (t <= maxTokens) return t;
}
return 0;
}
export function geminiImageTokens(w: number, h: number) {
if (w <= 384 && h <= 384) return 258;
const crop = Math.floor(Math.min(w, h) / 1.5);
return Math.ceil(w / crop) * Math.ceil(h / crop) * 258;
}Run each against the numbers its own vendor prints:
OpenAI, gpt-5.4 at detail:high (2048 px, 2,500 patches, 1.2x)
1024x1024 -> 1024 patches -> 1229 tokens doc says 1229 MATCH
2048x2048 -> 2500 patches -> 3000 tokens doc says 3000 MATCH
Anthropic, the published table (one tier per row shown)
200x200 std 64 @ 200x200 doc 64, not resized OK
1000x1000 std 1296 @ 1000x1000 doc 1296, not resized OK
1092x1092 std 1521 @ 1092x1092 doc 1521, not resized OK
1920x1080 std 1560 @ 1456x819 doc 1560, 1456x819 OK
2000x1500 std 1564 @ 1269x952 doc 1564, 1269x952 OK
3840x2160 hi 4784 @ 2576x1449 doc 4784, 2576x1449 OK
Google, the worked example
960x540 -> crop 360 -> 3 x 2 = 6 tiles doc says 6 MATCHNine agreements are printed; the full run checks fifteen, since Anthropic's table gives both tiers for all six sizes. The rules are now yours to run on any photograph you have, which is the point: these are the only three functions in this chapter you cannot get from a price page.
What "bigger" means, three times
Link to the section: What "bigger" means, three timesPut the same 4:3 photograph through all three at six sizes:
| size | OpenAI, high | Anthropic, standard | Anthropic, high-res | Gemini |
|---|---|---|---|---|
| 384 × 288 | 130 | 154 | 154 | 258 |
| 640 × 480 | 360 | 414 | 414 | 1,032 |
| 800 × 600 | 570 | 638 | 638 | 1,032 |
| 1600 × 1200 | 2,280 | 1,564 | 2,494 | 1,032 |
| 3200 × 2400 | 2,942 | 1,564 | 4,740 | 1,032 |
| 4000 × 3000 | 2,942 | 1,564 | 4,740 | 1,032 |
Read the last column downwards. Once the picture is over 384 pixels the number never changes again, and that is not a coincidence or a cap. Substitute the crop unit back into the tile formula, for an image at least as wide as it is tall:
The size cancels. Google's image tokens depend on the aspect ratio and nothing else. A 4:3 photograph is four tiles whether it is a thumbnail or a poster. That single algebraic fact is the entire explanation of the zero in the savings table above, and no price page anywhere states it.
The other two columns cap instead, at different heights and for different reasons — Anthropic at a declared token ceiling, OpenAI at a patch budget after a pixel limit — which is why the three curves cross at different sizes.
Now break it. The obvious way to spend less on a vision model is to ask for less detail, so send detail: "low":
1600x1200 low = 2280 high = 2280 ratio 1.00
3200x2400 low = 3687 high = 2942 ratio 1.25Asking for less detail cost 25 % more. This is not a bug and OpenAI says so in one line of the sizing table: on that model family, low uses a 2048-pixel limit with a 6,144-patch budget while high uses the same pixel limit with a 2,500-patch budget, "so it can use more tokens than high".7 The word low names a fidelity setting, not a price: on two of the five documented model families it buys no saving at all, and on one of those two it costs more.
Generating one is a different machine
Link to the section: Generating one is a different machineEverything so far has been a model reading an image. Making one runs on a mechanism with no tokens in it at all, and that is the reason it is sold by the picture rather than by the word.
Making an image: a per-picture price is a per-token price
Link to the section: Making an image: a per-picture price is a per-token priceVendors publish image generation as a price per picture. It is not one. GPT Image models emit specialised image tokens whose count depends on the requested size and quality; multiply the published counts by GPT Image 1's published image output rate of $40 per million and compare with the per-image prices on the same page:
| quality | 1024 × 1024 | 1024 × 1536 | 1536 × 1024 |
|---|---|---|---|
| low | 272 tok → $0.0109 ($0.011) | 408 tok → $0.0163 ($0.016) | 400 tok → $0.0160 ($0.016) |
| medium | 1,056 tok → $0.0422 ($0.042) | 1,584 tok → $0.0634 ($0.063) | 1,568 tok → $0.0627 ($0.063) |
| high | 4,160 tok → $0.1664 ($0.167) | 6,240 tok → $0.2496 ($0.25) | 6,208 tok → $0.2483 ($0.25) |
Nine derived figures against nine published ones, every pair agreeing to within $0.002.11 Google is more explicit still and does the conversion for you on the price page itself: image output at $60 per million tokens, "output images at 1K (1024x1024px) consume 1120 tokens and are equivalent to $0.067 per image".12
So a per-image price is a per-token price with the count folded in. Which is fine, and it hides something. Take the current generation's table and divide backwards:
quality 1024x1024 1024x1536
low $0.006 -> 200 tok $0.005 -> 167 tok
medium $0.053 -> 1767 tok $0.041 -> 1367 tok
high $0.211 -> 7033 tok $0.165 -> 5500 tokThe larger image is the cheaper one at every quality. A 1024 × 1536 canvas is 50 % more pixels than a 1024 × 1024 one and costs 23 % fewer tokens at medium. OpenAI flags it in a sentence you would skip — "a larger non-square resolution can sometimes produce fewer output tokens than a smaller or square resolution at the same quality setting" — and on the previous model generation it ran the other way, portrait costing 50 % more than square.11 Every default of 1024x1024 written before that change is now the expensive option.
Sound, billed by the second, the character, and the token
Link to the section: Sound, billed by the second, the character, and the tokenAsk three products to speak the same 519 characters — about 38 seconds of audio — and you get three unit systems from two vendors:
| model | unit | price |
|---|---|---|
tts-1 | per character | $15.00 per million characters → $0.007785 |
tts-1-hd | per character | $30.00 per million characters → $0.015570 |
gemini-3.1-flash-tts | per audio token, 25 per second | $20.00 per million → $0.019319 |
The same vendor sells both units: OpenAI's tts-1 is priced per million characters while gpt-4o-mini-tts is priced per million tokens, $0.60 in and $12.00 out.13 So "cheapest text-to-speech" is not a question with an answer until you say what you are speaking.
And the two units are blind to opposite things. A per-character price cannot see duration: choose a slow, deliberate voice, or add pauses, and the bill does not move while the audio gets longer. A per-second price cannot see content: thirty seconds costs the same whether it is a dense technical paragraph or somebody counting to ten. Change the voice and exactly one of your two vendors reprices.
Transcription runs the other way and is the simplest line on the whole invoice — per minute of audio, flat:
whisper $0.005960 ($0.006 / min)
gpt-transcribe $0.004470 ($0.0045 / min)
gpt-4o-mini-transcribe $0.002980 ($0.003 / min)
gpt-live-transcribe $0.016887 ($0.017 / min)Note the last row against the third: doing it live, as the words arrive, costs 5.7 times doing it on a finished file. That gap is the price of not being able to batch, and it is what makes the next section expensive.
One minute of voice, itemised
Link to the section: One minute of voice, itemisedNow the number that decides whether voice is a feature or a product.
The call: a ten-turn support conversation, 149 words, which at a declared 150 words per minute is 59.6 seconds of speech — 21.2 spoken by the caller, 38.4 spoken back. The token conversions are the providers' own. OpenAI: "audio tokens in user messages are 1 token per 100 ms of audio, while audio tokens in assistant messages are 1 token per 50 ms".14 Google: 25 tokens per second, in both directions, which its price page confirms by publishing $12.00 per million and $0.018 per minute on the same line.12
The conversation accumulates exactly as Chapter 16 said it would, because it is the same mechanism: "the entire conversation is sent to the model for each Response... thus turns later in the session will be more expensive".14 Only now the history is measured in audio tokens.
| turn | user | assistant | fresh audio in | cached audio in | audio out | cost |
|---|---|---|---|---|---|---|
| 1 | 4.4 s | 9.2 s | 44 | 0 | 184 | $0.013224 |
| 2 | 5.6 s | 9.6 s | 56 | 228 | 192 | $0.014211 |
| 3 | 5.2 s | 9.2 s | 52 | 476 | 184 | $0.013670 |
| 4 | 4.0 s | 4.8 s | 40 | 712 | 96 | $0.007749 |
| 5 | 2.0 s | 5.6 s | 20 | 848 | 112 | $0.008187 |
Now the comparison that decides the product, all four normalised to a minute:
| per minute | versus text | |
|---|---|---|
gpt-realtime-2.1, no caching | $0.131259 | 37.9× |
gpt-realtime-2.1, history cached | $0.057425 | 16.6× |
gemini-3.1-flash-live, no caching | $0.023965 | 6.9× |
the same words typed, gpt-5.6-terra | $0.003461 | — |
Thirty-eight times. Not thirty-eight per cent. The identical exchange, conducted in sound instead of text, is nearly two orders of magnitude dearer, and none of that gap is a margin somebody chose to charge — it is the conversion rate. One second of assistant audio is twenty tokens. That same second carries 2.5 words at the declared rate, and the measured transcript runs at 1.26 tokens per word, so as text it is 3.15 tokens. Sound is a 6.3 times bulkier package for the same meaning, and each of its tokens is billed at 5.3 times the text output rate and 16 times the text input rate. Multiply a bulk ratio by a price ratio and the order of magnitude is already there before any accounting begins.
Two operational consequences fall straight out of the table.
Audio caching is not an optimisation, it is the business model. Cached audio input is $0.40 per million against $32.00 fresh — a 98.75 % discount that halves the call. The rule is Chapter 16's, unchanged: the cache matches a prefix, so anything inserted at the front of the conversation mid-call destroys it, and the natural place to put "the caller is now verified" is exactly there.
And nothing you do in the client un-bills a sound. The user talks over the assistant, your code stops the playback, the speaker goes quiet. Whatever had already been generated was already charged, because billing accrues when the response is created; and by Chapter 16's rule whatever stays in the conversation is re-sent, as input audio, every turn after. Chapter 14 made this point about aborting a text stream. In voice it costs thirty times more.
Video, GPU-seconds, and a price that is not a price
Link to the section: Video, GPU-seconds, and a price that is not a priceVideo is sold per second by some vendors and per clip by others, with tiers for resolution and sometimes for duration. Those two shapes do not merely differ in convenience; they cross.
| model | 1 s | 2 s | 5 s | 10 s | 20 s |
|---|---|---|---|---|---|
veo-3.1, per second, 1080p | $0.400 | $0.800 | $2.000 | $4.000 | $8.000 |
veo-3.1-fast, per second, 1080p | $0.120 | $0.240 | $0.600 | $1.200 | $2.400 |
sora-2, per second, 720p | $0.100 | $0.200 | $0.500 | $1.000 | $2.000 |
hailuo-02, per clip, 1080p | $0.480 | $0.480 | $0.480 | $0.480 | $0.480 |
mochi, per GPU-second | $0.018 | $0.037 | $0.092 | $0.183 | $0.366 |
The per-clip vendor is dearer than the per-second one below 1.2 seconds and 16.7 times cheaper at twenty. No ordering of those two models survives a change in clip length, so "which video model is cheapest" is not a question about models.
The last row is worse, and it is the honest heart of the chapter. mochi is billed against real GPU seconds — the measured prediction time of the job — at $0.001400 per second on an A100 and $0.001525 on an H100, which are the rented machine's rates and nothing else.15 That is a perfectly precise tariff and it is not a price, because the quantity it multiplies is unknown until after you have committed to paying it. The row above assumes twelve GPU-seconds per second of output; quadruple that assumption and it leaves the cheapest band, and only at six times does it land mid-table. It is the only tariff on this page you cannot put in a quote.
The normaliser
Link to the section: The normaliserSo: tokens, image tokens, characters, minutes, video seconds, whole clips, GPU seconds, flat units. Eight quantities, and the only way to put them on one axis is to declare a workload and price it.
That is the extension to Chapter 16's computeCost — the same tier machinery, now with criteria that are not prompt length:
export interface MediaCriteria {
resolution?: string[]; quality?: string[];
hasAudio?: boolean; maxDurationSeconds?: number;
}
export interface MediaTier { when?: MediaCriteria; price: number }
export type MediaRate = number | MediaTier[];
const matches = (when: MediaCriteria, u: Usage) => {
const inList = (l?: string[], v?: string) => !l || (v !== undefined && l.includes(v));
if (!inList(when.resolution, u.resolution)) return false;
if (!inList(when.quality, u.quality)) return false;
if (when.hasAudio !== undefined && when.hasAudio !== (u.hasAudio ?? false)) return false;
if (when.maxDurationSeconds !== undefined
&& (u.videoSeconds ?? 0) > when.maxDurationSeconds) return false;
return true;
};
const mediaPrice = (rate: MediaRate | undefined, u: Usage): number => {
if (rate === undefined) return 0;
if (typeof rate === "number") return rate;
for (const t of rate.filter((t) => t.when)) if (matches(t.when!, u)) return t.price;
return rate.find((t) => !t.when)?.price ?? 0; // the tier with no criteria is the default
};
export function computeCost(p: Pricing, u: Usage): number {
let c = textCost(p, u); // Chapter 16, unchanged
if (p.imageInputToken || p.imageOutputToken) {
c += (u.imageInputTokens ?? 0) * (p.imageInputToken ?? 0)
+ (u.imageOutputTokens ?? 0) * (p.imageOutputToken ?? 0);
} else if (p.imageUnit !== undefined) c += (u.images ?? 1) * mediaPrice(p.imageUnit, u);
if (p.videoSecond !== undefined) c += (u.videoSeconds ?? 0) * mediaPrice(p.videoSecond, u);
if (p.videoUnit !== undefined) c += (u.videoCount ?? 1) * mediaPrice(p.videoUnit, u);
c += (u.audioInputTokens ?? 0) * (p.audioInputToken ?? 0)
+ (u.cachedAudioInputTokens ?? 0) * (p.cachedAudioInputToken ?? p.audioInputToken ?? 0)
+ (u.audioOutputTokens ?? 0) * (p.audioOutputToken ?? 0)
+ (u.computeSeconds ?? 0) * (p.computeSecond ?? 0)
+ (u.chars ?? 0) * (p.perChar ?? 0)
+ (u.minutes ?? 0) * (p.perMinute ?? 0);
return c;
}The two marked lines are where it breaks. A tariff quoted per unit multiplies u.images ?? 1; a tariff quoted per token multiplies something that defaults to zero. Feed both an empty usage — the shape you get when a measurement failed — and watch:
per image (nano-banana-pro) empty usage => $0.1500
per clip (hailuo-02) empty usage => $0.1500
per unit (a cloned voice) empty usage => $3.0000
per token (gpt-image-2) empty usage => $0.0000
per second (veo-3.1) empty usage => $0.0000
per GPU-second (mochi) empty usage => $0.0000Nothing happened, six times, and it cost three dollars once and nothing five times. That is not a rounding difference; it is a decision about what an absent number means, taken separately for each unit and never written down. The sound rule is that a field nobody measured stays absent, because "not measured" and "measured and came out zero" are different things. This function quietly disagrees.
The second failure is duration. The clip-priced tariff selects its tier with maxDurationSeconds against u.videoSeconds ?? 0, so a usage that never recorded a duration matches the shortest tier:
duration recorded -> $0.45
duration missing -> $0.27Forty per cent off for not knowing how long the video was. Both bugs have the same root: a default chosen for convenience inside a function whose whole job is to be exact.
Making the number comparable
Link to the section: Making the number comparableWith costs computable, the comparison needs the other half — a declared representative workload, one per engine, stated in public so a reader can disagree with it:
export const representative = {
text: { blend: [[{ promptTokens: 1e6 }, 0.25], [{ completionTokens: 1e6 }, 0.75]] },
image: { images: 1, imageInputTokens: 50, imageOutputTokens: 1500 },
video: { videoSeconds: 5, videoCount: 1, resolution: "1080p", hasAudio: true, computeSeconds: 60 },
voice: { chars: 1000, computeSeconds: 10 },
stt: { minutes: 1 },
};Every one of those lines is an argument. Text mixes a quarter input and three quarters output because real usage skews to output; a fifty-fifty blend ranks the models differently. The image workload assumes 1,500 output tokens, between OpenAI's 1,056 for a medium square and its 1,584 for a medium portrait. Video assumes five seconds at 1080p, and we have just seen two vendors swap places at 1.2 seconds. The compute entry assumes sixty GPU-seconds because there is nothing else to assume.
Which is the method, and it is the only honest one available: you cannot compare prices in different units; you can only compare the cost of a workload you have written down. Any table that ranks multimodal models without printing its workload is ranking its own assumptions.
Where this goes next
Link to the section: Where this goes nextYou can now price anything a model can produce, in whatever unit it is sold, and say out loud which workload your comparison assumed. That closes the invoice Chapter 16 opened, and it closes Part III: everything from Chapter 14 to here has been about one call — how to make it, what to put in it, how to sample it, what it returns, what it costs.
Chapter 22 changes the unit of analysis, and the change is expensive. An agent is not one call; it is a loop that decides for itself how many calls to make, and the arithmetic of the last two chapters is what turns that from an architecture diagram into a budget. It opens by asking the same question of the same model twice, with one tool added to the catalogue the second time, and measuring what that one tool did: one call became two, thirty-nine input tokens became 420.
Whether that makes it an agent depends on which of two published definitions you open, and they do not agree. One of them does not agree with itself.
Sources and method
Link to the section: Sources and methodEvery price, formula and conversion rate in this chapter was read from the provider's own page on 7 September 2026 and is quoted with that date, because all of them will move. The token counts, costs and comparisons were computed on that data by the code printed above, on one machine, with no paid API call made — which is also the honest reason there is not a single latency claim in this chapter.
The image-token functions, the cost tables, the voice-call breakdown and the empty-usage results were produced by the TypeScript printed in this chapter, run on Node 22. The dialogue used for the voice comparison is 149 words and was tokenized with tiktoken under the o200k_base encoding at 188 tokens; its duration follows from a declared rate of 150 words per minute, which is a parameter of the comparison and not a measurement. Every provider figure carries the footnote that names the page it came from.
References
Link to the section: References-
Dosovitskiy, A. et al. An Image Is Worth 16x16 Words: Transformers for Image Recognition at Scale. arXiv:2010.11929 (2020). Patches, the linear projection into the embedding dimension, and the position embeddings that make the grid legible to a sequence model. ↩
-
Radford, A. et al. Learning Transferable Visual Models From Natural Language Supervision. arXiv:2103.00020 (2021). Contrastive training of an image encoder and a text encoder on 400 million pairs, and the shared space that everything downstream assumes. ↩
-
Alayrac, J.-B. et al. Flamingo: a Visual Language Model for Few-Shot Learning. arXiv:2204.14198 (2022). Frozen vision encoder, frozen language model, trained bridging layers — the architecture that turned image understanding into a chat capability. ↩
-
Liu, H., Li, C., Wu, Q. and Lee, Y. J. Visual Instruction Tuning. arXiv:2304.08485 (2023). A single linear projection as the bridge and generated instruction data as the training set; the reason open vision-language models converged on one shape. ↩
-
Anthropic, Vision,
platform.claude.com/docs/en/build-with-claude/vision, accessed 2026-09-07. "Claude views images in patches instead of pixels. Each patch is a 28×28-pixel block of the image, referred to as a visual token. An image, therefore, costs ⌈width / 28⌉ × ⌈height / 28⌉ visual tokens." Also the two resolution tiers (standard: 1568-pixel long edge, 1568 visual tokens; high-resolution, on Claude 4.7 and later: 2576 pixels and 4784 tokens), the downsizing rule, and the six-row table of sizes and token counts reproduced above. Model rates from Anthropic, Pricing,platform.claude.com/docs/en/about-claude/pricing, same date: Claude Haiku 4.5 at $1 and $5 per million input and output tokens. ↩ -
Google, Image understanding,
ai.google.dev/gemini-api/docs/image-understanding, accessed 2026-09-07. "258 tokens if both dimensions <= 384 pixels. Larger images are tiled into 768x768 pixel tiles, each costing 258 tokens", with the crop-unit formula —floor(min(width, height) / 1.5), dimensions divided by it and multiplied together — and the worked example of 960 × 540 giving 3 × 2 = 6 tiles. Google calls it "a rough formula"; the scale-invariance derived above is a property of the formula as published. Audio input on the same family is 32 tokens per second of audio (ai.google.dev/gemini-api/docs/audio, same date). ↩ -
OpenAI, Images and vision,
developers.openai.com/api/docs/guides/images-vision, accessed 2026-09-07. Source of the patch-based rule (32 × 32 patches,patch_count = ceil(width/32)×ceil(height/32), theshrink_factorformula and its integer adjustment, the 30,000-patch rejection limit); the model sizing table, including thatlowongpt-5.4uses a 2048-pixel limit and a 6,144-patch budget "so it can use more tokens thanhigh", againsthigh's 2,500-patch budget; the multiplier table (1.2 for the GPT-5.x families, 1.62 forgpt-4.1-mini, 2.46 forgpt-4.1-nano); the two worked examples reproduced above (1024 × 1024 → 1229 tokens, 2048 × 2048 → 3000 tokens); the tile-based rules for older models (base plus 512-pixel tiles, 85 + 170 ongpt-4o); and the limitations list quoted in the vision box. ↩ ↩2 -
Ho, J., Jain, A. and Abbeel, P. Denoising Diffusion Probabilistic Models. arXiv:2006.11239 (2020). The forward noising schedule, the reparameterisation that turns the objective into predicting the added noise, and the sampling loop. ↩
-
Rombach, R., Blattmann, A., Lorenz, D., Esser, P. and Ommer, B. High-Resolution Image Synthesis with Latent Diffusion Models. arXiv:2112.10752 (2022). Running the diffusion process in a compressed latent space, which is what made the fixed step count affordable enough to sell per image. ↩
-
Prince, S. J. D. Understanding Deep Learning (MIT Press, 2023), chapter 18. The declared delegation for everything this chapter skipped about diffusion — the variational bound, the noise schedules, classifier-free guidance and the sampler families. Hu, E. et al., LoRA: Low-Rank Adaptation of Large Language Models, arXiv:2106.09685 (2021), is the adapter itself, introduced in Chapter 11 on a language model and used here on an image model without a change of mathematics. Radford, A. et al., Robust Speech Recognition via Large-Scale Weak Supervision (Whisper), arXiv:2212.04356 (2022), is the transcription model whose per-minute price appears above. ↩
-
OpenAI, Image generation,
developers.openai.com/api/docs/guides/image-generation, Pricing,developers.openai.com/api/docs/pricing, and the model page forgpt-image-1, all accessed 2026-09-07. The model page forgpt-image-2carries no pricing section; its rates come from the pricing page above. GPT Image 1's page publishes text input at $5.00, image input at $10.00 and image output at $40.00 per million tokens beside the per-image table used in the derivation above. Also: the output-token table for models prior to gpt-image-2 (272 / 408 / 400 low, 1056 / 1584 / 1568 medium, 4160 / 6240 / 6208 high, for square, portrait and landscape); the per-image price tables for GPT Image 2, 1.5, 1 and 1 Mini used in the derivations above; the sentence "a larger non-square resolution can sometimes produce fewer output tokens than a smaller or square resolution at the same quality setting"; the note that each streamed partial image costs an extra 100 image output tokens; and gpt-image-2's rates of $8.00 image input, $2.00 cached image input, $30.00 image output and $5.00 text input per million tokens. Text model rates used for the comparisons:gpt-5.6-terraat $2.00 input, $0.20 cached input and $12.00 output,gpt-5.6-lunaat $0.20 and $1.20, standard tier, short context. Video:sora-2at $0.10 per second at 720p andsora-2-proat $0.30, $0.50 and $0.70 at 720p, 1024p and 1080p. Transcription: $0.006, $0.0045, $0.003 and $0.017 per minute forgpt-4o-transcribe,gpt-transcribe,gpt-4o-mini-transcribeandgpt-live-transcribe. ↩ ↩2 -
Google, Gemini Developer API pricing,
ai.google.dev/gemini-api/docs/pricing, accessed 2026-09-07. Gemini 3.1 Flash-Lite at $0.25 per million input tokens (text, image and video) and $1.50 output. Gemini 3.1 Flash Image: image output at $60 per million tokens, with the published equivalences of 747, 1120, 1680 and 2520 tokens for 0.5K, 1K, 2K and 4K images and their per-image prices of $0.045, $0.067, $0.101 and $0.151. Gemini 3.1 Flash TTS: $1.00 text input, $20.00 audio output, "audio tokens correspond to 25 tokens per second of audio". Gemini 3.1 Flash Live Preview: $0.75 text and "$3.00 or $0.005/min" audio input, "$4.50 (text) $12.00 or $0.018/min (audio)" output. Veo 3.1 per second with audio: $0.40 at 720p and 1080p and $0.60 at 4K standard; $0.10, $0.12 and $0.30 fast. Gemini Omni Flash bills video output "at a rate of 5,792 tokens per second of 720p video", which the same footnote converts to about $0.10 per second — the clearest published statement anywhere that a per-second media price is a token price. ↩ ↩2 -
OpenAI model pages for
tts-1,tts-1-hdandgpt-4o-mini-tts,developers.openai.com/api/docs/models, accessed 2026-09-07.tts-1at $15.00 andtts-1-hdat $30.00 per million characters;gpt-4o-mini-ttsat $0.60 per million text input tokens and $12.00 per million audio output tokens — the same vendor, the same operation, two units. ↩ -
OpenAI, Managing costs (Realtime API),
developers.openai.com/api/docs/guides/realtime-costs, accessed 2026-09-07. "Audio tokens in user messages are 1 token per 100 ms of audio, while audio tokens in assistant messages are 1 token per 50ms of audio." Also: "The entire conversation is sent to the model for each Response... thus turns later in the session will be more expensive"; costs accrue when a Response is created; the worked two-turn example whose accumulation the table above reproduces; and theresponse.doneusage payload with itsinput_token_detailsandoutput_token_detailssplits. Rates from the pricing page, same date:gpt-realtime-2.1audio at $32.00 input, $0.40 cached input and $64.00 output per million tokens, text at $4.00, $0.40 and $24.00, image input at $5.00. ↩ ↩2 -
Replicate, Pricing,
replicate.com/pricing, accessed 2026-09-07. Nvidia A100 (80GB) at $0.001400 per second and $5.04 per hour; Nvidia H100 at $0.001525 per second and $5.49 per hour. ↩