33# Licensed under the MIT License.
44# --------------------------------------------------------------------------
55import argparse
6+ import importlib .util
67import json
78import sys
89import tempfile
2829)
2930MAX_ARTIFACT_SIZE_BYTES = 1024 * 1024
3031
32+ # Supported exporters for the discrepancy test
33+ EXPORTER_MODEL_BUILDER = "model_builder"
34+ EXPORTER_MOBIUS = "mobius"
35+ EXPORTER_TORCH = "torch_export"
36+
37+ _HAS_MOBIUS = importlib .util .find_spec ("mobius" ) is not None
38+
3139
3240def _save_local_tiny_llama (model_path : Path ):
3341 model = LlamaForCausalLM (
@@ -133,6 +141,7 @@ def _run_documented_test_model_smoke_flow(tmp_path: Path, model_id: str):
133141
134142class TestCliTestModelSmoke (unittest .TestCase ):
135143 model_ids = DEFAULT_MODEL_IDS
144+ exporters = (EXPORTER_MODEL_BUILDER ,)
136145 workdir = None
137146
138147 def test_documented_test_model_smoke_flow (self ):
@@ -173,7 +182,7 @@ def _assert_smoke_flows(self, tmp_path: Path):
173182 self ._assert_file_size_below_limit (run_output_dir / "model.onnx.data" )
174183
175184 def test_model_discrepancy (self ):
176- """Verify that OnnxDiscrepancyCheck runs successfully when auto-injected via --test ."""
185+ """Verify that OnnxDiscrepancyCheck runs successfully with the configured exporter ."""
177186 if self .workdir is None :
178187 with tempfile .TemporaryDirectory () as temp_dir :
179188 self ._assert_discrepancy (Path (temp_dir ))
@@ -183,48 +192,139 @@ def test_model_discrepancy(self):
183192 self ._assert_discrepancy (workdir )
184193
185194 def _assert_discrepancy (self , tmp_path : Path ):
186- for model_id in self .model_ids :
187- with self .subTest (model_id = model_id ):
188- model_name = model_id .replace ("/" , "--" )
189- model_path = tmp_path / "models" / f"{ model_name } -disc"
190- config_output_dir = tmp_path / f"{ model_name } -disc-cfg"
191- test_model_dir = tmp_path / f"{ model_name } -disc-test-model"
192- run_output_dir = tmp_path / f"{ model_name } -disc-run"
193-
194- _save_local_tiny_llama (model_path )
195- _run_cli_main (
196- [
197- "optimize" ,
198- "-m" ,
199- str (model_path ),
200- "--device" ,
201- "cpu" ,
202- "--provider" ,
203- "CPUExecutionProvider" ,
204- "--precision" ,
205- "int4" ,
206- "--output_path" ,
207- str (config_output_dir ),
208- "--dry_run" ,
209- ]
195+ for exporter in self .exporters :
196+ if exporter == EXPORTER_MOBIUS and not _HAS_MOBIUS :
197+ self .fail (
198+ "Requested exporter 'mobius' but mobius-ai is not installed. Install mobius-ai or remove '--exporter mobius'."
210199 )
200+ for model_id in self .model_ids :
201+ with self .subTest (model_id = model_id , exporter = exporter ):
202+ if exporter == EXPORTER_MODEL_BUILDER :
203+ self ._assert_discrepancy_model_builder (tmp_path , model_id )
204+ elif exporter == EXPORTER_MOBIUS :
205+ self ._assert_discrepancy_mobius (tmp_path , model_id )
206+ elif exporter == EXPORTER_TORCH :
207+ self ._assert_discrepancy_torch_export (tmp_path , model_id )
208+ else :
209+ self .fail (f"Unknown exporter: { exporter !r} " )
211210
212- config_path = config_output_dir / "config.json"
213- assert config_path .exists ()
214- _set_offline_gptq_data_config (config_path )
215-
216- # Run with --test; OnnxDiscrepancyCheck is auto-injected and reports discrepancy metrics (fails only if thresholds are configured)
217- _run_cli_main (
218- [
219- "run" ,
220- "--config" ,
221- str (config_path ),
222- "--test" ,
223- str (test_model_dir ),
224- "--output_path" ,
225- str (run_output_dir ),
226- ]
227- )
211+ @staticmethod
212+ def _run_discrepancy_with_test (config_path : Path , test_model_dir : Path , run_output_dir : Path ):
213+ _run_cli_main (
214+ [
215+ "run" ,
216+ "--config" ,
217+ str (config_path ),
218+ "--test" ,
219+ str (test_model_dir ),
220+ "--output_path" ,
221+ str (run_output_dir ),
222+ ]
223+ )
224+
225+ def _assert_discrepancy_model_builder (self , tmp_path : Path , model_id : str ):
226+ model_name = model_id .replace ("/" , "--" )
227+ model_path = tmp_path / "models" / f"{ model_name } -disc"
228+ config_output_dir = tmp_path / f"{ model_name } -disc-cfg"
229+ test_model_dir = tmp_path / f"{ model_name } -disc-test-model"
230+ run_output_dir = tmp_path / f"{ model_name } -disc-run"
231+
232+ _save_local_tiny_llama (model_path )
233+ _run_cli_main (
234+ [
235+ "optimize" ,
236+ "-m" ,
237+ str (model_path ),
238+ "--device" ,
239+ "cpu" ,
240+ "--provider" ,
241+ "CPUExecutionProvider" ,
242+ "--precision" ,
243+ "int4" ,
244+ "--output_path" ,
245+ str (config_output_dir ),
246+ "--dry_run" ,
247+ ]
248+ )
249+
250+ config_path = config_output_dir / "config.json"
251+ assert config_path .exists ()
252+ _set_offline_gptq_data_config (config_path )
253+
254+ # Run with --test; OnnxDiscrepancyCheck is auto-injected and reports discrepancy metrics
255+ self ._run_discrepancy_with_test (config_path , test_model_dir , run_output_dir )
256+
257+ def _assert_discrepancy_mobius (self , tmp_path : Path , model_id : str ):
258+ model_name = model_id .replace ("/" , "--" )
259+ model_path = tmp_path / "models" / f"{ model_name } -mobius-disc"
260+ test_model_dir = tmp_path / f"{ model_name } -mobius-disc-test-model"
261+ run_output_dir = tmp_path / f"{ model_name } -mobius-disc-run"
262+
263+ _save_local_tiny_llama (model_path )
264+
265+ run_config = {
266+ "input_model" : {
267+ "type" : "HfModel" ,
268+ "model_path" : str (model_path ),
269+ },
270+ "systems" : {
271+ "local_system" : {
272+ "type" : "LocalSystem" ,
273+ "accelerators" : [{"device" : "cpu" , "execution_providers" : ["CPUExecutionProvider" ]}],
274+ }
275+ },
276+ "output_dir" : str (run_output_dir ),
277+ "host" : "local_system" ,
278+ "target" : "local_system" ,
279+ "passes" : {
280+ "mobius_builder" : {
281+ "type" : "MobiusBuilder" ,
282+ "precision" : "fp32" ,
283+ "runtime" : "none" ,
284+ },
285+ "discrepancy_check" : {
286+ "type" : "OnnxDiscrepancyCheck" ,
287+ "reference_model_path" : str (test_model_dir ),
288+ },
289+ },
290+ }
291+ config_path = tmp_path / f"{ model_name } -mobius-disc-config.json"
292+ config_path .write_text (json .dumps (run_config , indent = 2 ))
293+
294+ self ._run_discrepancy_with_test (config_path , test_model_dir , run_output_dir )
295+
296+ def _assert_discrepancy_torch_export (self , tmp_path : Path , model_id : str ):
297+ model_name = model_id .replace ("/" , "--" )
298+ model_path = tmp_path / "models" / f"{ model_name } -torch-disc"
299+ test_model_dir = tmp_path / f"{ model_name } -torch-disc-test-model"
300+ run_output_dir = tmp_path / f"{ model_name } -torch-disc-run"
301+
302+ _save_local_tiny_llama (model_path )
303+
304+ run_config = {
305+ "input_model" : {
306+ "type" : "HfModel" ,
307+ "model_path" : str (model_path ),
308+ },
309+ "systems" : {
310+ "local_system" : {
311+ "type" : "LocalSystem" ,
312+ "accelerators" : [{"device" : "cpu" , "execution_providers" : ["CPUExecutionProvider" ]}],
313+ }
314+ },
315+ "output_dir" : str (run_output_dir ),
316+ "host" : "local_system" ,
317+ "target" : "local_system" ,
318+ "passes" : {
319+ "conversion" : {
320+ "type" : "OnnxConversion" ,
321+ "use_dynamo_exporter" : False ,
322+ }
323+ },
324+ }
325+ config_path = tmp_path / f"{ model_name } -torch-disc-config.json"
326+ config_path .write_text (json .dumps (run_config , indent = 2 ))
327+ self ._run_discrepancy_with_test (config_path , test_model_dir , run_output_dir )
228328
229329 def _assert_file_size_below_limit (self , path : Path ):
230330 assert path .exists ()
@@ -239,6 +339,13 @@ def _parse_args():
239339 parser = argparse .ArgumentParser (add_help = False )
240340 parser .add_argument ("--workdir" )
241341 parser .add_argument ("--model-id" , dest = "model_ids" , action = "append" )
342+ parser .add_argument (
343+ "--exporter" ,
344+ dest = "exporters" ,
345+ action = "append" ,
346+ choices = [EXPORTER_MODEL_BUILDER , EXPORTER_MOBIUS , EXPORTER_TORCH ],
347+ help = "Exporter(s) to test for discrepancy check (can be repeated)." ,
348+ )
242349 return parser .parse_known_args ()
243350
244351
@@ -248,4 +355,6 @@ def _parse_args():
248355 TestCliTestModelSmoke .workdir = Path (parsed_args .workdir )
249356 if parsed_args .model_ids :
250357 TestCliTestModelSmoke .model_ids = tuple (parsed_args .model_ids )
358+ if parsed_args .exporters :
359+ TestCliTestModelSmoke .exporters = tuple (parsed_args .exporters )
251360 unittest .main (argv = [__file__ , * remaining ])
0 commit comments