Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

#609 Ci fix

Merged
Ghost merged 1 commits into Deci-AI:master from deci-ai:bugfix/infra-000_ci
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  1. """
  2. Quantization utilities
  3. Methods are based on:
  4. https://github.com/NVIDIA/TensorRT/blob/51a4297753d3e12d0eed864be52400f429a6a94c/tools/pytorch-quantization/examples/torchvision/classification_flow.py#L385
  5. (Licensed under the Apache License, Version 2.0)
  6. """
  7. import torch
  8. from tqdm import tqdm
  9. from super_gradients.common.abstractions.abstract_logger import get_logger
  10. from super_gradients.training.utils.distributed_training_utils import get_local_rank, get_world_size
  11. from torch.distributed import all_gather
  12. logger = get_logger(__name__)
  13. try:
  14. from pytorch_quantization import nn as quant_nn
  15. from pytorch_quantization import calib
  16. _imported_pytorch_quantization_failure = None
  17. except (ImportError, NameError, ModuleNotFoundError) as import_err:
  18. logger.warning("Failed to import pytorch_quantization")
  19. _imported_pytorch_quantization_failure = import_err
  20. class QuantizationCalibrator:
  21. def __init__(self, torch_hist: bool = True, verbose: bool = True) -> None:
  22. if _imported_pytorch_quantization_failure is not None:
  23. raise _imported_pytorch_quantization_failure
  24. super().__init__()
  25. self.verbose = verbose
  26. self.torch_hist = torch_hist
  27. def calibrate_model(
  28. self,
  29. model: torch.nn.Module,
  30. calib_data_loader: torch.utils.data.DataLoader,
  31. method: str = "percentile",
  32. num_calib_batches: int = 2,
  33. percentile: float = 99.99,
  34. ):
  35. """
  36. Calibrates torch model with quantized modules.
  37. :param model: torch.nn.Module, model to perfrom the calibration on.
  38. :param calib_data_loader: torch.utils.data.DataLoader, data loader of the calibration dataset.
  39. Assumes that the first element of the tuple is the input image.
  40. :param method: str, One of [percentile, mse, entropy, max].
  41. Statistics method for amax computation of the quantized modules
  42. (Default=percentile).
  43. :param num_calib_batches: int, number of batches to collect the statistics from.
  44. :param percentile: float, percentile value to use when SgModel,quant_modules_calib_method='percentile'.
  45. Discarded when other methods are used (Default=99.99).
  46. """
  47. acceptable_methods = ["percentile", "mse", "entropy", "max"]
  48. if method in acceptable_methods:
  49. with torch.no_grad():
  50. self._collect_stats(model, calib_data_loader, num_batches=num_calib_batches)
  51. # FOR PERCENTILE WE MUST PASS PERCENTILE VALUE THROUGH KWARGS,
  52. # SO IT WOULD BE PASSED TO module.load_calib_amax(**kwargs), AND IN OTHER METHODS WE MUST NOT PASS IT.
  53. if method == "precentile":
  54. self._compute_amax(model, method="percentile", percentile=percentile)
  55. else:
  56. self._compute_amax(model, method=method)
  57. else:
  58. raise ValueError(f"Unsupported quantization calibration method, " f"expected one of: {'.'.join(acceptable_methods)}, however, received: {method}")
  59. def _collect_stats(self, model, data_loader, num_batches):
  60. """Feed data to the network and collect statistics"""
  61. local_rank = get_local_rank()
  62. world_size = get_world_size()
  63. device = next(model.parameters()).device
  64. # Enable calibrators
  65. self._enable_calibrators(model)
  66. # Feed data to the network for collecting stats
  67. for i, (image, *_) in tqdm(enumerate(data_loader), total=num_batches, disable=local_rank > 0):
  68. if world_size > 1:
  69. all_batches = [torch.zeros_like(image, device=device) for _ in range(world_size)]
  70. all_gather(all_batches, image.to(device=device))
  71. else:
  72. all_batches = [image]
  73. for local_image in all_batches:
  74. model(local_image.to(device=device))
  75. if i >= num_batches:
  76. break
  77. # Disable calibrators
  78. self._disable_calibrators(model)
  79. def _disable_calibrators(self, model):
  80. for name, module in model.named_modules():
  81. if isinstance(module, quant_nn.TensorQuantizer):
  82. if module._calibrator is not None:
  83. module.disable_calib()
  84. module.enable_quant()
  85. else:
  86. module.enable()
  87. def _enable_calibrators(self, model):
  88. for name, module in model.named_modules():
  89. if isinstance(module, quant_nn.TensorQuantizer):
  90. if module._calibrator is not None:
  91. if isinstance(module._calibrator, calib.HistogramCalibrator):
  92. module._calibrator._torch_hist = self.torch_hist # TensorQuantizer does not expose it as API
  93. module.disable_quant()
  94. module.enable_calib()
  95. else:
  96. module.disable()
  97. def _compute_amax(self, model, **kwargs):
  98. for name, module in model.named_modules():
  99. if isinstance(module, quant_nn.TensorQuantizer):
  100. if module._calibrator is not None:
  101. if isinstance(module._calibrator, calib.MaxCalibrator):
  102. module.load_calib_amax()
  103. else:
  104. module.load_calib_amax(**kwargs)
  105. if hasattr(module, "clip"):
  106. module.init_learn_amax()
  107. if self.verbose:
  108. print(f"{name:40}: {module}")
Discard
Tip!

Press p or to see the previous file or, n or to see the next file