|
import math |
|
|
|
import tiktoken |
|
|
|
|
|
async def calculate_image_tokens(width, height, detail): |
|
if detail == "low": |
|
return 85 |
|
else: |
|
max_dimension = max(width, height) |
|
if max_dimension > 2048: |
|
scale_factor = 2048 / max_dimension |
|
new_width = int(width * scale_factor) |
|
new_height = int(height * scale_factor) |
|
else: |
|
new_width = width |
|
new_height = height |
|
|
|
width, height = new_width, new_height |
|
min_dimension = min(width, height) |
|
if min_dimension > 768: |
|
scale_factor = 768 / min_dimension |
|
new_width = int(width * scale_factor) |
|
new_height = int(height * scale_factor) |
|
else: |
|
new_width = width |
|
new_height = height |
|
|
|
width, height = new_width, new_height |
|
num_masks_w = math.ceil(width / 512) |
|
num_masks_h = math.ceil(height / 512) |
|
total_masks = num_masks_w * num_masks_h |
|
|
|
tokens_per_mask = 170 |
|
total_tokens = total_masks * tokens_per_mask + 85 |
|
|
|
return total_tokens |
|
|
|
|
|
async def num_tokens_from_messages(messages, model=''): |
|
try: |
|
encoding = tiktoken.encoding_for_model(model) |
|
except KeyError: |
|
encoding = tiktoken.get_encoding("cl100k_base") |
|
if model == "gpt-3.5-turbo-0301": |
|
tokens_per_message = 4 |
|
else: |
|
tokens_per_message = 3 |
|
num_tokens = 0 |
|
for message in messages: |
|
num_tokens += tokens_per_message |
|
for key, value in message.items(): |
|
if isinstance(value, list): |
|
for item in value: |
|
if item.get("type") == "text": |
|
num_tokens += len(encoding.encode(item.get("text"))) |
|
if item.get("type") == "image_url": |
|
pass |
|
else: |
|
num_tokens += len(encoding.encode(value)) |
|
num_tokens += 3 |
|
return num_tokens |
|
|
|
|
|
async def num_tokens_from_content(content, model=None): |
|
try: |
|
encoding = tiktoken.encoding_for_model(model) |
|
except KeyError: |
|
encoding = tiktoken.get_encoding("cl100k_base") |
|
encoded_content = encoding.encode(content) |
|
len_encoded_content = len(encoded_content) |
|
return len_encoded_content |
|
|
|
|
|
async def split_tokens_from_content(content, max_tokens, model=None): |
|
try: |
|
encoding = tiktoken.encoding_for_model(model) |
|
except KeyError: |
|
encoding = tiktoken.get_encoding("cl100k_base") |
|
encoded_content = encoding.encode(content) |
|
len_encoded_content = len(encoded_content) |
|
if len_encoded_content >= max_tokens: |
|
content = encoding.decode(encoded_content[:max_tokens]) |
|
return content, max_tokens, "length" |
|
else: |
|
return content, len_encoded_content, "stop" |
|
|