38 from hydra.core.hydra_config
import HydraConfig
39 from omegaconf
import DictConfig
40 from typing
import Optional
42 warnings.filterwarnings(
"ignore")
43 os.environ[
'TF_CPP_MIN_LOG_LEVEL'] =
'3'
45 from common.utils
import get_model_name_and_its_input_shape, get_model_name
46 from common.deployment
import stm32ai_deploy_stm32n6, stm32ai_deploy_mpu
47 from common.benchmarking
import cloud_connect
48 from src.utils
import gen_h_user_file_n6
51 def deploy(cfg: DictConfig =
None, model_path_to_deploy: Optional[str] =
None,
52 credentials: list =
None) ->
None:
54 @brief Deploy a quantized INT8 model onto an STM32N6 MCU board.
57 This function implements the full deployment pipeline for STM32N6-series boards:
59 **Step 1 — Parameter extraction from YAML config:**
60 All deployment parameters are read from the Hydra configuration object:
61 - `board` : Target board name (e.g., "STM32N6570-DK").
62 - `stlink_serial_number`: ST-Link serial number for multi-board setups.
63 - `c_project_path` : Path to the STM32CubeIDE C project directory.
64 - `stm32ai_version` : Version of ST Edge AI Core to use.
65 - `optimization` : Optimization level for code generation (e.g., "balanced").
66 - `path_to_stm32ai` : Local path to the stedgeai executable.
67 - `path_to_cube_ide` : Local path to the STM32CubeIDE executable.
68 - `stm32ai_ide` : IDE/compiler to use (must be "gcc" for STM32N6).
69 - `stm32ai_serie` : MCU series (must be "STM32N6" for this path).
71 **Step 2 — C header file generation:**
72 gen_h_user_file_n6() generates `ai_model_config.h`, a C header that embeds
73 model metadata (input/output shapes, number of keypoints, confidence thresholds)
74 into the firmware. This allows the C application to configure itself at compile time.
76 **Step 3 — Board configuration file selection:**
77 A board-specific .conf file is selected:
78 - `stmaic_STM32N6570-DK.conf` for the STM32N6570-DK Discovery Kit.
79 - `stmaic_NUCLEO-N657X0-Q.conf` for the NUCLEO-N657X0-Q board.
81 **Step 4 — Full deployment via stm32ai_deploy_stm32n6():**
83 a. Invokes ST Edge AI Core to convert the .tflite model into optimized C arrays.
84 b. Integrates the C code into the STM32CubeIDE project.
85 c. Compiles the firmware using GCC.
86 d. Flashes the binary onto the board via ST-Link (USB debugger).
88 @note After flashing, the user must manually toggle the boot switches on the
89 STM32N6570-DK to the left and power-cycle the board to boot from flash.
91 @param cfg Hydra DictConfig loaded from user_config.yaml.
92 @param model_path_to_deploy Path to the quantized .tflite model to deploy.
93 If None, uses cfg.general.model_path.
94 @param credentials Optional cloud credentials from a prior cloud_connect() call.
97 @throws ValueError If the hardware series is STM32H7 (not supported in this flow).
98 @throws TypeError If the board name or IDE/serie combination is not supported.
102 board = cfg.deployment.hardware_setup.board
103 stlink_serial_number = cfg.deployment.hardware_setup.stlink_serial_number
104 c_project_path = cfg.deployment.c_project_path
105 output_dir = HydraConfig.get().runtime.output_dir
108 stm32ai_output = output_dir +
"/generated"
110 stm32ai_version = cfg.tools.stm32ai.version
111 optimization = cfg.tools.stm32ai.optimization
112 path_to_stm32ai = cfg.tools.stm32ai.path_to_stm32ai
113 path_to_cube_ide = cfg.tools.path_to_cubeIDE
114 verbosity = cfg.deployment.verbosity
115 stm32ai_ide = cfg.deployment.IDE
116 stm32ai_serie = cfg.deployment.hardware_setup.serie
117 check_large_model =
False
122 model_path = model_path_to_deploy
if model_path_to_deploy
else cfg.general.model_path
123 model_name, input_shape = get_model_name_and_its_input_shape(model_path=model_path)
125 get_model_name_output = get_model_name(model_type=
str(model_name),
126 input_shape=
str(input_shape[0]),
127 project_name=cfg.general.project_name)
134 print(
"[INFO] : Generating C header file for Getting Started...")
135 if stm32ai_serie.upper() ==
"STM32H7":
137 raise ValueError(
"STM32H7 is not supported in this deployment flow.")
142 if stm32ai_serie.upper() ==
"STM32N6" and stm32ai_ide.lower() ==
"gcc":
147 if board ==
"STM32N6570-DK":
148 stmaic_conf_filename =
"stmaic_STM32N6570-DK.conf"
149 elif board ==
"NUCLEO-N657X0-Q":
150 stmaic_conf_filename =
"stmaic_NUCLEO-N657X0-Q.conf"
153 "The hardware selected in cfg.deployment.hardware_setup.board is not supported yet!\n"
154 "Please choose one of the following boards: "
155 "`STM32N6570-DK` or `NUCLEO-N657X0-Q`.")
168 stlink_serial_number=stlink_serial_number,
169 stm32ai_version=stm32ai_version,
170 c_project_path=c_project_path,
171 output_dir=output_dir,
172 stm32ai_output=stm32ai_output,
173 optimization=optimization,
174 path_to_stm32ai=path_to_stm32ai,
175 path_to_cube_ide=path_to_cube_ide,
176 stmaic_conf_filename=stmaic_conf_filename,
179 model_path=model_path,
180 get_model_name_output=get_model_name_output,
181 stm32ai_ide=stm32ai_ide,
182 stm32ai_serie=stm32ai_serie,
183 on_cloud=cfg.tools.stm32ai.on_cloud,
184 build_conf=cfg.deployment.build_conf,
185 check_large_model=
True,
187 input_data_type=
'uint8',
189 inputs_ch_position=
'chlast',
190 outputs_ch_position=
''
194 "Options for cfg.deployment.hardware_setup.serie and cfg.deployment.IDE not supported yet!\n"
195 "The only supported combination is serie=`STM32N6` and IDE=`gcc`.")
198 def deploy_mpu(cfg: DictConfig =
None, model_path_to_deploy: Optional[str] =
None,
199 credentials: list =
None) ->
None:
201 @brief Deploy an AI model onto an STM32MP MPU target device.
204 This function handles deployment on STM32MP-series Microprocessor Units (MPUs),
205 which run Linux and have more memory and compute resources than MCUs.
207 Unlike the MCU path, MPU deployment can optionally leverage the STM32Cube.AI
208 Developer Cloud to generate an optimized NBG (Neural Binary Graph) file,
209 which is a proprietary binary format optimized for ST's NPU on MP2 devices.
211 Cloud optimization flow (STM32MP2 + .tflite or .onnx + on_cloud=True):
212 1. Upload the model to the Developer Cloud.
213 2. Request NBG generation (optimized binary format for the NPU).
214 3. Download the resulting .nb file.
215 4. Deploy the .nb file instead of the original model.
217 If cloud optimization is not available or fails, the original model is used directly.
224 @param cfg Hydra DictConfig loaded from user_config.yaml.
225 @param model_path_to_deploy Path to the model file to deploy (.tflite or .onnx).
226 If None, uses cfg.general.model_path.
227 @param credentials Optional cloud credentials from a prior cloud_connect() call.
230 @throws TypeError If the board is not in the list of supported MPU boards,
231 or if the deployment process fails.
235 board = cfg.deployment.hardware_setup.board
236 c_project_path = cfg.deployment.c_project_path
237 keypoints_file_path = cfg.dataset.keypoints_file_path
238 board_deploy_path = cfg.deployment.board_deploy_path
239 verbosity = cfg.deployment.verbosity
240 board_serie = cfg.deployment.hardware_setup.serie
241 board_ip = cfg.deployment.hardware_setup.ip_address
244 optimized_model_path = c_project_path +
"Optimized_models/"
246 model_path = model_path_to_deploy
if model_path_to_deploy
else cfg.general.model_path
247 model_extension = os.path.splitext(model_path)[1]
248 model_name, input_shape = get_model_name_and_its_input_shape(model_path=model_path)
253 if board_serie ==
"STM32MP2" and (model_extension ==
".tflite" or model_extension ==
".onnx") \
254 and cfg.tools.stm32ai.on_cloud:
255 login_success, ai, _ = cloud_connect(stm32ai_version=
None, credentials=credentials)
258 ai.upload_model(model_path)
259 model = model_name + model_extension
260 res = ai.generate_nbg(model)
261 ai.download_model(res, optimized_model_path + res)
262 model_path = os.path.join(optimized_model_path, res)
263 model_name = model_name +
".nb"
264 rename_model_path = os.path.join(optimized_model_path, model_name)
265 os.rename(model_path, rename_model_path)
266 model_path = rename_model_path
267 print(
"[INFO] : Optimized Model Name:", model_name)
268 print(
"[INFO] : Optimization done! Model available at:", optimized_model_path)
269 except Exception
as e:
270 print(f
"[FAIL] : Model optimization via Cloud failed: {e}.")
271 print(
"[INFO] : Use default model instead of optimized ...")
274 if board
in [
"STM32MP257F-EV1",
"STM32MP157F-DK2",
"STM32MP135F-DK"]:
277 board_ip_address=board_ip,
278 class_names=keypoints_file_path,
279 board_deploy=board_deploy_path,
280 c_project_path=c_project_path,
283 model_path=model_path,
287 raise TypeError(
"Deployment on the target failed\n")
290 "Options for cfg.deployment.hardware_setup.board not supported!\n"
291 "Only valid options are STM32MP257F-EV1, STM32MP157F-DK2, STM32MP135F-DK\n")
None stm32ai_deploy_mpu(bool target=False, str board_ip_address=None, str board_deploy=None, List class_names=None, str c_project_path=None, int verbosity=None, bool debug=False, str model_path=None, cfg=None)
None stm32ai_deploy_stm32n6(bool target=False, str stlink_serial_number=None, str stm32ai_version=None, str c_project_path=None, str output_dir=None, str stm32ai_output=None, str optimization=None, str path_to_stm32ai=None, str path_to_cube_ide=None, list additional_files=None, str stmaic_conf_filename='stmaic_c_project.conf', int verbosity=None, bool debug=False, str model_path=None, str get_model_name_output=None, str stm32ai_ide=None, str stm32ai_serie=None, list credentials=None, bool on_cloud=False, bool check_large_model=False, str build_conf=None, cfg=None, Dict custom_objects=None, str input_data_type='', str output_data_type='', str inputs_ch_position='', str outputs_ch_position='')
None deploy(DictConfig cfg=None, Optional[str] model_path_to_deploy=None, list credentials=None)
Key parameters:
None deploy_mpu(DictConfig cfg=None, Optional[str] model_path_to_deploy=None, list credentials=None)
None gen_h_user_file_n6(DictConfig config=None, str quantized_model_path=None)