Instructions to use sujitvasanth/piper-mnn-cpugpu-inputoutput-streaming with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Piper
How to use sujitvasanth/piper-mnn-cpugpu-inputoutput-streaming with Piper:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
Download scripts/make_static_dp.py from sujitvasanth/piper-mnn-cpugpu-inputoutput-streaming: direct link, hf CLI and curl.
- Browser
- Download file 5.92 kB
-
https://huggingface.co/sujitvasanth/piper-mnn-cpugpu-inputoutput-streaming/resolve/main/scripts/make_static_dp.py
- Command line
-
hf download hf://sujitvasanth/piper-mnn-cpugpu-inputoutput-streaming/scripts/make_static_dp.py
-
curl -L -o make_static_dp.py https://huggingface.co/sujitvasanth/piper-mnn-cpugpu-inputoutput-streaming/resolve/main/scripts/make_static_dp.py
5.92 kB
| """Remove data-dependent shapes from the duration predictor's spline flows. | |
| Each spline flow (dp/flows.3/5/7) uses NonZero(mask) to pick the elements inside | |
| the spline range (+-5), runs the spline on just those, then scatters results back. | |
| That makes tensor sizes depend on the data. | |
| Dense rewrite, same output: | |
| - every NonZero is replaced by a constant listing all positions, so gathers and | |
| scatters always see all N elements | |
| - the spline input is clamped to the spline range so out-of-range elements can't | |
| index past the bins (their results are discarded below) | |
| - the final "inside" scatter becomes Where(inside_mask, spline_result, previous), | |
| so outside elements keep the identity value written by the "outside" scatter | |
| """ | |
| import sys | |
| from pathlib import Path | |
| import numpy as np | |
| import onnx | |
| from onnx import TensorProto, helper, numpy_helper | |
| ROOT = Path(__file__).resolve().parent | |
| SRC = sys.argv[1] if len(sys.argv) > 1 else "data.encoder.fixed64x160.onnx" | |
| DST = sys.argv[2] if len(sys.argv) > 2 else SRC.replace(".onnx", ".static.onnx") | |
| def main() -> None: | |
| m = onnx.load(ROOT / SRC) | |
| g = m.graph | |
| m = onnx.shape_inference.infer_shapes(m) | |
| g = m.graph | |
| shapes = {} | |
| for vi in list(g.value_info) + list(g.input) + list(g.output): | |
| shapes[vi.name] = [d.dim_value if d.HasField("dim_value") else None for d in vi.type.tensor_type.shape.dim] | |
| producer = {o: n for n in g.node for o in n.output} | |
| consumers = {} | |
| for n in g.node: | |
| for x in n.input: | |
| consumers.setdefault(x, []).append(n) | |
| def mask_root(name): | |
| # Follow Expand back to the And / Not node that made the mask. | |
| n = producer[name] | |
| while n.op_type == "Expand": | |
| n = producer[n.input[0]] | |
| return n | |
| new_nodes, extra = [], [] | |
| nz_kind = {} # NonZero output -> "in" / "out" | |
| for n in g.node: | |
| if n.op_type != "NonZero": | |
| continue | |
| root = mask_root(n.input[0]) | |
| shp = shapes.get(n.input[0]) | |
| if not (shp and all(shp)): | |
| # Expanded masks: batch and channel are 1 here, same as the source mask. | |
| shp = shapes.get(root.output[0]) | |
| # dp flows act on one channel of a [1, 2, N] tensor: masks are [1, 1, N]. | |
| shp = [d if d else 1 for d in (shp or [None, None, None])] | |
| assert len(shp) == 3 and shp[-1] > 1, f"unexpected mask shape for {n.name}: {shp}" | |
| nz_kind[n.output[0]] = "in" if root.op_type == "And" else "out" | |
| idx = np.stack(np.meshgrid(*[np.arange(s) for s in shp], indexing="ij")).reshape(len(shp), -1).astype(np.int64) | |
| n.op_type = "Constant" | |
| del n.input[:] | |
| del n.attribute[:] | |
| n.attribute.append(helper.make_attribute("value", numpy_helper.from_array(idx, n.output[0] + "_all"))) | |
| def idx_kind(idx_name): | |
| # GatherND/ScatterND indices = Transpose(NonZero) (possibly via Cast/Reshape). | |
| n = producer.get(idx_name) | |
| while n is not None and n.output[0] not in nz_kind: | |
| n = producer.get(n.input[0]) if n.input else None | |
| return nz_kind.get(n.output[0]) if n is not None else None | |
| clamped = where_fixed = 0 | |
| nodes = list(g.node) | |
| out_nodes = [] | |
| for n in nodes: | |
| if n.op_type == "GatherND" and idx_kind(n.input[1]) == "in" and len(shapes.get(n.input[0], [])) == 3: | |
| # Spline input x (shape [1,1,N]): clamp into the spline range. | |
| lo = n.name + "/lo"; hi = n.name + "/hi"; cl = n.input[0] + "_clamped_" + str(clamped) | |
| out_nodes.append(helper.make_node("Constant", [], [lo], value=numpy_helper.from_array(np.array(-5.0, np.float32)))) | |
| out_nodes.append(helper.make_node("Constant", [], [hi], value=numpy_helper.from_array(np.array(5.0, np.float32)))) | |
| out_nodes.append(helper.make_node("Clip", [n.input[0], lo, hi], [cl], name=n.name + "/Clamp")) | |
| n.input[0] = cl | |
| clamped += 1 | |
| out_nodes.append(n) | |
| elif n.op_type == "ScatterND" and idx_kind(n.input[1]) == "in": | |
| data, idx, upd = n.input | |
| shp = shapes.get(data) | |
| # The mask fed to the (now constant) NonZero: find it via the original Expand node. | |
| nz = producer[idx] | |
| while nz.output[0] not in nz_kind: | |
| nz = producer[nz.input[0]] | |
| # Rebuild the boolean mask: inside = And(...) expanded to data's shape. | |
| and_node = None | |
| for cand in g.node: | |
| if cand.op_type == "And" and cand.name.rsplit("/", 1)[0] == n.name.rsplit("/", 1)[0]: | |
| and_node = cand | |
| assert and_node is not None, n.name | |
| if not (shp and all(shp)): | |
| shp = shapes[and_node.output[0]] | |
| shp = [d if d else 1 for d in shp] | |
| shp_name = n.name + "/shape" | |
| out_nodes.append(helper.make_node("Constant", [], [shp_name], value=numpy_helper.from_array(np.array(shp, np.int64)))) | |
| mask = n.name + "/inside_mask" | |
| out_nodes.append(helper.make_node("Expand", [and_node.output[0], shp_name], [mask], name=n.name + "/MaskExpand")) | |
| upd_r = n.name + "/upd_dense" | |
| out_nodes.append(helper.make_node("Reshape", [upd, shp_name], [upd_r], name=n.name + "/UpdReshape")) | |
| out_nodes.append(helper.make_node("Where", [mask, upd_r, data], list(n.output), name=n.name + "/Where")) | |
| where_fixed += 1 | |
| else: | |
| out_nodes.append(n) | |
| g.ClearField("node") | |
| g.node.extend(out_nodes) | |
| g.ClearField("value_info") | |
| m = onnx.shape_inference.infer_shapes(m) | |
| onnx.checker.check_model(m) | |
| onnx.save(m, ROOT / DST) | |
| left = sum(1 for n in m.graph.node if n.op_type == "NonZero") | |
| print(f"NonZero replaced: {len(nz_kind)}; clamps: {clamped}; inside scatters -> Where: {where_fixed}; NonZero left: {left}") | |
| print("saved", DST) | |
| if __name__ == "__main__": | |
| main() | |