Multimodal 가격: 이미지, 오디오, 비디오는 실제로 무엇에 과금될까
같은 500장의 사진도 model 3개가 5.5배 차이를 보이고, 리사이즈 순간 최저가 model이 바뀝니다.
이 페이지에서
여기 한 가지 작업이 있습니다. 제품 사진 500장을 설명하되, 각각 짧은 캡션 하나씩입니다. 같은 사진, 같은 지시, 같은 답변 길이입니다. 달라지는 것은 어느 model이 그것을 읽느냐뿐입니다.
| 사진 | 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 |
이 표에서 멈춰 볼 만한 점이 세 가지 있습니다.
같은 작업인데도 누군가 사진 크기를 바꿨다는 이유만으로, 세 번째 행과 네 번째 행 사이에서 가장 저렴한 model이 바뀝니다. 캡션 대신 문단을 요청하면 교차점도 다시 움직입니다. 1280 × 960에서는 40-token 캡션의 승자는 Gemini이고, 400-token 문단의 승자는 OpenAI입니다.
Gemini 열은 어떤 행에서도 전혀 움직이지 않습니다. 4000 \u00d7 3000 사진의 비용이 640 \u00d7 480 사진과 정확히 같습니다. 4000 × 3000 사진의 비용이 640 × 480 사진과 정확히 같습니다. 이것은 cap이 아닙니다. 그것이 count하는 방식의 결과입니다. 그리고 이 업계에서 가장 흔한 비용 최적화, 즉 업로드 전에 다운샘플링하기가 이렇게 보상된다는 뜻입니다.
| image tokens, 4000 × 3000 → 800 × 600 | 실행 비용 | 절감 | |
|---|---|---|---|
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 % |
저 숫자 중 어느 것도 vendor가 게시한 가격이 아닙니다. 세 값 모두 서로 다른 세 규칙에서 계산해야 했습니다. 어디에서도 사진은 과금 단위가 아니기 때문입니다. 사진은 먼저 token으로 변환되며, 그 산술은 서로 맞지 않는 세 곳에 적혀 있습니다.
16장은 텍스트의 청구서를 만들고 텍스트가 끝나는 지점에서 멈췄습니다. 이 장은 청구서의 나머지입니다. 이미지, 음성, transcription, 비디오, raw compute입니다. 이들은 합쳐서 여덟 가지 서로 다른 단위로 과금되며, 같은 척도로 팔리지 않는 것들을 비교하는 방법을 다룹니다.
세부 정보 보기
이 장이 앞 장들에서 필요로 하는 것.
- **7장**은 tokenizer와 단위를 만들었습니다. 여기의 모든 것은 텍스트가 아닌 것을 그 단위로 바꾸려는 시도입니다.
- **8장**은 model이 소비하는 것이 기호가 아니라 embedding 공간의 벡터라는 점을 세웠습니다. 그래서 이미지도 token으로 가격이 매겨질 수 있습니다.
- 16장은
computeCost, 그 가격 tier, 그리고 다섯 개의 token bucket을 만들었습니다. 이 장은 그 함수를 대체하지 않고 확장합니다. - **11장**은 LoRA를 fine-tuning 기법으로 소개했고, **20장**은 그것을 예산 의사결정으로 가격화했습니다. 여기서는 그것이 언어 model이 아닌 model에서 등장합니다.
14장의 규칙에 따라 tensor는 없습니다. 이것은 tariff, 변환, 회계이므로 TypeScript입니다.
사진에 token 가격이 붙는 이유
섹션 링크: 사진에 token 가격이 붙는 이유transformer는 벡터의 sequence를 받습니다. 그 벡터가 어디에서 왔는지에는 관심이 없습니다. 8장은 token id에서 조회한 embeddings를 넣었지만, 아키텍처 어디에도 그 조회가 필수라는 조건은 없습니다.
따라서 그림을 고정된 정사각형으로 자르고, 각 정사각형을 숫자 목록으로 펼친 뒤, 각 목록을 학습된 하나의 선형 layer에 통과시켜 model 폭의 벡터를 얻습니다. 컬러 픽셀의 32 × 32 patch는 개의 숫자입니다. projection 은 그것을 하나의 차원 벡터로 바꾸며, 이는 text token이 들어오는 모양과 정확히 같습니다. 전부가 이것입니다. 그리고 제목 그대로 말하는 논문이 있습니다. 이미지는 16 × 16개의 단어만큼의 가치가 있습니다.1 positional encoding을 더해 model이 어느 정사각형이 어디에 있었는지 알게 하고, 그 결과를 text embeddings와 섞으면 model이 읽는 sequence는 일부는 그림이고 일부는 문장입니다.
세 논문이 이것을 제품으로 만들었습니다. CLIP은 스크랩한 4억 쌍에서 image encoder와 text encoder가 서로 동의하도록 학습시켰고, 픽셀과 단어가 하나의 공간을 공유할 수 있다는 생각이 가설이 아니게 된 지점이 바로 그곳입니다.2 Flamingo는 frozen vision encoder를 frozen language model에 몇 개의 학습된 bridging layer로 붙였습니다.3 LLaVA는 bridge가 하나의 선형 projection일 수 있고 instruction-following을 생성 데이터로 가르칠 수 있음을 보였으며, 그래서 이후의 모든 open vision-language model이 대략 같은 모습을 하게 되었습니다.4
청구서에 대한 결과는 즉각적이고 화려하지 않습니다. patch는 sequence 안의 position이므로 input token이고, 따라서 input rate로 비용을 냅니다. 몇 개인지는 산술이고, provider마다 다르게 합니다.
세 가지 규칙, 모두 공개되어 있지만 같은 것은 없음
섹션 링크: 세 가지 규칙, 모두 공개되어 있지만 같은 것은 없음아래의 모든 규칙은 provider 자체 문서에서 구현했으며, 같은 문서의 계산 예시와 대조했습니다.
OpenAI는 이미지를 32 × 32 patch로 덮고 그 count에 model별 factor를 곱합니다. patch count가 해당 model과 detail level의 budget을 넘으면, 이미지는 맞을 때까지 축소됩니다.
Anthropic은 28 × 28 patch로 덮고, patch 하나가 visual token 하나이며, 긴 변과 token count를 모두 cap합니다. standard-tier model에서는 1,568픽셀과 1,568 token, high-resolution tier에서는 2,576과 4,784입니다. 너무 큰 이미지는 둘 다 만족하는 최대 크기로 축소됩니다.5
Google은 픽셀을 전혀 세지 않습니다. 양쪽 변이 모두 384픽셀 이하인 이미지는 고정 258 token입니다. 그보다 큰 것은 각각 258 token인 tile로 잘리며, tile grid는 의 crop unit에서 나옵니다.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;
}각 vendor가 직접 인쇄한 숫자에 대해 실행해 보겠습니다.
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 MATCH아홉 개의 일치가 출력됩니다. Anthropic 표는 여섯 크기 모두에 대해 두 tier를 제공하므로 전체 실행은 열다섯 개를 확인합니다. 이제 이 규칙들은 당신이 가진 어떤 사진에도 실행할 수 있습니다. 그것이 핵심입니다. 이 장에서 가격 페이지에서 얻을 수 없는 함수는 이 세 개뿐입니다.
“더 크다”는 말의 세 가지 의미
섹션 링크: “더 크다”는 말의 세 가지 의미같은 4:3 사진을 여섯 크기로 세 방식 모두에 넣어 보겠습니다.
| 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 |
마지막 열을 아래로 읽어 보세요. 그림이 384픽셀을 넘는 순간 숫자는 다시는 변하지 않습니다. 우연도 cap도 아닙니다. 적어도 가로가 세로만큼 긴 이미지에 대해 crop unit을 tile formula에 다시 대입하면 다음과 같습니다.
크기가 약분됩니다. Google의 image tokens는 aspect ratio에만 의존하고 다른 것에는 의존하지 않습니다. 4:3 사진은 thumbnail이든 poster든 tile 네 개입니다. 이 단 하나의 대수적 사실이 위 절감 표의 0을 전부 설명하며, 어떤 가격 페이지도 이것을 명시하지 않습니다.
다른 두 열은 대신 cap에 걸립니다. Anthropic은 선언된 token ceiling에서, OpenAI는 pixel limit 뒤의 patch budget에서 걸리며, 그 높이와 이유가 다릅니다. 그래서 세 curve가 서로 다른 크기에서 교차합니다.
이제 깨뜨려 보겠습니다. vision model 비용을 줄이는 분명한 방법은 더 적은 detail을 요청하는 것이므로 detail: "low"를 보내 봅니다.
1600x1200 low = 2280 high = 2280 ratio 1.00
3200x2400 low = 3687 high = 2942 ratio 1.25더 적은 detail을 요청했는데 비용은 25 % 더 들었습니다. 버그가 아니며 OpenAI도 sizing table 한 줄에서 그렇게 말합니다. 그 model family에서 low는 2048-pixel limit과 6,144-patch budget을 쓰고, high는 같은 pixel limit에 2,500-patch budget을 쓰므로 “high보다 더 많은 tokens를 사용할 수 있습니다”.7 low라는 단어는 fidelity setting의 이름이지 가격의 이름이 아닙니다. 문서화된 다섯 model family 중 둘에서는 아무 절감도 사지 못하고, 그 둘 중 하나에서는 더 비쌉니다.
하나를 생성하는 것은 다른 기계입니다
섹션 링크: 하나를 생성하는 것은 다른 기계입니다지금까지의 모든 것은 model이 이미지를 읽는 일이었습니다. 하나를 만드는 일은 token이 전혀 없는 mechanism에서 돌아가며, 그래서 단어가 아니라 그림 단위로 팔립니다.
이미지 만들기: per-picture price는 per-token price입니다
섹션 링크: 이미지 만들기: per-picture price는 per-token price입니다vendor들은 image generation을 그림당 가격으로 게시합니다. 사실은 아닙니다. GPT Image model은 요청한 size와 quality에 따라 count가 달라지는 특수 image tokens를 내보냅니다. 공개된 count에 GPT Image 1의 공개 image output rate인 백만 개당 $40를 곱하고, 같은 페이지의 per-image price와 비교해 보세요.
| 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) |
공개된 아홉 값에 대해 파생한 아홉 수치가 모두 $0.002 이내로 일치합니다.11 Google은 더 명시적이며 가격 페이지에서 직접 변환까지 해 줍니다. image output은 백만 tokens당 $60이며, “1K(1024x1024px) output images는 1120 tokens를 소비하고 이미지당 $0.067에 해당한다”고 합니다.12
따라서 per-image price는 count가 접힌 per-token price입니다. 괜찮습니다. 그리고 무언가를 숨깁니다. 현 generation의 표를 뒤로 나눠 보세요.
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 tok모든 quality에서 더 큰 이미지가 더 저렴합니다. 1024 × 1536 canvas는 1024 × 1024보다 pixel이 50 % 더 많지만 medium에서 token은 23 % 적게 듭니다. OpenAI는 당신이 지나칠 문장 하나로 이를 표시합니다. “더 큰 non-square resolution이 같은 quality setting에서 더 작거나 정사각형인 resolution보다 때때로 더 적은 output tokens를 만들 수 있다.” 이전 model generation에서는 반대였고, portrait가 square보다 50 % 더 비쌌습니다.11 그 변경 전에 작성된 1024x1024의 모든 default는 이제 비싼 선택지입니다.
소리, 초·문자·token으로 과금됨
섹션 링크: 소리, 초·문자·token으로 과금됨세 제품에 같은 519자를 말하게 하면, 약 38초의 audio에 대해 두 vendor에서 세 가지 unit system이 나옵니다.
| model | unit | price |
|---|---|---|
tts-1 | 문자당 | 백만 문자당 $15.00 → $0.007785 |
tts-1-hd | 문자당 | 백만 문자당 $30.00 → $0.015570 |
gemini-3.1-flash-tts | audio token당, 초당 25개 | 백만 개당 $20.00 → $0.019319 |
같은 vendor가 두 단위를 모두 팝니다. OpenAI의 tts-1는 백만 문자당 가격이고, gpt-4o-mini-tts는 백만 tokens당 가격입니다. input $0.60, output $12.00입니다.13 그래서 “가장 저렴한 text-to-speech”는 무엇을 말할지 말하기 전까지 답이 있는 질문이 아닙니다.
그리고 두 단위는 서로 반대의 것을 보지 못합니다. per-character price는 duration을 보지 못합니다. 느리고 신중한 voice를 고르거나 pause를 추가해도 bill은 움직이지 않지만 audio는 길어집니다. per-second price는 content를 보지 못합니다. 30초는 조밀한 기술 문단이든 누군가 10까지 세는 것이든 같은 비용입니다. voice를 바꾸면 두 vendor 중 정확히 하나만 다시 가격을 매깁니다.
Transcription은 반대로 움직이며 전체 invoice에서 가장 단순한 줄입니다. 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)마지막 행을 세 번째와 비교해 보세요. 단어가 도착하는 대로 live로 하는 것은 완성된 파일에서 하는 것보다 5.7배 비쌉니다. 그 차이는 batch할 수 없음의 가격이며, 다음 section을 비싸게 만드는 이유입니다.
음성 1분, 항목별 분해
섹션 링크: 음성 1분, 항목별 분해이제 voice가 feature인지 product인지 결정하는 숫자입니다.
통화는 10-turn support conversation입니다. 149 words이고, 선언된 150 words per minute 기준으로 59.6초의 speech입니다. caller가 21.2초, 되돌아 말한 쪽이 38.4초입니다. token conversion은 provider 자체의 것입니다. OpenAI: “user messages의 audio tokens는 audio 100 ms당 1 token이고, assistant messages의 audio tokens는 50 ms당 1 token입니다.”14 Google: 양방향 모두 초당 25 tokens이며, 가격 페이지가 같은 줄에서 백만 개당 $12.00와 분당 $0.018을 게시해 이를 확인합니다.12
대화는 16장이 말한 것과 정확히 같은 방식으로 누적됩니다. 같은 mechanism이기 때문입니다. “각 Response마다 전체 conversation이 model로 전송된다... 따라서 session의 나중 turn은 더 비싸진다.”14 다만 이제 history가 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 |
이제 product를 결정하는 비교입니다. 네 가지 모두 1분으로 정규화했습니다.
| 분당 | text 대비 | |
|---|---|---|
gpt-realtime-2.1, caching 없음 | $0.131259 | 37.9× |
gpt-realtime-2.1, history cached | $0.057425 | 16.6× |
gemini-3.1-flash-live, caching 없음 | $0.023965 | 6.9× |
같은 words를 typed, gpt-5.6-terra | $0.003461 | — |
서른여덟 배입니다. 38퍼센트가 아닙니다. 동일한 교환을 text 대신 sound로 수행하면 거의 두 자릿수 규모만큼 비싸지며, 그 차이 중 어느 것도 누군가 선택해 붙인 margin이 아닙니다. conversion rate입니다. assistant audio 1초는 token 20개입니다. 그 같은 1초는 선언된 rate에서 2.5 words를 담고, 측정한 transcript는 word당 1.26 tokens이므로 text로는 3.15 tokens입니다. sound는 같은 의미에 대해 6.3배 더 bulky한 package이며, 그 token 각각은 text output rate의 5.3배, text input rate의 16배로 과금됩니다. bulk ratio에 price ratio를 곱하면, 어떤 accounting이 시작되기 전부터 이미 order of magnitude가 나옵니다.
표에서 바로 나오는 운영상 결과가 두 가지 있습니다.
Audio caching은 optimisation이 아니라 business model입니다. cached audio input은 fresh $32.00 대비 백만 개당 $0.40입니다. 98.75 % discount로 call 비용을 절반으로 줄입니다. 규칙은 16장의 것과 동일합니다. cache는 prefix를 match하므로 통화 중 conversation 앞쪽에 무언가를 끼워 넣으면 그것을 파괴합니다. 그리고 “caller is now verified”를 넣을 자연스러운 위치가 정확히 거기입니다.
그리고 client에서 무엇을 해도 이미 발생한 sound 비용은 취소되지 않습니다. user가 assistant 말을 끊고, code가 playback을 멈추고, speaker가 조용해집니다. 이미 생성된 것은 이미 청구되었습니다. billing은 response가 생성될 때 누적되기 때문입니다. 그리고 16장의 규칙에 따라 conversation에 남아 있는 것은 이후 모든 turn에서 input audio로 다시 전송됩니다. 14장은 text stream을 abort하는 것에 대해 이 점을 말했습니다. voice에서는 30배 더 비쌉니다.
Video, GPU-seconds, 그리고 가격이 아닌 가격
섹션 링크: Video, GPU-seconds, 그리고 가격이 아닌 가격Video는 어떤 vendor에게서는 초당 팔리고, 다른 vendor에게서는 clip당 팔립니다. resolution tier가 있고 때로는 duration tier도 있습니다. 이 두 형태는 단지 편의성만 다른 것이 아닙니다. 서로 교차합니다.
| model | 1 s | 2 s | 5 s | 10 s | 20 s |
|---|---|---|---|---|---|
veo-3.1, 초당, 1080p | $0.400 | $0.800 | $2.000 | $4.000 | $8.000 |
veo-3.1-fast, 초당, 1080p | $0.120 | $0.240 | $0.600 | $1.200 | $2.400 |
sora-2, 초당, 720p | $0.100 | $0.200 | $0.500 | $1.000 | $2.000 |
hailuo-02, clip당, 1080p | $0.480 | $0.480 | $0.480 | $0.480 | $0.480 |
mochi, GPU-second당 | $0.018 | $0.037 | $0.092 | $0.183 | $0.366 |
per-clip vendor는 1.2초 아래에서는 per-second vendor보다 비싸고, 20초에서는 16.7배 저렴합니다. clip length가 바뀌어도 살아남는 두 model의 ordering은 없습니다. 따라서 “어느 video model이 가장 저렴한가”는 model에 대한 질문이 아닙니다.
마지막 행은 더 어렵고, 이 장의 정직한 핵심입니다. mochi는 real GPU seconds, 즉 job의 측정된 prediction time에 대해 과금됩니다. A100에서는 초당 $0.001400, H100에서는 $0.001525이며, 이는 빌린 machine의 rate일 뿐입니다.15 완벽하게 정확한 tariff이지만 가격은 아닙니다. 곱해지는 quantity를 지불에 동의한 뒤에야 알 수 있기 때문입니다. 위 행은 output 1초당 12 GPU-seconds를 가정합니다. 그 가정을 네 배로 하면 cheapest band를 벗어나고, 여섯 배가 되어야 table 중간에 옵니다. 이 페이지에서 quote에 넣을 수 없는 유일한 tariff입니다.
normaliser
섹션 링크: normaliser정리하면 tokens, image tokens, characters, minutes, video seconds, whole clips, GPU seconds, flat units입니다. 여덟 quantity이고, 하나의 축에 올리는 유일한 방법은 workload를 선언하고 가격을 매기는 것입니다.
이것이 16장의 computeCost에 대한 확장입니다. 같은 tier machinery이지만 이제 prompt length가 아닌 criteria를 가집니다.
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;
}표시된 두 줄이 깨지는 지점입니다. unit당 quote된 tariff는 u.images ?? 1를 곱합니다. token당 quote된 tariff는 기본값이 0인 무언가를 곱합니다. measurement가 실패했을 때 얻는 shape인 empty usage를 둘 다에 넣고 보겠습니다.
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.0000여섯 번은 아무 일도 일어나지 않았고, 한 번은 3달러가 들었으며, 다섯 번은 아무것도 들지 않았습니다. rounding difference가 아닙니다. absent number가 무엇을 의미하는지에 대한 결정이며, unit마다 따로 내려졌고 어디에도 적혀 있지 않습니다. 건전한 규칙은 아무도 측정하지 않은 field는 absent로 남는다는 것입니다. “not measured”와 “measured and came out zero”는 다르기 때문입니다. 이 function은 조용히 동의하지 않습니다.
두 번째 실패는 duration입니다. clip-priced tariff는 maxDurationSeconds로 u.videoSeconds ?? 0에 대해 tier를 선택하므로, duration을 기록하지 않은 usage는 가장 짧은 tier와 match합니다.
duration recorded -> $0.45
duration missing -> $0.27video 길이를 모르면 40퍼센트 할인입니다. 두 bug의 root는 같습니다. 정확해야 하는 것이 전체 업무인 함수 안에서 편의를 위해 선택한 default입니다.
숫자를 비교 가능하게 만들기
섹션 링크: 숫자를 비교 가능하게 만들기비용을 계산할 수 있게 되면, 비교에는 나머지 절반이 필요합니다. engine마다 하나씩 선언된 representative workload를 공개적으로 적어 독자가 반박할 수 있게 해야 합니다.
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 },
};저 줄 하나하나가 argument입니다. Text는 실제 사용이 output 쪽으로 치우치므로 input 1/4, output 3/4를 섞습니다. 50 대 50 blend는 model 순위를 다르게 만듭니다. image workload는 1,500 output tokens를 가정합니다. OpenAI의 medium square 1,056과 medium portrait 1,584 사이입니다. Video는 1080p에서 5초를 가정하고, 우리는 이미 두 vendor가 1.2초에서 자리를 바꾸는 것을 보았습니다. compute entry는 달리 가정할 것이 없으므로 60 GPU-seconds를 가정합니다.
이것이 방법이며, 사용할 수 있는 유일하게 정직한 방법입니다. 서로 다른 unit의 가격은 비교할 수 없습니다. 적어 둔 workload의 비용만 비교할 수 있습니다. workload를 인쇄하지 않고 multimodal model의 순위를 매기는 어떤 표도 자기 자신의 가정을 순위 매기는 것입니다.
다음은 어디로 가는가
섹션 링크: 다음은 어디로 가는가이제 model이 생산할 수 있는 무엇이든, 어떤 unit으로 팔리든 가격을 매길 수 있고, 비교가 어떤 workload를 가정했는지 소리 내어 말할 수 있습니다. 이것으로 16장이 연 invoice가 닫히고 Part III도 닫힙니다. 14장부터 여기까지의 모든 것은 one call에 관한 것이었습니다. 어떻게 만들고, 무엇을 넣고, 어떻게 sample하고, 무엇을 반환하며, 무엇이 드는가입니다.
22장은 분석 단위를 바꾸고, 그 변화는 비쌉니다. agent는 one call이 아닙니다. 몇 번의 call을 만들지 스스로 결정하는 loop입니다. 그리고 지난 두 장의 산술이 그것을 architecture diagram에서 budget으로 바꿉니다. 같은 model에 같은 질문을 두 번 묻되, 두 번째에는 catalogue에 tool 하나를 추가하고, 그 tool 하나가 무엇을 했는지 측정하면서 시작합니다. one call은 two가 되었고, 39 input tokens는 420이 되었습니다.
그것이 agent인지 여부는 당신이 두 개의 공개 definition 중 어느 것을 여느냐에 달려 있으며, 둘은 일치하지 않습니다. 그중 하나는 자기 자신과도 일치하지 않습니다.
Sources and method
섹션 링크: Sources and method이 장의 모든 가격, formula, conversion rate는 2026년 9월 7일 provider 자체 페이지에서 읽었고 그 날짜와 함께 인용합니다. 전부 움직일 것이기 때문입니다. token counts, costs, comparisons는 위에 출력한 code가 그 data로 계산했으며, 한 machine에서 실행했고 유료 API call은 하지 않았습니다. 이것이 이 장에 latency claim이 하나도 없는 정직한 이유이기도 합니다.
image-token functions, cost tables, voice-call breakdown, empty-usage results는 이 장에 출력한 TypeScript로 생성했으며 Node 22에서 실행했습니다. voice comparison에 사용한 dialogue는 149 words이고 o200k_base encoding에서 tiktoken로 tokenize했을 때 188 tokens였습니다. duration은 선언된 150 words per minute rate에서 나온 것이며, 이는 comparison의 parameter이지 measurement가 아닙니다. 모든 provider figure에는 그것이 나온 page를 naming하는 footnote가 붙어 있습니다.
-
Dosovitskiy, A. et al. An Image Is Worth 16x16 Words: Transformers for Image Recognition at Scale. arXiv:2010.11929 (2020). patch, embedding dimension으로의 linear projection, sequence model이 grid를 읽을 수 있게 하는 position embeddings. ↩
-
Radford, A. et al. Learning Transferable Visual Models From Natural Language Supervision. arXiv:2103.00020 (2021). image encoder와 text encoder를 4억 pairs에서 contrastive training한 것, 그리고 downstream의 모든 것이 가정하는 shared space. ↩
-
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 — image understanding을 chat capability로 바꾼 architecture. ↩
-
Liu, H., Li, C., Wu, Q. and Lee, Y. J. Visual Instruction Tuning. arXiv:2304.08485 (2023). bridge로서 하나의 linear projection과 training set으로서 generated instruction data; open vision-language models가 한 형태로 수렴한 이유. ↩
-
Anthropic, Vision,
platform.claude.com/docs/en/build-with-claude/vision, accessed 2026-09-07. “Claude는 이미지를 pixel 대신 patch로 봅니다. 각 patch는 이미지의 28×28-pixel block이며 visual token이라고 부릅니다. 따라서 이미지는 ⌈width / 28⌉ × ⌈height / 28⌉ visual tokens의 비용이 듭니다.” 또한 두 resolution tier(standard: 1568-pixel long edge, 1568 visual tokens; Claude 4.7 이후의 high-resolution: 2576 pixels와 4784 tokens), downsizing rule, 그리고 위에 재현한 six-row table of sizes and token counts의 출처입니다. Model rates는 Anthropic, Pricing,platform.claude.com/docs/en/about-claude/pricing, same date: Claude Haiku 4.5는 백만 input 및 output tokens당 $1 및 $5입니다. ↩ -
Google, Image understanding,
ai.google.dev/gemini-api/docs/image-understanding, accessed 2026-09-07. “두 dimensions가 모두 <= 384 pixels이면 258 tokens. 더 큰 이미지는 768x768 pixel tiles로 tiled되며, 각각 258 tokens가 듭니다.” crop-unit formula —floor(min(width, height) / 1.5), dimensions를 그것으로 나누고 서로 곱함 — 및 960 × 540이 3 × 2 = 6 tiles가 되는 worked example의 출처입니다. Google은 이를 “rough formula”라고 부릅니다. 위에서 유도한 scale-invariance는 공개된 formula의 property입니다. 같은 family의 audio input은 audio 초당 32 tokens입니다(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. patch-based rule(32 × 32 patches,patch_count = ceil(width/32)×ceil(height/32),shrink_factorformula와 integer adjustment, 30,000-patch rejection limit)의 출처입니다. 또한 model sizing table, 그중gpt-5.4의low가 2048-pixel limit과 6,144-patch budget을 사용해high의 2,500-patch budget 대비 “high보다 더 많은 tokens를 사용할 수 있다”는 부분, multiplier table(GPT-5.x families는 1.2,gpt-4.1-mini는 1.62,gpt-4.1-nano는 2.46), 위에서 재현한 두 worked examples(1024 × 1024 → 1229 tokens, 2048 × 2048 → 3000 tokens), older models의 tile-based rules(base plus 512-pixel tiles,gpt-4o에서 85 + 170), 그리고 vision box에 인용한 limitations list의 출처입니다. ↩ ↩2 -
Ho, J., Jain, A. and Abbeel, P. Denoising Diffusion Probabilistic Models. arXiv:2006.11239 (2020). forward noising schedule, objective를 added noise 예측으로 바꾸는 reparameterisation, 그리고 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). compressed latent space에서 diffusion process를 실행하는 것, 즉 fixed step count를 image당 팔 수 있을 만큼 저렴하게 만든 것. ↩
-
Prince, S. J. D. Understanding Deep Learning (MIT Press, 2023), chapter 18. diffusion에 대해 이 장이 건너뛴 모든 것, 즉 variational bound, noise schedules, classifier-free guidance, sampler families에 대한 선언된 위임입니다. Hu, E. et al., LoRA: Low-Rank Adaptation of Large Language Models, arXiv:2106.09685 (2021)는 adapter 자체이며, 11장에서 language model 위에서 소개되었고 여기서는 수학의 변화 없이 image model 위에서 사용됩니다. Radford, A. et al., Robust Speech Recognition via Large-Scale Weak Supervision (Whisper), arXiv:2212.04356 (2022)는 위에 per-minute price가 등장한 transcription model입니다. ↩
-
OpenAI, Image generation,
developers.openai.com/api/docs/guides/image-generation, Pricing,developers.openai.com/api/docs/pricing, 그리고gpt-image-1의 model page, all accessed 2026-09-07.gpt-image-2의 model page에는 pricing section이 없으므로 rate는 위 pricing page에서 왔습니다. GPT Image 1 page는 위 derivation에 사용한 per-image table 옆에 text input $5.00, image input $10.00, image output $40.00 per million tokens를 게시합니다. 또한 gpt-image-2 이전 model의 output-token table(square, portrait, landscape에 대해 low 272 / 408 / 400, medium 1056 / 1584 / 1568, high 4160 / 6240 / 6208), 위 derivations에 사용한 GPT Image 2, 1.5, 1, 1 Mini의 per-image price tables, “a larger non-square resolution can sometimes produce fewer output tokens than a smaller or square resolution at the same quality setting”이라는 문장, streamed partial image마다 추가 100 image output tokens가 든다는 note, 그리고 gpt-image-2의 백만 tokens당 image input $8.00, cached image input $2.00, image output $30.00, text input $5.00 rate의 출처입니다. 비교에 사용한 text model rates:gpt-5.6-terra는 input $2.00, cached input $0.20, output $12.00,gpt-5.6-luna는 $0.20 및 $1.20, standard tier, short context. Video:sora-2는 720p에서 초당 $0.10,sora-2-pro는 720p, 1024p, 1080p에서 $0.30, $0.50, $0.70. Transcription:gpt-4o-transcribe,gpt-transcribe,gpt-4o-mini-transcribe,gpt-live-transcribe에 대해 분당 $0.006, $0.0045, $0.003, $0.017. ↩ ↩2 -
Google, Gemini Developer API pricing,
ai.google.dev/gemini-api/docs/pricing, accessed 2026-09-07. Gemini 3.1 Flash-Lite는 input tokens(text, image, video) 백만 개당 $0.25, output $1.50입니다. Gemini 3.1 Flash Image: image output은 백만 tokens당 $60이며, 0.5K, 1K, 2K, 4K images에 대해 747, 1120, 1680, 2520 tokens와 per-image prices $0.045, $0.067, $0.101, $0.151의 공개 equivalences가 있습니다. Gemini 3.1 Flash TTS: text input $1.00, audio output $20.00, “audio tokens correspond to 25 tokens per second of audio”. Gemini 3.1 Flash Live Preview: text $0.75 및 audio input “$3.00 또는 $0.005/min”, output “$4.50 (text) $12.00 또는 $0.018/min (audio)”. Veo 3.1 per second with audio: standard에서 720p와 1080p는 $0.40, 4K는 $0.60; fast는 $0.10, $0.12, $0.30입니다. Gemini Omni Flash는 video output을 “720p video 초당 5,792 tokens의 rate”로 bill하며, 같은 footnote가 이를 초당 약 $0.10으로 변환합니다. per-second media price가 token price라는 가장 명확한 공개 statement입니다. ↩ ↩2 -
tts-1,tts-1-hd,gpt-4o-mini-tts에 대한 OpenAI model pages,developers.openai.com/api/docs/models, accessed 2026-09-07.tts-1는 백만 characters당 $15.00,tts-1-hd는 $30.00입니다.gpt-4o-mini-tts는 text input tokens 백만 개당 $0.60, audio output tokens 백만 개당 $12.00입니다. 같은 vendor, 같은 operation, 두 unit입니다. ↩ -
OpenAI, Managing costs (Realtime API),
developers.openai.com/api/docs/guides/realtime-costs, accessed 2026-09-07. “user messages의 Audio tokens는 audio 100 ms당 1 token이고, assistant messages의 audio tokens는 audio 50ms당 1 token입니다.” 또한 “각 Response마다 entire conversation이 model로 전송된다... 따라서 session의 later turns는 더 비싸진다”; costs accrue when a Response is created; 위 table이 재현한 accumulation의 worked two-turn example; 그리고input_token_details와output_token_detailssplits가 있는response.doneusage payload의 출처입니다. Rates는 pricing page, same date:gpt-realtime-2.1audio는 백만 tokens당 input $32.00, cached input $0.40, output $64.00, text는 $4.00, $0.40, $24.00, image input은 $5.00입니다. ↩ ↩2 -
Replicate, Pricing,
replicate.com/pricing, accessed 2026-09-07. Nvidia A100 (80GB)는 초당 $0.001400, 시간당 $5.04이고, Nvidia H100은 초당 $0.001525, 시간당 $5.49입니다. ↩