Spaces:
Running
Running
Download patch_runtime.py from STATICAI/Motion-Rig: direct link, hf CLI and curl.
- Browser
- Download file 4.47 kB
-
https://huggingface.co/spaces/STATICAI/Motion-Rig/resolve/4fe8759fcb7c339eafdbe4b677f012ab3f3bdc2d/patch_runtime.py
- Command line
-
hf download hf://spaces/STATICAI/Motion-Rig@4fe8759fcb7c339eafdbe4b677f012ab3f3bdc2d/patch_runtime.py
-
curl -L -o patch_runtime.py https://huggingface.co/spaces/STATICAI/Motion-Rig/resolve/4fe8759fcb7c339eafdbe4b677f012ab3f3bdc2d/patch_runtime.py
4.47 kB
| from pathlib import Path | |
| import os | |
| import subprocess | |
| # The upstream checkout lives on persistent storage and therefore retains edits | |
| # across container restarts. Restore only the files managed by this patcher from | |
| # its pinned Git commit before applying changes, making this script idempotent. | |
| for relative_path in ( | |
| "util/dataset_mixamo_additional.py", | |
| "model.py", | |
| "models_ae.py", | |
| "app.py", | |
| ): | |
| pristine = subprocess.check_output( | |
| ["git", "-C", "app", "show", f"HEAD:{relative_path}"] | |
| ) | |
| Path("app", relative_path).write_bytes(pristine) | |
| # ββ 1. dataset_mixamo_additional.py β optional extended skeleton guard βββββββββ | |
| path = Path("app/util/dataset_mixamo_additional.py") | |
| if path.exists(): | |
| source = path.read_text() | |
| old = """TEMPLATE_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../data/Mixamo/bones_vroid.fbx")) | |
| KINEMATIC_TREE = get_kinematic_tree(TEMPLATE_PATH, BONES_IDX_DICT) | |
| assert len(KINEMATIC_TREE) == len(MIXAMO_JOINTS) | |
| """ | |
| new = """TEMPLATE_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../data/Mixamo/bones_vroid.fbx")) | |
| if os.path.isfile(TEMPLATE_PATH): | |
| KINEMATIC_TREE = get_kinematic_tree(TEMPLATE_PATH, BONES_IDX_DICT) | |
| assert len(KINEMATIC_TREE) == len(MIXAMO_JOINTS) | |
| else: | |
| # The optional extended skeleton lives in the restricted Mixamo dataset. | |
| # Standard humanoid inference does not use it (joints_additional=False). | |
| KINEMATIC_TREE = dataset_mixamo.KINEMATIC_TREE | |
| """ | |
| if old in source: | |
| path.write_text(source.replace(old, new)) | |
| print("[dataset_mixamo_additional.py] extended-skeleton guard patched") | |
| else: | |
| print("[dataset_mixamo_additional.py] already patched or block not found") | |
| # ββ fps fallback: replaces torch_cluster.fps with pytorch3d equivalent βββββββββ | |
| FPS_FALLBACK = """try: | |
| from torch_cluster import fps | |
| except ImportError: | |
| import numpy as np | |
| from pytorch3d.ops import sample_farthest_points | |
| def fps(x, batch, ratio): | |
| import torch | |
| sampled = [] | |
| for batch_id in torch.unique(batch, sorted=True): | |
| global_idx = torch.nonzero(batch == batch_id, as_tuple=False).flatten() | |
| points = x[global_idx].unsqueeze(0) | |
| count = max(1, int(np.ceil(points.shape[1] * ratio))) | |
| _, local_idx = sample_farthest_points(points, K=count, random_start_point=True) | |
| sampled.append(global_idx[local_idx[0]]) | |
| return torch.cat(sampled) | |
| """ | |
| CLUSTER_IMPORT = "from torch_cluster import fps" | |
| # ββ 2. model.py βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| model_path = Path("app/model.py") | |
| if model_path.exists(): | |
| src = model_path.read_text() | |
| if CLUSTER_IMPORT in src: | |
| model_path.write_text(src.replace(CLUSTER_IMPORT, FPS_FALLBACK, 1)) | |
| print("[model.py] torch_cluster fps patched") | |
| else: | |
| print("[model.py] already patched") | |
| else: | |
| print("[model.py] not found") | |
| # ββ 3. models_ae.py β THE CRITICAL MISSING PATCH βββββββββββββββββββββββββββββ | |
| # The original patch_runtime.py only patched model.py but NOT models_ae.py, | |
| # which also imports torch_cluster. This caused the ModuleNotFoundError. | |
| models_ae_path = Path("app/models_ae.py") | |
| if models_ae_path.exists(): | |
| src = models_ae_path.read_text() | |
| if CLUSTER_IMPORT in src: | |
| models_ae_path.write_text(src.replace(CLUSTER_IMPORT, FPS_FALLBACK, 1)) | |
| print("[models_ae.py] torch_cluster fps patched") | |
| else: | |
| print("[models_ae.py] already patched") | |
| else: | |
| print("[models_ae.py] not found") | |
| # ββ 4. app/app.py β @spaces.GPU duration βββββββββββββββββββββββββββββββββββββ | |
| app_path = Path("app/app.py") | |
| if app_path.exists(): | |
| src = app_path.read_text() | |
| bare_gpu_decorators = src.count("@spaces.GPU\n") | |
| if bare_gpu_decorators != 2: | |
| raise RuntimeError(f"Expected 2 bare GPU decorators, found {bare_gpu_decorators}") | |
| app_path.write_text(src.replace("@spaces.GPU\n", "@spaces.GPU(duration=300)\n")) | |
| print(f"[app/app.py] {bare_gpu_decorators} @spaces.GPU -> duration=300 patched") | |
| else: | |
| print("[app/app.py] not found") | |
| print("patch_runtime.py done.") | |