1import re
2
3ATOM_TOKENS = ["Ag","Al","As","Au","Bi","Br","Ca","Cl","Cr","Cu","Fe","Ga","Gd","Ge","Hg","Li","Mg","Mo","Na","Pt","Ru","Sb","Se","Si","Sn","Sc","B","C","F","H","I","K","M","N","O","P","S","V","W","Z","c","e","n","o","p","s"]
4
5SMI_REGEX_PATTERN = (
6 r"(\[|\]|\(|\)|\.|=|#|-|\+|\\|\/|:|~|@|\?|>>?|\*|\$|\%[0-9]{2}|[0-9]|"
7 + "|".join(ATOM_TOKENS)
8 + ")"
9)
10smi_regex = re.compile(SMI_REGEX_PATTERN)
11
12def isolate_sequence(s):
13 return "".join(["<sm_" + tok + ">" for tok in smi_regex.findall(s)])
14
15def deisolate_sequence(s):
16 s = re.sub("[<\s]?sm_[^>]+>", lambda matchobj: matchobj.group(0)[4:-1], s).strip()
17 return s
18
19# Prepare prompts
20product_smiles = "N1C(=O)Cc2ccc(Nc3ccc(N[C@@H]4CN(C(c5cc(NCCO)ccc5)=O)C[C@@H]4c4scnc4)cc3)cc21"
21prompt = f"What are the possible reactants that could have formed the following product <smiles>{isolate_sequence(product_smiles)}</smiles>? Wrap an answer in <smiles> tags/think"
22
23input_ids = tokenizer.apply_chat_template(
24 [
25 {"role": "system", "content": "You are a helpful assistant in chemistry and biology."},
26 {"role": "user", "content": prompt}
27 ],
28 add_generation_prompt=True,
29 return_tensors="pt",
30 tokenize=True,
31)['input_ids'].to(model.device)
32
33# Generate answer
34output = model.generate(
35 input_ids,
36 do_sample=True,
37 temperature=0.3,
38 min_p=0.15,
39 repetition_penalty=1.05,
40 max_new_tokens=512,
41)
42
43for out in output:
44 out = tokenizer.decode(out, skip_special_tokens=False)
45 answer_part = out.split('</think>')[1].split('<smiles>')[1].split('</smiles>')[0]
46 answer_part = deisolate_sequence(answer_part)
47 print('Reactants: ', answer_part)