Skip to content

Commit ba696ea

Browse files
authored
feat: reduce computations in backprop of lfilter (#3831)
* feat: efficient backprop for a_coeffs * update lfilter docstring * doc: double quotation * use dafx paper for reference as it includes more details * revise docstring
1 parent 97ed7b3 commit ba696ea

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

docs/source/refs.bib

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,3 +633,11 @@ @article{forgione2021dynonet
633633
year={2021},
634634
publisher={Wiley Online Library}
635635
}
636+
637+
@inproceedings{ycy2024diffapf,
638+
title={Differentiable All-pole Filters for Time-varying Audio Systems},
639+
author={Chin-Yun Yu and Christopher Mitcheltree and Alistair Carson and Stefan Bilbao and Joshua D. Reiss and György Fazekas},
640+
booktitle={International Conference on Digital Audio Effects (DAFx)},
641+
year={2024},
642+
pages={345--352},
643+
}

src/libtorchaudio/lfilter.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ class DifferentiableIIR : public torch::autograd::Function<DifferentiableIIR> {
151151
auto a_coeffs_normalized = saved[1];
152152
auto y = saved[2];
153153

154-
int64_t n_batch = x.size(0);
155154
int64_t n_channel = x.size(1);
156155
int64_t n_order = a_coeffs_normalized.size(1);
157156

@@ -161,26 +160,24 @@ class DifferentiableIIR : public torch::autograd::Function<DifferentiableIIR> {
161160

162161
namespace F = torch::nn::functional;
163162

164-
if (a_coeffs_normalized.requires_grad()) {
165-
auto dyda = F::pad(
166-
DifferentiableIIR::apply(-y, a_coeffs_normalized),
167-
F::PadFuncOptions({n_order - 1, 0}));
168-
169-
da = F::conv1d(
170-
dyda.view({1, n_batch * n_channel, -1}),
171-
dy.reshape({n_batch * n_channel, 1, -1}),
172-
F::Conv1dFuncOptions().groups(n_batch * n_channel))
173-
.view({n_batch, n_channel, -1})
174-
.sum(0)
175-
.flip(1);
176-
}
163+
auto tmp =
164+
DifferentiableIIR::apply(dy.flip(2).contiguous(), a_coeffs_normalized)
165+
.flip(2);
177166

178167
if (x.requires_grad()) {
179-
dx =
180-
DifferentiableIIR::apply(dy.flip(2).contiguous(), a_coeffs_normalized)
181-
.flip(2);
168+
dx = tmp;
182169
}
183170

171+
if (a_coeffs_normalized.requires_grad()) {
172+
da = -torch::matmul(
173+
tmp.transpose(0, 1).reshape({n_channel, 1, -1}),
174+
F::pad(y, F::PadFuncOptions({n_order - 1, 0}))
175+
.unfold(2, n_order, 1)
176+
.transpose(0, 1)
177+
.reshape({n_channel, -1, n_order}))
178+
.squeeze(1)
179+
.flip(1);
180+
}
184181
return {dx, da};
185182
}
186183
};

src/torchaudio/functional/filtering.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,8 @@ def _lfilter_core(
999999

10001000
def lfilter(waveform: Tensor, a_coeffs: Tensor, b_coeffs: Tensor, clamp: bool = True, batching: bool = True) -> Tensor:
10011001
r"""Perform an IIR filter by evaluating difference equation, using differentiable implementation
1002-
developed independently by *Yu et al.* :cite:`ismir_YuF23` and *Forgione et al.* :cite:`forgione2021dynonet`.
1002+
developed separately by *Yu et al.* :cite:`ismir_YuF23` and *Forgione et al.* :cite:`forgione2021dynonet`.
1003+
The gradients of ``a_coeffs`` are computed based on a faster algorithm from :cite:`ycy2024diffapf`.
10031004
10041005
.. devices:: CPU CUDA
10051006

0 commit comments

Comments
 (0)