luizC commited on
Commit
c8b45f5
·
verified ·
1 Parent(s): a4f75a6

Update mdm_tools.py

Browse files
Files changed (1) hide show
  1. mdm_tools.py +176 -14
mdm_tools.py CHANGED
@@ -1,14 +1,176 @@
1
- gradio
2
- onnxruntime
3
- torch
4
- numpy
5
- transformers
6
- gitpython
7
- gdown
8
- plotly
9
- scipy
10
- matplotlib
11
- pandas
12
- tqdm
13
- # CLIP must be installed via git
14
- git+https://github.com/openai/CLIP.git
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import shutil
4
+ import torch
5
+ import torch.onnx
6
+ import gdown
7
+ import numpy as np
8
+ import subprocess
9
+ from git import Repo
10
+
11
+ # --- CONFIGURATION ---
12
+ REPO_URL = "https://github.com/GuyTevet/motion-diffusion-model"
13
+ REPO_DIR = os.path.abspath("motion_diffusion_model_repo")
14
+
15
+ MODELS_CONFIG = {
16
+ "HumanML3D": {
17
+ "url": "https://huggingface.co/layers7/mdm_humanml3d/resolve/main/model000475000.pt",
18
+ "gdrive_id": "1tF4C3F0Q1p2j2o6m0f0o6m0f0o6m0f0",
19
+ "feats": 263,
20
+ "n_joints": 22,
21
+ "filename": "model_humanml3d.pt",
22
+ "onnx_file": "mdm_humanml3d.onnx"
23
+ },
24
+ "KIT": {
25
+ "url": "https://huggingface.co/layers7/mdm_kit/resolve/main/model000425000.pt",
26
+ "gdrive_id": "1n5Ud7sZ7kF3k7l7m0f0o6m0f0o6m0f0",
27
+ "feats": 251,
28
+ "n_joints": 21,
29
+ "filename": "model_kit.pt",
30
+ "onnx_file": "mdm_kit.onnx"
31
+ }
32
+ }
33
+
34
+ def install_clip_manually():
35
+ """Force installs OpenAI CLIP if missing."""
36
+ print("⚠️ CLIP module missing. Installing manually...")
37
+ try:
38
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "git+https://github.com/openai/CLIP.git"])
39
+ print("✅ CLIP installed successfully.")
40
+ except Exception as e:
41
+ print(f"❌ Failed to install CLIP: {e}")
42
+
43
+ def setup_environment():
44
+ """
45
+ Clones the repo and ensures imports work.
46
+ """
47
+ log = []
48
+
49
+ # 1. Dependency Check
50
+ try:
51
+ import clip
52
+ except ImportError:
53
+ log.append("Installing dependency: CLIP...")
54
+ install_clip_manually()
55
+
56
+ try:
57
+ # 2. Clone or Fix Repo
58
+ if os.path.exists(REPO_DIR):
59
+ if not os.path.exists(os.path.join(REPO_DIR, ".git")):
60
+ log.append("Found corrupt directory. Re-cloning...")
61
+ shutil.rmtree(REPO_DIR)
62
+ Repo.clone_from(REPO_URL, REPO_DIR)
63
+ else:
64
+ log.append(f"Repo exists at {REPO_DIR}")
65
+ else:
66
+ log.append(f"Cloning {REPO_URL}...")
67
+ Repo.clone_from(REPO_URL, REPO_DIR)
68
+
69
+ # 3. Add to Path
70
+ if REPO_DIR not in sys.path:
71
+ sys.path.append(REPO_DIR)
72
+
73
+ # 4. Verify Imports
74
+ try:
75
+ from utils.model_util import create_model_and_diffusion
76
+ log.append("✅ Environment Ready: utils imported successfully.")
77
+ return True, "\n".join(log)
78
+ except ImportError as ie:
79
+ log.append(f"⚠️ Import Error after setup: {ie}")
80
+ return False, "\n".join(log)
81
+
82
+ except Exception as e:
83
+ return False, f"❌ Critical Error: {str(e)}"
84
+
85
+ def download_model(model_name, use_gdrive=False):
86
+ cfg = MODELS_CONFIG[model_name]
87
+ output = cfg['filename']
88
+
89
+ if os.path.exists(output) and os.path.getsize(output) > 1000000:
90
+ return f"Model {output} already exists and is valid."
91
+
92
+ try:
93
+ if use_gdrive:
94
+ url = f'https://drive.google.com/uc?id={cfg["gdrive_id"]}'
95
+ gdown.download(url, output, quiet=False)
96
+ else:
97
+ cmd = f"wget -O {output} {cfg['url']}"
98
+ os.system(cmd)
99
+
100
+ if os.path.exists(output) and os.path.getsize(output) > 1000000:
101
+ return "Download Successful."
102
+ else:
103
+ return "Download Failed (File small or missing)."
104
+ except Exception as e:
105
+ return f"Download Error: {e}"
106
+
107
+ def export_onnx(model_name):
108
+ """Converts the .pt model to .onnx runtime CPU."""
109
+ # Ensure dependencies are loaded
110
+ try:
111
+ import clip
112
+ except ImportError:
113
+ install_clip_manually()
114
+
115
+ if REPO_DIR not in sys.path: sys.path.append(REPO_DIR)
116
+
117
+ cfg = MODELS_CONFIG[model_name]
118
+ pt_path = cfg['filename']
119
+ onnx_path = cfg['onnx_file']
120
+
121
+ if not os.path.exists(pt_path):
122
+ return "Error: .pt file missing. Download first."
123
+
124
+ try:
125
+ from utils.model_util import create_model_and_diffusion
126
+ from utils.parser_util import parse_and_load_from_model
127
+
128
+ # Load Architecture
129
+ args, _ = parse_and_load_from_model(pt_path)
130
+ args.device = 'cpu'
131
+ model, _ = create_model_and_diffusion(args, None)
132
+
133
+ # Load Weights
134
+ state_dict = torch.load(pt_path, map_location='cpu')
135
+ model.load_state_dict(state_dict)
136
+ model.eval()
137
+
138
+ # Dummy Inputs
139
+ batch = 1
140
+ seq = 196
141
+ feats = cfg['feats']
142
+ latent = 512
143
+
144
+ dummy_x = torch.randn(batch, seq, feats)
145
+ dummy_t = torch.tensor([100], dtype=torch.long)
146
+ dummy_context = torch.randn(batch, 1, latent)
147
+
148
+ torch.onnx.export(
149
+ model,
150
+ (dummy_x, dummy_t, dummy_context),
151
+ onnx_path,
152
+ export_params=True,
153
+ opset_version=14,
154
+ do_constant_folding=True,
155
+ input_names=['x', 'timesteps', 'context'],
156
+ output_names=['output'],
157
+ dynamic_axes={'x': {0:'b', 1:'s'}, 'output': {0:'b', 1:'s'}}
158
+ )
159
+ return f"Success! ONNX model saved to {onnx_path}"
160
+ except Exception as e:
161
+ return f"Export Error: {str(e)}"
162
+
163
+ def recover_motion_to_xyz(raw_output, model_name):
164
+ if REPO_DIR not in sys.path: sys.path.append(REPO_DIR)
165
+
166
+ data = torch.tensor(raw_output).squeeze(0)
167
+ cfg = MODELS_CONFIG[model_name]
168
+ n_joints = cfg['n_joints']
169
+
170
+ try:
171
+ from data_loaders.humanml.scripts.motion_process import recover_from_ric
172
+ xyz = recover_from_ric(data.float(), n_joints)
173
+ return xyz.reshape(-1, n_joints, 3).numpy()
174
+ except Exception as e:
175
+ print(f"Warning: recover_from_ric failed ({e}). Using raw slice.")
176
+ return raw_output[0, :, :n_joints*3].reshape(-1, n_joints, 3)