mav23 commited on
Commit
fbec43b
·
verified ·
1 Parent(s): 1e7dfc2

Create onnx_export.py

Browse files
Files changed (1) hide show
  1. onnx_export.py +108 -0
onnx_export.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import shutil
3
+ from tempfile import TemporaryDirectory
4
+ from typing import List, Optional, Tuple
5
+
6
+ from huggingface_hub import (
7
+ CommitOperationAdd,
8
+ HfApi,
9
+ )
10
+ from huggingface_hub.file_download import repo_folder_name
11
+ from optimum.exporters.onnx import main_export
12
+
13
+ SPACES_URL = "https://huggingface.co/spaces/onnx/export"
14
+
15
+
16
+ def previous_pr(api: "HfApi", model_id: str, pr_title: str) -> Optional["Discussion"]:
17
+ try:
18
+ discussions = api.get_repo_discussions(repo_id=model_id)
19
+ except Exception:
20
+ return None
21
+ for discussion in discussions:
22
+ if (
23
+ discussion.status == "open"
24
+ and discussion.is_pull_request
25
+ and discussion.title == pr_title
26
+ ):
27
+ return discussion
28
+
29
+
30
+ def export_and_git_add(model_id: str, task: str, folder: str, opset: int) -> List:
31
+ main_export(
32
+ model_name_or_path=model_id,
33
+ output=folder,
34
+ task=task,
35
+ opset=opset,
36
+ )
37
+
38
+ n_files = len(
39
+ [
40
+ name
41
+ for name in os.listdir(folder)
42
+ if os.path.isfile(os.path.join(folder, name)) and not name.startswith(".")
43
+ ]
44
+ )
45
+
46
+ if n_files == 1:
47
+ operations = [
48
+ CommitOperationAdd(
49
+ path_in_repo=file_name, path_or_fileobj=os.path.join(folder, file_name)
50
+ )
51
+ for file_name in os.listdir(folder)
52
+ ]
53
+ else:
54
+ operations = [
55
+ CommitOperationAdd(
56
+ path_in_repo=os.path.join("onnx", file_name),
57
+ path_or_fileobj=os.path.join(folder, file_name),
58
+ )
59
+ for file_name in os.listdir(folder)
60
+ ]
61
+
62
+ return operations
63
+
64
+
65
+ def convert(
66
+ api: "HfApi",
67
+ model_id: str,
68
+ task: str,
69
+ force: bool = False,
70
+ opset: int = None,
71
+ ) -> Tuple[int, "CommitInfo"]:
72
+ pr_title = "Adding ONNX file of this model"
73
+ info = api.model_info(model_id)
74
+ filenames = set(s.rfilename for s in info.siblings)
75
+
76
+ requesting_user = api.whoami()["name"]
77
+
78
+ with TemporaryDirectory() as d:
79
+ folder = os.path.join(d, repo_folder_name(repo_id=model_id, repo_type="models"))
80
+ os.makedirs(folder)
81
+ new_pr = None
82
+ try:
83
+ pr = previous_pr(api, model_id, pr_title)
84
+ if "model.onnx" in filenames and not force:
85
+ raise Exception(f"Model {model_id} is already converted, skipping the export.")
86
+ elif pr is not None and not force:
87
+ url = f"https://huggingface.co/{model_id}/discussions/{pr.num}"
88
+ new_pr = pr
89
+ raise Exception(
90
+ f"Model {model_id} already has an open PR check out [{url}]({url})"
91
+ )
92
+ else:
93
+ operations = export_and_git_add(model_id, task, folder, opset)
94
+
95
+ commit_description = f"""I am using the [ONNX Exporter tool 🤖🏎️]({SPACES_URL}) to convert this model to ONNX format. I, [{requesting_user}](https://huggingface.co/{requesting_user}), would like to add the converted ONNX model to this repository.
96
+ What is ONNX? It stands for "Open Neural Network Exchange", and is the most commonly used open standard for machine learning interoperability. You can find out more at [onnx.ai](https://onnx.ai/)!
97
+ The exported ONNX model can be then be consumed by various backends as TensorRT or TVM, or simply be used in a few lines with 🤗 Optimum through ONNX Runtime, check out how [here](https://huggingface.co/docs/optimum/main/en/onnxruntime/usage_guides/models)!
98
+ """
99
+ new_pr = api.create_commit(
100
+ repo_id=model_id,
101
+ operations=operations,
102
+ commit_message=pr_title,
103
+ commit_description=commit_description, # TODO
104
+ create_pr=True,
105
+ )
106
+ finally:
107
+ shutil.rmtree(folder)
108
+ return "0", new_pr