Один узел используется дважды
Пусть u=x²,L=u+u,x=2. Forward даёт u=4,L=8. Add передаёт в grad(u) два вклада1, итого2. Затем квадрат передаёт grad(x)=2×2x=8. При перезаписи grad(u)=1 вместо += получится4: forward останется правильным, backward сломается.
Topological sort посещает каждый узел один раз, а edges сохраняют кратность. Удалять повторные contributions нельзя. В batch MLP общий параметр тоже влияет на несколько примеров; его gradient суммирует все эти пути с учётом усреднения loss.
Исследовать. Создайте L=(x+x)*(x+x). Сравните вариант с общим u=x+x и вариант с разными u,v, содержащими одинаковые выражения. Правильная derivative8x совпадёт, хотя число операций различается.
Повторный backward. Некоторые frameworks накапливают gradients между batches. Наш engine перед полным backward обнуляет все достижимые узлы: второй вызов повторяет результат, не удваивает его. Это явное соглашение учебной реализации, не универсальный контракт PyTorch.