acids-cc 3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- acids_cc-3.0/PKG-INFO +220 -0
- acids_cc-3.0/README.md +195 -0
- acids_cc-3.0/acids_cc.egg-info/PKG-INFO +220 -0
- acids_cc-3.0/acids_cc.egg-info/SOURCES.txt +25 -0
- acids_cc-3.0/acids_cc.egg-info/dependency_links.txt +1 -0
- acids_cc-3.0/acids_cc.egg-info/requires.txt +11 -0
- acids_cc-3.0/acids_cc.egg-info/top_level.txt +1 -0
- acids_cc-3.0/cached_conv/__init__.py +200 -0
- acids_cc-3.0/cached_conv/conv_1d.py +312 -0
- acids_cc-3.0/cached_conv/conv_2d.py +213 -0
- acids_cc-3.0/cached_conv/conv_3d.py +184 -0
- acids_cc-3.0/cached_conv/upsample.py +176 -0
- acids_cc-3.0/cached_conv/utils.py +133 -0
- acids_cc-3.0/cached_conv/variants.py +185 -0
- acids_cc-3.0/pyproject.toml +33 -0
- acids_cc-3.0/setup.cfg +4 -0
- acids_cc-3.0/tests/test_align_branches.py +186 -0
- acids_cc-3.0/tests/test_audio.py +477 -0
- acids_cc-3.0/tests/test_conv.py +76 -0
- acids_cc-3.0/tests/test_conv_3d.py +230 -0
- acids_cc-3.0/tests/test_conv_t.py +68 -0
- acids_cc-3.0/tests/test_device.py +84 -0
- acids_cc-3.0/tests/test_group_norm.py +48 -0
- acids_cc-3.0/tests/test_padding.py +187 -0
- acids_cc-3.0/tests/test_script.py +65 -0
- acids_cc-3.0/tests/test_sequential.py +71 -0
- acids_cc-3.0/tests/test_variants.py +333 -0
acids_cc-3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: acids-cc
|
|
3
|
+
Version: 3.0
|
|
4
|
+
Summary: Cached convolution layers for real-time streaming inference with PyTorch (upgrade of Caillon's cached_conv 2021 package)
|
|
5
|
+
Author: Axel Chemla--Romeu-Santos, Nils Demerlé
|
|
6
|
+
Author-email: ACIDS <acids.paris@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Documentation, https://cached-conv.readthedocs.io
|
|
9
|
+
Project-URL: Repository, https://github.com/acids-ircam/acids-cc
|
|
10
|
+
Keywords: deep learning,pytorch,convolution,streaming,real-time
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: torch>1.8
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest; extra == "dev"
|
|
19
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
20
|
+
Provides-Extra: docs
|
|
21
|
+
Requires-Dist: sphinx>=7; extra == "docs"
|
|
22
|
+
Requires-Dist: furo; extra == "docs"
|
|
23
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
24
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
25
|
+
|
|
26
|
+
# cached_conv
|
|
27
|
+
|
|
28
|
+
[](https://acids-cc.readthedocs.io/en/latest/)
|
|
29
|
+
[](https://github.com/acids-ircam/acids-cc/actions/workflows/docs.yml)
|
|
30
|
+
|
|
31
|
+
**Cached convolutions for real-time streaming inference with PyTorch.**
|
|
32
|
+
|
|
33
|
+
`cached_conv` provides drop-in replacements for PyTorch convolutional layers
|
|
34
|
+
that process a signal **block by block** and give the same result as
|
|
35
|
+
processing it all at once. Each layer keeps the end of the previous block in
|
|
36
|
+
an internal cache, used instead of zero padding at block boundaries.
|
|
37
|
+
|
|
38
|
+
The same model definition can be built in two modes:
|
|
39
|
+
|
|
40
|
+
- **eager** (default): regular layers, for training on full signals;
|
|
41
|
+
- **cached**: streaming layers, for real-time inference, e.g. once exported
|
|
42
|
+
with TorchScript.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- 1D, 2D and 3D convolutions and transposed convolutions. Time is the last
|
|
47
|
+
axis, the only one that is streamed.
|
|
48
|
+
- `"same"`, `"causal"` and `"anticausal"` padding, computed from the kernel
|
|
49
|
+
size and dilation.
|
|
50
|
+
- Strides, dilation and groups.
|
|
51
|
+
- Latency tracking: every layer exposes its `cumulative_delay`, which
|
|
52
|
+
accumulates across a whole model.
|
|
53
|
+
- Windowed convolutions: the kernel is multiplied by a window before
|
|
54
|
+
convolving.
|
|
55
|
+
- StyleGAN 2-modulated convolutions. The style can change from one block to
|
|
56
|
+
the next.
|
|
57
|
+
- Streamable upsampling (nearest and linear), group normalization and
|
|
58
|
+
alignment of parallel branches.
|
|
59
|
+
- TorchScript export, on CPU, CUDA and MPS.
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install git+https://github.com/acids-ircam/acids-cc.git
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Requires Python ≥ 3.9 and PyTorch ≥ 1.9.
|
|
68
|
+
|
|
69
|
+
## Quick start
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import torch
|
|
73
|
+
import cached_conv as cc
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def build_model():
|
|
77
|
+
conv1 = cc.Conv1d(1, 16, 5, padding="same")
|
|
78
|
+
conv2 = cc.Conv1d(16, 1, 5, padding="same",
|
|
79
|
+
cumulative_delay=conv1.cumulative_delay)
|
|
80
|
+
return cc.CachedSequential(conv1, conv2)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# 1. train in eager mode (the default)
|
|
84
|
+
model = build_model()
|
|
85
|
+
|
|
86
|
+
# 2. build the same model with cached layers, and load the trained weights
|
|
87
|
+
cc.use_cached_conv(True)
|
|
88
|
+
streaming_model = build_model()
|
|
89
|
+
streaming_model.load_state_dict(model.state_dict())
|
|
90
|
+
|
|
91
|
+
# 3. process a stream block by block
|
|
92
|
+
stream = torch.randn(1, 1, 8192)
|
|
93
|
+
y = torch.cat([streaming_model(block) for block in stream.split(512, -1)], -1)
|
|
94
|
+
|
|
95
|
+
# the output is delayed by the model's latency, in samples. The edges differ:
|
|
96
|
+
# before the signal starts, eager layers see zero padding, cached layers see
|
|
97
|
+
# the previous layer's response to silence
|
|
98
|
+
delay = streaming_model.cumulative_delay
|
|
99
|
+
offline = model(stream)
|
|
100
|
+
assert torch.allclose(y[..., 2 * delay:], offline[..., delay:-delay],
|
|
101
|
+
atol=1e-5)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Cached layers can't look into the future: centered convolutions delay their
|
|
105
|
+
output instead. Pass each layer's `cumulative_delay` to the next one so that
|
|
106
|
+
the total latency is tracked correctly. With `padding="causal"` everywhere,
|
|
107
|
+
the latency only comes from strides.
|
|
108
|
+
|
|
109
|
+
## Layers
|
|
110
|
+
|
|
111
|
+
The layers exposed by the package (`cc.Conv1d`, `cc.Upsample2d`...) are
|
|
112
|
+
factories: they return a regular or a cached layer, depending on
|
|
113
|
+
`cc.use_cached_conv` at construction time.
|
|
114
|
+
|
|
115
|
+
| | 1D | 2D | 3D |
|
|
116
|
+
| --- | --- | --- | --- |
|
|
117
|
+
| Convolution | `Conv1d` | `Conv2d` | `Conv3d` |
|
|
118
|
+
| Transposed convolution | `ConvTranspose1d` | `ConvTranspose2d` | `ConvTranspose3d` |
|
|
119
|
+
| Windowed convolution | `WindowedConv1d` | `WindowedConv2d` | `WindowedConv3d` |
|
|
120
|
+
| Modulated convolution | `ModulatedConv1d` | `ModulatedConv2d` | `ModulatedConv3d` |
|
|
121
|
+
| Upsampling | `Upsample1d` | `Upsample2d` | `Upsample3d` |
|
|
122
|
+
| Branch alignment | `AlignBranches1d` | `AlignBranches2d` | `AlignBranches3d` |
|
|
123
|
+
| Group normalization | `CachedGroupNorm1d` | `CachedGroupNorm2d` | `CachedGroupNorm3d` |
|
|
124
|
+
|
|
125
|
+
Inputs are shaped `(batch, channels, time)`,
|
|
126
|
+
`(batch, channels, height, time)` and `(batch, channels, depth, height, time)`.
|
|
127
|
+
In 2D and 3D, `padding` sets the mode along time; the other axes are always
|
|
128
|
+
padded "same".
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# encoder / decoder; the transposed kernel size along time must be
|
|
132
|
+
# stride + 2 * padding
|
|
133
|
+
down = cc.Conv1d(16, 16, 4, stride=2, padding="same")
|
|
134
|
+
up = cc.ConvTranspose1d(16, 16, 4, stride=2, padding=1,
|
|
135
|
+
cumulative_delay=down.cumulative_delay)
|
|
136
|
+
|
|
137
|
+
# spectrogram convolution (frequency, time), windowed along time only
|
|
138
|
+
conv = cc.WindowedConv2d(1, 16, (3, 33), window=(None, "hann"))
|
|
139
|
+
|
|
140
|
+
# StyleGAN 2 modulation
|
|
141
|
+
mod = cc.ModulatedConv1d(16, 32, 3, padding="same", style_dim=64)
|
|
142
|
+
y = mod(torch.randn(2, 16, 512), torch.randn(2, 64))
|
|
143
|
+
|
|
144
|
+
# upsampling by an integer factor along time
|
|
145
|
+
upsample = cc.Upsample1d(2, mode="linear",
|
|
146
|
+
cumulative_delay=down.cumulative_delay)
|
|
147
|
+
|
|
148
|
+
# residual connection: delays the identity branch to match the convolution
|
|
149
|
+
conv = cc.Conv1d(16, 16, 3, padding="same")
|
|
150
|
+
residual = cc.AlignBranches1d(conv, torch.nn.Identity(),
|
|
151
|
+
delays=[conv.cumulative_delay, 0])
|
|
152
|
+
y_conv, y_identity = residual(torch.randn(1, 16, 512))
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Exporting with TorchScript
|
|
156
|
+
|
|
157
|
+
Caches are allocated on the first call. Run the cached model once before
|
|
158
|
+
scripting it:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
cc.use_cached_conv(True)
|
|
162
|
+
model = build_model().eval()
|
|
163
|
+
|
|
164
|
+
with torch.no_grad():
|
|
165
|
+
model(torch.zeros(1, 1, 512))
|
|
166
|
+
|
|
167
|
+
torch.jit.script(model).save("model.ts")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Caches have room for `max_batch_size` streams (a layer argument). Block
|
|
171
|
+
lengths must be divisible by the model's total stride.
|
|
172
|
+
|
|
173
|
+
## Testing
|
|
174
|
+
|
|
175
|
+
`cc.test_equal` checks that a model gives the same output when streamed as
|
|
176
|
+
when processed offline:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
assert cc.test_equal(build_model, torch.randn(1, 1, 4096))
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
To run the library's test suite, on all available devices:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pip install -e ".[dev]"
|
|
186
|
+
pytest tests
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
To run it against several Python / PyTorch versions with
|
|
190
|
+
[uv](https://docs.astral.sh/uv/):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
./test_versions.sh -p "3.9 3.12" -t "1.13 2.0 latest"
|
|
194
|
+
./test_versions.sh --lowest # oldest torch for each Python version
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`tests/test_audio.py` also writes audio examples to `tests/audio_outputs/`
|
|
198
|
+
(waveforms in 1D, spectrograms in 2D / 3D), in eager and streaming modes.
|
|
199
|
+
|
|
200
|
+
## Documentation
|
|
201
|
+
|
|
202
|
+
The full documentation is on
|
|
203
|
+
[cached-conv.readthedocs.io](https://cached-conv.readthedocs.io). To build it
|
|
204
|
+
locally:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pip install -r docs/requirements.txt
|
|
208
|
+
sphinx-build -b html docs docs/_build/html
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Credits
|
|
212
|
+
|
|
213
|
+
Developed at [ACIDS](https://acids.ircam.fr) (IRCAM) by Axel
|
|
214
|
+
Chemla--Romeu-Santos and Nils Demerlé. Upgrade of the original
|
|
215
|
+
[cached_conv](https://github.com/acids-ircam/cached_conv) package by Antoine
|
|
216
|
+
Caillon (2021).
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
acids_cc-3.0/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# cached_conv
|
|
2
|
+
|
|
3
|
+
[](https://acids-cc.readthedocs.io/en/latest/)
|
|
4
|
+
[](https://github.com/acids-ircam/acids-cc/actions/workflows/docs.yml)
|
|
5
|
+
|
|
6
|
+
**Cached convolutions for real-time streaming inference with PyTorch.**
|
|
7
|
+
|
|
8
|
+
`cached_conv` provides drop-in replacements for PyTorch convolutional layers
|
|
9
|
+
that process a signal **block by block** and give the same result as
|
|
10
|
+
processing it all at once. Each layer keeps the end of the previous block in
|
|
11
|
+
an internal cache, used instead of zero padding at block boundaries.
|
|
12
|
+
|
|
13
|
+
The same model definition can be built in two modes:
|
|
14
|
+
|
|
15
|
+
- **eager** (default): regular layers, for training on full signals;
|
|
16
|
+
- **cached**: streaming layers, for real-time inference, e.g. once exported
|
|
17
|
+
with TorchScript.
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- 1D, 2D and 3D convolutions and transposed convolutions. Time is the last
|
|
22
|
+
axis, the only one that is streamed.
|
|
23
|
+
- `"same"`, `"causal"` and `"anticausal"` padding, computed from the kernel
|
|
24
|
+
size and dilation.
|
|
25
|
+
- Strides, dilation and groups.
|
|
26
|
+
- Latency tracking: every layer exposes its `cumulative_delay`, which
|
|
27
|
+
accumulates across a whole model.
|
|
28
|
+
- Windowed convolutions: the kernel is multiplied by a window before
|
|
29
|
+
convolving.
|
|
30
|
+
- StyleGAN 2-modulated convolutions. The style can change from one block to
|
|
31
|
+
the next.
|
|
32
|
+
- Streamable upsampling (nearest and linear), group normalization and
|
|
33
|
+
alignment of parallel branches.
|
|
34
|
+
- TorchScript export, on CPU, CUDA and MPS.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install git+https://github.com/acids-ircam/acids-cc.git
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Requires Python ≥ 3.9 and PyTorch ≥ 1.9.
|
|
43
|
+
|
|
44
|
+
## Quick start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import torch
|
|
48
|
+
import cached_conv as cc
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def build_model():
|
|
52
|
+
conv1 = cc.Conv1d(1, 16, 5, padding="same")
|
|
53
|
+
conv2 = cc.Conv1d(16, 1, 5, padding="same",
|
|
54
|
+
cumulative_delay=conv1.cumulative_delay)
|
|
55
|
+
return cc.CachedSequential(conv1, conv2)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# 1. train in eager mode (the default)
|
|
59
|
+
model = build_model()
|
|
60
|
+
|
|
61
|
+
# 2. build the same model with cached layers, and load the trained weights
|
|
62
|
+
cc.use_cached_conv(True)
|
|
63
|
+
streaming_model = build_model()
|
|
64
|
+
streaming_model.load_state_dict(model.state_dict())
|
|
65
|
+
|
|
66
|
+
# 3. process a stream block by block
|
|
67
|
+
stream = torch.randn(1, 1, 8192)
|
|
68
|
+
y = torch.cat([streaming_model(block) for block in stream.split(512, -1)], -1)
|
|
69
|
+
|
|
70
|
+
# the output is delayed by the model's latency, in samples. The edges differ:
|
|
71
|
+
# before the signal starts, eager layers see zero padding, cached layers see
|
|
72
|
+
# the previous layer's response to silence
|
|
73
|
+
delay = streaming_model.cumulative_delay
|
|
74
|
+
offline = model(stream)
|
|
75
|
+
assert torch.allclose(y[..., 2 * delay:], offline[..., delay:-delay],
|
|
76
|
+
atol=1e-5)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Cached layers can't look into the future: centered convolutions delay their
|
|
80
|
+
output instead. Pass each layer's `cumulative_delay` to the next one so that
|
|
81
|
+
the total latency is tracked correctly. With `padding="causal"` everywhere,
|
|
82
|
+
the latency only comes from strides.
|
|
83
|
+
|
|
84
|
+
## Layers
|
|
85
|
+
|
|
86
|
+
The layers exposed by the package (`cc.Conv1d`, `cc.Upsample2d`...) are
|
|
87
|
+
factories: they return a regular or a cached layer, depending on
|
|
88
|
+
`cc.use_cached_conv` at construction time.
|
|
89
|
+
|
|
90
|
+
| | 1D | 2D | 3D |
|
|
91
|
+
| --- | --- | --- | --- |
|
|
92
|
+
| Convolution | `Conv1d` | `Conv2d` | `Conv3d` |
|
|
93
|
+
| Transposed convolution | `ConvTranspose1d` | `ConvTranspose2d` | `ConvTranspose3d` |
|
|
94
|
+
| Windowed convolution | `WindowedConv1d` | `WindowedConv2d` | `WindowedConv3d` |
|
|
95
|
+
| Modulated convolution | `ModulatedConv1d` | `ModulatedConv2d` | `ModulatedConv3d` |
|
|
96
|
+
| Upsampling | `Upsample1d` | `Upsample2d` | `Upsample3d` |
|
|
97
|
+
| Branch alignment | `AlignBranches1d` | `AlignBranches2d` | `AlignBranches3d` |
|
|
98
|
+
| Group normalization | `CachedGroupNorm1d` | `CachedGroupNorm2d` | `CachedGroupNorm3d` |
|
|
99
|
+
|
|
100
|
+
Inputs are shaped `(batch, channels, time)`,
|
|
101
|
+
`(batch, channels, height, time)` and `(batch, channels, depth, height, time)`.
|
|
102
|
+
In 2D and 3D, `padding` sets the mode along time; the other axes are always
|
|
103
|
+
padded "same".
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
# encoder / decoder; the transposed kernel size along time must be
|
|
107
|
+
# stride + 2 * padding
|
|
108
|
+
down = cc.Conv1d(16, 16, 4, stride=2, padding="same")
|
|
109
|
+
up = cc.ConvTranspose1d(16, 16, 4, stride=2, padding=1,
|
|
110
|
+
cumulative_delay=down.cumulative_delay)
|
|
111
|
+
|
|
112
|
+
# spectrogram convolution (frequency, time), windowed along time only
|
|
113
|
+
conv = cc.WindowedConv2d(1, 16, (3, 33), window=(None, "hann"))
|
|
114
|
+
|
|
115
|
+
# StyleGAN 2 modulation
|
|
116
|
+
mod = cc.ModulatedConv1d(16, 32, 3, padding="same", style_dim=64)
|
|
117
|
+
y = mod(torch.randn(2, 16, 512), torch.randn(2, 64))
|
|
118
|
+
|
|
119
|
+
# upsampling by an integer factor along time
|
|
120
|
+
upsample = cc.Upsample1d(2, mode="linear",
|
|
121
|
+
cumulative_delay=down.cumulative_delay)
|
|
122
|
+
|
|
123
|
+
# residual connection: delays the identity branch to match the convolution
|
|
124
|
+
conv = cc.Conv1d(16, 16, 3, padding="same")
|
|
125
|
+
residual = cc.AlignBranches1d(conv, torch.nn.Identity(),
|
|
126
|
+
delays=[conv.cumulative_delay, 0])
|
|
127
|
+
y_conv, y_identity = residual(torch.randn(1, 16, 512))
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Exporting with TorchScript
|
|
131
|
+
|
|
132
|
+
Caches are allocated on the first call. Run the cached model once before
|
|
133
|
+
scripting it:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
cc.use_cached_conv(True)
|
|
137
|
+
model = build_model().eval()
|
|
138
|
+
|
|
139
|
+
with torch.no_grad():
|
|
140
|
+
model(torch.zeros(1, 1, 512))
|
|
141
|
+
|
|
142
|
+
torch.jit.script(model).save("model.ts")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Caches have room for `max_batch_size` streams (a layer argument). Block
|
|
146
|
+
lengths must be divisible by the model's total stride.
|
|
147
|
+
|
|
148
|
+
## Testing
|
|
149
|
+
|
|
150
|
+
`cc.test_equal` checks that a model gives the same output when streamed as
|
|
151
|
+
when processed offline:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
assert cc.test_equal(build_model, torch.randn(1, 1, 4096))
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
To run the library's test suite, on all available devices:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pip install -e ".[dev]"
|
|
161
|
+
pytest tests
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
To run it against several Python / PyTorch versions with
|
|
165
|
+
[uv](https://docs.astral.sh/uv/):
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
./test_versions.sh -p "3.9 3.12" -t "1.13 2.0 latest"
|
|
169
|
+
./test_versions.sh --lowest # oldest torch for each Python version
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`tests/test_audio.py` also writes audio examples to `tests/audio_outputs/`
|
|
173
|
+
(waveforms in 1D, spectrograms in 2D / 3D), in eager and streaming modes.
|
|
174
|
+
|
|
175
|
+
## Documentation
|
|
176
|
+
|
|
177
|
+
The full documentation is on
|
|
178
|
+
[cached-conv.readthedocs.io](https://cached-conv.readthedocs.io). To build it
|
|
179
|
+
locally:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
pip install -r docs/requirements.txt
|
|
183
|
+
sphinx-build -b html docs docs/_build/html
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Credits
|
|
187
|
+
|
|
188
|
+
Developed at [ACIDS](https://acids.ircam.fr) (IRCAM) by Axel
|
|
189
|
+
Chemla--Romeu-Santos and Nils Demerlé. Upgrade of the original
|
|
190
|
+
[cached_conv](https://github.com/acids-ircam/cached_conv) package by Antoine
|
|
191
|
+
Caillon (2021).
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
MIT
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: acids-cc
|
|
3
|
+
Version: 3.0
|
|
4
|
+
Summary: Cached convolution layers for real-time streaming inference with PyTorch (upgrade of Caillon's cached_conv 2021 package)
|
|
5
|
+
Author: Axel Chemla--Romeu-Santos, Nils Demerlé
|
|
6
|
+
Author-email: ACIDS <acids.paris@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Documentation, https://cached-conv.readthedocs.io
|
|
9
|
+
Project-URL: Repository, https://github.com/acids-ircam/acids-cc
|
|
10
|
+
Keywords: deep learning,pytorch,convolution,streaming,real-time
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: torch>1.8
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest; extra == "dev"
|
|
19
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
20
|
+
Provides-Extra: docs
|
|
21
|
+
Requires-Dist: sphinx>=7; extra == "docs"
|
|
22
|
+
Requires-Dist: furo; extra == "docs"
|
|
23
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
24
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
25
|
+
|
|
26
|
+
# cached_conv
|
|
27
|
+
|
|
28
|
+
[](https://acids-cc.readthedocs.io/en/latest/)
|
|
29
|
+
[](https://github.com/acids-ircam/acids-cc/actions/workflows/docs.yml)
|
|
30
|
+
|
|
31
|
+
**Cached convolutions for real-time streaming inference with PyTorch.**
|
|
32
|
+
|
|
33
|
+
`cached_conv` provides drop-in replacements for PyTorch convolutional layers
|
|
34
|
+
that process a signal **block by block** and give the same result as
|
|
35
|
+
processing it all at once. Each layer keeps the end of the previous block in
|
|
36
|
+
an internal cache, used instead of zero padding at block boundaries.
|
|
37
|
+
|
|
38
|
+
The same model definition can be built in two modes:
|
|
39
|
+
|
|
40
|
+
- **eager** (default): regular layers, for training on full signals;
|
|
41
|
+
- **cached**: streaming layers, for real-time inference, e.g. once exported
|
|
42
|
+
with TorchScript.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- 1D, 2D and 3D convolutions and transposed convolutions. Time is the last
|
|
47
|
+
axis, the only one that is streamed.
|
|
48
|
+
- `"same"`, `"causal"` and `"anticausal"` padding, computed from the kernel
|
|
49
|
+
size and dilation.
|
|
50
|
+
- Strides, dilation and groups.
|
|
51
|
+
- Latency tracking: every layer exposes its `cumulative_delay`, which
|
|
52
|
+
accumulates across a whole model.
|
|
53
|
+
- Windowed convolutions: the kernel is multiplied by a window before
|
|
54
|
+
convolving.
|
|
55
|
+
- StyleGAN 2-modulated convolutions. The style can change from one block to
|
|
56
|
+
the next.
|
|
57
|
+
- Streamable upsampling (nearest and linear), group normalization and
|
|
58
|
+
alignment of parallel branches.
|
|
59
|
+
- TorchScript export, on CPU, CUDA and MPS.
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install git+https://github.com/acids-ircam/acids-cc.git
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Requires Python ≥ 3.9 and PyTorch ≥ 1.9.
|
|
68
|
+
|
|
69
|
+
## Quick start
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import torch
|
|
73
|
+
import cached_conv as cc
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def build_model():
|
|
77
|
+
conv1 = cc.Conv1d(1, 16, 5, padding="same")
|
|
78
|
+
conv2 = cc.Conv1d(16, 1, 5, padding="same",
|
|
79
|
+
cumulative_delay=conv1.cumulative_delay)
|
|
80
|
+
return cc.CachedSequential(conv1, conv2)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# 1. train in eager mode (the default)
|
|
84
|
+
model = build_model()
|
|
85
|
+
|
|
86
|
+
# 2. build the same model with cached layers, and load the trained weights
|
|
87
|
+
cc.use_cached_conv(True)
|
|
88
|
+
streaming_model = build_model()
|
|
89
|
+
streaming_model.load_state_dict(model.state_dict())
|
|
90
|
+
|
|
91
|
+
# 3. process a stream block by block
|
|
92
|
+
stream = torch.randn(1, 1, 8192)
|
|
93
|
+
y = torch.cat([streaming_model(block) for block in stream.split(512, -1)], -1)
|
|
94
|
+
|
|
95
|
+
# the output is delayed by the model's latency, in samples. The edges differ:
|
|
96
|
+
# before the signal starts, eager layers see zero padding, cached layers see
|
|
97
|
+
# the previous layer's response to silence
|
|
98
|
+
delay = streaming_model.cumulative_delay
|
|
99
|
+
offline = model(stream)
|
|
100
|
+
assert torch.allclose(y[..., 2 * delay:], offline[..., delay:-delay],
|
|
101
|
+
atol=1e-5)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Cached layers can't look into the future: centered convolutions delay their
|
|
105
|
+
output instead. Pass each layer's `cumulative_delay` to the next one so that
|
|
106
|
+
the total latency is tracked correctly. With `padding="causal"` everywhere,
|
|
107
|
+
the latency only comes from strides.
|
|
108
|
+
|
|
109
|
+
## Layers
|
|
110
|
+
|
|
111
|
+
The layers exposed by the package (`cc.Conv1d`, `cc.Upsample2d`...) are
|
|
112
|
+
factories: they return a regular or a cached layer, depending on
|
|
113
|
+
`cc.use_cached_conv` at construction time.
|
|
114
|
+
|
|
115
|
+
| | 1D | 2D | 3D |
|
|
116
|
+
| --- | --- | --- | --- |
|
|
117
|
+
| Convolution | `Conv1d` | `Conv2d` | `Conv3d` |
|
|
118
|
+
| Transposed convolution | `ConvTranspose1d` | `ConvTranspose2d` | `ConvTranspose3d` |
|
|
119
|
+
| Windowed convolution | `WindowedConv1d` | `WindowedConv2d` | `WindowedConv3d` |
|
|
120
|
+
| Modulated convolution | `ModulatedConv1d` | `ModulatedConv2d` | `ModulatedConv3d` |
|
|
121
|
+
| Upsampling | `Upsample1d` | `Upsample2d` | `Upsample3d` |
|
|
122
|
+
| Branch alignment | `AlignBranches1d` | `AlignBranches2d` | `AlignBranches3d` |
|
|
123
|
+
| Group normalization | `CachedGroupNorm1d` | `CachedGroupNorm2d` | `CachedGroupNorm3d` |
|
|
124
|
+
|
|
125
|
+
Inputs are shaped `(batch, channels, time)`,
|
|
126
|
+
`(batch, channels, height, time)` and `(batch, channels, depth, height, time)`.
|
|
127
|
+
In 2D and 3D, `padding` sets the mode along time; the other axes are always
|
|
128
|
+
padded "same".
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# encoder / decoder; the transposed kernel size along time must be
|
|
132
|
+
# stride + 2 * padding
|
|
133
|
+
down = cc.Conv1d(16, 16, 4, stride=2, padding="same")
|
|
134
|
+
up = cc.ConvTranspose1d(16, 16, 4, stride=2, padding=1,
|
|
135
|
+
cumulative_delay=down.cumulative_delay)
|
|
136
|
+
|
|
137
|
+
# spectrogram convolution (frequency, time), windowed along time only
|
|
138
|
+
conv = cc.WindowedConv2d(1, 16, (3, 33), window=(None, "hann"))
|
|
139
|
+
|
|
140
|
+
# StyleGAN 2 modulation
|
|
141
|
+
mod = cc.ModulatedConv1d(16, 32, 3, padding="same", style_dim=64)
|
|
142
|
+
y = mod(torch.randn(2, 16, 512), torch.randn(2, 64))
|
|
143
|
+
|
|
144
|
+
# upsampling by an integer factor along time
|
|
145
|
+
upsample = cc.Upsample1d(2, mode="linear",
|
|
146
|
+
cumulative_delay=down.cumulative_delay)
|
|
147
|
+
|
|
148
|
+
# residual connection: delays the identity branch to match the convolution
|
|
149
|
+
conv = cc.Conv1d(16, 16, 3, padding="same")
|
|
150
|
+
residual = cc.AlignBranches1d(conv, torch.nn.Identity(),
|
|
151
|
+
delays=[conv.cumulative_delay, 0])
|
|
152
|
+
y_conv, y_identity = residual(torch.randn(1, 16, 512))
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Exporting with TorchScript
|
|
156
|
+
|
|
157
|
+
Caches are allocated on the first call. Run the cached model once before
|
|
158
|
+
scripting it:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
cc.use_cached_conv(True)
|
|
162
|
+
model = build_model().eval()
|
|
163
|
+
|
|
164
|
+
with torch.no_grad():
|
|
165
|
+
model(torch.zeros(1, 1, 512))
|
|
166
|
+
|
|
167
|
+
torch.jit.script(model).save("model.ts")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Caches have room for `max_batch_size` streams (a layer argument). Block
|
|
171
|
+
lengths must be divisible by the model's total stride.
|
|
172
|
+
|
|
173
|
+
## Testing
|
|
174
|
+
|
|
175
|
+
`cc.test_equal` checks that a model gives the same output when streamed as
|
|
176
|
+
when processed offline:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
assert cc.test_equal(build_model, torch.randn(1, 1, 4096))
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
To run the library's test suite, on all available devices:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pip install -e ".[dev]"
|
|
186
|
+
pytest tests
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
To run it against several Python / PyTorch versions with
|
|
190
|
+
[uv](https://docs.astral.sh/uv/):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
./test_versions.sh -p "3.9 3.12" -t "1.13 2.0 latest"
|
|
194
|
+
./test_versions.sh --lowest # oldest torch for each Python version
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`tests/test_audio.py` also writes audio examples to `tests/audio_outputs/`
|
|
198
|
+
(waveforms in 1D, spectrograms in 2D / 3D), in eager and streaming modes.
|
|
199
|
+
|
|
200
|
+
## Documentation
|
|
201
|
+
|
|
202
|
+
The full documentation is on
|
|
203
|
+
[cached-conv.readthedocs.io](https://cached-conv.readthedocs.io). To build it
|
|
204
|
+
locally:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pip install -r docs/requirements.txt
|
|
208
|
+
sphinx-build -b html docs docs/_build/html
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Credits
|
|
212
|
+
|
|
213
|
+
Developed at [ACIDS](https://acids.ircam.fr) (IRCAM) by Axel
|
|
214
|
+
Chemla--Romeu-Santos and Nils Demerlé. Upgrade of the original
|
|
215
|
+
[cached_conv](https://github.com/acids-ircam/cached_conv) package by Antoine
|
|
216
|
+
Caillon (2021).
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
acids_cc.egg-info/PKG-INFO
|
|
4
|
+
acids_cc.egg-info/SOURCES.txt
|
|
5
|
+
acids_cc.egg-info/dependency_links.txt
|
|
6
|
+
acids_cc.egg-info/requires.txt
|
|
7
|
+
acids_cc.egg-info/top_level.txt
|
|
8
|
+
cached_conv/__init__.py
|
|
9
|
+
cached_conv/conv_1d.py
|
|
10
|
+
cached_conv/conv_2d.py
|
|
11
|
+
cached_conv/conv_3d.py
|
|
12
|
+
cached_conv/upsample.py
|
|
13
|
+
cached_conv/utils.py
|
|
14
|
+
cached_conv/variants.py
|
|
15
|
+
tests/test_align_branches.py
|
|
16
|
+
tests/test_audio.py
|
|
17
|
+
tests/test_conv.py
|
|
18
|
+
tests/test_conv_3d.py
|
|
19
|
+
tests/test_conv_t.py
|
|
20
|
+
tests/test_device.py
|
|
21
|
+
tests/test_group_norm.py
|
|
22
|
+
tests/test_padding.py
|
|
23
|
+
tests/test_script.py
|
|
24
|
+
tests/test_sequential.py
|
|
25
|
+
tests/test_variants.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cached_conv
|