Fix gradient: use torch.empty + copy_ to escape inference tensor flag

.clone() on an inference tensor inherits the inference flag even inside
inference_mode(False). torch.empty() inside that context creates a true
normal tensor; copy_() fills it from the inference tensor without flag
inheritance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-05-29 04:38:24 +03:00
co-authored by Claude Sonnet 4.6
parent 4dd8fcd674
commit 55d905e6ee
+8 -3
View File
@@ -74,11 +74,16 @@ class OnlineValueFunction(nn.Module):
def gradient(self, conditioning):
"""∂reward/∂conditioning — same shape as input."""
mlp_device = next(self.parameters()).device
orig_device = conditioning.device
with torch.inference_mode(False), torch.enable_grad():
c_in = conditioning.detach().clone().float().to(mlp_device).requires_grad_(True)
reward = self.forward(self.compress(c_in).unsqueeze(0))
# new_empty inside inference_mode(False) creates a normal (non-inference) tensor.
# copy_ fills it from the inference tensor without inheriting the flag.
c_fresh = torch.empty(conditioning.shape, dtype=torch.float32, device=mlp_device)
c_fresh.copy_(conditioning)
c_fresh.requires_grad_(True)
reward = self.forward(self.compress(c_fresh).unsqueeze(0))
reward.backward()
return c_in.grad.to(conditioning.device, conditioning.dtype)
return c_fresh.grad.to(orig_device, conditioning.dtype)
def is_ready(self):
return len(self.buffer_c) >= self.MIN_SAMPLES