PersonaLive / src /modeling /onnx_export.py
apolinario's picture
ZeroGPU backend self-test: PersonaLive pipeline on Blackwell
d1d91bf
Raw
History Blame Contribute Delete
3.2 kB
# adapted from https://github.com/NVIDIA/TensorRT/blob/main/demo/Diffusion/utilities.py
#
# Copyright 2022 The HuggingFace Inc. team.
# SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import onnx
import gc
import onnx_graphsurgeon as gs
import torch
from onnx import shape_inference
from polygraphy.backend.onnx.loader import fold_constants
import os
from onnxsim import simplify
@torch.no_grad()
def export_onnx(
model,
onnx_path: str,
opt_image_height: int,
opt_image_width: int,
opt_batch_size: int,
onnx_opset: int,
dtype,
device,
auto_cast: bool = True,
):
from contextlib import contextmanager
@contextmanager
def auto_cast_manager(enabled):
if enabled:
with torch.inference_mode(), torch.autocast("cuda"):
yield
else:
yield
# 确保父目录存在
os.makedirs(os.path.dirname(onnx_path), exist_ok=True)
with auto_cast_manager(auto_cast):
inputs = model.get_sample_input(opt_batch_size, opt_image_height, opt_image_width, dtype, device)
print(model.get_output_names())
print(f"开始导出 ONNX 模型到: {onnx_path} ...")
torch.onnx.utils.export(
model,
inputs,
onnx_path,
export_params=True,
opset_version=onnx_opset,
do_constant_folding=True,
input_names=model.get_input_names(),
output_names=model.get_output_names(),
dynamic_axes=model.get_dynamic_axes(),
)
del model
gc.collect()
torch.cuda.empty_cache()
def optimize_onnx(onnx_path, onnx_opt_path):
model = onnx.load(onnx_path)
name = os.path.splitext(os.path.basename(onnx_opt_path))[0]
model_opt = model
print(f"Saving to {onnx_opt_path}...")
onnx.save(
model_opt,
onnx_opt_path,
save_as_external_data=True,
all_tensors_to_one_file=True,
location=f"{name}.onnx.data",
size_threshold=1024
)
print("Optimization done.")
def handle_onnx_batch_norm(onnx_path: str):
onnx_model = onnx.load(onnx_path)
for node in onnx_model.graph.node:
if node.op_type == "BatchNormalization":
for attribute in node.attribute:
if attribute.name == "training_mode":
if attribute.i == 1:
node.output.remove(node.output[1])
node.output.remove(node.output[1])
attribute.i = 0
onnx.save_model(onnx_model, onnx_path)