jyliuAI's picture
Add files using upload-large-folder tool
93cd35a verified
Raw History Blame Contribute Delete
2.03 kB
import torch
from functools import partial
def base_n(x, base, max_length):
powers = base ** torch.arange(max_length, device=x.device)
digits = (x.unsqueeze(-1) // powers) % base # shape: (B, L, max_length)
return digits.reshape(x.shape[0], -1)
def base_n_inv(x, base, max_length):
x = x.reshape(x.shape[0], -1, max_length)
powers = base ** torch.arange(max_length, device=x.device)
return (x * powers).sum(dim=-1)
def find_bos_and_shift_fn(base, max_length, tokenizer):
_base_n = partial(base_n, base=base, max_length=max_length)
_base_n_inv = partial(base_n_inv, base=base, max_length=max_length)
if tokenizer.bos_token_id is not None:
bos_idx = _base_n(torch.tensor([tokenizer.bos_token_id])).squeeze(0) # Shape: N
def fn(seq):
# seq: B x L
windows = seq.unfold(dimension=1, size=max_length, step=1)
match = (windows == bos_idx.view(1, 1, -1))
match_all = match.all(dim=-1)
# Find the first occurrence of a match in each batch
idx = torch.argmax(match_all.int(), dim=-1) # Shape: B
# If there's no match, set the result to -1
no_match = ~match_all.any(dim=-1)
idx[no_match] = -1
sentences = []
shifted_samples = []
for i in range(len(seq)):
shift_idx = idx[i]
if shift_idx == -1:
shift_idx = 0
fin = - (max_length - shift_idx % max_length) if shift_idx > 0 else len(seq[i])
shifted = seq[i][shift_idx:fin]
shifted = _base_n_inv(shifted.reshape(1, 1, -1)).squeeze(0)
sentences.append(tokenizer.decode(shifted))
shifted_samples.append(shifted)
return sentences, shifted_samples
else:
def fn(seq):
sample = _base_n_inv(seq)
sentences = tokenizer.batch_decode(sample)
return sentences, sample.tolist()
return fn