97 lines
2.6 KiB
Python
97 lines
2.6 KiB
Python
from typing import Tuple
|
|
|
|
from PIL import Image
|
|
|
|
|
|
def scale_to_fit(
|
|
img: Image.Image,
|
|
max_size: Tuple[int, int] = (3072, 2048),
|
|
min_size: Tuple[int, int] = (1792, 28),
|
|
grid_size: int = 28,
|
|
) -> Image.Image:
|
|
resample_method = Image.Resampling.LANCZOS
|
|
|
|
width, height = img.size
|
|
|
|
if width <= 0 or height <= 0:
|
|
return img
|
|
|
|
original_ar = width / height
|
|
current_pixels = width * height
|
|
max_pixels = max_size[0] * max_size[1]
|
|
min_pixels = min_size[0] * min_size[1]
|
|
|
|
scale = 1.0
|
|
if current_pixels > max_pixels:
|
|
scale = (max_pixels / current_pixels) ** 0.5
|
|
elif current_pixels < min_pixels:
|
|
scale = (min_pixels / current_pixels) ** 0.5
|
|
|
|
w_blocks = max(1, round((width * scale) / grid_size))
|
|
h_blocks = max(1, round((height * scale) / grid_size))
|
|
|
|
while (w_blocks * h_blocks * grid_size * grid_size) > max_pixels:
|
|
if w_blocks == 1 and h_blocks == 1:
|
|
break
|
|
|
|
if w_blocks == 1:
|
|
h_blocks -= 1
|
|
continue
|
|
if h_blocks == 1:
|
|
w_blocks -= 1
|
|
continue
|
|
|
|
ar_w_loss = abs(((w_blocks - 1) / h_blocks) - original_ar)
|
|
ar_h_loss = abs((w_blocks / (h_blocks - 1)) - original_ar)
|
|
|
|
if ar_w_loss < ar_h_loss:
|
|
w_blocks -= 1
|
|
else:
|
|
h_blocks -= 1
|
|
|
|
new_width = w_blocks * grid_size
|
|
new_height = h_blocks * grid_size
|
|
|
|
if (new_width, new_height) == (width, height):
|
|
return img
|
|
|
|
return img.resize((new_width, new_height), resample=resample_method)
|
|
|
|
|
|
def detect_repeat_token(
|
|
predicted_tokens: str,
|
|
base_max_repeats: int = 4,
|
|
window_size: int = 500,
|
|
cut_from_end: int = 0,
|
|
scaling_factor: float = 3.0,
|
|
) -> bool:
|
|
if cut_from_end > 0:
|
|
predicted_tokens = predicted_tokens[:-cut_from_end]
|
|
|
|
for seq_len in range(1, window_size // 2 + 1):
|
|
candidate_seq = predicted_tokens[-seq_len:]
|
|
|
|
max_repeats = int(base_max_repeats * (1 + scaling_factor / seq_len))
|
|
|
|
repeat_count = 0
|
|
pos = len(predicted_tokens) - seq_len
|
|
if pos < 0:
|
|
continue
|
|
|
|
while pos >= 0:
|
|
if predicted_tokens[pos : pos + seq_len] == candidate_seq:
|
|
repeat_count += 1
|
|
pos -= seq_len
|
|
else:
|
|
break
|
|
|
|
if repeat_count > max_repeats:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def image_token_budget(block_count: int, ceiling: int = 4096, floor: int = 64) -> int:
|
|
"""Per-block max_tokens: count + 100, clamped to [floor, ceiling]."""
|
|
return min(max(block_count + 100, floor), ceiling)
|