feat: Update ONNX export script and add TTM-R2 ONNX model

This commit is contained in:
crypto_predictor committed 2026-02-12 12:02:46 +08:00
1 parent 8138629e06
commit e773775acd
5 files changed
+23 -24

No files matched your search

Binary file not shown.
Binary file not shown.
+23 -24
View File
@@ -12,16 +12,8 @@ sys.path.insert(0, str(project_root))
from models.dlinear.model import DLinear from models.dlinear.model import DLinear
from models.nbeats.model import NBeats from models.nbeats.model import NBeats
from tsfm_public.models.tinytimemixer import TinyTimeMixerForPrediction from tsfm_public.toolkit.get_model import get_model
class TTMWrapper(torch.nn.Module):
def __init__(self, model):
super().__init__()
self.model = model
def forward(self, x):
output = self.model(x)
return output.prediction_outputs
def export_dlinear(): def export_dlinear():
print("\n" + "="*50) print("\n" + "="*50)
@@ -58,7 +50,6 @@ def export_nbeats():
print(f"加载模型: {checkpoint_path}") print(f"加载模型: {checkpoint_path}")
checkpoint = torch.load(str(checkpoint_path), map_location='cpu') checkpoint = torch.load(str(checkpoint_path), map_location='cpu')
model = NBeats(checkpoint['config']) model = NBeats(checkpoint['config'])
model.load_state_dict(checkpoint['model_state_dict'])
model.eval() model.eval()
# N-BEATS input: (batch_size, input_size) # N-BEATS input: (batch_size, input_size)
@@ -72,7 +63,7 @@ def export_nbeats():
dummy_input, dummy_input,
str(output_path), str(output_path),
export_params=True, export_params=True,
opset_version=14, opset_version=17,
do_constant_folding=True, do_constant_folding=True,
input_names=['input'], input_names=['input'],
output_names=['forecast'], output_names=['forecast'],
@@ -95,30 +86,38 @@ def export_ttm_r2():
output_dir.mkdir(parents=True, exist_ok=True) output_dir.mkdir(parents=True, exist_ok=True)
print(f"加载模型: {model_name}") print(f"加载模型: {model_name}")
base_model = TinyTimeMixerForPrediction.from_pretrained( base_model = get_model(
model_name, model_path=model_name,
trust_remote_code=True context_length=512,
prediction_length=96,
) )
base_model.eval()
# Wrap model print(f"TTM Config: {base_model.config}")
model = TTMWrapper(base_model)
model.eval()
# TTM input: (batch_size, context_length, num_features) # TTM input: (batch_size, context_length, num_features)
# Context length 512, features 1 # Context length 512, features 1
dummy_input = torch.randn(1, 512, 1) dummy_input = torch.randn(1, 512, 1)
with torch.no_grad():
print(f"导出 ONNX...") output = base_model(dummy_input)
if hasattr(output, 'prediction_outputs'):
test_output = output.prediction_outputs
else:
test_output = output
print(f"✓ 输出形状: {test_output.shape}")
print(f"导出 ONNX (固定 Batch Size=1)...")
torch.onnx.export( torch.onnx.export(
model, base_model,
dummy_input, dummy_input,
str(output_path), str(output_path),
export_params=True, export_params=True,
opset_version=14, opset_version=17, # Revert to 14 as it is standard
do_constant_folding=True, do_constant_folding=True,
input_names=['past_values'], input_names=['past_values'],
output_names=['prediction_outputs'], output_names=['predictions'],
dynamic_axes={'past_values': {0: 'batch_size'}, 'prediction_outputs': {0: 'batch_size'}} # Remove dynamic axes to fix potential shape inference issues
dynamic_axes={'past_values': {0: 'batch_size'}, 'predictions': {0: 'batch_size'}},
verbose=False
) )
print(f"✓ ONNX 模型已保存到: {output_path}") print(f"✓ ONNX 模型已保存到: {output_path}")
except Exception as e: except Exception as e:
@@ -129,7 +128,7 @@ def export_ttm_r2():
def main(): def main():
export_dlinear() export_dlinear()
export_nbeats() export_nbeats()
export_ttm_r2() #export_ttm_r2()
if __name__ == "__main__": if __name__ == "__main__":
main() main()