Repository navigation
Expand file tree
/
Copy pathgenerate.py
More file actions
88 lines (62 loc) · 3.55 KB
/
Copy pathgenerate.py
File metadata and controls
88 lines (62 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from typing import Optional, List, Dict
import torch
from torch import Tensor as _T
from transformers import AutoModelForCausalLM, AutoTokenizer
Conversations = List[List[Dict[str, str]]]
def format_conversation(user_prompts: List[str], system_prompt: Optional[str | List[str]] = None) -> Conversations:
if isinstance(system_prompt, str):
batch_messages = [[{"role": "system", "content": system_prompt}] for _ in user_prompts]
elif isinstance(system_prompt, list):
assert len(system_prompt) == len(user_prompts)
batch_messages = [[{"role": "system", "content": sp}] for sp in system_prompt]
else:
assert system_prompt is None
batch_messages = [[] for _ in user_prompts]
for bm, up in zip(batch_messages, user_prompts):
bm.append({"role": "user", "content": up})
return batch_messages
def transform_conversations(conversations: Conversations, prefiller: Optional[str | List[str]] = None) -> List[str]:
print('transform_conversations currently only for Deepseek models!')
output_conversations = []
if isinstance(prefiller, list):
assert len(prefiller) == len(conversations)
for c_i, conversation in enumerate(conversations):
output_conversation = ""
for message in conversation:
role = message["role"]
content = message["content"]
if role == "user":
output_conversation += f"<|User|> {content}\n"
elif role == "assistant" or role == "system": # Doing system prompts in first person, to make them look like OCR
output_conversation += f"<|Assistant|> {content}\n"
if isinstance(prefiller, list):
output_conversation += f"<|Assistant|> {prefiller[c_i]}\n"
elif isinstance(prefiller, str):
output_conversation += f"<|Assistant|> {prefiller}\n"
else:
assert output_conversation is None
output_conversations.append(output_conversation)
return output_conversations
def full_tokenize(prompts: List[str], tokenizer: AutoTokenizer, device: str, add_special_tokens: bool = True) -> List[Dict[str, torch.TensorType]]:
print('full_tokenize currently only for Deepseek models!')
return tokenizer(
prompts,
return_tensors="pt",
padding=True,
truncation=True,
add_special_tokens=add_special_tokens
).to(device)
def generate_text(model: AutoModelForCausalLM, prompt: str | List[str], system_prompt: str| List[str], prefiller: Optional[str| List[str]], tokenizer: AutoTokenizer, generation_config: dict, device: str):
if isinstance(prompt, str):
prompt = [prompt]
pre_transformed_conversation = format_conversation(user_prompts = prompt, system_prompt=system_prompt)
full_prompts = tokenizer.apply_chat_template(pre_transformed_conversation,
prefiller=prefiller,
tokenize=False,
add_generation_prompt=True # adds the <|Assistant|> token at the end
)
inputs = full_tokenize(prompts=full_prompts, tokenizer=tokenizer, device = device, add_special_tokens=False)
print('prompt tokens shape:', inputs['input_ids'].shape)
all_model_outputs = model.generate(**inputs, **generation_config)
decoded_responses = tokenizer.decode(all_model_outputs[0].squeeze())
return decoded_responses, all_model_outputs