DianShi-RetroStepLM-Direct

arXiv

DianShi-RetroStepLM-Direct (RetroStepLM-Direct for short) is a single-step retrosynthesis model from the paper Reaction precedents extend retrosynthetic prediction beyond training coverage. Given a target product, it predicts a set of precursor molecules directly from the target structure alone โ€” there is no retrieval and no reaction-template lookup at inference time.

Model details

Architecture Qwen3ForCausalLM (Qwen3 dense, model_type: qwen3)
Parameters ~4B
Layers / hidden / heads 36 / 2560 / 32 (8 KV heads, head_dim 128)
Intermediate size 9728
Vocab size 151936
Context length 40960 (rope_theta 1000000)
Dtype bfloat16
tie_word_embeddings true
EOS / PAD token id 151645 / 151643
Weights 2 safetensors shards (~7.6 GB)
Transformers >= 4.57.6 (config transformers_version)

Method

Input. The system prompt from prompt_sft_intermediate_label.txt plus a user message The product SMILES is <SMILES>., where the SMILES is written atom-wise (tokens separated by spaces).

Output. The intermediate-label target sequence: synthon SMILES, then leaving groups, then the final reactant set, which is additionally enclosed in <answer>...</answer>; multiple reactants are separated by .. Only the final reactant set is scored; the intermediate fields are not scored independently.

Training. Full-parameter supervised fine-tuning from Qwen3-4B-Base with intermediate-label supervision, on the 2,712,259 pre-2025 reactions of DianShi-PatentRxnStep-Train-Full. The synthon and leaving-group labels are derived from atom-mapped reactions.

Usage

The model is run the same way as in the DianShi-RetroStepLM single-step pipeline: vLLM beam search (beam width 10, max 1024 new tokens).

On enable_thinking. Use enable_thinking=True, as below โ€” this is the setting the reported results were produced with, and it is the default in the repository's evaluation scripts and in the multi-step frameworks. The model emits its intermediate labels inside <think>...</think> before the <answer> tag, because that is the training format. The flag does not switch the reasoning on or off: it only controls whether the chat template pre-seeds an empty <think>\n\n</think> block after the generation prompt. Either way the answer is read from the <answer> tag, so the extraction below is unaffected.

With the DianShi-RetroStepLM repository

git clone https://github.com/DianShiGroup/DianShi-RetroStepLM.git
cd DianShi-RetroStepLM
pip install -r requirements.txt

# Build the Test-2025 evaluation set from the source data in the repository.
scripts/build_model_tests.sh --datasets test_2025 --splits test

scripts/infer_beam_search.sh \
  --model-path DianShiGroup/DianShi-RetroStepLM-Direct \
  --data-path model_tests/test_2025/intermediate_label/testset_intermediate_label_new_cached

This runs beam search and then prints Top-1/3/5/10 exact-match accuracy. See the repository README for Test-2001-2024, USPTO-50K and the other build options.

Standalone

import re

from vllm import LLM
from vllm.sampling_params import BeamSearchParams

SYSTEM = """You are an expert chemist specializing in retrosynthetic analysis. Given the SMILES representation of a product molecule, your task is to predict the SMILES of the reactants required to synthesize it.
Input:
The product SMILES.
Task requirements (step-by-step reasoning is required):
1.Infer the synthons based on the structure of the product.
2.Identify the corresponding leaving groups associated with these synthons.
3.Reconstruct the most plausible reactant molecules by combining the synthons with appropriate leaving groups.
You must explicitly show your reasoning step by step for each of the above stages.
Please output the reasoning process, and write the final reactant SMILES strictly in the following format:
<answer>REACTANT_SMILES</answer>
If multiple reactants are required, separate their SMILES using a period (.)."""

ANSWER_RE = re.compile(r"<answer>(.*?)</answer>", re.IGNORECASE | re.DOTALL)


def extract_reactants(text: str) -> str | None:
    """Last non-empty <answer> value, with the atom-wise spaces removed."""
    for match in reversed(ANSWER_RE.findall(text)):
        answer = re.sub(r"\s+", "", match)
        if answer:
            return answer
    return None


llm = LLM(model="DianShiGroup/DianShi-RetroStepLM-Direct")
tok = llm.get_tokenizer()

# Atom-wise SMILES of CC(=O)Oc1ccccc1C(=O)O
messages = [
    {"role": "system", "content": SYSTEM},
    {"role": "user", "content": "The product SMILES is C C ( = O ) O c 1 c c c c c 1 C ( = O ) O ."},
]
prompt = tok.apply_chat_template(
    messages, tokenize=False, add_generation_prompt=True, enable_thinking=True
)
outputs = llm.beam_search([{"prompt": prompt}], params=BeamSearchParams(beam_width=10, max_tokens=1024))
for seq in outputs[0].sequences:
    reactants = extract_reactants(seq.text)
    if reactants:
        print(seq.cum_logprob, reactants)

seq.text holds the full intermediate-label sequence plus the <answer> tag, so read the prediction through extract_reactants rather than printing seq.text directly. It mirrors what the repository's evaluator does: take the last <answer> value and strip whitespace, which also joins the atom-wise tokens back into a plain SMILES. A beam that produced no complete tag yields None and is skipped above. For the example product the reactants print as CC(=O)OC(C)=O.OC(=O)c1ccccc1O โ€” one dot-separated mixture per beam.

Convert plain SMILES to the atom-wise input format with transform_messages from dianshi_retrosteplm.data.smiles_atomwise. The evaluator canonicalizes reactants with RDKit and ignores reactant order.

Citation

If you use this model, please cite:

@misc{sun2026reactionprecedents,
  title         = {Reaction precedents extend retrosynthetic prediction beyond training coverage},
  author        = {Jiaxing Sun and Xuli Shen and Jiang Wu and Ruiyi Ding and Ruikang Zhang and Xiao An and Xibao Li and Yubin Wang and Xingjian Wei and Yinfan Wang and Yu Liu and Lingli Ge and Xi Xue and Xiaojian Wang and Lijun Wu and Chang-Yu Hsieh and Yuqiang Li and Bowen Zhou and Dahua Lin and Conghui He},
  year          = {2026},
  eprint        = {2610.40249},
  archivePrefix = {arXiv},
  primaryClass  = {cs.AI},
  doi           = {10.48550/arXiv.2610.40249},
  url           = {https://arxiv.org/abs/2610.40249}
}

Please also cite the upstream works used by the multi-step frameworks (RetroAgent, Retro-R1, AOT*, rdchiral, SCScore); bibtex entries are in the component READMEs.

Downloads last month
222
Safetensors
Model size
196k params
Tensor type
BF16
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for DianShiGroup/DianShi-RetroStepLM-Direct

Finetuned
(533)
this model
Quantizations
1 model

Paper for DianShiGroup/DianShi-RetroStepLM-Direct