frontend.py Source File

frontend.py Source File#

Mobilint SDK qb Compiler: frontend.py Source File
Mobilint SDK qb Compiler v1.0
MCS002-KR
frontend.py
Go to the documentation of this file.
1
4
5import pathlib
6from pathlib import Path
7from typing import Any, Optional
8
9import torch
10
11from qbcompiler.compiler.compiler import Compiler
12from qbcompiler.compiler.compiler import _quantization_task
13from qbcompiler.configs import *
14from qbcompiler.version import __version__
15
16
21
22
23class Model_Dict(Compiler):
24 """
25 @brief Wrapper around the Mobilint compiler to support compilation and inference workflows.
26
27 @details Capabilities include:
28 - Compilation of models into MXQ artifacts runnable on Mobilint NPUs.
29 - Inference using the full-precision high-level compiled model on CPU or GPU.
30 - Inference with the quantized model on CPU or GPU.
31 """
32
34 self,
35 model,
36 backend="onnx",
37 device="cpu",
38 feed_dict=None,
39 dynamic_axes=None,
40 in_dformats=None,
41 yolo_decode_include=False,
42 use_custom_mask=False,
43 exclude_first_subgraph=False,
44 **kwargs,
45 ):
46 """
47 @brief Initialize the Mobilint compiler wrapper.
48
49 @param model string or model instance. Model path or in-memory model to compile.
50 @param backend string. Framework identifier for the model (for example "onnx"). Defaults to "onnx".
51 @param device string. Target device for inference ("cpu" or "gpu"). Defaults to "cpu".
52 @param feed_dict dict. Example inputs for shape resolution.
53 @param dynamic_axes dict. Marks model axes as dynamic.
54 @param in_dformats dict. Describes input data formats.
55 @param yolo_decode_include bool. Runs YOLO decode on NPU when @c True.
56 @param use_custom_mask bool. For non-LLM models that include a mask, use a custom mask provided as a separate input instead of the causal mask.
57 @param exclude_first_subgraph bool. Applies only when CPU offloading is enabled: exclude the first subgraph from the final graph if it is unsupported.
58 @param kwargs dict. Additional compiler arguments.
59 """
60 super().__init__(
61 model=model,
62 backend=backend,
63 device=device,
64 feed_dict=feed_dict,
65 in_dformats=in_dformats,
66 dynamic_axes=dynamic_axes,
67 yolo_decode_include=yolo_decode_include,
68 use_custom_mask=use_custom_mask,
69 exclude_first_subgraph=exclude_first_subgraph,
70 **kwargs,
71 )
72
74 self,
75 calib_data_path: str = None,
76 save_path: str = None,
77 save_subgraph_type: int = 0,
78 output_subgraph_path="",
79 model_nickname: str = None,
80 save_sample=False,
81 use_random_calib=False,
82 inference_scheme="single",
83 cpu_offload=False,
84 optimize_option=1,
85 sample_dtype: str = "float",
86 buffer_mode=1,
87 compile_config=None, # CompileConfig object
88 **kwargs,
89 ):
90 """
91 @brief Compile the wrapped model into an MXQ artifact.
92
93 @param calib_data_path string. Calibration dataset directory or meta file (.txt/.json) listing NumPy samples.
94 @param save_path string. Output MXQ filename.
95 @param save_subgraph_type int. Controls optional MBLT exports: 0 disables; 1 saves graph structure; 2 saves
96 structure and weights; 3 splits structure into multiple subgraphs; 4 splits structure and weights.
97 @param output_subgraph_path string. Destination for exported .mblt when @p save_subgraph_type is 1–4.
98 @param model_nickname string. Friendly name stored in qbcompiler for faster recompile.
99 @param save_sample bool. Persists inputs/outputs for debugging in ./sampleInOut.
100 @param use_random_calib bool. Uses randomly generated calibration samples when @c True.
101 @param inference_scheme string. NPU inference configuration ("single", "multi", "global", etc.).
102 @param cpu_offload bool. Enables CPU offload for unsupported groups.
103 @param optimize_option int. Compiler optimization selector.
104 @param sample_dtype string. Data type used for saved sample outputs.
105 @param buffer_mode int. Buffer serialization mode (0 naive, 1 mmap).
106 @param compile_config CompileConfig. Compile configuration object.
107 @param kwargs dict. Additional arguments forwarded to the compiler.
108
109 """
110 super().compile(
111 calib_data_path=calib_data_path,
112 save_path=save_path,
113 save_subgraph_type=save_subgraph_type,
114 output_subgraph_path=output_subgraph_path,
115 model_nickname=model_nickname,
116 save_sample=save_sample,
117 inference_scheme=inference_scheme,
118 use_random_calib=use_random_calib,
119 cpu_offload=cpu_offload,
120 optimize_option=optimize_option,
121 sample_dtype=sample_dtype,
122 buffer_mode=buffer_mode,
123 compile_config=compile_config,
124 **kwargs,
125 )
126
127
128def mxq_compile(
129 model,
130 calib_data_path: str = "",
131 save_subgraph_type: int = 0,
132 output_subgraph_path="",
133 model_nickname: str = None,
134 save_path: str = None,
135 backend="onnx",
136 device="cpu",
137 feed_dict=None,
138 dynamic_axes=None,
139 in_dformats=None,
140 save_sample=False,
141 inference_scheme="single",
142 yolo_decode_include=False,
143 use_random_calib=False,
144 cpu_offload=False,
145 optimize_option=1,
146 sample_dtype="float",
147 buffer_mode=1,
148 input_shape_dict=dict(),
149 use_custom_mask=False,
150 exclude_first_subgraph=False,
151 compile_config: Optional[CompileConfig] = None,
152 resource_management_config: Optional[ResourceManagementConfig] = None,
153 quantization_config: Optional[QuantizationConfig] = None,
154 advanced_quantization_config: Optional[AdvancedQuantizationConfig] = None,
155 llm_config: Optional[LlmConfig] = None,
156 input_process_config: Optional[InputProcessConfig] = None,
157 **kwargs,
158):
159 """
160 @brief Compile a model into a Mobilint eXeCUtable (MXQ) package for execution on Mobilint NPUs.
161
162 @param model string or model instance. Model path. When using @c backend="onnx", this should be the path to an ONNX
163 model file. When @c backend is "torchscript", provide a TorchScript module; when "torch", provide a standard
164 PyTorch model. For @c backend="tf", pass the directory that contains the TensorFlow SavedModel graph and assets. For
165 @c backend="tflite", pass the TF Lite model path.
166 @param calib_data_path string. Path to the calibration dataset. Accepts either a text/json file that lists NumPy
167 files or a directory that contains the pre-processed NumPy files.
168 @param save_subgraph_type int. Controls optional MBLT subgraph exports: 0 disables exports; 1 saves only the graph
169 structure; 2 saves graph structure plus weights; 3 saves the graph structure split into multiple subgraphs; 4 saves
170 both structure and weights split into multiple subgraphs.
171 @param output_subgraph_path string. Destination path for the exported .mblt file when @p save_subgraph_type is 1, 2,
172 3, or 4. The resulting file can be used for visualization.
173 @param model_nickname string. Friendly name stored in qbcompiler. Defaults to the model basename (for example, the file
174 "/workspace/onnx/resnet50.onnx" becomes "resnet50"). Falls back to "temporary" when it cannot be inferred.
175 @param save_path string. Output MXQ filename. Defaults to "{model_nickname}.mxq" when omitted.
176 @param backend string. Framework used to generate the Mobilint IR. Must be one of "onnx", "tf", "tflite",
177 "torchscript", or "torch". Defaults to "onnx".
178 @param device string. Compilation and inference device: "cpu" or "gpu". Defaults to "cpu".
179 @param feed_dict dict. Example input tensors for shape inference and inference validation.
180 @param dynamic_axes dict. Marks model axes as dynamic. Keys are input names and values map dimension indices to
181 aliases (for example {"input": {2: "seq_len"}}).
182 @param in_dformats dict. Describes input tensor data formats.
183 @param save_sample bool. Stores input/output tensors in ./sampleInOut when @c True to aid debugging. Defaults to
184 @c False.
185 @param inference_scheme string. NPU inference scheme. One of "single", "multi", "global", "global4", or
186 "global8".
187 @param yolo_decode_include bool. Determines whether YOLO decode runs on NPU.
188 @param use_random_calib bool. Generates random calibration data to validate model compilability. Defaults to @c
189 False.
190 @param cpu_offload bool. Enables CPU offloading during NPU inference. Defaults to @c False.
191 @param optimize_option int. Compiler optimization strategy selector.
192 @param sample_dtype string. Data type for saved sample inference outputs: "float" or "int8".
193 @param buffer_mode int. Buffer serialization mode: 0 uses a naïve buffer, 1 uses an mmap-backed buffer. Defaults to
194 1.
195 @param input_shape_dict:multi-shape compilation specification for STT/TTS models only (e.g., Conformer-CTC, MeloTTS).
196 The dynamic axis is defined with respect to each input tensor’s shape. During compilation, the same axis is varied across all model inputs
197 using the provided values. Currently, only a single entry key ("multi_shape0") is supported. Example: {"multi_shape0": {"axis": 2, "values": [100, 200, 300]}}
198 @param use_custom_mask bool. For non-LLM models that include a mask, use a custom mask provided as a separate input instead of the causal mask.
199 For LLMs that incorporate RoPE, setting LLMConfig.dynamic_rope to True not only enables the use of dynamic RoPE provided via an additional input, but also activates the custom mask.
200 @param exclude_first_subgraph bool. Applies only when CPU offloading is enabled: exclude the first subgraph from the final graph if it is unsupported.
201 @param compile_config string. Path to JSON configuration file containing all quantization-related settings
202 (resourceManagement, quantization, advancedQuantization, llmConfig). If provided, this takes precedence over
203 individual sub-config parameters.
204 @param resource_management_config ResourceManagementConfig. Resource management configuration object.
205 @param quantization_config QuantizationConfig. Quantization configuration object.
206 @param advanced_quantization_config AdvancedQuantizationConfig. Advanced quantization configuration object.
207 @param llm_config LlmConfig. LLM configuration object.
208 @param input_process_config InputProcessConfig. Unified input processing configuration containing
209 uint8 input handling, image channels, and preprocessing pipeline settings.
210 @param kwargs dict. Additional compiler arguments propagated to the backend implementation. Moreover, If you want to override only
211 a subset of configuration values, you can pass them to `mxq_compile` as keyword arguments (`kwargs`), and they will be applied.
212 Note that `AdvancedQuantizationConfig` and its sub-configurations are not updated automatically from `kwargs`. In contrast, `ResourceManagementConfig`,
213 `QuantizationConfig`, and `LlmConfig` support automatic updates via each configuration class’s `from_kwargs` method. See Example 3 below for a usage example.
214 @return None.
215
216 @par Using configuration
217 There are two ways to configure quantization settings:
218
219 1. Load all settings from a JSON config file:
220 @code{.py}
221 from qbcompiler import mxq_compile
222
223 mxq_compile(
224 model="path/to/model.onnx",
225 calib_data_path="path/to/calib",
226 compile_config="path/to/config.json",
227 device="gpu",
228 )
229 @endcode
230
231 2. Pass individual sub-config objects:
232 @code{.py}
233 from qbcompiler import mxq_compile
234 from qbcompiler.configs import (
235 ResourceManagementConfig,
236 QuantizationConfig,
237 AdvancedQuantizationConfig,
238 LlmConfig,
239 )
240
241 resource_mgmt = ResourceManagementConfig(weight_dtype="float32")
242 quant_cfg = QuantizationConfig(...)
243 adv_quant_cfg = AdvancedQuantizationConfig(...)
244 llm_cfg = LlmConfig(...)
245
246 mxq_compile(
247 model="path/to/model.onnx",
248 calib_data_path="path/to/calib",
249 resource_management_config=resource_mgmt,
250 quantization_config=quant_cfg,
251 advanced_quantization_config=adv_quant_cfg,
252 llm_config=llm_cfg,
253 device="gpu",
254 )
255 @endcode
256
257 3. Automatically applied partial configuration overrides:
258 @code{.py}
259 from qbcompiler import mxq_compile
260
261 mxq_compile(
262 model="path/to/model.onnx",
263 calib_data_path="path/to/calib",
264 quantization_method=1, # per channel quantization
265 quantization_mode=1, # max percentile quantization
266 percentile=0.999, # percentile value for max percentile quantization
267 quantization_output=0, # per layer quantization for the output layer
268 device="gpu",
269 )
270 @endcode
271 Please refer to the mxq_compile function and the quantization configuration section for the meaning of the quantization-related numeric values.
272
273
274 @par Compiling models with custom inputs (ONNX/Torch/TensorFlow)
275 Provide NumPy inputs whenever the model omits shape information so that qbcompiler can infer unknown dimensions and data
276 formats.
277
278 @code{.py}
279 from qbcompiler import mxq_compile
280 import numpy as np
281
282 example_input = {
283 "input_node_name_1": np.random.randn(1, 3, 224, 224).astype(np.float32),
284 "input_node_name_2": np.random.randn(1, 8, 224, 224).astype(np.float32),
285 "input_node_name_3": np.random.randn(1, 4, 56, 56).astype(np.float32),
286 }
287
288 in_dformats = {
289 "input_node_name_1": "NCHW",
290 "input_node_name_2": "NCHW",
291 "input_node_name_3": "NCHW",
292 }
293
294 onnx_model_path = "path/to/your/model.onnx"
295 mxq_compile(
296 model=onnx_model_path,
297 feed_dict=example_input,
298 in_dformats=in_dformats,
299 backend="onnx",
300 compile_config="path/to/config.json",
301 )
302 @endcode
303 """
304 if model_nickname and isinstance(model_nickname, str):
305 model_name = model_nickname
306 elif isinstance(model, str): # in the case of model path
307 model_name = Path(model).stem
308 else: # in the case of model instance
309 if save_path is None:
310 raise ValueError("Please set the save_path with .mxq extension")
311 model_name = "model"
312 if save_path is None:
313 save_path = f"{model_name}.mxq"
314
315 # Handle config loading
316 if compile_config is not None:
317 # Accept both CompileConfig object and JSON file path
318 if isinstance(compile_config, CompileConfig):
319 compile_cfg = compile_config
320 elif isinstance(compile_config, str):
321 compile_cfg = CompileConfig.from_json(
322 compile_config,
323 calib_data_path=calib_data_path,
324 use_random_calib=use_random_calib,
325 save_path=save_path,
326 save_msgpack_name=None,
327 model_nickname=model_name,
328 model_path=None,
329 inference_scheme=inference_scheme,
330 save_sample=save_sample,
331 cpu_offload=cpu_offload,
332 optimize_option=optimize_option,
333 sample_dtype=sample_dtype,
334 buffer_mode=buffer_mode,
335 version=__version__,
336 input_shape_dict=input_shape_dict,
337 )
338 else:
339 raise ValueError(
340 "compile_config must be either a CompileConfig object or a path to JSON configuration file"
341 )
342 else:
343 pairs = [
344 (
345 "resource_management_config",
346 resource_management_config,
347 ResourceManagementConfig,
348 ),
349 ("quantization_config", quantization_config, QuantizationConfig),
350 (
351 "advanced_quantization_config",
352 advanced_quantization_config,
353 AdvancedQuantizationConfig,
354 ),
355 ("llm_config", llm_config, LlmConfig),
356 ("input_process_config", input_process_config, InputProcessConfig),
357 ]
358 for name, obj, expected_cls in pairs:
359 if obj is None:
360 continue
361 if not isinstance(obj, expected_cls):
362 raise TypeError(
363 f"Invalid type for '{name}': expected {expected_cls.__name__} or None, "
364 f"but got {type(obj).__name__}."
365 )
366
367 compile_cfg = get_compile_config(
368 calib_data_path=calib_data_path,
369 use_random_calib=use_random_calib,
370 save_path=save_path,
371 save_msgpack_name=None,
372 model_nickname=model_name,
373 model_path=None,
374 inference_scheme=inference_scheme,
375 save_sample=save_sample,
376 cpu_offload=cpu_offload,
377 optimize_option=optimize_option,
378 sample_dtype=sample_dtype,
379 buffer_mode=buffer_mode,
380 version=__version__,
381 input_shape_dict=input_shape_dict,
382 resource_management_config=resource_management_config,
383 quantization_config=quantization_config,
384 llm_config=llm_config,
385 advanced_quantization_config=advanced_quantization_config, # AdvancedQuantizationConfig config don't use "from_kwargs" because of shared key names, such as "apply".
386 input_process_config=input_process_config,
387 **kwargs,
388 )
389
390 if isinstance(model, str) and model.endswith(".mblt") and os.path.isfile(model):
391 _quantization_task(model, device, compile_config=compile_cfg)
392 else:
393 model_dict = Model_Dict(
394 model=model,
395 backend=backend,
396 device=device,
397 feed_dict=feed_dict,
398 in_dformats=in_dformats,
399 dynamic_axes=dynamic_axes,
400 yolo_decode_include=yolo_decode_include,
401 use_custom_mask=use_custom_mask,
402 exclude_first_subgraph=exclude_first_subgraph,
403 **kwargs,
404 )
405 model_dict.compile(
406 model_nickname=model_name,
407 calib_data_path=calib_data_path,
408 save_path=save_path,
409 save_subgraph_type=save_subgraph_type,
410 output_subgraph_path=output_subgraph_path,
411 save_sample=save_sample,
412 inference_scheme=inference_scheme,
413 use_random_calib=use_random_calib,
414 cpu_offload=cpu_offload,
415 optimize_option=optimize_option,
416 sample_dtype=sample_dtype,
417 buffer_mode=buffer_mode,
418 compile_config=compile_cfg,
419 )
420 torch.cuda.empty_cache()
421 del model_dict
422
423
424def mblt_compile(
425 model: str | Any,
426 mblt_save_path: str,
427 backend="onnx",
428 device="cpu",
429 feed_dict=None,
430 dynamic_axes=None,
431 in_dformats=None,
432 yolo_decode_include=False,
433 cpu_offload=False,
434 use_custom_mask=False,
435 exclude_first_subgraph=False,
436 **kwargs,
437):
438 """
439 @brief Export a model to the Mobilint .mblt format without producing an MXQ package.
440
441 @param model string or model instance. Source model or path to compile.
442 @param mblt_save_path string. Output path for the .mblt artifact.
443 @param backend string. Framework identifier ("onnx", "tf", "tflite", "torchscript", or "torch"). Defaults to
444 "onnx".
445 @param device string. Compilation device ("cpu" or "gpu"). Defaults to "cpu".
446 @param feed_dict dict. Example inputs used for shape inference.
447 @param dynamic_axes dict. Declares dynamic axes per input name.
448 @param in_dformats dict. Input dataformat metadata.
449 @param yolo_decode_include bool. Runs YOLO decode on NPU when True.
450 @param cpu_offload bool. Enables CPU offloading for unsupported groups.
451 @param use_custom_mask bool. For non-LLM models that include a mask, use a custom mask provided as a separate input instead of the causal mask.
452 For LLMs that incorporate RoPE, setting LLMConfig.dynamic_rope to True not only enables the use of dynamic RoPE provided via an additional input, but also activates the custom mask.
453 @param exclude_first_subgraph bool. Applies only when CPU offloading is enabled: exclude the first subgraph from the final graph if it is unsupported.
454 @param kwargs dict. Additional arguments forwarded to the compiler.
455 @return None.
456 """
457 model_dict = Model_Dict(
458 model=model,
459 backend=backend,
460 device=device,
461 feed_dict=feed_dict,
462 dynamic_axes=dynamic_axes,
463 in_dformats=in_dformats,
464 yolo_decode_include=yolo_decode_include,
465 use_custom_mask=use_custom_mask,
466 exclude_first_subgraph=exclude_first_subgraph,
467 **kwargs,
468 )
469
470 model_dict.mblt_compile(
471 model,
472 mblt_save_path=mblt_save_path,
473 backend=backend,
474 cpu_offload=cpu_offload,
475 **kwargs,
476 )
477
478
479
481
482
483def run_mblt_model(
484 path_to_mblt: str,
485 save_all_outputs: bool = True,
486 inference_output_path: Optional[str] = None,
487 target_subgraph: Optional[int] = None,
488):
489 from qbcompiler.model_dict.common.model_dict import ValueDict
490 from qbcompiler.model_dict.inference.model import ModelInference
491 from qbcompiler.model_dict.serialize import load_mblt_model
492
493 assert path_to_mblt.endswith(".mblt")
494 if not save_all_outputs:
495 raise NotImplementedError(
496 f"save_all_outputs={save_all_outputs} is not supported yet."
497 )
498 if target_subgraph:
499 raise NotImplementedError(
500 f"target_subgraph={target_subgraph} is not supported yet."
501 )
502 import numpy
503
504 if not inference_output_path:
505 inference_output_path = str(pathlib.Path(path_to_mblt).with_suffix(".infer"))
506
507 vd = ValueDict()
508 md, wd = load_mblt_model(path_to_mblt, load_weight=True)
509 for sg in md.subgraphs:
510 for iidx in sg.inputs:
511 inact = sg.activations[iidx]
512 if inact.name in set(md.inputs):
513 vd[inact.name] = numpy.random.random(tuple(map(int, inact.src_shape)))
514
515 model_inference = ModelInference(
516 model_dict=md,
517 weight_dict=wd,
518 value_dict=vd,
519 save_all_outputs=save_all_outputs,
520 inference_all_outputs_write_path=inference_output_path,
521 )
522
523 model_inference.run_inference(use_value_dict_data_for_next_input=False)
Wrapper around the Mobilint compiler to support compilation and inference workflows.
Definition frontend.py:23
compile(self, str calib_data_path=None, str save_path=None, int save_subgraph_type=0, output_subgraph_path="", str model_nickname=None, save_sample=False, use_random_calib=False, inference_scheme="single", cpu_offload=False, optimize_option=1, str sample_dtype="float", buffer_mode=1, compile_config=None, **kwargs)
Compile the wrapped model into an MXQ artifact.
Definition frontend.py:89
__init__(self, model, backend="onnx", device="cpu", feed_dict=None, dynamic_axes=None, in_dformats=None, yolo_decode_include=False, use_custom_mask=False, exclude_first_subgraph=False, **kwargs)
Initialize the Mobilint compiler wrapper.
Definition frontend.py:45
mxq_compile(model, str calib_data_path="", int save_subgraph_type=0, output_subgraph_path="", str model_nickname=None, str save_path=None, backend="onnx", device="cpu", feed_dict=None, dynamic_axes=None, in_dformats=None, save_sample=False, inference_scheme="single", yolo_decode_include=False, use_random_calib=False, cpu_offload=False, optimize_option=1, sample_dtype="float", buffer_mode=1, input_shape_dict=dict(), use_custom_mask=False, exclude_first_subgraph=False, Optional[CompileConfig] compile_config=None, Optional[ResourceManagementConfig] resource_management_config=None, Optional[QuantizationConfig] quantization_config=None, Optional[AdvancedQuantizationConfig] advanced_quantization_config=None, Optional[LlmConfig] llm_config=None, Optional[InputProcessConfig] input_process_config=None, **kwargs)
Compile a model into a Mobilint eXeCUtable (MXQ) package for execution on Mobilint NPUs.
Definition frontend.py:158
mblt_compile(str|Any model, str mblt_save_path, backend="onnx", device="cpu", feed_dict=None, dynamic_axes=None, in_dformats=None, yolo_decode_include=False, cpu_offload=False, use_custom_mask=False, exclude_first_subgraph=False, **kwargs)
Export a model to the Mobilint .mblt format without producing an MXQ package.
Definition frontend.py:437