1
1
import base64
2
2
import math
3
3
import re
4
+ from fractions import Fraction
4
5
from io import BytesIO
6
+ from typing import Optional
5
7
6
8
from PIL import Image
7
9
@@ -16,20 +18,23 @@ def get_image_dims(image_uri: str) -> tuple[int, int]:
16
18
raise ValueError ("Image must be a base64 string." )
17
19
18
20
19
- def count_tokens_for_image (image_uri : str , detail : str = "auto" ) -> int :
21
+ def count_tokens_for_image (image_uri : str , detail : str = "auto" , model : Optional [ str ] = None ) -> int :
20
22
# From https://github.com/openai/openai-cookbook/pull/881/files
21
23
# Based on https://platform.openai.com/docs/guides/vision
22
- LOW_DETAIL_COST = 85
23
- HIGH_DETAIL_COST_PER_TILE = 170
24
- ADDITIONAL_COST = 85
24
+ multiplier = Fraction (1 , 1 )
25
+ if model == "gpt-4o-mini" :
26
+ multiplier = Fraction (100 , 3 )
27
+ COST_PER_TILE = 85 * multiplier
28
+ LOW_DETAIL_COST = COST_PER_TILE
29
+ HIGH_DETAIL_COST_PER_TILE = COST_PER_TILE * 2
25
30
26
31
if detail == "auto" :
27
32
# assume high detail for now
28
33
detail = "high"
29
34
30
35
if detail == "low" :
31
36
# Low detail images have a fixed cost
32
- return LOW_DETAIL_COST
37
+ return int ( LOW_DETAIL_COST )
33
38
elif detail == "high" :
34
39
# Calculate token cost for high detail images
35
40
width , height = get_image_dims (image_uri )
@@ -47,8 +52,8 @@ def count_tokens_for_image(image_uri: str, detail: str = "auto") -> int:
47
52
# Calculate the number of 512px squares
48
53
num_squares = math .ceil (width / 512 ) * math .ceil (height / 512 )
49
54
# Calculate the total token cost
50
- total_cost = num_squares * HIGH_DETAIL_COST_PER_TILE + ADDITIONAL_COST
51
- return total_cost
55
+ total_cost = num_squares * HIGH_DETAIL_COST_PER_TILE + COST_PER_TILE
56
+ return math . ceil ( total_cost )
52
57
else :
53
58
# Invalid detail_option
54
59
raise ValueError ("Invalid value for detail parameter. Use 'low' or 'high'." )
0 commit comments