frontend.py Source File

frontend.py Source File#

Mobilint SDK qb Compiler: frontend.py Source File
Mobilint SDK qb Compiler v1.1
MCS002-EN
frontend.py
Go to the documentation of this file.
1
4
5import os
6import pathlib
7import warnings
8from pathlib import Path
9from typing import Any, List, Optional, Union
10
11import torch
12
13from qbcompiler.compiler.compiler import Compiler
14from qbcompiler.compiler.compiler import _quantization_task
15from qbcompiler.configs import (
16 CompileConfig,
17 CalibrationConfig,
18 BitConfig,
19 ResourceManagementConfig,
20 OptqConfig,
21 ModConfig,
22 LlmConfig,
23 EquivalentTransformationConfig,
24 SearchWeightScaleConfig,
25 SaveSampleConfig,
26 Uint8InputConfig,
27 PreprocessingConfig,
28)
29from qbcompiler.compiler.utils import _to_list
30from qbcompiler.version import __version__
31
32_UNSET = object()
33"""Sentinel to distinguish 'not passed' from explicit defaults."""
34
35
36def _resolve_deprecated_kwargs(
37 *,
38 calibration_config,
39 optq_config,
40 mod_config,
41 equivalent_transformation_config,
42 search_weight_scale_config,
43 uint8_input_config,
44 preprocessing_config,
45 save_sample_config,
46 **kwargs,
47):
48 """Extract and resolve deprecated parameters from kwargs into modern equivalents.
49
50 Mutates kwargs by popping consumed deprecated keys.
51 Returns a tuple of resolved sub-config values.
52 """
53 quantization_config = kwargs.pop("quantization_config", None)
54 if quantization_config is not None and calibration_config is None:
55 warnings.warn(
56 "quantization_config is deprecated. Use calibration_config instead.",
57 DeprecationWarning,
58 stacklevel=3,
59 )
60 calibration_config = quantization_config
61
62 advanced_quantization_config = kwargs.pop("advanced_quantization_config", None)
63 if advanced_quantization_config is not None:
64 warnings.warn(
65 "advanced_quantization_config is deprecated. Use individual configs "
66 "(optq_config, mod_config, equivalent_transformation_config, search_weight_scale_config) instead.",
67 DeprecationWarning,
68 stacklevel=3,
69 )
70 if hasattr(advanced_quantization_config, "optq") and optq_config is None:
71 optq_config = advanced_quantization_config.optq
72 if hasattr(advanced_quantization_config, "mod") and mod_config is None:
73 mod_config = advanced_quantization_config.mod
74 if (
75 hasattr(advanced_quantization_config, "equivalent_transformation")
76 and equivalent_transformation_config is None
77 ):
78 equivalent_transformation_config = (
79 advanced_quantization_config.equivalent_transformation
80 )
81 if (
82 hasattr(advanced_quantization_config, "search_weight_scale")
83 and search_weight_scale_config is None
84 ):
85 search_weight_scale_config = (
86 advanced_quantization_config.search_weight_scale
87 )
88
89 input_process_config = kwargs.pop("input_process_config", None)
90 if input_process_config is not None:
91 warnings.warn(
92 "input_process_config is deprecated. Use uint8_input_config and preprocessing_config instead.",
93 DeprecationWarning,
94 stacklevel=3,
95 )
96 if hasattr(input_process_config, "uint8_input") and uint8_input_config is None:
97 uint8_input_config = input_process_config.uint8_input
98 if (
99 hasattr(input_process_config, "preprocessing")
100 and preprocessing_config is None
101 ):
102 preprocessing_config = input_process_config.preprocessing
103
104 save_sample = kwargs.pop("save_sample", None)
105 sample_dtype = kwargs.pop("sample_dtype", None)
106 if (
107 save_sample is not None or sample_dtype is not None
108 ) and save_sample_config is None:
109 warnings.warn(
110 "save_sample and sample_dtype are deprecated. Use save_sample_config instead.",
111 DeprecationWarning,
112 stacklevel=3,
113 )
114 save_sample_kwargs = {}
115 if save_sample is not None:
116 save_sample_kwargs["apply"] = save_sample
117 if sample_dtype is not None:
118 save_sample_kwargs["dtype"] = sample_dtype
119 save_sample_config = SaveSampleConfig(**save_sample_kwargs)
120
121 return (
122 calibration_config,
123 optq_config,
124 mod_config,
125 equivalent_transformation_config,
126 search_weight_scale_config,
127 uint8_input_config,
128 preprocessing_config,
129 save_sample_config,
130 )
131
132
133
138
139
140class Model_Dict(Compiler):
141 """
142 @brief Wrapper around the Mobilint compiler to support compilation and inference workflows.
143
144 @details Capabilities include:
145 - Compilation of models into MXQ artifacts runnable on Mobilint NPUs.
146 - Inference using the full-precision high-level compiled model on CPU or GPU.
147 - Inference with the quantized model on CPU or GPU.
148 """
149
151 self,
152 model,
153 backend="onnx",
154 device="cpu",
155 feed_dict=None,
156 dynamic_axes=None,
157 in_dformats=None,
158 yolo_decode_include=False,
159 use_custom_mask=False,
160 exclude_first_subgraph=False,
161 **kwargs,
162 ):
163 """
164 @brief Initialize the Mobilint compiler wrapper.
165
166 @param model string or model instance. Model path or in-memory model to compile.
167 @param backend string. Framework identifier for the model (for example "onnx"). Defaults to "onnx".
168 @param device string. Target device for inference ("cpu" or "gpu"). Defaults to "cpu".
169 @param feed_dict dict. Example inputs for shape resolution.
170 @param dynamic_axes dict. Marks model axes as dynamic.
171 @param in_dformats dict. Describes input data formats.
172 @param yolo_decode_include bool. Runs YOLO decode on NPU when @c True.
173 @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.
174 @param exclude_first_subgraph bool. Applies only when CPU offloading is enabled: exclude the first subgraph from the final graph if it is unsupported.
175 @param kwargs dict. Additional compiler arguments.
176 """
177
178 super().__init__(
179 model=model,
180 backend=backend,
181 device=device,
182 feed_dict=feed_dict,
183 in_dformats=in_dformats,
184 dynamic_axes=dynamic_axes,
185 yolo_decode_include=yolo_decode_include,
186 use_custom_mask=use_custom_mask,
187 exclude_first_subgraph=exclude_first_subgraph,
188 **kwargs,
189 )
190
192 self,
193 save_subgraph_type: int = 0,
194 output_subgraph_path="",
195 compile_config: CompileConfig = None,
196 **kwargs,
197 ):
198 """
199 @brief Compile the wrapped model into an MXQ artifact.
200
201 @param save_subgraph_type int. Controls optional MBLT exports: 0 disables; 1 saves graph structure; 2 saves
202 structure and weights; 3 splits structure into multiple subgraphs; 4 splits structure and weights.
203 @param output_subgraph_path string. Destination for exported .mblt when @p save_subgraph_type is 1–4.
204 @param compile_config CompileConfig. Compile configuration object.
205 @param kwargs dict. Additional arguments forwarded to the compiler.
206
207 """
208 save_sample = kwargs.pop("save_sample", None)
209 sample_dtype = kwargs.pop("sample_dtype", None)
210 if save_sample is not None or sample_dtype is not None:
211 warnings.warn(
212 "save_sample and sample_dtype are deprecated. Use compile_config with saveSample instead.",
213 DeprecationWarning,
214 stacklevel=2,
215 )
216 if compile_config is None:
217 compile_config = CompileConfig()
218 if not compile_config.save_sample.apply:
219 save_sample_kwargs = {}
220 if save_sample is not None:
221 save_sample_kwargs["apply"] = save_sample
222 if sample_dtype is not None:
223 save_sample_kwargs["dtype"] = sample_dtype
224 compile_config = compile_config.with_save_sample(**save_sample_kwargs)
225
226 super().compile(
227 save_subgraph_type=save_subgraph_type,
228 output_subgraph_path=output_subgraph_path,
229 compile_config=compile_config,
230 **kwargs,
231 )
232
233
234def mxq_compile(
235 model,
236 calib_data_path: Union[str, List[str]] = _UNSET,
237 save_subgraph_type: int = 0,
238 output_subgraph_path="",
239 save_path: Union[str, List[str]] = _UNSET,
240 backend="onnx",
241 # -- ModelDict params --
242 feed_dict=None,
243 dynamic_axes=None,
244 in_dformats=None,
245 yolo_decode_include=False,
246 use_custom_mask=False,
247 exclude_first_subgraph=False,
248 # -- CompileConfig-overridable (_UNSET = defer to config) --
249 device=_UNSET,
250 inference_scheme=_UNSET,
251 use_random_calib=_UNSET,
252 cpu_offload=_UNSET,
253 optimize_option=_UNSET,
254 buffer_mode=_UNSET,
255 input_shape_dict=_UNSET,
256 force_npu_input_reposition=_UNSET,
257 force_npu_output_reposition=_UNSET,
258 image_channels=_UNSET,
259 split_blocks=_UNSET,
260 split_parts=_UNSET,
261 # -- Config objects --
262 config_preset: Optional[str] = None,
263 compile_config: Optional[CompileConfig] = None,
264 resource_management_config: Optional[ResourceManagementConfig] = None,
265 calibration_config: Optional[CalibrationConfig] = None,
266 bit_config: Optional[BitConfig] = None,
267 llm_config: Optional[LlmConfig] = None,
268 optq_config: Optional[OptqConfig] = None,
269 mod_config: Optional[ModConfig] = None,
270 equivalent_transformation_config: Optional[EquivalentTransformationConfig] = None,
271 search_weight_scale_config: Optional[SearchWeightScaleConfig] = None,
272 save_sample_config: Optional[SaveSampleConfig] = None,
273 uint8_input_config: Optional[Uint8InputConfig] = None,
274 preprocessing_config: Optional[PreprocessingConfig] = None,
275 **kwargs,
276):
277 """
278 @brief Compile a model into a Mobilint eXeCUtable (MXQ) package for execution on Mobilint NPUs.
279
280 @details When no explicit value is provided for a parameter marked with @c _UNSET, the default
281 from CompileConfig is used. This allows a compile_config file or object to supply the value
282 without being overridden by function-level defaults.
283
284 Configuration is resolved in priority order (highest to lowest):
285 1. Explicitly passed function arguments
286 2. Individual sub-config objects (calibration_config, llm_config, etc.)
287 3. kwargs partial overrides (quantization_method, weight_dtype, etc.)
288 4. compile_config (CompileConfig object or JSON/YAML file) or config_preset
289 5. CompileConfig field defaults
290
291 @param model string or model instance. Model path. When using @c backend="onnx", this should be the path to an ONNX
292 model file. When @c backend is "torchscript", provide a TorchScript module; when "torch", provide a standard
293 PyTorch model. For @c backend="tf", pass the directory that contains the TensorFlow SavedModel graph and assets. For
294 @c backend="tflite", pass the TF Lite model path.
295 @param calib_data_path string or list of strings. Path(s) to the calibration dataset. Accepts either a text/json file
296 that lists NumPy files or a directory that contains the pre-processed NumPy files.
297 @param save_subgraph_type int. Controls optional MBLT subgraph exports: 0 disables exports; 1 saves only the graph
298 structure; 2 saves graph structure plus weights; 3 saves the graph structure split into multiple subgraphs; 4 saves
299 both structure and weights split into multiple subgraphs. Defaults to 0.
300 @param output_subgraph_path string. Destination path for the exported .mblt file when @p save_subgraph_type is 1–4.
301 The resulting file can be used for visualization. Defaults to "".
302 @param save_path string or list of strings. Output MXQ filename(s). When omitted, defaults to "{model_name}.mxq"
303 derived from the model path basename.
304 @param backend string. Framework used to generate the Mobilint IR. Must be one of "onnx", "tf", "tflite",
305 "torchscript", or "torch". Defaults to "onnx".
306 @param device string. Compilation and inference device: "cpu" or "gpu". When omitted, uses CompileConfig default.
307 @param feed_dict dict. Example input tensors for shape inference and inference validation.
308 @param dynamic_axes dict. Marks model axes as dynamic. Keys are input names and values map dimension indices to
309 aliases (for example {"input": {2: "seq_len"}}).
310 @param in_dformats dict. Describes input tensor data formats.
311 @param inference_scheme string. NPU inference scheme. One of "single", "multi", "global", "global4", or
312 "global8". When omitted, uses CompileConfig default.
313 @param yolo_decode_include bool. Determines whether YOLO decode runs on NPU. Defaults to @c False.
314 @param use_random_calib bool. Generates random calibration data to validate model compilability.
315 When omitted, uses CompileConfig default.
316 @param cpu_offload bool. Enables CPU offloading during NPU inference. When omitted, uses CompileConfig default.
317 @param optimize_option int. Compiler optimization strategy selector. When omitted, uses CompileConfig default.
318 @param buffer_mode int. Buffer serialization mode: 0 uses a naive buffer, 1 uses an mmap-backed buffer.
319 When omitted, uses CompileConfig default.
320 @param input_shape_dict dict. Multi-shape compilation specification for STT/TTS models only (e.g., Conformer-CTC,
321 MeloTTS). The dynamic axis is defined with respect to each input tensor's shape. During compilation, the same axis
322 is varied across all model inputs using the provided values. Currently, only a single entry key ("multi_shape0") is
323 supported. Example: {"multi_shape0": {"axis": 2, "values": [100, 200, 300]}}
324 @param force_npu_input_reposition bool. Force input reposition operations to run on NPU instead of CPU.
325 When omitted, uses CompileConfig default.
326 @param force_npu_output_reposition bool. Force output reposition operations to run on NPU instead of CPU.
327 When omitted, uses CompileConfig default.
328 @param image_channels int. Number of image channels (0 for auto-detect).
329 When omitted, uses CompileConfig default.
330 @param split_blocks list of int. Multi-MXQ split points by transformer block index.
331 Only supported for LLM models. When omitted, uses CompileConfig default.
332 @param split_parts int. Evenly split transformer blocks into N MXQ parts.
333 Only supported for LLM models. When omitted, uses CompileConfig default.
334 @param use_custom_mask bool. For non-LLM models that include a mask, use a custom mask provided as a separate input
335 instead of the causal mask. For LLMs that incorporate RoPE, setting LLMConfig.dynamic_rope to @c True not only
336 enables the use of dynamic RoPE provided via an additional input, but also activates the custom mask. Defaults to
337 @c False.
338 @param exclude_first_subgraph bool. Applies only when CPU offloading is enabled: exclude the first subgraph from
339 the final graph if it is unsupported. Defaults to @c False.
340 @param config_preset string. Name of a built-in configuration preset. When provided, loads the preset
341 via CompileConfig.from_preset(). Defaults to None (no preset). Available presets:
342 - "classification": Image classification models (ResNet, EfficientNet, ViT, etc.)
343 - "detection": Object detection models (YOLO, SSD, DETR, etc.)
344 - "classification_torchvision": Torchvision classification models with standard preprocessing
345 - "yolo_640": YOLO detection models with 640x640 letterbox preprocessing
346 - "yolo_1280": YOLO detection models with 1280x1280 letterbox preprocessing
347 - "llm": Large Language Models (LLaMA, Qwen, Gemma, etc.)
348 - "llm_fast": LLM with faster compilation (less accuracy optimization)
349 - "vision_transformer": Vision Transformer models (ViT, DeiT, Swin, etc.)
350 - "multimodal": Multimodal models (CLIP, BLIP, LLaVA, etc.)
351 @param compile_config CompileConfig or string. CompileConfig object or path to JSON/YAML configuration file
352 containing all compilation settings (resourceManagement, calibration, bit, optq, mod, llm, etc.).
353 @param resource_management_config ResourceManagementConfig. Resource management configuration object.
354 @param calibration_config CalibrationConfig. Calibration configuration object.
355 @param bit_config BitConfig. Bit configuration object for quantization precision settings.
356 @param llm_config LlmConfig. LLM configuration object.
357 @param optq_config OptqConfig. OPTQ (Optimal Brain Quantization) configuration object.
358 @param mod_config ModConfig. MOD (Metric-based Optimization and Distillation) configuration object.
359 @param equivalent_transformation_config EquivalentTransformationConfig. Configuration for equivalent
360 transformations like SmoothQuant.
361 @param search_weight_scale_config SearchWeightScaleConfig. Configuration for weight scale search.
362 @param save_sample_config SaveSampleConfig. Configuration for sample data generation and saving.
363 @param uint8_input_config Uint8InputConfig. Configuration for uint8 input handling.
364 @param preprocessing_config PreprocessingConfig. Preprocessing pipeline configuration.
365 @param kwargs dict. Additional compiler arguments. Supports partial config overrides such as
366 @c quantization_method, @c quantization_mode, @c percentile, @c weight_dtype, @c ram_usage,
367 @c max_sequence_length, etc. Also accepts deprecated parameters (@c quantization_config,
368 @c advanced_quantization_config, @c input_process_config, @c save_sample, @c sample_dtype)
369 which will emit DeprecationWarning.
370 @return None.
371
372 @par Using configuration
373 There are three ways to configure quantization settings:
374
375 1. Load all settings from a JSON/YAML config file:
376 @code{.py}
377 from qbcompiler import mxq_compile
378
379 mxq_compile(
380 model="path/to/model.onnx",
381 calib_data_path="path/to/calib",
382 compile_config="path/to/config.json", # or config.yaml
383 device="gpu",
384 )
385 @endcode
386
387 2. Pass individual sub-config objects:
388 @code{.py}
389 from qbcompiler import mxq_compile
390 from qbcompiler.configs import (
391 ResourceManagementConfig,
392 CalibrationConfig,
393 BitConfig,
394 OptqConfig,
395 ModConfig,
396 LlmConfig,
397 )
398
399 resource_mgmt = ResourceManagementConfig(weight_dtype="float32")
400 calib_cfg = CalibrationConfig(method=1, mode=1)
401 bit_cfg = BitConfig(...)
402 optq_cfg = OptqConfig(apply=True)
403 mod_cfg = ModConfig(apply=False)
404 llm_cfg = LlmConfig(apply=True)
405
406 mxq_compile(
407 model="path/to/model.onnx",
408 calib_data_path="path/to/calib",
409 resource_management_config=resource_mgmt,
410 calibration_config=calib_cfg,
411 bit_config=bit_cfg,
412 optq_config=optq_cfg,
413 mod_config=mod_cfg,
414 llm_config=llm_cfg,
415 device="gpu",
416 )
417 @endcode
418
419 3. Automatically applied partial configuration overrides:
420 @code{.py}
421 from qbcompiler import mxq_compile
422
423 mxq_compile(
424 model="path/to/model.onnx",
425 calib_data_path="path/to/calib",
426 quantization_method=1, # per channel quantization
427 quantization_mode=1, # max percentile quantization
428 percentile=0.999, # percentile value for max percentile quantization
429 quantization_output=0, # per layer quantization for the output layer
430 device="gpu",
431 )
432 @endcode
433 Please refer to the mxq_compile function and the quantization configuration section for the meaning of the quantization-related numeric values.
434
435
436 @par Compiling models with custom inputs (ONNX/Torch/TensorFlow)
437 Provide NumPy inputs whenever the model omits shape information so that qbcompiler can infer unknown dimensions and data
438 formats.
439
440 @code{.py}
441 from qbcompiler import mxq_compile
442 import numpy as np
443
444 example_input = {
445 "input_node_name_1": np.random.randn(1, 3, 224, 224).astype(np.float32),
446 "input_node_name_2": np.random.randn(1, 8, 224, 224).astype(np.float32),
447 "input_node_name_3": np.random.randn(1, 4, 56, 56).astype(np.float32),
448 }
449
450 in_dformats = {
451 "input_node_name_1": "NCHW",
452 "input_node_name_2": "NCHW",
453 "input_node_name_3": "NCHW",
454 }
455
456 onnx_model_path = "path/to/your/model.onnx"
457 mxq_compile(
458 model=onnx_model_path,
459 feed_dict=example_input,
460 in_dformats=in_dformats,
461 backend="onnx",
462 compile_config="path/to/config.json",
463 )
464 @endcode
465 """
466 # --- Handle deprecated kwargs ---
467 (
468 calibration_config,
469 optq_config,
470 mod_config,
471 equivalent_transformation_config,
472 search_weight_scale_config,
473 uint8_input_config,
474 preprocessing_config,
475 save_sample_config,
476 ) = _resolve_deprecated_kwargs(
477 calibration_config=calibration_config,
478 optq_config=optq_config,
479 mod_config=mod_config,
480 equivalent_transformation_config=equivalent_transformation_config,
481 search_weight_scale_config=search_weight_scale_config,
482 uint8_input_config=uint8_input_config,
483 preprocessing_config=preprocessing_config,
484 save_sample_config=save_sample_config,
485 **kwargs,
486 )
487
488 # --- Step 1: Base CompileConfig ---
489 if config_preset is not None:
490 compile_cfg = CompileConfig.from_preset(config_preset)
491 elif compile_config is None:
492 compile_cfg = CompileConfig()
493 elif isinstance(compile_config, CompileConfig):
494 compile_cfg = compile_config
495 elif isinstance(compile_config, str):
496 compile_cfg = CompileConfig.from_file(compile_config)
497 else:
498 raise ValueError(
499 "compile_config must be a CompileConfig object or a path to JSON/YAML configuration file"
500 )
501
502 # --- Step 2: Override with individual sub-configs ---
503 _sub_config_pairs = [
504 ("resource_management", resource_management_config, ResourceManagementConfig),
505 ("calibration", calibration_config, CalibrationConfig),
506 ("bit", bit_config, BitConfig),
507 ("llm", llm_config, LlmConfig),
508 ("optq", optq_config, OptqConfig),
509 ("mod", mod_config, ModConfig),
510 (
511 "equivalent_transformation",
512 equivalent_transformation_config,
513 EquivalentTransformationConfig,
514 ),
515 ("search_weight_scale", search_weight_scale_config, SearchWeightScaleConfig),
516 ("save_sample", save_sample_config, SaveSampleConfig),
517 ("uint8_input", uint8_input_config, Uint8InputConfig),
518 ("preprocessing", preprocessing_config, PreprocessingConfig),
519 ]
520 sub_overrides = {}
521 for field_name, config_obj, expected_cls in _sub_config_pairs:
522 if config_obj is None:
523 continue
524 if not isinstance(config_obj, expected_cls):
525 raise TypeError(
526 f"Invalid type for '{field_name}': expected {expected_cls.__name__} or None, "
527 f"but got {type(config_obj).__name__}."
528 )
529 sub_overrides[field_name] = config_obj
530 if sub_overrides:
531 compile_cfg = compile_cfg.model_copy(update=sub_overrides)
532
533 # --- Step 3: Override with kwargs (partial config overrides) ---
534 calib_kwargs = {}
535 if "quantization_method" in kwargs:
536 calib_kwargs["method"] = kwargs.pop("quantization_method")
537 if "quantization_output" in kwargs:
538 calib_kwargs["output"] = kwargs.pop("quantization_output")
539 if "quantization_mode" in kwargs:
540 calib_kwargs["mode"] = kwargs.pop("quantization_mode")
541 if "percentile" in kwargs:
542 if "percentile_config" not in calib_kwargs:
543 calib_kwargs["percentile_config"] = {}
544 calib_kwargs["percentile_config"]["percentile"] = kwargs.pop("percentile")
545 if "act_scale_min" in kwargs:
546 calib_kwargs["act_scale_min"] = kwargs.pop("act_scale_min")
547 if "weight_scale_min" in kwargs:
548 calib_kwargs["weight_scale_min"] = kwargs.pop("weight_scale_min")
549 if calib_kwargs:
550 updated_calib = compile_cfg.calibration.model_copy(update=calib_kwargs)
551 compile_cfg = compile_cfg.model_copy(update={"calibration": updated_calib})
552
553 llm_kwargs = {}
554 if "llm_config_apply" in kwargs:
555 llm_kwargs["apply"] = kwargs.pop("llm_config_apply")
556 if "max_sequence_length" in kwargs:
557 if "attributes" not in llm_kwargs:
558 llm_kwargs["attributes"] = {}
559 llm_kwargs["attributes"]["max_sequence_length"] = kwargs.pop(
560 "max_sequence_length"
561 )
562 if "max_cache_length" in kwargs:
563 if "attributes" not in llm_kwargs:
564 llm_kwargs["attributes"] = {}
565 llm_kwargs["attributes"]["max_cache_length"] = kwargs.pop("max_cache_length")
566 if llm_kwargs:
567 updated_llm = compile_cfg.llm.model_copy(update=llm_kwargs)
568 compile_cfg = compile_cfg.model_copy(update={"llm": updated_llm})
569
570 rm_kwargs = {}
571 if "weight_dtype" in kwargs:
572 rm_kwargs["weight_dtype"] = kwargs.pop("weight_dtype")
573 if "ram_usage" in kwargs:
574 rm_kwargs["ram_usage"] = kwargs.pop("ram_usage")
575 if rm_kwargs:
576 updated_rm = compile_cfg.resource_management.model_copy(update=rm_kwargs)
577 compile_cfg = compile_cfg.model_copy(update={"resource_management": updated_rm})
578
579 # --- Step 4: Override with explicitly passed external params ---
580 external_overrides = {}
581 if save_path is not _UNSET:
582 external_overrides["save_paths"] = _to_list(save_path)
583 elif isinstance(model, str):
584 external_overrides["save_paths"] = [f"{Path(model).stem}.mxq"]
585 else:
586 raise ValueError("Please set the save_path with .mxq extension")
587 if calib_data_path is not _UNSET:
588 external_overrides["calib_data_path"] = _to_list(calib_data_path)
589 if use_random_calib is not _UNSET:
590 external_overrides["use_random_calib"] = use_random_calib
591 if inference_scheme is not _UNSET:
592 external_overrides["inference_scheme"] = inference_scheme
593 if cpu_offload is not _UNSET:
594 external_overrides["cpu_offload"] = cpu_offload
595 if optimize_option is not _UNSET:
596 external_overrides["optimize_option"] = optimize_option
597 if buffer_mode is not _UNSET:
598 external_overrides["buffer_mode"] = buffer_mode
599 if input_shape_dict is not _UNSET:
600 external_overrides["input_shape_dict"] = input_shape_dict
601 if device is not _UNSET:
602 external_overrides["device"] = device
603 if force_npu_input_reposition is not _UNSET:
604 external_overrides["force_npu_input_reposition"] = force_npu_input_reposition
605 if force_npu_output_reposition is not _UNSET:
606 external_overrides["force_npu_output_reposition"] = force_npu_output_reposition
607 if image_channels is not _UNSET:
608 external_overrides["image_channels"] = image_channels
609 if split_blocks is not _UNSET:
610 external_overrides["split_blocks"] = split_blocks
611 if split_parts is not _UNSET:
612 external_overrides["split_parts"] = split_parts
613 compile_cfg = compile_cfg.model_copy(update=external_overrides)
614
615 # Resolve values from final config for downstream use
616 resolved_device = compile_cfg.device
617
618 if isinstance(model, str) and model.endswith(".mblt") and os.path.isfile(model):
619 _quantization_task(model, compile_config=compile_cfg)
620 else:
621 model_dict = Model_Dict(
622 model=model,
623 backend=backend,
624 device=resolved_device,
625 feed_dict=feed_dict,
626 in_dformats=in_dformats,
627 dynamic_axes=dynamic_axes,
628 yolo_decode_include=yolo_decode_include,
629 use_custom_mask=use_custom_mask,
630 exclude_first_subgraph=exclude_first_subgraph,
631 **kwargs,
632 )
633 model_dict.compile(
634 save_subgraph_type=save_subgraph_type,
635 output_subgraph_path=output_subgraph_path,
636 compile_config=compile_cfg,
637 )
638 torch.cuda.empty_cache()
639 del model_dict
640
641
642def mblt_compile(
643 model: str | Any,
644 mblt_save_path: str,
645 backend="onnx",
646 device="cpu",
647 feed_dict=None,
648 dynamic_axes=None,
649 in_dformats=None,
650 yolo_decode_include=False,
651 cpu_offload=False,
652 use_custom_mask=False,
653 exclude_first_subgraph=False,
654 **kwargs,
655):
656 """
657 @brief Export a model to the Mobilint .mblt format without producing an MXQ package.
658
659 @param model string or model instance. Source model or path to compile.
660 @param mblt_save_path string. Output path for the .mblt artifact.
661 @param backend string. Framework identifier ("onnx", "tf", "tflite", "torchscript", or "torch"). Defaults to
662 "onnx".
663 @param device string. Compilation device ("cpu" or "gpu"). Defaults to "cpu".
664 @param feed_dict dict. Example inputs used for shape inference.
665 @param dynamic_axes dict. Declares dynamic axes per input name.
666 @param in_dformats dict. Input dataformat metadata.
667 @param yolo_decode_include bool. Runs YOLO decode on NPU when True.
668 @param cpu_offload bool. Enables CPU offloading for unsupported groups.
669 @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.
670 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.
671 @param exclude_first_subgraph bool. Applies only when CPU offloading is enabled: exclude the first subgraph from the final graph if it is unsupported.
672 @param kwargs dict. Additional arguments forwarded to the compiler.
673 @return None.
674 """
675 model_dict = Model_Dict(
676 model=model,
677 backend=backend,
678 device=device,
679 feed_dict=feed_dict,
680 dynamic_axes=dynamic_axes,
681 in_dformats=in_dformats,
682 yolo_decode_include=yolo_decode_include,
683 use_custom_mask=use_custom_mask,
684 exclude_first_subgraph=exclude_first_subgraph,
685 **kwargs,
686 )
687
688 model_dict.mblt_compile(
689 model,
690 mblt_save_path=mblt_save_path,
691 backend=backend,
692 cpu_offload=cpu_offload,
693 **kwargs,
694 )
695
696
697
699
700
701def run_mblt_model(
702 path_to_mblt: str,
703 save_all_outputs: bool = True,
704 inference_output_path: Optional[str] = None,
705 target_subgraph: Optional[int] = None,
706):
707 from qbcompiler.model_dict.common.model_dict import ValueDict
708 from qbcompiler.model_dict.inference.model import ModelInference
709 from qbcompiler.model_dict.serialize import load_mblt_model
710
711 assert path_to_mblt.endswith(".mblt")
712 if not save_all_outputs:
713 raise NotImplementedError(
714 f"save_all_outputs={save_all_outputs} is not supported yet."
715 )
716 if target_subgraph:
717 raise NotImplementedError(
718 f"target_subgraph={target_subgraph} is not supported yet."
719 )
720 import numpy
721
722 if not inference_output_path:
723 inference_output_path = str(pathlib.Path(path_to_mblt).with_suffix(".infer"))
724
725 vd = ValueDict()
726 md, wd = load_mblt_model(path_to_mblt, load_weight=True)
727 for sg in md.subgraphs:
728 for iidx in sg.inputs:
729 inact = sg.activations[iidx]
730 if inact.name in set(md.inputs):
731 vd[inact.name] = numpy.random.random(tuple(map(int, inact.src_shape)))
732
733 model_inference = ModelInference(
734 model_dict=md,
735 weight_dict=wd,
736 value_dict=vd,
737 save_all_outputs=save_all_outputs,
738 inference_all_outputs_write_path=inference_output_path,
739 )
740
741 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:140
__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:162
compile(self, int save_subgraph_type=0, output_subgraph_path="", CompileConfig compile_config=None, **kwargs)
Compile the wrapped model into an MXQ artifact.
Definition frontend.py:197
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:655
mxq_compile(model, Union[str, List[str]] calib_data_path=_UNSET, int save_subgraph_type=0, output_subgraph_path="", Union[str, List[str]] save_path=_UNSET, backend="onnx", feed_dict=None, dynamic_axes=None, in_dformats=None, yolo_decode_include=False, use_custom_mask=False, exclude_first_subgraph=False, device=_UNSET, inference_scheme=_UNSET, use_random_calib=_UNSET, cpu_offload=_UNSET, optimize_option=_UNSET, buffer_mode=_UNSET, input_shape_dict=_UNSET, force_npu_input_reposition=_UNSET, force_npu_output_reposition=_UNSET, image_channels=_UNSET, split_blocks=_UNSET, split_parts=_UNSET, Optional[str] config_preset=None, Optional[CompileConfig] compile_config=None, Optional[ResourceManagementConfig] resource_management_config=None, Optional[CalibrationConfig] calibration_config=None, Optional[BitConfig] bit_config=None, Optional[LlmConfig] llm_config=None, Optional[OptqConfig] optq_config=None, Optional[ModConfig] mod_config=None, Optional[EquivalentTransformationConfig] equivalent_transformation_config=None, Optional[SearchWeightScaleConfig] search_weight_scale_config=None, Optional[SaveSampleConfig] save_sample_config=None, Optional[Uint8InputConfig] uint8_input_config=None, Optional[PreprocessingConfig] preprocessing_config=None, **kwargs)
Compile a model into a Mobilint eXeCUtable (MXQ) package for execution on Mobilint NPUs.
Definition frontend.py:276