deca_vision / export_deca.py
mraiser's picture
Upload 3 files
f284828 verified
Raw
History Blame Contribute Delete
2.58 kB
import os
import sys
import torch
import torch.nn as nn
import numpy as np
import inspect
# --- PROACTIVE PYTHON 3.12 / NUMPY 2.0 PATCH ---
if not hasattr(np, 'bool'):
np.bool = np.bool_
if not hasattr(np, 'float'):
np.float = np.float64
if not hasattr(np, 'int'):
np.int = np.int_
if not hasattr(np, 'complex'):
np.complex = complex
if not hasattr(np, 'object'):
np.object = object
if not hasattr(np, 'unicode'):
np.unicode = str
if not hasattr(np, 'str'):
np.str = str
if not hasattr(inspect, 'getargspec'):
inspect.getargspec = inspect.getfullargspec
# -----------------------------------------------
# Path setup based on your layout
# Download from https://github.com/yfeng95/DECA
DECA_DIR = os.path.abspath("DECA")
sys.path.insert(0, DECA_DIR)
from decalib.deca import DECA
from decalib.utils.config import cfg as deca_cfg
# --- THE ULTIMATE PYTORCH3D BYPASS ---
DECA._setup_renderer = lambda self, *args, **kwargs: None
# -------------------------------------
# ---------------------------------------------------------
# The Custom Rust Wrapper
# ---------------------------------------------------------
class DecaVisionONNXWrapper(nn.Module):
def __init__(self, deca_model):
super().__init__()
# Extract just the ResNet50 vision encoder from DECA
self.encoder = deca_model.E_flame
def forward(self, images):
parameters = self.encoder(images)
flame_vector = parameters[:, 0:150]
return flame_vector
# ---------------------------------------------------------
def main():
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f"Loading DECA on {device.upper()}...")
# Initialize standard DECA
deca_cfg.model.use_tex = False
deca_cfg.rasterizer_type = 'pytorch3d'
deca = DECA(config=deca_cfg, device=device)
deca.eval()
print("Wrapping model for seamless 150-dim output...")
wrapper = DecaVisionONNXWrapper(deca).to(device)
wrapper.eval()
print("Tracing and exporting to ONNX...")
dummy_input = torch.randn(1, 3, 224, 224).to(device)
torch.onnx.export(
wrapper,
dummy_input,
"deca_vision.onnx",
export_params=True,
opset_version=17,
do_constant_folding=True,
input_names=['image_input'],
output_names=['flame_vector'],
dynamic_axes={
'image_input': {0: 'batch_size'},
'flame_vector': {0: 'batch_size'}
}
)
print("\nSuccess! 'deca_vision.onnx' is fully baked.")
if __name__ == "__main__":
main()