compressed-tensors 0.10.1a20250604__tar.gz → 0.10.2a20250606__tar.gz

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 (136) hide show
  1. {compressed_tensors-0.10.1a20250604/src/compressed_tensors.egg-info → compressed_tensors-0.10.2a20250606}/PKG-INFO +1 -1
  2. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/transform/transform_args.py +18 -2
  3. compressed_tensors-0.10.2a20250606/src/compressed_tensors/transform/utils/hadamard.py +161 -0
  4. compressed_tensors-0.10.2a20250606/src/compressed_tensors/transform/utils/utils.py +91 -0
  5. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/utils/helpers.py +53 -0
  6. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/utils/offload.py +9 -7
  7. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/version.py +2 -2
  8. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606/src/compressed_tensors.egg-info}/PKG-INFO +1 -1
  9. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors.egg-info/SOURCES.txt +4 -0
  10. compressed_tensors-0.10.2a20250606/tests/test_transform/utils/test_hadamard.py +84 -0
  11. compressed_tensors-0.10.2a20250606/tests/test_utils/__init__.py +13 -0
  12. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_utils/test_helpers.py +41 -1
  13. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/.gitkeep +0 -0
  14. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/actions/test/action.yml +0 -0
  15. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/scripts/step-status +0 -0
  16. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/workflows/build-test.yml +0 -0
  17. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/workflows/build.yml +0 -0
  18. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/workflows/report.yml +0 -0
  19. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/workflows/test-check.yaml +0 -0
  20. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/workflows/test.yml +0 -0
  21. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/workflows/trigger-all.yml +0 -0
  22. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.github/workflows/upload.yml +0 -0
  23. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/.gitignore +0 -0
  24. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/LICENSE +0 -0
  25. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/Makefile +0 -0
  26. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/README.md +0 -0
  27. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/bit_packing/ex_quantize_and_pack.py +0 -0
  28. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/bit_packing/int4_config.json +0 -0
  29. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/bitmask_compression.ipynb +0 -0
  30. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/llama_1.1b/ex_config_quantization.py +0 -0
  31. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/llama_1.1b/ex_llmcompressor_quantization.py +0 -0
  32. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/llama_1.1b/example_quant_config.json +0 -0
  33. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/llama_1.1b/example_quant_recipe.yaml +0 -0
  34. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/examples/quantize_and_pack_int4.ipynb +0 -0
  35. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/pyproject.toml +0 -0
  36. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/setup.cfg +0 -0
  37. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/setup.py +0 -0
  38. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/__init__.py +0 -0
  39. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/README.md +0 -0
  40. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/__init__.py +0 -0
  41. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/base.py +0 -0
  42. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/__init__.py +0 -0
  43. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/base.py +0 -0
  44. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/helpers.py +0 -0
  45. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/model_compressors/__init__.py +0 -0
  46. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/model_compressors/model_compressor.py +0 -0
  47. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/quantized_compressors/__init__.py +0 -0
  48. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/quantized_compressors/base.py +0 -0
  49. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/quantized_compressors/naive_quantized.py +0 -0
  50. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/quantized_compressors/nvfp4_quantized.py +0 -0
  51. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/quantized_compressors/pack_quantized.py +0 -0
  52. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/sparse_compressors/__init__.py +0 -0
  53. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/sparse_compressors/base.py +0 -0
  54. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/sparse_compressors/dense.py +0 -0
  55. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/sparse_compressors/sparse_24_bitmask.py +0 -0
  56. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/sparse_compressors/sparse_bitmask.py +0 -0
  57. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/sparse_quantized_compressors/__init__.py +0 -0
  58. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/compressors/sparse_quantized_compressors/marlin_24.py +0 -0
  59. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/config/__init__.py +0 -0
  60. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/config/base.py +0 -0
  61. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/config/dense.py +0 -0
  62. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/config/sparse_24_bitmask.py +0 -0
  63. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/config/sparse_bitmask.py +0 -0
  64. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/linear/__init__.py +0 -0
  65. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/linear/compressed_linear.py +0 -0
  66. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/__init__.py +0 -0
  67. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/lifecycle/__init__.py +0 -0
  68. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/lifecycle/apply.py +0 -0
  69. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/lifecycle/compressed.py +0 -0
  70. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/lifecycle/forward.py +0 -0
  71. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/lifecycle/helpers.py +0 -0
  72. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/lifecycle/initialize.py +0 -0
  73. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/quant_args.py +0 -0
  74. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/quant_config.py +0 -0
  75. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/quant_scheme.py +0 -0
  76. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/utils/__init__.py +0 -0
  77. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/quantization/utils/helpers.py +0 -0
  78. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/registry/__init__.py +0 -0
  79. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/registry/registry.py +0 -0
  80. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/transform/__init__.py +0 -0
  81. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/transform/transform_config.py +0 -0
  82. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/transform/transform_scheme.py +0 -0
  83. {compressed_tensors-0.10.1a20250604/tests → compressed_tensors-0.10.2a20250606/src/compressed_tensors/transform/utils}/__init__.py +0 -0
  84. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/utils/__init__.py +0 -0
  85. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/utils/permutations_24.py +0 -0
  86. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/utils/permute.py +0 -0
  87. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/utils/safetensors_load.py +0 -0
  88. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors/utils/semi_structured_conversions.py +0 -0
  89. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors.egg-info/dependency_links.txt +0 -0
  90. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors.egg-info/requires.txt +0 -0
  91. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/src/compressed_tensors.egg-info/top_level.txt +0 -0
  92. {compressed_tensors-0.10.1a20250604/tests/test_compressors → compressed_tensors-0.10.2a20250606/tests}/__init__.py +0 -0
  93. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/conftest.py +0 -0
  94. {compressed_tensors-0.10.1a20250604/tests/test_compressors/model_compressors → compressed_tensors-0.10.2a20250606/tests/test_compressors}/__init__.py +0 -0
  95. {compressed_tensors-0.10.1a20250604/tests/test_compressors/quantized_compressors → compressed_tensors-0.10.2a20250606/tests/test_compressors/model_compressors}/__init__.py +0 -0
  96. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/model_compressors/test_model_compressor.py +0 -0
  97. {compressed_tensors-0.10.1a20250604/tests/test_compressors/sparse_compressors → compressed_tensors-0.10.2a20250606/tests/test_compressors/quantized_compressors}/__init__.py +0 -0
  98. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/quantized_compressors/test_fp8_quant.py +0 -0
  99. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/quantized_compressors/test_int_quant.py +0 -0
  100. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/quantized_compressors/test_nvfp4_quant.py +0 -0
  101. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/quantized_compressors/test_pack_quant.py +0 -0
  102. {compressed_tensors-0.10.1a20250604/tests/test_compressors/sparse_quantized_compressors → compressed_tensors-0.10.2a20250606/tests/test_compressors/sparse_compressors}/__init__.py +0 -0
  103. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/sparse_compressors/test_bitmask.py +0 -0
  104. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/sparse_compressors/test_sparse_24_bitmask.py +0 -0
  105. {compressed_tensors-0.10.1a20250604/tests/test_configs → compressed_tensors-0.10.2a20250606/tests/test_compressors/sparse_quantized_compressors}/__init__.py +0 -0
  106. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_compressors/sparse_quantized_compressors/test_marlin_24.py +0 -0
  107. {compressed_tensors-0.10.1a20250604/tests/test_linear → compressed_tensors-0.10.2a20250606/tests/test_configs}/__init__.py +0 -0
  108. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_configs/test_base.py +0 -0
  109. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_examples/test_bitmask_compression_ipynb.py +0 -0
  110. {compressed_tensors-0.10.1a20250604/tests/test_quantization → compressed_tensors-0.10.2a20250606/tests/test_linear}/__init__.py +0 -0
  111. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_linear/test_compressed_linear.py +0 -0
  112. {compressed_tensors-0.10.1a20250604/tests/test_quantization/lifecycle → compressed_tensors-0.10.2a20250606/tests/test_quantization}/__init__.py +0 -0
  113. {compressed_tensors-0.10.1a20250604/tests/test_quantization/test_configs → compressed_tensors-0.10.2a20250606/tests/test_quantization/lifecycle}/__init__.py +0 -0
  114. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/conftest.py +0 -0
  115. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/test_apply.py +0 -0
  116. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/test_dynamic_lifecycle.py +0 -0
  117. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/test_enabled.py +0 -0
  118. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/test_forward.py +0 -0
  119. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/test_helpers.py +0 -0
  120. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/test_initialize.py +0 -0
  121. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/lifecycle/test_lifecycle.py +0 -0
  122. {compressed_tensors-0.10.1a20250604/tests/test_utils → compressed_tensors-0.10.2a20250606/tests/test_quantization/test_configs}/__init__.py +0 -0
  123. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/test_configs/test_bit_depths.py +0 -0
  124. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/test_configs/test_strategies.py +0 -0
  125. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/test_quant_args.py +0 -0
  126. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/test_quant_config.py +0 -0
  127. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/test_quant_scheme.py +0 -0
  128. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_quantization/test_utils/test_helpers.py +0 -0
  129. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_registry.py +0 -0
  130. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_transform/test_transform_args.py +0 -0
  131. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_transform/test_transform_config.py +0 -0
  132. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_transform/test_transform_scheme.py +0 -0
  133. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_utils/test_offload.py +0 -0
  134. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/test_utils/test_safetensors_load.py +0 -0
  135. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/tests/testing_utils.py +0 -0
  136. {compressed_tensors-0.10.1a20250604 → compressed_tensors-0.10.2a20250606}/utils/copyright.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compressed-tensors
3
- Version: 0.10.1a20250604
3
+ Version: 0.10.2a20250606
4
4
  Summary: Library for utilization of compressed safetensors of neural network models
5
5
  Home-page: https://github.com/neuralmagic/compressed-tensors
6
6
  Author: Neuralmagic, Inc.
@@ -13,15 +13,31 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from enum import Enum
16
- from typing import Any, List
16
+ from typing import List
17
17
 
18
18
  from pydantic import BaseModel, Field, field_validator
19
19
 
20
20
 
21
- __all__ = ["TransformArgs"]
21
+ __all__ = ["TransformArgs", "TransformLocation"]
22
22
 
23
23
 
24
24
  class TransformLocation(str, Enum):
25
+ """
26
+ Enum representing which parameters/activations a transform weight should be applied
27
+ to on a given module.
28
+
29
+ | -------------------------------------------------------------------------------------------------------- | # noqa: E501
30
+ | Name | Runtime | Values | Locations Where Inverse Could Be Applied | # noqa: E501
31
+ | --------------- | ----------- | ------------- | -------------------------------------------------------- | # noqa: E501
32
+ | `INPUT` | online | activations | `prev.WEIGHT_OUTPUT`, `prev.OUTPUT`, `this.WEIGHT_INPUT` | # noqa: E501
33
+ | `WEIGHT_INPUT` | offline | weight | `prev.WEIGHT_OUTPUT`, `prev.OUTPUT`, `this.INPUT` | # noqa: E501
34
+ | `WEIGHT_OUTPUT` | offline | weight | `this.OUTPUT`, `next.INPUT`, `next.WEIGHT_INPUT` | # noqa: E501
35
+ | `OUTPUT` | online | activations | `this.WEIGHT_OUTPUT`, `next.INPUT`, `next.WEIGHT_INPUT` | # noqa: E501
36
+ | `K_CACHE` | online | key_values | `q_proj.Q_ATTN` | # noqa: E501
37
+ | `Q_ATTN` | online | query_values | `k_proj.K_CACHE` | # noqa: E501
38
+ | -------------------------------------------------------------------------------------------------------- | # noqa: E501
39
+ """
40
+
25
41
  INPUT = "input"
26
42
  WEIGHT_INPUT = "weight_input"
27
43
  WEIGHT_OUTPUT = "weight_output"
@@ -0,0 +1,161 @@
1
+ # Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing,
10
+ # software distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import math
16
+ from typing import Optional, Tuple
17
+
18
+ import numpy
19
+ import torch
20
+
21
+
22
+ __all__ = ["random_hadamard_matrix", "deterministic_hadamard_matrix"]
23
+
24
+ # adapted from:
25
+ # https://github.com/scipy/scipy/blob/v1.15.2/scipy/linalg/_special_matrices.py
26
+ def deterministic_hadamard_matrix(size: int) -> torch.Tensor:
27
+ """
28
+ Construct an n-by-n Hadamard matrix, using Sylvester's construction.
29
+ `n` must be a power of 2.
30
+
31
+ :param size: order of the matrix, must be a power of 2
32
+ :return: hadamard matrix of size `size`
33
+ """
34
+ if size <= 0:
35
+ raise ValueError("Cannot construct deterministic hadamard of size <= 0")
36
+
37
+ log2 = int(math.log(size, 2))
38
+ if size != 2**log2:
39
+ raise ValueError("Cannot construct deterministic hadamard of size != 2^n")
40
+
41
+ H = numpy.array([[1]], dtype=int)
42
+
43
+ # Sylvester's construction
44
+ for i in range(0, log2):
45
+ H = numpy.vstack((numpy.hstack((H, H)), numpy.hstack((H, -H))))
46
+
47
+ return torch.from_numpy(H / math.sqrt(size))
48
+
49
+
50
+ # adapted from:
51
+ # https://github.com/facebookresearch/SpinQuant/blob/main/utils/hadamard_utils.py
52
+
53
+ # TODO: the following library exists for online rotations and should be considered
54
+ # in the future:
55
+ # https://github.com/Dao-AILab/fast-hadamard-transform/tree/master
56
+
57
+
58
+ def random_hadamard_matrix(
59
+ size: int, gen: Optional[torch.Generator] = None
60
+ ) -> torch.Tensor:
61
+ """
62
+ Produces a randomly generated Hadamard matrix.
63
+ See https://cornell-relaxml.github.io/quip-sharp/ ,
64
+ Section "Randomized Hadamard Transformation"
65
+
66
+ :param size: The dimension of the hamadard matrix
67
+ :param gen: Optional generator random values
68
+ :return: randomly generated hadamard matrix
69
+ """
70
+ # Benefits: support other shapes / non powers of 2, support randomization
71
+ Q = torch.randint(low=0, high=2, size=(size,), generator=gen, dtype=torch.float64)
72
+ Q = Q * 2 - 1
73
+ Q = torch.diag(Q)
74
+ return _matmul_hadU(Q) / math.sqrt(size)
75
+
76
+
77
+ def _get_hadK(n: int, transpose: bool = False) -> Tuple[torch.Tensor, int]:
78
+ # NOTE: we can easily extend the list of supported shapes/sizes
79
+ # by adding to these methods
80
+ hadK, K = None, None
81
+ if n % 20 == 0:
82
+ assert _is_pow2(n // 20)
83
+ K = 20
84
+ hadK = _get_had20().T if transpose else _get_had20()
85
+ elif n % 12 == 0:
86
+ assert _is_pow2(n // 12)
87
+ K = 12
88
+ hadK = _get_had12().T if transpose else _get_had12()
89
+ else:
90
+ assert _is_pow2(n)
91
+ K = 1
92
+
93
+ return hadK, K
94
+
95
+
96
+ def _matmul_hadU(X, transpose=False) -> torch.Tensor:
97
+ n = X.shape[-1]
98
+ # Check if we have the determined hadamard matrix
99
+ hadK, K = _get_hadK(n, transpose)
100
+ # Reshape diag matrix with randomized -1/+1
101
+ input = X.clone().view(-1, n, 1)
102
+ output = input.clone()
103
+
104
+ # for cases when hadK is not predetermined, determine hadamard matrix
105
+ while input.shape[1] > K:
106
+ input = input.view(input.shape[0], input.shape[1] // 2, 2, input.shape[2])
107
+ output = output.view(input.shape)
108
+ output[:, :, 0, :] = input[:, :, 0, :] + input[:, :, 1, :]
109
+ output[:, :, 1, :] = input[:, :, 0, :] - input[:, :, 1, :]
110
+ output = output.view(input.shape[0], input.shape[1], -1)
111
+ (input, output) = (output, input)
112
+ del output
113
+
114
+ # K == 1 when hadK is None; this happens when the size dim (n)
115
+ # is not comaptible with any of the maintained hadamard matrices
116
+
117
+ if K > 1:
118
+ # Do not explicitly repeat - OOM
119
+ # input = torch.bmm(
120
+ # hadK.repeat(len(input), 1, 1).to(input.device).to(input.dtype), input)
121
+ # Use bcast instead
122
+
123
+ # for cases when hadK is pre-determined
124
+ input = hadK.view(1, K, K).to(input) @ input
125
+
126
+ # normalize
127
+ return input.view(X.shape)
128
+
129
+
130
+ def _is_pow2(n: int) -> bool:
131
+ return (n & (n - 1) == 0) and (n > 0)
132
+
133
+
134
+ def _reshape_bits(packed_bits: numpy.ndarray, original_size: int) -> numpy.ndarray:
135
+ had_unpacked = numpy.unpackbits(packed_bits)
136
+ had_unpacked = [1 if x == 1 else -1 for x in had_unpacked]
137
+ had_unpacked = numpy.array(had_unpacked).reshape((original_size, original_size))
138
+ return had_unpacked
139
+
140
+
141
+ # http://www.neilsloane.com/hadamard/index.html
142
+ def _get_had12() -> torch.Tensor:
143
+ # fmt: off
144
+ had_12 = numpy.array([128, 13, 29, 232, 235, 71, 218,
145
+ 62, 209, 246, 139, 180, 157, 168, 237, 199, 106, 59], dtype=numpy.uint8)
146
+ # fmt: on
147
+ # TODO: just unpack during apply
148
+ had_12_unpacked = _reshape_bits(had_12, original_size=12)
149
+ return torch.tensor(had_12_unpacked)
150
+
151
+
152
+ def _get_had20() -> torch.Tensor:
153
+ # fmt: off
154
+ had_20 = numpy.array([128, 0, 13, 133, 121, 236, 43, 203, 97, 94, 155, 10, 252,
155
+ 216, 87, 230, 194, 191, 54, 21, 249, 176, 171, 205, 133, 222, 108, 42, 243,
156
+ 97, 215, 155, 10, 188, 216, 149, 230, 200, 175, 54, 133, 121, 188, 43,
157
+ 205, 225, 94, 107, 10, 243], dtype=numpy.uint8)
158
+ # fmt: on
159
+ # TODO: just unpack during apply
160
+ had_20_unpacked = _reshape_bits(had_20, original_size=20)
161
+ return torch.tensor(had_20_unpacked)
@@ -0,0 +1,91 @@
1
+ # Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing,
10
+ # software distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import torch
16
+ from compressed_tensors.transform import TransformLocation
17
+
18
+
19
+ __all__ = ["get_matrix_size", "apply_transform_weight"]
20
+
21
+
22
+ def get_matrix_size(module: torch.nn.Module, location: TransformLocation) -> int:
23
+ """
24
+ Determine the size of a matrix given its location on the module
25
+
26
+ :param module: module that matrix will be applied to
27
+ :param location: location on module
28
+ :return: size of matrix
29
+ """
30
+ assert isinstance(module, torch.nn.Linear)
31
+ if location in ("input", TransformLocation.WEIGHT_INPUT):
32
+ return module.in_features
33
+ else:
34
+ return module.out_features
35
+
36
+
37
+ def apply_transform_weight(
38
+ weight: torch.Tensor,
39
+ value: torch.Tensor,
40
+ location: TransformLocation,
41
+ ) -> torch.Tensor:
42
+ """
43
+ Using the transform location, determine how to apply the transform weight to the
44
+ given value. For more info on input and output transforms, see `TransformLocation`
45
+
46
+ The following explains how weights should be applied to values according to location
47
+
48
+ let x be input activation
49
+ W be weight,
50
+ yh, xh, Wh be transformed output, input, weight
51
+
52
+ note that
53
+ y = (x W.T) // torch.nn.Linear
54
+
55
+ Choose values for yh, xh, and Wh which incorporate matrix transforms
56
+
57
+ let V, Vi be transform matrices on input side
58
+ U, Ui be transform matrices on output side
59
+
60
+ pick xh = (x V)
61
+ Wh = (U.T W Vi.T)
62
+ yh = (y U)
63
+
64
+ The following shows that `yh = (xh) (Wh).T` for the chosen values of yh, xh, and Wh
65
+
66
+ (xh) (Wh).T = (x V) (U.T W Vi.T).T
67
+ = (x V) (Vi W.T U) // transpose matrix product identity
68
+ = (x W.T) U
69
+ = y U
70
+ = yh
71
+
72
+ :param weight: transform weight to apply
73
+ :param value: value to apply weight to
74
+ :param location: determines how weight should be applied
75
+ :return: value after transform weight has been applied
76
+ """
77
+
78
+ if location == TransformLocation.INPUT:
79
+ return value @ weight
80
+
81
+ elif location == TransformLocation.WEIGHT_INPUT:
82
+ return value @ weight.T
83
+
84
+ elif location == TransformLocation.WEIGHT_OUTPUT:
85
+ return weight.T @ value
86
+
87
+ elif location == TransformLocation.OUTPUT:
88
+ return value @ weight
89
+
90
+ else:
91
+ raise NotImplementedError(f"{location} has not been implemented yet")
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import contextlib
15
16
  import warnings
16
17
  from functools import wraps
17
18
  from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional
@@ -38,6 +39,8 @@ __all__ = [
38
39
  "shard_tensor",
39
40
  "pack_bitmasks",
40
41
  "unpack_bitmasks",
42
+ "patch_attr",
43
+ "ParameterizedDefaultDict",
41
44
  ]
42
45
 
43
46
  FSDP_WRAPPER_NAME = "_fsdp_wrapped_module"
@@ -328,3 +331,53 @@ def unpack_bitmasks(
328
331
  )
329
332
 
330
333
  return unpacked_bitmasks_torch
334
+
335
+
336
+ @contextlib.contextmanager
337
+ def patch_attr(base: object, attr: str, value: Any):
338
+ """
339
+ Patch the value of an object attribute. Original value is restored upon exit
340
+
341
+ :param base: object which has the attribute to patch
342
+ :param attr: name of the the attribute to patch
343
+ :param value: used to replace original value
344
+
345
+ Usage:
346
+ >>> from types import SimpleNamespace
347
+ >>> obj = SimpleNamespace()
348
+ >>> with patch_attr(obj, "attribute", "value"):
349
+ ... assert obj.attribute == "value"
350
+ >>> assert not hasattr(obj, "attribute")
351
+ """
352
+ _sentinel = object()
353
+ original_value = getattr(base, attr, _sentinel)
354
+
355
+ setattr(base, attr, value)
356
+ try:
357
+ yield
358
+ finally:
359
+ if original_value is not _sentinel:
360
+ setattr(base, attr, original_value)
361
+ else:
362
+ delattr(base, attr)
363
+
364
+
365
+ class ParameterizedDefaultDict(dict):
366
+ """
367
+ Similar to `collections.DefaultDict`, but upon fetching a key which is missing,
368
+ the key is passed as arguments to the `default_factory`
369
+
370
+ :param default_factory: function which takes a key as input and returns the
371
+ corresponding default value
372
+ """
373
+
374
+ def __init__(self, default_factory: Callable[[Any], Any]):
375
+ self.default_factory = default_factory
376
+
377
+ def __missing__(self, key):
378
+ if isinstance(key, tuple):
379
+ value = self.default_factory(*key)
380
+ else:
381
+ value = self.default_factory(key)
382
+ self[key] = value
383
+ return value
@@ -87,13 +87,15 @@ def check_accelerate(fallback: Any):
87
87
  if not _has_accelerate:
88
88
 
89
89
  if fallback == "error":
90
- raise ValueError(
91
- "Please install `accelerate` in order to use this function"
92
- )
93
-
94
- @wraps(func)
95
- def fallback_fn(*args, **kwargs):
96
- return fallback
90
+ @wraps(func)
91
+ def fallback_fn(*args, **kwargs):
92
+ raise ValueError(
93
+ "Please install `accelerate` in order to use this function"
94
+ )
95
+ else:
96
+ @wraps(func)
97
+ def fallback_fn(*args, **kwargs):
98
+ return fallback
97
99
 
98
100
  return fallback_fn
99
101
 
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.10.1.a20250604'
21
- __version_tuple__ = version_tuple = (0, 10, 1)
20
+ __version__ = version = '0.10.2.a20250606'
21
+ __version_tuple__ = version_tuple = (0, 10, 2)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compressed-tensors
3
- Version: 0.10.1a20250604
3
+ Version: 0.10.2a20250606
4
4
  Summary: Library for utilization of compressed safetensors of neural network models
5
5
  Home-page: https://github.com/neuralmagic/compressed-tensors
6
6
  Author: Neuralmagic, Inc.
@@ -75,6 +75,9 @@ src/compressed_tensors/transform/__init__.py
75
75
  src/compressed_tensors/transform/transform_args.py
76
76
  src/compressed_tensors/transform/transform_config.py
77
77
  src/compressed_tensors/transform/transform_scheme.py
78
+ src/compressed_tensors/transform/utils/__init__.py
79
+ src/compressed_tensors/transform/utils/hadamard.py
80
+ src/compressed_tensors/transform/utils/utils.py
78
81
  src/compressed_tensors/utils/__init__.py
79
82
  src/compressed_tensors/utils/helpers.py
80
83
  src/compressed_tensors/utils/offload.py
@@ -124,6 +127,7 @@ tests/test_quantization/test_utils/test_helpers.py
124
127
  tests/test_transform/test_transform_args.py
125
128
  tests/test_transform/test_transform_config.py
126
129
  tests/test_transform/test_transform_scheme.py
130
+ tests/test_transform/utils/test_hadamard.py
127
131
  tests/test_utils/__init__.py
128
132
  tests/test_utils/test_helpers.py
129
133
  tests/test_utils/test_offload.py
@@ -0,0 +1,84 @@
1
+ # Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing,
10
+ # software distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ import numpy
17
+ import pytest
18
+ import torch
19
+ from compressed_tensors.transform.utils.hadamard import (
20
+ _get_had12,
21
+ _get_had20,
22
+ deterministic_hadamard_matrix,
23
+ random_hadamard_matrix,
24
+ )
25
+
26
+
27
+ @pytest.mark.parametrize(
28
+ "had_func",
29
+ [
30
+ _get_had12,
31
+ _get_had20,
32
+ ],
33
+ )
34
+ def test_packed_hadamard_compliant(had_func):
35
+ had_matrix = had_func()
36
+ size = had_matrix.size(0)
37
+ # HH.T == nI
38
+ product = had_matrix @ had_matrix.T
39
+ assert torch.equal(product, size * torch.eye(size))
40
+
41
+
42
+ @pytest.mark.parametrize(
43
+ "size",
44
+ [4096, 2048],
45
+ )
46
+ def test_random_hadamard_matrix_compliant(size):
47
+ had_matrix = random_hadamard_matrix(size)
48
+ product = torch.round(had_matrix @ had_matrix.T)
49
+ assert torch.equal(product, torch.eye(size))
50
+
51
+
52
+ def test_random_hadamard_generator():
53
+ generator = torch.Generator().manual_seed(42)
54
+ one = random_hadamard_matrix(2048, generator)
55
+ two = random_hadamard_matrix(2048, generator)
56
+
57
+ one_true = torch.tensor(
58
+ [
59
+ [-1, -1, -1],
60
+ [+1, -1, +1],
61
+ [-1, -1, +1],
62
+ ]
63
+ )
64
+ two_true = torch.tensor(
65
+ [
66
+ [-1, -1, -1],
67
+ [-1, +1, -1],
68
+ [+1, +1, -1],
69
+ ]
70
+ )
71
+
72
+ assert torch.all(one[:3, :3].sign() == one_true.sign())
73
+ assert torch.all(two[:3, :3].sign() == two_true.sign())
74
+
75
+
76
+ @pytest.mark.parametrize(
77
+ "size",
78
+ [1024],
79
+ )
80
+ def test_deterministic_hadamard_compliant(size):
81
+ had_matrix = deterministic_hadamard_matrix(size)
82
+ # (H / sqrt(n))(H.T / sqrt(n)) == I
83
+ product = had_matrix @ had_matrix.T
84
+ assert numpy.array_equal(product, numpy.eye(size))
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing,
10
+ # software distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
@@ -13,10 +13,17 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import os
16
+ from types import SimpleNamespace
16
17
 
17
18
  import pytest
18
19
  import torch
19
- from compressed_tensors import load_compressed, save_compressed, save_compressed_model
20
+ from compressed_tensors import (
21
+ ParameterizedDefaultDict,
22
+ load_compressed,
23
+ patch_attr,
24
+ save_compressed,
25
+ save_compressed_model,
26
+ )
20
27
  from compressed_tensors.config import BitmaskConfig
21
28
  from safetensors.torch import save_model
22
29
  from transformers import AutoModelForCausalLM
@@ -151,3 +158,36 @@ def test_save_compressed_model(tmp_path, llama_model):
151
158
  # make sure that compressed model is smaller
152
159
  # than uncompressed by roughly 1.14 (value established empirically)
153
160
  assert pytest.approx(size_uncompressed_kb / size_compressed_kb, 0.01) == 1.14
161
+
162
+
163
+ def test_patch_attr():
164
+ # patch, original value
165
+ obj = SimpleNamespace()
166
+ obj.attribute = "original"
167
+ with patch_attr(obj, "attribute", "patched"):
168
+ assert obj.attribute == "patched"
169
+ obj.attribute = "modified"
170
+ assert obj.attribute == "original"
171
+
172
+ # patch, no original attribute
173
+ obj = SimpleNamespace()
174
+ with patch_attr(obj, "attribute", "patched"):
175
+ assert obj.attribute == "patched"
176
+ obj.attribute = "modified"
177
+ assert not hasattr(obj, "attribute")
178
+
179
+
180
+ def test_parameterized_default_dict():
181
+ def add_one(value):
182
+ return value + 1
183
+
184
+ add_dict = ParameterizedDefaultDict(add_one)
185
+ assert add_dict[0] == 1
186
+ assert add_dict[1] == 2
187
+
188
+ def sum_vals(a, b):
189
+ return a + b
190
+
191
+ sum_dict = ParameterizedDefaultDict(sum_vals)
192
+ assert sum_dict[0, 1] == 1
193
+ assert sum_dict[5, 7] == 12