mirror of
https://github.com/SakanaAI/doc-to-lora.git
synced 2026-07-23 17:01:04 +02:00
- work with vllm self-gen data (everything is tokenized during self-gen) - fix chat template! - not use liger kernel for distillation (for both training and eval)
143 lines
4.3 KiB
Python
143 lines
4.3 KiB
Python
import argparse
|
|
|
|
import torch
|
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
|
|
from ctx_to_lora.data.processing import load_and_process_dataset
|
|
|
|
|
|
def add_logits(row, model, tok, device, args):
|
|
ctx = row["context"]
|
|
qs = row["prompts"]
|
|
ans = row["responses"]
|
|
responses_masks = []
|
|
all_logits_values = []
|
|
all_logits_positions = []
|
|
|
|
for question, answer in zip(qs, ans):
|
|
messages = [
|
|
{
|
|
"role": "user",
|
|
"content": f"Answer the question based on the following information:\n{ctx}.\n\n{question}",
|
|
},
|
|
{"role": "assistant", "content": answer},
|
|
]
|
|
all_tokens = tok.apply_chat_template(
|
|
messages,
|
|
tokenize=True,
|
|
add_special_tokens=False,
|
|
truncation=False,
|
|
padding=False,
|
|
add_generation_prompt=False,
|
|
return_dict=True,
|
|
)
|
|
|
|
input = torch.tensor([all_tokens["input_ids"]], device=device)
|
|
with torch.no_grad():
|
|
logits = model(input).logits
|
|
|
|
top_logits, top_logits_positions = torch.topk(
|
|
logits, args.max_logits_to_store, dim=-1
|
|
)
|
|
|
|
# Convert logits to specified precision
|
|
dtype_map = {
|
|
"float32": torch.float32,
|
|
"bfloat16": torch.bfloat16,
|
|
"float16": torch.float16,
|
|
}
|
|
target_dtype = dtype_map[args.logit_precision]
|
|
top_logits = top_logits.to(target_dtype)
|
|
|
|
tokens_to_mask = tok.apply_chat_template(
|
|
[messages[0]], # Just the user message
|
|
tokenize=True,
|
|
add_special_tokens=False,
|
|
truncation=False,
|
|
padding=False,
|
|
add_generation_prompt=True,
|
|
return_dict=True,
|
|
)
|
|
number_of_tokens_to_mask = len(tokens_to_mask["input_ids"])
|
|
|
|
# Create mask: False for prompt tokens, True for response tokens
|
|
responses_mask = torch.zeros(len(all_tokens["input_ids"]), dtype=torch.bool)
|
|
responses_mask[number_of_tokens_to_mask:] = True
|
|
|
|
responses_masks.append(responses_mask)
|
|
all_logits_values.append(top_logits.cpu())
|
|
all_logits_positions.append(top_logits_positions.cpu())
|
|
|
|
row["labels_logits_values"] = all_logits_values
|
|
row["labels_logits_positions"] = all_logits_positions
|
|
row["responses_mask"] = responses_masks
|
|
return row
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--ds_name", required=True, help="name of the dataset")
|
|
ap.add_argument("--split", required=True, help="split of the dataset")
|
|
ap.add_argument(
|
|
"--max_logits_to_store",
|
|
type=int,
|
|
default=100,
|
|
help="max number of logits kept per completion",
|
|
)
|
|
ap.add_argument(
|
|
"--limit_samples",
|
|
type=int,
|
|
default=None,
|
|
help="process only the first n dataset rows",
|
|
)
|
|
ap.add_argument(
|
|
"--logit_precision",
|
|
default="bfloat16",
|
|
choices=["float32", "bfloat16", "float16"],
|
|
help="dtype for saved logits",
|
|
)
|
|
ap.add_argument(
|
|
"--model_name", required=True, help="model name to use for generating logits"
|
|
)
|
|
ap.add_argument(
|
|
"--output_path", required=True, help="path to save the processed dataset"
|
|
)
|
|
args = ap.parse_args()
|
|
|
|
# Load model and tokenizer
|
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
model = AutoModelForCausalLM.from_pretrained(args.model_name)
|
|
model = model.to(device)
|
|
model.eval()
|
|
tok = AutoTokenizer.from_pretrained(args.model_name)
|
|
|
|
# Load dataset
|
|
ds = load_and_process_dataset(
|
|
args.ds_name,
|
|
args.split,
|
|
add_negative_prompt=False,
|
|
add_repeat_prompt=False,
|
|
repeat_prob=0,
|
|
is_pretrain=False,
|
|
streaming=False,
|
|
num_proc=8,
|
|
)
|
|
|
|
# Limit samples if specified
|
|
if args.limit_samples:
|
|
ds = ds.select(range(min(args.limit_samples, len(ds))))
|
|
|
|
# Process dataset with logits
|
|
ds = ds.map(
|
|
lambda row: add_logits(row, model, tok, device, args),
|
|
batched=False,
|
|
desc="Adding logits to dataset",
|
|
)
|
|
|
|
# Save the processed dataset
|
|
ds.save_to_disk(args.output_path)
|
|
print(f"Dataset saved to {args.output_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|