| from __future__ import annotations |
| import argparse, json, os, sys, time, gc |
| from pathlib import Path |
|
|
| os.environ.setdefault("ATTN_BACKEND", "sdpa") |
|
|
| import torch |
|
|
| MODEL_ID = "VAST-AI/AniGen" |
|
|
|
|
| class SSDecoderExport(torch.nn.Module): |
| def __init__(self, model): |
| super().__init__() |
| self.model = model |
|
|
| def forward(self, z, z_skl): |
| occ, occ_skl = self.model(z, z_skl) |
| return occ, occ_skl |
|
|
|
|
| def main(): |
| ap = argparse.ArgumentParser() |
| ap.add_argument("--out", default=os.environ.get("CF_ONNX_OUT", "/tmp/cf-ss-decoder")) |
| ap.add_argument("--model-root", default=os.environ.get("ANIGEN_MODEL_ROOT", "/tmp/anigen-model")) |
| ap.add_argument("--app-root", default=os.environ.get("ANIGEN_APP_ROOT", "/home/user/app")) |
| args = ap.parse_args() |
|
|
| out = Path(args.out) |
| model_root = Path(args.model_root) |
| app_root = Path(args.app_root) |
| out_dir = out / "onnx/anigen/ss-decoder" |
| out_dir.mkdir(parents=True, exist_ok=True) |
| sys.path.insert(0, str(app_root)) |
|
|
| from huggingface_hub import snapshot_download |
| snapshot_download( |
| MODEL_ID, |
| token=os.environ.get("HF_TOKEN"), |
| local_dir=model_root, |
| allow_patterns=[ |
| "ckpts/anigen/ss_dae/config.json", |
| "ckpts/anigen/ss_dae/ckpts/decoder_final.pt", |
| ], |
| ) |
| os.chdir(model_root) |
|
|
| from anigen.utils.model_utils import load_decoder |
| model = load_decoder(str(model_root / "ckpts/anigen/ss_dae"), "final", "cuda").eval() |
| wrapper = SSDecoderExport(model).eval() |
|
|
| z = torch.zeros((1, 8, 16, 16, 16), device="cuda", dtype=torch.float32) |
| z_skl = torch.zeros((1, 4, 16, 16, 16), device="cuda", dtype=torch.float32) |
| path = out_dir / "model.onnx" |
|
|
| started = time.time() |
| with torch.inference_mode(): |
| torch.onnx.export( |
| wrapper, |
| (z, z_skl), |
| str(path), |
| input_names=["z", "z_skl"], |
| output_names=["occupancy", "occupancy_skl"], |
| opset_version=23, |
| dynamo=True, |
| external_data=True, |
| ) |
| export_s = time.time() - started |
|
|
| import onnx |
| onnx.checker.check_model(str(path)) |
|
|
| meta = { |
| "component": "anigen-ss-decoder", |
| "source": MODEL_ID, |
| "checkpoint": "ckpts/anigen/ss_dae/ckpts/decoder_final.pt", |
| "opset": 23, |
| "static_profile": { |
| "z": [1, 8, 16, 16, 16], |
| "z_skl": [1, 4, 16, 16, 16], |
| "occupancy": [1, 1, 64, 64, 64], |
| "occupancy_skl": [1, 1, 64, 64, 64], |
| }, |
| "export_seconds": round(export_s, 3), |
| "torch": torch.__version__, |
| "cuda": torch.version.cuda, |
| "gpu": torch.cuda.get_device_name(0), |
| } |
| (out_dir / "export_meta.json").write_text(json.dumps(meta, indent=2)) |
| print("SS_DECODER_EXPORTED", json.dumps(meta), flush=True) |
|
|
| del wrapper, model, z, z_skl |
| gc.collect(); torch.cuda.empty_cache() |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|