skills/torchdrug/references/retrosynthesis.md
The official TorchDrug 0.2.1 retrosynthesis tutorial implements the G2Gs workflow:
This is a single-step reactant prediction pipeline. Multi-step route search,
commercial availability, conditions, yields, and cost optimization are not
provided by tasks.Retrosynthesis.
import torch
from torchdrug import datasets
reaction_dataset = datasets.USPTO50k(
"~/molecule-datasets/",
atom_feature="center_identification",
kekulize=True,
)
synthon_dataset = datasets.USPTO50k(
"~/molecule-datasets/",
as_synthon=True,
atom_feature="synthon_completion",
kekulize=True,
)
torch.manual_seed(1)
reaction_train, reaction_valid, reaction_test = reaction_dataset.split()
torch.manual_seed(1)
synthon_train, synthon_valid, synthon_test = synthon_dataset.split()
The repeated seed is required to align the reaction and synthon splits.
(reactants, product) pairs.(reactant, synthon) pairs.The official tutorial uses RGCN and three feature groups:
from torchdrug import core, models, tasks
reaction_model = models.RGCN(
input_dim=reaction_dataset.node_feature_dim,
hidden_dims=[256, 256, 256, 256, 256, 256],
num_relation=reaction_dataset.num_bond_type,
concat_hidden=True,
)
reaction_task = tasks.CenterIdentification(
reaction_model,
feature=("graph", "atom", "bond"),
)
reaction_optimizer = torch.optim.Adam(
reaction_task.parameters(),
lr=1e-3,
)
reaction_solver = core.Engine(
reaction_task,
reaction_train,
reaction_valid,
reaction_test,
reaction_optimizer,
batch_size=128,
)
reaction_solver.train(num_epoch=50)
reaction_solver.evaluate("valid")
reaction_solver.save("g2gs-reaction.pth")
CenterIdentification predicts reaction centers. Its
predict_synthon(batch, k=...) method returns top-k records containing synthons,
reaction centers, reaction metadata, and log likelihoods.
The official tutorial again uses RGCN:
synthon_model = models.RGCN(
input_dim=synthon_dataset.node_feature_dim,
hidden_dims=[256, 256, 256, 256, 256, 256],
num_relation=synthon_dataset.num_bond_type,
concat_hidden=True,
)
synthon_task = tasks.SynthonCompletion(
synthon_model,
feature=("graph",),
)
synthon_optimizer = torch.optim.Adam(
synthon_task.parameters(),
lr=1e-3,
)
synthon_solver = core.Engine(
synthon_task,
synthon_train,
synthon_valid,
synthon_test,
synthon_optimizer,
batch_size=128,
)
synthon_solver.train(num_epoch=10)
synthon_solver.evaluate("valid")
synthon_solver.save("g2gs-synthon.pth")
Do not substitute a GIN constructor copied from another implementation unless you intentionally redesign and validate the model.
Combine the tasks, not the raw models:
task = tasks.Retrosynthesis(
reaction_task,
synthon_task,
center_topk=2,
num_synthon_beam=5,
max_prediction=10,
)
If neither subtask has been attached to an Engine, preprocess them manually
before composition:
reaction_task.preprocess(reaction_train, None, None)
synthon_task.preprocess(synthon_train, None, None)
The Retrosynthesis constructor accepts:
center_identificationsynthon_completioncenter_topknum_synthon_beammax_predictionIt does not accept model=, synthon_model=, or a raw GNN pair.
The official workflow saves each subtask and loads checkpoints without optimizer state when composing the pipeline:
optimizer = torch.optim.Adam(task.parameters(), lr=1e-3)
solver = core.Engine(
task,
reaction_train,
reaction_valid,
reaction_test,
optimizer,
batch_size=32,
)
solver.load("g2gs-reaction.pth", load_optimizer=False)
solver.load("g2gs-synthon.pth", load_optimizer=False)
solver.evaluate("valid")
Keep model architectures, feature sets, and dataset metadata identical to the training run. Inspect missing or unexpected keys if adapting this pattern.
The end-to-end task returns packed reactant predictions and a count per input:
from torchdrug import data, utils
batch = data.graph_collate(reaction_valid[:4])
batch = utils.cuda(batch)
predictions, num_prediction = task.predict(batch)
top1_index = num_prediction.cumsum(0) - num_prediction
for index in top1_index.tolist():
reactants = predictions[index].connected_components()[0]
print(reactants.to_smiles())
Call utils.cuda only when the task/models are on CUDA. Keep the batch on CPU
for CPU execution.
The end-to-end task supports top-k exact-match metrics such as top-1, top-3, top-5, and top-10. Also inspect:
Top-k exact match against USPTO50k is not proof that a reaction is practical.
TorchDrug's tutorial predicts reactant connectivity. It does not directly predict:
Treat outputs as model proposals requiring forward validation, literature precedent, and expert chemistry review.
Reset the same seed immediately before each split().
Use the dedicated center_identification and synthon_completion atom features
and derive model dimensions from each corresponding dataset.
Pass reaction_task and synthon_task, not their models.
Construct each subtask's engine first or call preprocess() manually.