from transformers import AutoTokenizer
import torch
# Extract subjects from prompt
def extract_subjects(prompt, start_subject="", end_subject=""):
subjects = []
start = 0
while True:
start = prompt.find(start_subject, start)
if start == -1:
break
end = prompt.find(end_subject, start)
if end == -1:
break
subjects.append(prompt[start + len(start_subject):end])
start = end + len(end_subject)
return subjects
# Remove delimiters from prompt
def remove_delimiters(prompt, start_subject="", end_subject=""):
return prompt.replace(start_subject, "").replace(end_subject, "")
# Find subject positions in clean prompt
def find_subject_positions(clean_prompt, subjects):
positions = []
for subject in subjects:
start = 0
while True:
start = clean_prompt.find(subject, start)
if start == -1:
break
end = start + len(subject)
positions.append([start, end])
start = end
return positions
# Create binary mask
def create_binary_mask(clean_prompt, adjusted_positions, offsets):
mask = [0] * len(offsets)
for start, end in adjusted_positions:
for i, (token_start, token_end) in enumerate(offsets):
if token_start >= start and token_end <= end:
mask[i] = 1
return mask
# Process list of prompts
def create_binary_mask_from_list(dirty_prompts, offsets, start_subject="", end_subject=""):
clean_prompts = [remove_delimiters(prompt, start_subject, end_subject) for prompt in dirty_prompts]
if isinstance(offsets, torch.Tensor):
offsets = offsets.tolist()
masks = []
for dirty_prompt, clean_prompt, offset in zip(dirty_prompts, clean_prompts, offsets):
subjects = extract_subjects(dirty_prompt, start_subject, end_subject)
adjusted_positions = find_subject_positions(clean_prompt, subjects)
mask = create_binary_mask(clean_prompt, adjusted_positions, offset)
masks.append(mask)
return {
"masks": masks,
"clean_prompts": clean_prompts
}