maya2-native-fast / tools /maya_export /export_depth.py
mrwine's picture
Initial release: optimized CPU runtime and converted weights of maya2-native
4f5f309 verified
Raw History Blame Contribute Delete
3.14 kB
"""Export the 15 per-level depth graphs (fp32) to work_dir()/depth_build/fp32/level_XX.onnx.
Each level's weights are read from the checkpoint and loaded into a fresh DepthLevel; one level at a time.
.venv/bin/python tools/memguard.py --rss-limit-mb 4000 --min-free-mb 4000 -- \
.venv-tts/bin/python -m tools.maya_export.export_depth
"""
from __future__ import annotations
import torch
from tts.model.depth_v2 import GROUP_OF_LEVEL
from tts.tokens import N_Q
from tools.maya_export.common import ckpt_paths, work_dir
from tools.maya_export.depth_frame import DepthLevel, Q_SERVE
from tools.maya_export.export_backbone import D_MODEL, _export, _quantize_wo8, _save_external
from tools.maya_export.streamed_backbone import _Weights, shard_files
D_DEPTH = 1024
N_LEVELS = 15 # serving q_serve = 16: levels 1..15 (the checkpoint has up to 31)
def ckpt_name(name: str, level: int) -> str:
"""DepthLevel parameter name -> checkpoint key (without the model. prefix)."""
if name.startswith("trunk."):
_, li, rest = name.split(".", 2)
return f"depth.groups.{GROUP_OF_LEVEL[level]}.{li}.{rest}"
if name.startswith("head."):
return f"depth.heads.{level - 1}.weight"
return f"depth.{name}"
def _head_nodes(model) -> list[str]:
"""Names of the node(s) producing the `logits` output (the level head's MatMul): kept in fp32 for wo8_fph."""
names = []
for node in model.graph.node:
if "logits" in node.output:
names.append(node.name)
return names
def export_level(level: int, weights: _Weights, build, precision: str) -> None:
mod = DepthLevel(level).eval()
state = {name: weights.get(ckpt_name(name, level)).float() for name, _ in mod.named_parameters()}
mod.load_state_dict(state, strict=True)
del state
h = torch.randn(1, D_MODEL) * 0.02
codes = torch.zeros(1, Q_SERVE, dtype=torch.long)
mem = torch.zeros(1, 1, D_DEPTH)
tmp = build / f"level_{level:02d}_raw.onnx"
_export(mod, (h, codes, mem), tmp, input_names=["h", "codes", "mem"], output_names=["logits"],
dynamic_axes={"h": {0: "B"}, "codes": {0: "B"}, "mem": {0: "B"}, "logits": {0: "B"}})
import onnx
model = onnx.load(str(tmp))
if precision == "wo8":
model = _quantize_wo8(model)
elif precision == "wo8_fph": # int8 trunks, fp32 head
model = _quantize_wo8(model, exclude=_head_nodes(model))
_save_external(model, build / f"level_{level:02d}.onnx")
tmp.unlink()
tmp.with_suffix(".onnx.data").unlink(missing_ok=True)
del mod
def main() -> None:
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("--precision", choices=("fp32", "wo8", "wo8_fph"), default="fp32")
precision = ap.parse_args().precision
build = work_dir() / "depth_build" / precision
build.mkdir(parents=True, exist_ok=True)
paths = ckpt_paths()
weights = _Weights(shard_files(paths["ckpt"]))
for level in range(1, N_LEVELS + 1):
export_level(level, weights, build, precision)
print(f"level {level:02d} fp32 ok", flush=True)
if __name__ == "__main__":
main()