onnx-diagnostic 0.7.3__py3-none-any.whl → 0.7.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. onnx_diagnostic/__init__.py +1 -1
  2. onnx_diagnostic/_command_lines_parser.py +82 -12
  3. onnx_diagnostic/export/shape_helper.py +71 -0
  4. onnx_diagnostic/helpers/_log_helper.py +461 -0
  5. onnx_diagnostic/helpers/cache_helper.py +11 -1
  6. onnx_diagnostic/helpers/log_helper.py +404 -315
  7. onnx_diagnostic/reference/ops/op_cast_like.py +12 -8
  8. onnx_diagnostic/tasks/automatic_speech_recognition.py +6 -2
  9. onnx_diagnostic/tasks/feature_extraction.py +92 -7
  10. onnx_diagnostic/tasks/fill_mask.py +6 -2
  11. onnx_diagnostic/tasks/image_classification.py +7 -3
  12. onnx_diagnostic/tasks/image_text_to_text.py +6 -2
  13. onnx_diagnostic/tasks/mixture_of_expert.py +1 -1
  14. onnx_diagnostic/tasks/object_detection.py +7 -3
  15. onnx_diagnostic/tasks/sentence_similarity.py +6 -2
  16. onnx_diagnostic/tasks/summarization.py +6 -2
  17. onnx_diagnostic/tasks/text2text_generation.py +8 -4
  18. onnx_diagnostic/tasks/text_classification.py +6 -2
  19. onnx_diagnostic/tasks/text_generation.py +5 -3
  20. onnx_diagnostic/tasks/text_to_image.py +6 -2
  21. onnx_diagnostic/tasks/zero_shot_image_classification.py +6 -2
  22. onnx_diagnostic/torch_export_patches/onnx_export_errors.py +63 -7
  23. onnx_diagnostic/torch_export_patches/patches/patch_transformers.py +188 -51
  24. onnx_diagnostic/torch_models/hghub/model_inputs.py +6 -1
  25. onnx_diagnostic/torch_models/validate.py +49 -10
  26. {onnx_diagnostic-0.7.3.dist-info → onnx_diagnostic-0.7.5.dist-info}/METADATA +1 -1
  27. {onnx_diagnostic-0.7.3.dist-info → onnx_diagnostic-0.7.5.dist-info}/RECORD +30 -29
  28. {onnx_diagnostic-0.7.3.dist-info → onnx_diagnostic-0.7.5.dist-info}/WHEEL +0 -0
  29. {onnx_diagnostic-0.7.3.dist-info → onnx_diagnostic-0.7.5.dist-info}/licenses/LICENSE.txt +0 -0
  30. {onnx_diagnostic-0.7.3.dist-info → onnx_diagnostic-0.7.5.dist-info}/top_level.txt +0 -0
@@ -3,5 +3,5 @@ Patches, Investigates onnx models.
3
3
  Functions, classes to dig into a model when this one is right, slow, wrong...
4
4
  """
5
5
 
6
- __version__ = "0.7.3"
6
+ __version__ = "0.7.5"
7
7
  __author__ = "Xavier Dupré"
@@ -349,6 +349,15 @@ def get_parser_validate() -> ArgumentParser:
349
349
  python -m onnx_diagnostic validate -m microsoft/Phi-4-mini-reasoning \\
350
350
  --run -v 1 -o dump_test --no-quiet --repeat 2 --warmup 2 \\
351
351
  --dtype float16 --device cuda --export modelbuilder
352
+
353
+ position_ids is usually not needed, they can be removed by adding:
354
+
355
+ --drop position_ids
356
+
357
+ The behaviour may be modified compare the original configuration,
358
+ the following argument can be rope_scaling to dynamic:
359
+
360
+ --mop \"rope_scaling={'rope_type': 'dynamic', 'factor': 10.0}\""
352
361
  """
353
362
  ),
354
363
  formatter_class=RawTextHelpFormatter,
@@ -403,10 +412,12 @@ def get_parser_validate() -> ArgumentParser:
403
412
  )
404
413
  parser.add_argument(
405
414
  "--inputs2",
406
- default=True,
407
- action=BooleanOptionalAction,
415
+ default=1,
416
+ type=int,
408
417
  help="Validates the model on a second set of inputs\n"
409
- "to check the exported model supports dynamism.",
418
+ "to check the exported model supports dynamism. The values is used "
419
+ "as an increment to the first set of inputs. A high value may trick "
420
+ "a different behavior in the model and missed by the exporter.",
410
421
  )
411
422
  parser.add_argument(
412
423
  "--runtime",
@@ -422,7 +433,8 @@ def get_parser_validate() -> ArgumentParser:
422
433
  parser.add_argument(
423
434
  "--drop",
424
435
  help="Drops the following inputs names, it should be a list\n"
425
- "with comma separated values.",
436
+ "with comma separated values, example:\n"
437
+ "--drop position_ids",
426
438
  )
427
439
  parser.add_argument(
428
440
  "--opset",
@@ -471,6 +483,12 @@ def get_parser_validate() -> ArgumentParser:
471
483
  parser.add_argument(
472
484
  "--warmup", default=0, type=int, help="number of times to run the model to do warmup"
473
485
  )
486
+ parser.add_argument(
487
+ "--outnames",
488
+ help="This comma separated list defines the output names "
489
+ "the onnx exporter should use.",
490
+ default="",
491
+ )
474
492
  return parser
475
493
 
476
494
 
@@ -530,6 +548,9 @@ def _cmd_validate(argv: List[Any]):
530
548
  repeat=args.repeat,
531
549
  warmup=args.warmup,
532
550
  inputs2=args.inputs2,
551
+ output_names=(
552
+ None if len(args.outnames.strip()) < 2 else args.outnames.strip().split(",")
553
+ ),
533
554
  )
534
555
  print("")
535
556
  print("-- summary --")
@@ -633,6 +654,27 @@ def _cmd_stats(argv: List[Any]):
633
654
  print("done.")
634
655
 
635
656
 
657
+ class _ParseNamedDict(argparse.Action):
658
+ def __call__(self, parser, namespace, values, option_string=None):
659
+ assert ":" in values, f"':' missing from {values!r}"
660
+ namespace_key, rest = values.split(":", 1)
661
+ pairs = rest.split(",")
662
+ inner_dict = {}
663
+
664
+ for pair in pairs:
665
+ if "=" not in pair:
666
+ raise argparse.ArgumentError(self, f"Expected '=' in pair '{pair}'")
667
+ key, value = pair.split("=", 1)
668
+ inner_dict[key] = value
669
+ assert inner_dict, f"Unable to parse {rest!r} into a dictionary"
670
+ if not hasattr(namespace, self.dest) or getattr(namespace, self.dest) is None:
671
+ setattr(namespace, self.dest, {})
672
+ assert isinstance(
673
+ getattr(namespace, self.dest), dict
674
+ ), f"Unexpected type for namespace.{self.dest}={getattr(namespace, self.dest)}"
675
+ getattr(namespace, self.dest).update({namespace_key: inner_dict})
676
+
677
+
636
678
  def get_parser_agg() -> ArgumentParser:
637
679
  parser = ArgumentParser(
638
680
  prog="agg",
@@ -641,13 +683,23 @@ def get_parser_agg() -> ArgumentParser:
641
683
  Aggregates statistics coming from benchmarks.
642
684
  Every run is a row. Every row is indexed by some keys,
643
685
  and produces values. Every row has a date.
686
+ The data can come any csv files produces by benchmarks,
687
+ it can concatenates many csv files, or csv files inside zip files.
688
+ It produces an excel file with many tabs, one per view.
644
689
  """
645
690
  ),
646
691
  epilog=textwrap.dedent(
647
692
  """
648
- examples:\n
693
+ examples:
649
694
 
650
695
  python -m onnx_diagnostic agg test_agg.xlsx raw/*.zip -v 1
696
+ python -m onnx_diagnostic agg agg.xlsx raw/*.zip raw/*.csv -v 1 \\
697
+ --no-raw --keep-last-date --filter-out "exporter:test-exporter"
698
+
699
+ Another to create timeseries:
700
+
701
+ python -m onnx_diagnostic agg history.xlsx raw/*.csv -v 1 --no-raw \\
702
+ --no-recent
651
703
  """
652
704
  ),
653
705
  formatter_class=RawTextHelpFormatter,
@@ -725,7 +777,15 @@ def get_parser_agg() -> ArgumentParser:
725
777
  "--views",
726
778
  default="agg-suite,agg-all,disc,speedup,time,time_export,err,cmd,"
727
779
  "bucket-speedup,raw-short,counts,peak-gpu,onnx",
728
- help="Views to add to the output files.",
780
+ help=textwrap.dedent(
781
+ """
782
+ Views to add to the output files. Each view becomes a tab.
783
+ A view is defined by its name, among
784
+ agg-suite, agg-all, disc, speedup, time, time_export, err,
785
+ cmd, bucket-speedup, raw-short, counts, peak-gpu, onnx.
786
+ Their definition is part of class CubeLogsPerformance.
787
+ """
788
+ ),
729
789
  )
730
790
  parser.add_argument(
731
791
  "--csv",
@@ -745,16 +805,24 @@ def get_parser_agg() -> ArgumentParser:
745
805
  help="adds a filter to filter out data, syntax is\n"
746
806
  '``"<column1>:<value1>;<value2>/<column2>:<value3>"`` ...',
747
807
  )
808
+ parser.add_argument(
809
+ "--sbs",
810
+ help=textwrap.dedent(
811
+ """
812
+ Defines an exporter to compare to another, there must be at least
813
+ two arguments defined with --sbs. Example:
814
+ --sbs dynamo:exporter=onnx-dynamo,opt=ir,attn_impl=eager
815
+ --sbs custom:exporter=custom,opt=default,attn_impl=eager
816
+ """
817
+ ),
818
+ action=_ParseNamedDict,
819
+ )
748
820
  return parser
749
821
 
750
822
 
751
823
  def _cmd_agg(argv: List[Any]):
752
- from .helpers.log_helper import (
753
- CubeLogsPerformance,
754
- open_dataframe,
755
- enumerate_csv_files,
756
- filter_data,
757
- )
824
+ from .helpers._log_helper import open_dataframe, enumerate_csv_files, filter_data
825
+ from .helpers.log_helper import CubeLogsPerformance
758
826
 
759
827
  parser = get_parser_agg()
760
828
  args = parser.parse_args(argv[1:])
@@ -800,6 +868,8 @@ def _cmd_agg(argv: List[Any]):
800
868
  verbose=args.verbose,
801
869
  csv=args.csv.split(","),
802
870
  raw=args.raw,
871
+ time_mask=True,
872
+ sbs=args.sbs,
803
873
  )
804
874
  if args.verbose:
805
875
  print(f"Wrote {args.output!r}")
@@ -30,6 +30,77 @@ def all_dynamic_shape_from_inputs(inputs: Any, dim_prefix: Any = "d") -> Any:
30
30
  )
31
31
  ds = all_dynamic_shape_from_inputs(inputs)
32
32
  pprint.pprint(ds)
33
+
34
+ For this function to work, patches must be enabled if :epkg:`transformers`
35
+ does not implement the serialization functions.
36
+
37
+ .. runpython::
38
+ :showcode:
39
+
40
+ import pprint
41
+ import torch
42
+ from onnx_diagnostic.helpers.cache_helper import (
43
+ make_dynamic_cache,
44
+ make_encoder_decoder_cache,
45
+ make_mamba_cache,
46
+ make_sliding_window_cache,
47
+ make_static_cache,
48
+ )
49
+ from onnx_diagnostic.export.shape_helper import all_dynamic_shape_from_inputs
50
+ from onnx_diagnostic.torch_export_patches import torch_export_patches
51
+
52
+ caches = [
53
+ make_dynamic_cache(
54
+ [
55
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
56
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
57
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
58
+ ]
59
+ ),
60
+ make_encoder_decoder_cache(
61
+ make_dynamic_cache(
62
+ [
63
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
64
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
65
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
66
+ ]
67
+ ),
68
+ make_dynamic_cache(
69
+ [
70
+ (torch.rand((5, 5, 5)), torch.rand((5, 5, 5))),
71
+ (torch.rand((5, 5, 5)), torch.rand((5, 5, 5))),
72
+ (torch.rand((5, 5, 5)), torch.rand((5, 5, 5))),
73
+ ]
74
+ ),
75
+ ),
76
+ make_sliding_window_cache(
77
+ [
78
+ (torch.rand((4, 5, 6, 7)), torch.rand((4, 5, 6, 7))),
79
+ (torch.rand((4, 5, 6, 7)), torch.rand((4, 5, 6, 7))),
80
+ (torch.rand((4, 5, 6, 7)), torch.rand((4, 5, 6, 7))),
81
+ ]
82
+ ),
83
+ make_static_cache(
84
+ [
85
+ (torch.rand((4, 5, 6, 7)), torch.rand((4, 5, 6, 7))),
86
+ (torch.rand((4, 5, 6, 7)), torch.rand((4, 5, 6, 7))),
87
+ (torch.rand((4, 5, 6, 7)), torch.rand((4, 5, 6, 7))),
88
+ ],
89
+ max_cache_len=15,
90
+ ),
91
+ make_mamba_cache(
92
+ [
93
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
94
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
95
+ (torch.rand((4, 4, 4)), torch.rand((4, 4, 4))),
96
+ ]
97
+ ),
98
+ ]
99
+
100
+ with torch_export_patches(patch_transformers=True):
101
+ for cache in caches:
102
+ print(f"-- {cache.__class__.__name__}")
103
+ pprint.pprint(all_dynamic_shape_from_inputs(cache))
33
104
  """
34
105
  if isinstance(dim_prefix, str):
35
106
  prefixes: Set[str] = set()