Download export/sources.py from anira-project/simple-gain: direct link, hf CLI and curl.
- Browser
- Download file 2.74 kB
-
https://huggingface.co/anira-project/simple-gain/resolve/main/export/sources.py
- Command line
-
hf download hf://anira-project/simple-gain/export/sources.py
-
curl -L -o sources.py https://huggingface.co/anira-project/simple-gain/resolve/main/export/sources.py
2.74 kB
| # SPDX-License-Identifier: Apache-2.0 | |
| """The PyTorch module an exporter takes for an ONNX model, with the ONNX model's input names and | |
| static shapes: onnx_to_torch.py's conversion, or for GuitarLSTM (an LSTM, which onnx2torch does not | |
| convert) its rebuild from the TorchScript model. A description gives the input shapes where the ONNX | |
| model's are dynamic (matched by position, as anira binds tensors whose names differ).""" | |
| import json | |
| import onnxruntime | |
| import torch | |
| import torch.nn.functional as F | |
| from onnx_to_torch import torch_module | |
| class GuitarLstm(torch.nn.Module): | |
| """GuitarLSTM (libtorch/GuitarLSTM-dynamic.pt): pad, two strided convolutions, an LSTM from a zero | |
| state over each window, the last step through a linear layer; stateless between calls.""" | |
| def __init__(self, ts): | |
| super().__init__() | |
| self.conv1 = torch.nn.Conv1d(ts.conv1.weight.shape[1], ts.conv1.weight.shape[0], ts.conv1.weight.shape[2], stride=12) | |
| self.conv2 = torch.nn.Conv1d(ts.conv2.weight.shape[1], ts.conv2.weight.shape[0], ts.conv2.weight.shape[2], stride=12) | |
| self.lstm = torch.nn.LSTM(ts.lstm.weight_ih_l0.shape[1], ts.lstm.weight_hh_l0.shape[1], batch_first=True) | |
| self.linear = torch.nn.Linear(ts.linear.weight.shape[1], ts.linear.weight.shape[0]) | |
| for name in ("conv1", "conv2", "lstm", "linear"): | |
| getattr(self, name).load_state_dict({k: v.detach().clone() for k, v in getattr(ts, name).state_dict().items()}) | |
| def forward(self, x): | |
| x = self.conv2(F.pad(self.conv1(F.pad(x, (12, 12))), (12, 12))).permute(0, 2, 1) | |
| return self.linear(self.lstm(x)[0][:, -1, :]) | |
| def load(onnx_path, description=None, guitar_lstm=None): | |
| """(module, input names, output names, shapes by input name).""" | |
| torch.set_grad_enabled(False) | |
| session = onnxruntime.InferenceSession(onnx_path) | |
| input_names = [v.name for v in session.get_inputs()] | |
| output_names = [v.name for v in session.get_outputs()] | |
| overrides = {} | |
| if description: | |
| for tensor, name in zip(json.load(open(description))["inputs"], input_names): | |
| overrides[name] = [n for _, n in tensor["axes"]] | |
| if guitar_lstm: | |
| module, shapes = GuitarLstm(torch.jit.load(guitar_lstm).eval()).eval(), {} | |
| else: | |
| module, shapes = torch_module(onnx_path, overrides) | |
| shapes.update(overrides) | |
| return module, input_names, output_names, shapes | |
| def options(args): | |
| """The description and --guitar-lstm <pt> among the command line's optional arguments.""" | |
| description = next((a for a in args if a.endswith(".model.json")), None) | |
| guitar_lstm = args[args.index("--guitar-lstm") + 1] if "--guitar-lstm" in args else None | |
| return description, guitar_lstm | |