InternVL3-9B-CVRR / source_helpers.py
dmis-lab's picture
Add files using upload-large-folder tool
a381a62 verified
Raw
History Blame Contribute Delete
2.31 kB
def _layer_hidden(output):
"""Return the hidden tensor from a decoder-layer output."""
import torch
if torch.is_tensor(output):
return output
if isinstance(output, (tuple, list)) and output and torch.is_tensor(output[0]):
return output[0]
raise TypeError(f"unsupported decoder-layer output type: {type(output)!r}")
def _closest_ratio(aspect, ratios, width, height, image_size):
best = (1, 1)
difference = float("inf")
area = width * height
for ratio in ratios:
candidate = ratio[0] / ratio[1]
current = abs(aspect - candidate)
if current < difference or (
current == difference
and area > 0.5 * image_size * image_size * ratio[0] * ratio[1]
):
difference = current
best = ratio
return best
def dynamic_tiles(image, *, image_size: int, max_tiles: int, thumbnail: bool):
"""Official InternVL dynamic tiling, kept local for reproducibility."""
ratios = sorted(
{
(i, j)
for n in range(1, max_tiles + 1)
for i in range(1, n + 1)
for j in range(1, n + 1)
if 1 <= i * j <= max_tiles
},
key=lambda item: item[0] * item[1],
)
width, height = image.size
columns, rows = _closest_ratio(
width / height, ratios, width, height, image_size
)
resized = image.convert("RGB").resize(
(image_size * columns, image_size * rows), resample=3
)
tiles = []
for index in range(columns * rows):
left = (index % columns) * image_size
top = (index // columns) * image_size
tiles.append(
resized.crop((left, top, left + image_size, top + image_size))
)
if thumbnail and len(tiles) != 1:
tiles.append(image.convert("RGB").resize((image_size, image_size), 3))
return tiles
def _normalize_tiles(tiles):
import numpy as np
import torch
mean = torch.tensor((0.485, 0.456, 0.406)).view(3, 1, 1)
std = torch.tensor((0.229, 0.224, 0.225)).view(3, 1, 1)
tensors = []
for tile in tiles:
array = np.asarray(tile, dtype=np.float32) / 255.0
tensor = torch.from_numpy(array).permute(2, 0, 1)
tensors.append((tensor - mean) / std)
return torch.stack(tensors)