"""Load checkpoint and run autoregressive pose generation.""" from __future__ import annotations import os from typing import Tuple import numpy as np import torch from audio_features import CONTEXT_LEN from model import Music2PoseTransformer DEFAULT_CHECKPOINT = "pytorch_model.pt" def load_checkpoint( ckpt_path: str = DEFAULT_CHECKPOINT, device: torch.device | None = None, ) -> Tuple[Music2PoseTransformer, dict]: """Load model weights and normalisation stats from a checkpoint file.""" if device is None: device = torch.device("cuda" if torch.cuda.is_available() else "cpu") ckpt = torch.load(ckpt_path, map_location=device, weights_only=False) model = Music2PoseTransformer( audio_dim=ckpt["audio_dim"], pose_dim=ckpt["pose_dim"], **ckpt["config"], ).to(device) model.load_state_dict(ckpt["model_state"]) model.eval() return model, ckpt def generate_poses( model: Music2PoseTransformer, audio_feat: np.ndarray, x_mean: np.ndarray, x_std: np.ndarray, y_mean: np.ndarray, y_std: np.ndarray, device: torch.device, ) -> np.ndarray: """ Autoregressive inference. Returns ------- poses_xyz : (T, 33, 3) normalised MediaPipe-style joint positions. """ T = audio_feat.shape[0] af_norm = (audio_feat - x_mean) / x_std af_t = torch.tensor(af_norm, dtype=torch.float32, device=device) pose_dim = model.pose_dim audio_ctx = torch.zeros(1, CONTEXT_LEN, af_t.shape[-1], device=device) pose_ctx = torch.zeros(1, CONTEXT_LEN, pose_dim, device=device) preds = [] with torch.no_grad(): for t in range(T): audio_ctx = torch.roll(audio_ctx, -1, dims=1) audio_ctx[0, -1] = af_t[t] next_pose = model.step(audio_ctx, pose_ctx)[0] preds.append(next_pose.cpu().numpy()) pose_ctx = torch.roll(pose_ctx, -1, dims=1) pose_ctx[0, -1] = next_pose pred_norm = np.stack(preds) pred_raw = pred_norm * y_std + y_mean return pred_raw.reshape(T, 33, 9)[:, :, :3] def resolve_checkpoint(path: str | None = None) -> str: """Return checkpoint path, defaulting to the bundled weights.""" if path: return path if os.path.exists(DEFAULT_CHECKPOINT): return DEFAULT_CHECKPOINT raise FileNotFoundError( f"No checkpoint found. Download weights or pass --checkpoint explicitly." )