-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathplot_export_with_modelbuilder.py
More file actions
128 lines (107 loc) · 3.51 KB
/
Copy pathplot_export_with_modelbuilder.py
File metadata and controls
128 lines (107 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""
.. _l-plot-export-model-builder:
Export with ModelBuilder
========================
"""
import sys
import os
import pandas
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoConfig
from onnx_diagnostic import doc
from onnx_diagnostic.investigate.input_observer import InputObserver
from onnx_diagnostic.helpers.rt_helper import onnx_generate
from onnx_diagnostic.torch_export_patches import (
register_additional_serialization_functions,
torch_export_patches,
)
from onnx_diagnostic.export.api import to_onnx
def generate_text(
prompt,
model,
tokenizer,
max_length=50,
temperature=0.01,
top_k=50,
top_p=0.95,
do_sample=True,
device="cpu",
):
inputs = tokenizer(prompt, return_tensors="pt")
input_ids = inputs["input_ids"].to(device)
attention_mask = inputs["attention_mask"].to(device)
outputs = model.generate(
input_ids=input_ids,
attention_mask=attention_mask,
max_length=max_length,
temperature=temperature,
top_k=top_k,
top_p=top_p,
do_sample=do_sample,
)
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
return generated_text
# %%
# filename for the model
MODEL_NAME = sys.argv[1] if sys.argv and len(sys.argv) > 1 else "arnir0/Tiny-LLM"
cache_dir = "dump_modelbuilder"
os.makedirs(cache_dir, exist_ok=True)
name = MODEL_NAME.replace("/", "_")
filename = os.path.join(cache_dir, f"plot_export_with_modelbuilder_{name}.onnx")
# %%
# Creating the model
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
if not os.path.exists(filename):
print(f"-- creating... on {device} into {filename!r}")
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, dtype=torch.bfloat16)
model = model.to(device)
config = model.config
else:
config = AutoConfig.from_pretrained(MODEL_NAME)
# %%
# Capturing inputs/outputs to infer dynamic shapes and arguments
print("-- capturing...")
prompt = "Continue: it rains, what should I do?"
if not os.path.exists(filename):
observer = InputObserver()
with register_additional_serialization_functions(patch_transformers=True), observer(model):
generate_text(prompt, model, tokenizer, device=device)
# %%
# Exporting.
if not os.path.exists(filename):
print("-- exporting...")
observer.remove_inputs(["cache_position", "logits_to_keep", "position_ids"])
ds = observer.infer_dynamic_shapes(set_batch_dimension_for=True)
kwargs = observer.infer_arguments()
with torch_export_patches(patch_transformers=True):
to_onnx(
model,
filename=filename,
kwargs=kwargs,
dynamic_shapes=ds,
exporter="modelbuilder",
)
data = observer.check_discrepancies(filename, progress_bar=True)
print(pandas.DataFrame(data))
# %%
# ONNX Prompt
# +++++++++++
print("-- ONNX prompts...")
inputs = tokenizer(prompt, return_tensors="pt")
input_ids = inputs["input_ids"].to(device)
attention_mask = inputs["attention_mask"].to(device)
onnx_tokens = onnx_generate(
filename,
input_ids=input_ids,
attention_mask=attention_mask,
eos_token_id=config.eos_token_id,
max_new_tokens=50,
)
onnx_generated_text = tokenizer.decode(onnx_tokens, skip_special_tokens=True)
print("-----------------")
print("\n".join(onnx_generated_text))
print("-----------------")
# %%
if os.stat(filename).st_size < 2**14:
doc.save_fig(doc.plot_dot(filename), f"{filename}.png", dpi=400)