Skip to content

Commit ad73e93

Browse files
Detach the tensors on batch-norm eval. (huggingface#1702)
* Detach the tensors on batch-norm eval. * Fix pyo3 bindings. * Black tweak. * Formatting. * Also update the pyo3-onnx formatting. * Apply black.
1 parent 13c6722 commit ad73e93

14 files changed

Lines changed: 117 additions & 27 deletions

File tree

candle-core/src/backprop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl Tensor {
175175
// the backprop graph of the backprop itself. This would be an issue for second order
176176
// derivatives but these are out of scope at the moment.
177177
let do_not_detach = CANDLE_GRAD_DO_NOT_DETACH.with(|b| *b);
178-
let grad = if do_not_detach { grad } else { grad.detach()? };
178+
let grad = if do_not_detach { grad } else { grad.detach() };
179179
if let Some(op) = node.op() {
180180
match op {
181181
Op::Binary(lhs, rhs, BinaryOp::Add) => {

candle-core/src/tensor.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,9 +1882,9 @@ impl Tensor {
18821882
/// this new node. The storage of this tensor is shared with the initial tensor.
18831883
///
18841884
/// If the tensor is already detached from the computation graph, the same tensor is returned.
1885-
pub fn detach(&self) -> Result<Tensor> {
1885+
pub fn detach(&self) -> Tensor {
18861886
if self.op.is_none() && !self.is_variable {
1887-
Ok(self.clone())
1887+
self.clone()
18881888
} else {
18891889
let tensor_ = Tensor_ {
18901890
id: TensorId::new(),
@@ -1895,7 +1895,7 @@ impl Tensor {
18951895
dtype: self.dtype,
18961896
device: self.device.clone(),
18971897
};
1898-
Ok(Tensor(Arc::new(tensor_)))
1898+
Tensor(Arc::new(tensor_))
18991899
}
19001900
}
19011901

candle-core/src/variable.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ impl Var {
107107
Ok(Self(inner))
108108
}
109109

110+
pub fn as_detached_tensor(&self) -> Tensor {
111+
self.0.detach()
112+
}
113+
110114
pub fn as_tensor(&self) -> &Tensor {
111115
&self.0
112116
}

candle-examples/examples/reinforcement-learning/ddpg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ impl DDPG<'_> {
411411
pub fn actions(&mut self, state: &Tensor) -> Result<f32> {
412412
let actions = self
413413
.actor
414-
.forward(&state.detach()?.unsqueeze(0)?)?
414+
.forward(&state.detach().unsqueeze(0)?)?
415415
.squeeze(0)?;
416416
let actions = if self.train {
417417
(actions + self.ou_noise.sample()?)?

candle-examples/examples/reinforcement-learning/policy_gradient.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub fn run() -> Result<()> {
7474
loop {
7575
let action = {
7676
let action_probs: Vec<f32> =
77-
softmax(&model.forward(&state.detach()?.unsqueeze(0)?)?, 1)?
77+
softmax(&model.forward(&state.detach().unsqueeze(0)?)?, 1)?
7878
.squeeze(0)?
7979
.to_vec1()?;
8080
weighted_sample(action_probs, &mut rng)? as i64
@@ -109,7 +109,7 @@ pub fn run() -> Result<()> {
109109

110110
let rewards = Tensor::from_vec(accumulate_rewards(&steps), batch_size, &Device::Cpu)?
111111
.to_dtype(DType::F32)?
112-
.detach()?;
112+
.detach();
113113

114114
let actions_mask = {
115115
let actions: Vec<i64> = steps.iter().map(|s| s.action).collect();
@@ -126,12 +126,12 @@ pub fn run() -> Result<()> {
126126
.unwrap()
127127
})
128128
.collect();
129-
Tensor::stack(&actions_mask, 0)?.detach()?
129+
Tensor::stack(&actions_mask, 0)?.detach()
130130
};
131131

132132
let states = {
133133
let states: Vec<Tensor> = steps.into_iter().map(|s| s.state).collect();
134-
Tensor::stack(&states, 0)?.detach()?
134+
Tensor::stack(&states, 0)?.detach()
135135
};
136136

137137
let log_probs = actions_mask

candle-nn/src/batch_norm.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,19 @@ impl BatchNorm {
262262
let target_shape = target_shape.as_slice();
263263

264264
let x = x
265-
.broadcast_sub(&self.running_mean.as_tensor().reshape(target_shape)?)?
265+
.broadcast_sub(
266+
&self
267+
.running_mean
268+
.as_detached_tensor()
269+
.reshape(target_shape)?,
270+
)?
266271
.broadcast_div(
267-
&(self.running_var.as_tensor().reshape(target_shape)? + self.eps)?.sqrt()?,
272+
&(self
273+
.running_var
274+
.as_detached_tensor()
275+
.reshape(target_shape)?
276+
+ self.eps)?
277+
.sqrt()?,
268278
)?;
269279

270280
match &self.weight_and_bias {

0 commit comments

Comments
 (0)