{"id":17617970,"url":"https://github.com/diffapf/torchlpc","last_synced_at":"2025-05-10T21:14:31.602Z","repository":{"id":179782319,"uuid":"663742577","full_name":"DiffAPF/torchlpc","owner":"DiffAPF","description":"Fast and differentiable time domain all-pole filter in PyTorch.","archived":false,"fork":false,"pushed_at":"2025-05-04T20:06:28.000Z","size":71,"stargazers_count":61,"open_issues_count":7,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-10T21:14:27.756Z","etag":null,"topics":["ddsp","linear-predictive-coding","speech-synthesis","time-varying-filter","time-varying-systems"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DiffAPF.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-08T02:11:11.000Z","updated_at":"2025-05-07T17:20:27.000Z","dependencies_parsed_at":"2024-02-22T23:25:20.764Z","dependency_job_id":"c3039ca8-9e39-42c3-ab47-47e05e6520fa","html_url":"https://github.com/DiffAPF/torchlpc","commit_stats":null,"previous_names":["yoyololicon/torchlpc","diffapf/torchlpc"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiffAPF%2Ftorchlpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiffAPF%2Ftorchlpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiffAPF%2Ftorchlpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiffAPF%2Ftorchlpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DiffAPF","download_url":"https://codeload.github.com/DiffAPF/torchlpc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253481086,"owners_count":21915261,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ddsp","linear-predictive-coding","speech-synthesis","time-varying-filter","time-varying-systems"],"created_at":"2024-10-22T19:23:56.059Z","updated_at":"2025-05-10T21:14:31.570Z","avatar_url":"https://github.com/DiffAPF.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TorchLPC\n[![PyPI version](https://badge.fury.io/py/torchlpc.svg)](https://badge.fury.io/py/torchlpc)\n\n`torchlpc` provides a PyTorch implementation of the Linear Predictive Coding (LPC) filter, also known as all-pole filter.\nIt's fast, differentiable, and supports batched inputs with time-varying filter coefficients.\n\nGiven an input signal $`\\mathbf{x} \\in \\mathbb{R}^T`$ and time-varying LPC coefficients $`\\mathbf{A} \\in \\mathbb{R}^{T \\times N}`$ with an order of $`N`$, the LPC filter is defined as:\n\n$$\ny_t = x_t - \\sum_{i=1}^N A_{t,i} y_{t-i}.\n$$\n\n## Usage\n\n```python\n\nimport torch\nfrom torchlpc import sample_wise_lpc\n\n# Create a batch of 10 signals, each with 100 time steps\nx = torch.randn(10, 100)\n\n# Create a batch of 10 sets of LPC coefficients, each with 100 time steps and an order of 3\nA = torch.randn(10, 100, 3)\n\n# Apply LPC filtering\ny = sample_wise_lpc(x, A)\n\n# Optionally, you can provide initial values for the output signal (default is 0)\nzi = torch.randn(10, 3)\ny = sample_wise_lpc(x, A, zi=zi)\n```\n\n\n## Installation\n\n```bash\npip install torchlpc\n```\n\nor from source\n\n```bash\npip install git+https://github.com/DiffAPF/torchlpc.git\n```\n\n## Derivation of the gradients of the LPC filter\n\nThe details of the derivation can be found in our preprints[^1][^2].\nWe show that, given the instataneous gradient $\\frac{\\partial \\mathcal{L}}{\\partial y_t}$ where $\\mathcal{L}$ is the loss function, the gradients of the LPC filter with respect to the input signal $\\bf x$ and the filter coefficients $\\bf A$ can be expresssed also through a time-varying filter:\n\n```math\n\\frac{\\partial \\mathcal{L}}{\\partial x_t}\n= \\frac{\\partial \\mathcal{L}}{\\partial y_t}\n- \\sum_{i=1}^{N} A_{t+i,i} \\frac{\\partial \\mathcal{L}}{\\partial x_{t+i}}\n```\n\n$$\n\\frac{\\partial \\mathcal{L}}{\\partial \\bf A}\n= -\\begin{vmatrix}\n\\frac{\\partial \\mathcal{L}}{\\partial x_1} \u0026 0 \u0026 \\dots \u0026 0 \\\\\n0 \u0026 \\frac{\\partial \\mathcal{L}}{\\partial x_2} \u0026 \\dots \u0026 0 \\\\\n\\vdots \u0026 \\vdots \u0026 \\ddots \u0026 \\vdots \\\\\n0 \u0026 0 \u0026 \\dots \u0026 \\frac{\\partial \\mathcal{L}}{\\partial x_t}\n\\end{vmatrix}\n\\begin{vmatrix}\ny_0 \u0026 y_{-1} \u0026 \\dots \u0026 y_{-N + 1} \\\\\ny_1 \u0026 y_0 \u0026 \\dots \u0026 y_{-N + 2} \\\\\n\\vdots \u0026 \\vdots \u0026 \\ddots \u0026 \\vdots \\\\\ny_{T-1} \u0026 y_{T - 2} \u0026 \\dots \u0026 y_{T - N}\n\\end{vmatrix}.\n$$\n\n### Gradients for the initial condition $`y_t|_{t \\leq 0}`$\n\nThe initial conditions provide an entry point at $t=1$ for filtering, as we cannot evaluate $t=-\\infty$.\nLet us assume $`A_{t, :}|_{t \\leq 0} = 0`$ so $`y_t|_{t \\leq 0} = x_t|_{t \\leq 0}`$, which also means $`\\frac{\\partial \\mathcal{L}}{\\partial y_t}|_{t \\leq 0} = \\frac{\\partial \\mathcal{L}}{\\partial x_t}|_{t \\leq 0}`$.\nThus, the initial condition gradients are\n\n$$\n\\frac{\\partial \\mathcal{L}}{\\partial y_t} \n= \\frac{\\partial \\mathcal{L}}{\\partial x_t}\n= -\\sum_{i=1-t}^{N} A_{t+i,i} \\frac{\\partial \\mathcal{L}}{\\partial x_{t+i}} \\quad \\text{for } -N \u003c t \\leq 0.\n$$\n\nIn practice, we pad $N$ and $N \\times N$ zeros to the beginning of $\\frac{\\partial \\mathcal{L}}{\\partial \\bf y}$ and $\\mathbf{A}$ before evaluating $\\frac{\\partial \\mathcal{L}}{\\partial \\bf x}$.\nThe first $N$ outputs are the gradients to $`y_t|_{t \\leq 0}`$ and the rest are to $`x_t|_{t \u003e 0}`$.\n\n### Time-invariant filtering\n\nIn the time-invariant setting, $`A_{t, i} = A_{1, i} \\forall t \\in [1, T]`$ and the filter is simplified to\n\n```math\ny_t = x_t - \\sum_{i=1}^N a_i y_{t-i}, \\mathbf{a} = A_{1,:}.\n```\n\nThe gradients $`\\frac{\\partial \\mathcal{L}}{\\partial \\mathbf{x}}`$ are filtering $`\\frac{\\partial \\mathcal{L}}{\\partial \\mathbf{y}}`$ with $\\mathbf{a}$ backwards in time, same as in the time-varying case.\n$\\frac{\\partial \\mathcal{L}}{\\partial \\mathbf{a}}$ is simply doing a vector-matrix multiplication:\n\n$$\n\\frac{\\partial \\mathcal{L}}{\\partial \\mathbf{a}^T} =\n-\\frac{\\partial \\mathcal{L}}{\\partial \\mathbf{x}^T}\n\\begin{vmatrix}\ny_0 \u0026 y_{-1} \u0026 \\dots \u0026 y_{-N + 1} \\\\\ny_1 \u0026 y_0 \u0026 \\dots \u0026 y_{-N + 2} \\\\\n\\vdots \u0026 \\vdots \u0026 \\ddots \u0026 \\vdots \\\\\ny_{T-1} \u0026 y_{T - 2} \u0026 \\dots \u0026 y_{T - N}\n\\end{vmatrix}.\n$$\n\nThis algorithm is more efficient than [^3] because it only needs one pass of filtering to get the two gradients while the latter needs two.\n\n[^1]: [Differentiable All-pole Filters for Time-varying Audio Systems](https://arxiv.org/abs/2404.07970).\n[^2]: [Differentiable Time-Varying Linear Prediction in the Context of End-to-End Analysis-by-Synthesis](https://arxiv.org/abs/2406.05128).\n[^3]: [Singing Voice Synthesis Using Differentiable LPC and Glottal-Flow-Inspired Wavetables](https://arxiv.org/abs/2306.17252).\n\n## TODO\n\n- [ ] Use PyTorch C++ extension for faster computation.\n- [ ] Use native CUDA kernels for GPU computation.\n- [ ] Add examples.\n\n## Related Projects\n\n- [torchcomp](https://github.com/DiffAPF/torchcomp): differentiable compressors that use `torchlpc` for differentiable backpropagation.\n- [jaxpole](https://github.com/rodrigodzf/jaxpole): equivalent implementation in JAX by @rodrigodzf.\n\n## Citation\n\nIf you find this repository useful in your research, please cite our work with the following BibTex entries:\n\n```bibtex\n@inproceedings{ycy2024diffapf,\n    title={Differentiable All-pole Filters for Time-varying Audio Systems},\n    author={Chin-Yun Yu and Christopher Mitcheltree and Alistair Carson and Stefan Bilbao and Joshua D. Reiss and György Fazekas},\n    booktitle={International Conference on Digital Audio Effects (DAFx)},\n    year={2024},\n    pages={345--352},\n}\n\n@inproceedings{ycy2024golf,\n    title     = {Differentiable Time-Varying Linear Prediction in the Context of End-to-End Analysis-by-Synthesis},\n    author    = {Chin-Yun Yu and György Fazekas},\n    year      = {2024},\n    booktitle = {Proc. Interspeech},\n    pages     = {1820--1824},\n    doi       = {10.21437/Interspeech.2024-1187},\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiffapf%2Ftorchlpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiffapf%2Ftorchlpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiffapf%2Ftorchlpc/lists"}