Diffusers
Safetensors
leewheel commited on
Commit
cd15ba7
·
verified ·
1 Parent(s): 2888c9b

Upload 23 files

Browse files
Files changed (24) hide show
  1. .gitattributes +1 -0
  2. python_env/lib/site-packages/safetensors-0.7.0.dist-info/INSTALLER +1 -0
  3. python_env/lib/site-packages/safetensors-0.7.0.dist-info/METADATA +133 -0
  4. python_env/lib/site-packages/safetensors-0.7.0.dist-info/RECORD +23 -0
  5. python_env/lib/site-packages/safetensors-0.7.0.dist-info/REQUESTED +0 -0
  6. python_env/lib/site-packages/safetensors-0.7.0.dist-info/WHEEL +4 -0
  7. python_env/lib/site-packages/safetensors-0.7.0.dist-info/licenses/LICENSE +201 -0
  8. python_env/lib/site-packages/safetensors/__init__.py +10 -0
  9. python_env/lib/site-packages/safetensors/__init__.pyi +164 -0
  10. python_env/lib/site-packages/safetensors/__pycache__/__init__.cpython-310.pyc +0 -0
  11. python_env/lib/site-packages/safetensors/__pycache__/flax.cpython-310.pyc +0 -0
  12. python_env/lib/site-packages/safetensors/__pycache__/mlx.cpython-310.pyc +0 -0
  13. python_env/lib/site-packages/safetensors/__pycache__/numpy.cpython-310.pyc +0 -0
  14. python_env/lib/site-packages/safetensors/__pycache__/paddle.cpython-310.pyc +0 -0
  15. python_env/lib/site-packages/safetensors/__pycache__/tensorflow.cpython-310.pyc +0 -0
  16. python_env/lib/site-packages/safetensors/__pycache__/torch.cpython-310.pyc +0 -0
  17. python_env/lib/site-packages/safetensors/_safetensors_rust.pyd +3 -0
  18. python_env/lib/site-packages/safetensors/flax.py +138 -0
  19. python_env/lib/site-packages/safetensors/mlx.py +140 -0
  20. python_env/lib/site-packages/safetensors/numpy.py +187 -0
  21. python_env/lib/site-packages/safetensors/paddle.py +290 -0
  22. python_env/lib/site-packages/safetensors/py.typed +0 -0
  23. python_env/lib/site-packages/safetensors/tensorflow.py +139 -0
  24. python_env/lib/site-packages/safetensors/torch.py +550 -0
.gitattributes CHANGED
@@ -511,3 +511,4 @@ python_env/lib/site-packages/scipy/stats/tests/__pycache__/test_distributions.cp
511
  python_env/lib/site-packages/scipy/stats/tests/__pycache__/test_morestats.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
512
  python_env/lib/site-packages/scipy/stats/tests/__pycache__/test_multivariate.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
513
  python_env/lib/site-packages/scipy/stats/tests/__pycache__/test_stats.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
 
 
511
  python_env/lib/site-packages/scipy/stats/tests/__pycache__/test_morestats.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
512
  python_env/lib/site-packages/scipy/stats/tests/__pycache__/test_multivariate.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
513
  python_env/lib/site-packages/scipy/stats/tests/__pycache__/test_stats.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
514
+ python_env/lib/site-packages/safetensors/_safetensors_rust.pyd filter=lfs diff=lfs merge=lfs -text
python_env/lib/site-packages/safetensors-0.7.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
python_env/lib/site-packages/safetensors-0.7.0.dist-info/METADATA ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: safetensors
3
+ Version: 0.7.0
4
+ Classifier: Development Status :: 5 - Production/Stable
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: Intended Audience :: Education
7
+ Classifier: Intended Audience :: Science/Research
8
+ Classifier: License :: OSI Approved :: Apache Software License
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.7
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Classifier: Typing :: Typed
17
+ Requires-Dist: numpy>=1.21.6 ; extra == 'numpy'
18
+ Requires-Dist: packaging ; extra == 'torch'
19
+ Requires-Dist: safetensors[numpy] ; extra == 'torch'
20
+ Requires-Dist: torch>=1.10 ; extra == 'torch'
21
+ Requires-Dist: safetensors[numpy] ; extra == 'tensorflow'
22
+ Requires-Dist: tensorflow>=2.11.0 ; extra == 'tensorflow'
23
+ Requires-Dist: safetensors[numpy] ; extra == 'pinned-tf'
24
+ Requires-Dist: tensorflow==2.18.0 ; extra == 'pinned-tf'
25
+ Requires-Dist: safetensors[numpy] ; extra == 'jax'
26
+ Requires-Dist: flax>=0.6.3 ; extra == 'jax'
27
+ Requires-Dist: jax>=0.3.25 ; extra == 'jax'
28
+ Requires-Dist: jaxlib>=0.3.25 ; extra == 'jax'
29
+ Requires-Dist: mlx>=0.0.9 ; extra == 'mlx'
30
+ Requires-Dist: safetensors[numpy] ; extra == 'paddlepaddle'
31
+ Requires-Dist: paddlepaddle>=2.4.1 ; extra == 'paddlepaddle'
32
+ Requires-Dist: ruff ; extra == 'quality'
33
+ Requires-Dist: safetensors[numpy] ; extra == 'testing'
34
+ Requires-Dist: h5py>=3.7.0 ; extra == 'testing'
35
+ Requires-Dist: huggingface-hub>=0.12.1 ; extra == 'testing'
36
+ Requires-Dist: setuptools-rust>=1.5.2 ; extra == 'testing'
37
+ Requires-Dist: pytest>=7.2.0 ; extra == 'testing'
38
+ Requires-Dist: pytest-benchmark>=4.0.0 ; extra == 'testing'
39
+ Requires-Dist: hypothesis>=6.70.2 ; extra == 'testing'
40
+ Requires-Dist: safetensors[numpy] ; extra == 'testingfree'
41
+ Requires-Dist: huggingface-hub>=0.12.1 ; extra == 'testingfree'
42
+ Requires-Dist: setuptools-rust>=1.5.2 ; extra == 'testingfree'
43
+ Requires-Dist: pytest>=7.2.0 ; extra == 'testingfree'
44
+ Requires-Dist: pytest-benchmark>=4.0.0 ; extra == 'testingfree'
45
+ Requires-Dist: hypothesis>=6.70.2 ; extra == 'testingfree'
46
+ Requires-Dist: safetensors[torch] ; extra == 'all'
47
+ Requires-Dist: safetensors[numpy] ; extra == 'all'
48
+ Requires-Dist: safetensors[pinned-tf] ; extra == 'all'
49
+ Requires-Dist: safetensors[jax] ; extra == 'all'
50
+ Requires-Dist: safetensors[paddlepaddle] ; extra == 'all'
51
+ Requires-Dist: safetensors[quality] ; extra == 'all'
52
+ Requires-Dist: safetensors[testing] ; extra == 'all'
53
+ Requires-Dist: safetensors[all] ; extra == 'dev'
54
+ Provides-Extra: numpy
55
+ Provides-Extra: torch
56
+ Provides-Extra: tensorflow
57
+ Provides-Extra: pinned-tf
58
+ Provides-Extra: jax
59
+ Provides-Extra: mlx
60
+ Provides-Extra: paddlepaddle
61
+ Provides-Extra: quality
62
+ Provides-Extra: testing
63
+ Provides-Extra: testingfree
64
+ Provides-Extra: all
65
+ Provides-Extra: dev
66
+ License-File: LICENSE
67
+ Author-email: Nicolas Patry <patry.nicolas@protonmail.com>
68
+ Requires-Python: >=3.9
69
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
70
+ Project-URL: Homepage, https://github.com/huggingface/safetensors
71
+ Project-URL: Source, https://github.com/huggingface/safetensors
72
+
73
+ ## Installation
74
+
75
+ ```
76
+ pip install safetensors
77
+ ```
78
+
79
+
80
+ ## Usage
81
+
82
+ ### Numpy
83
+
84
+ ```python
85
+ from safetensors.numpy import save_file, load_file
86
+ import numpy as np
87
+
88
+ tensors = {
89
+ "a": np.zeros((2, 2)),
90
+ "b": np.zeros((2, 3), dtype=np.uint8)
91
+ }
92
+
93
+ save_file(tensors, "./model.safetensors")
94
+
95
+
96
+ # Now loading
97
+ loaded = load_file("./model.safetensors")
98
+ ```
99
+
100
+ ### Torch
101
+
102
+ ```python
103
+ from safetensors.torch import save_file, load_file
104
+ import torch
105
+
106
+ tensors = {
107
+ "a": torch.zeros((2, 2)),
108
+ "b": torch.zeros((2, 3), dtype=torch.uint8)
109
+ }
110
+
111
+ save_file(tensors, "./model.safetensors")
112
+
113
+
114
+ # Now loading
115
+ loaded = load_file("./model.safetensors")
116
+ ```
117
+
118
+ ### Developing
119
+
120
+ ```
121
+ # inside ./safetensors/bindings/python
122
+ pip install .[dev]
123
+ ```
124
+ Should be enough to install this library locally.
125
+
126
+ ### Testing
127
+
128
+ ```
129
+ # inside ./safetensors/bindings/python
130
+ pip install .[dev]
131
+ pytest -sv tests/
132
+ ```
133
+
python_env/lib/site-packages/safetensors-0.7.0.dist-info/RECORD ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ safetensors-0.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ safetensors-0.7.0.dist-info/METADATA,sha256=j4yXpt97GFoHwriefq-dEwV9ZX_7SZKS795bMtYUiBs,4185
3
+ safetensors-0.7.0.dist-info/RECORD,,
4
+ safetensors-0.7.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ safetensors-0.7.0.dist-info/WHEEL,sha256=MW5GXj0PFGHxdts4kUIyLDU55oFjz5S6uZmcnjsRmds,95
6
+ safetensors-0.7.0.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
7
+ safetensors/__init__.py,sha256=HYY5VVsb3b-cxhZBwhNx53ZKqSIB4M14nIXLTOAM1Wc,204
8
+ safetensors/__init__.pyi,sha256=tnVaPqYbh8ggFbOZdYKUC4ArqitiWDfrIQt1BNJ377k,4183
9
+ safetensors/__pycache__/__init__.cpython-310.pyc,,
10
+ safetensors/__pycache__/flax.cpython-310.pyc,,
11
+ safetensors/__pycache__/mlx.cpython-310.pyc,,
12
+ safetensors/__pycache__/numpy.cpython-310.pyc,,
13
+ safetensors/__pycache__/paddle.cpython-310.pyc,,
14
+ safetensors/__pycache__/tensorflow.cpython-310.pyc,,
15
+ safetensors/__pycache__/torch.cpython-310.pyc,,
16
+ safetensors/_safetensors_rust.pyd,sha256=8gPLI70OVyFz6ze8U_qlSH1QD5vCVAkB0NpGbFq62vA,738304
17
+ safetensors/flax.py,sha256=SnuiGojmth0eCFIWoKEvAfh95nZP9uCZ9E-S4NndrbU,3991
18
+ safetensors/mlx.py,sha256=KvfTWusLSx1hSPWQgg99iL-z9VoD6zQ8l4-RAsCe7P8,3990
19
+ safetensors/numpy.py,sha256=8ci56gDXetlYHH1-Nru83auiUVi-Q1P9bKvfsdkLKPw,5215
20
+ safetensors/paddle.py,sha256=EhXpflqrhKr_NFh4jxV9SUnW0B1vcX_KdPdTqcytrDs,9011
21
+ safetensors/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ safetensors/tensorflow.py,sha256=DajI3qkz00Zy2h7jublSAvTaD51QOPdaIgKQIeSiCRs,4042
23
+ safetensors/torch.py,sha256=CLVWgWQdLm_tVzhRPaeihBHt-4iGAtUW5fY2ys3TyMc,19160
python_env/lib/site-packages/safetensors-0.7.0.dist-info/REQUESTED ADDED
File without changes
python_env/lib/site-packages/safetensors-0.7.0.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.10.2)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-abi3-win_amd64
python_env/lib/site-packages/safetensors-0.7.0.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
python_env/lib/site-packages/safetensors/__init__.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Re-export this
2
+ from ._safetensors_rust import ( # noqa: F401
3
+ SafetensorError,
4
+ __version__,
5
+ deserialize,
6
+ safe_open,
7
+ _safe_open_handle,
8
+ serialize,
9
+ serialize_file,
10
+ )
python_env/lib/site-packages/safetensors/__init__.pyi ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated content DO NOT EDIT
2
+ @staticmethod
3
+ def deserialize(bytes):
4
+ """
5
+ Opens a safetensors lazily and returns tensors as asked
6
+
7
+ Args:
8
+ data (`bytes`):
9
+ The byte content of a file
10
+
11
+ Returns:
12
+ (`List[str, Dict[str, Dict[str, any]]]`):
13
+ The deserialized content is like:
14
+ [("tensor_name", {"shape": [2, 3], "dtype": "F32", "data": b"\0\0.." }), (...)]
15
+ """
16
+ pass
17
+
18
+ @staticmethod
19
+ def serialize(tensor_dict, metadata=None):
20
+ """
21
+ Serializes raw data.
22
+
23
+ Args:
24
+ tensor_dict (`Dict[str, Dict[Any]]`):
25
+ The tensor dict is like:
26
+ {"tensor_name": {"dtype": "F32", "shape": [2, 3], "data": b"\0\0"}}
27
+ metadata (`Dict[str, str]`, *optional*):
28
+ The optional purely text annotations
29
+
30
+ Returns:
31
+ (`bytes`):
32
+ The serialized content.
33
+ """
34
+ pass
35
+
36
+ @staticmethod
37
+ def serialize_file(tensor_dict, filename, metadata=None):
38
+ """
39
+ Serializes raw data into file.
40
+
41
+ Args:
42
+ tensor_dict (`Dict[str, Dict[Any]]`):
43
+ The tensor dict is like:
44
+ {"tensor_name": {"dtype": "F32", "shape": [2, 3], "data": b"\0\0"}}
45
+ filename (`str`, or `os.PathLike`):
46
+ The name of the file to write into.
47
+ metadata (`Dict[str, str]`, *optional*):
48
+ The optional purely text annotations
49
+
50
+ Returns:
51
+ (`NoneType`):
52
+ On success return None
53
+ """
54
+ pass
55
+
56
+ class safe_open:
57
+ """
58
+ Opens a safetensors lazily and returns tensors as asked
59
+
60
+ Args:
61
+ filename (`str`, or `os.PathLike`):
62
+ The filename to open
63
+
64
+ framework (`str`):
65
+ The framework you want you tensors in. Supported values:
66
+ `pt`, `tf`, `flax`, `numpy`.
67
+
68
+ device (`str`, defaults to `"cpu"`):
69
+ The device on which you want the tensors.
70
+ """
71
+ def __init__(self, filename, framework, device=...):
72
+ pass
73
+
74
+ def __enter__(self):
75
+ """
76
+ Start the context manager
77
+ """
78
+ pass
79
+
80
+ def __exit__(self, _exc_type, _exc_value, _traceback):
81
+ """
82
+ Exits the context manager
83
+ """
84
+ pass
85
+
86
+ def get_slice(self, name):
87
+ """
88
+ Returns a full slice view object
89
+
90
+ Args:
91
+ name (`str`):
92
+ The name of the tensor you want
93
+
94
+ Returns:
95
+ (`PySafeSlice`):
96
+ A dummy object you can slice into to get a real tensor
97
+ Example:
98
+ ```python
99
+ from safetensors import safe_open
100
+
101
+ with safe_open("model.safetensors", framework="pt", device=0) as f:
102
+ tensor_part = f.get_slice("embedding")[:, ::8]
103
+
104
+ ```
105
+ """
106
+ pass
107
+
108
+ def get_tensor(self, name):
109
+ """
110
+ Returns a full tensor
111
+
112
+ Args:
113
+ name (`str`):
114
+ The name of the tensor you want
115
+
116
+ Returns:
117
+ (`Tensor`):
118
+ The tensor in the framework you opened the file for.
119
+
120
+ Example:
121
+ ```python
122
+ from safetensors import safe_open
123
+
124
+ with safe_open("model.safetensors", framework="pt", device=0) as f:
125
+ tensor = f.get_tensor("embedding")
126
+
127
+ ```
128
+ """
129
+ pass
130
+
131
+ def keys(self):
132
+ """
133
+ Returns the names of the tensors in the file.
134
+
135
+ Returns:
136
+ (`List[str]`):
137
+ The name of the tensors contained in that file
138
+ """
139
+ pass
140
+
141
+ def metadata(self):
142
+ """
143
+ Return the special non tensor information in the header
144
+
145
+ Returns:
146
+ (`Dict[str, str]`):
147
+ The freeform metadata.
148
+ """
149
+ pass
150
+
151
+ def offset_keys(self):
152
+ """
153
+ Returns the names of the tensors in the file, ordered by offset.
154
+
155
+ Returns:
156
+ (`List[str]`):
157
+ The name of the tensors contained in that file
158
+ """
159
+ pass
160
+
161
+ class SafetensorError(Exception):
162
+ """
163
+ Custom Python Exception for Safetensor errors.
164
+ """
python_env/lib/site-packages/safetensors/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (364 Bytes). View file
 
python_env/lib/site-packages/safetensors/__pycache__/flax.cpython-310.pyc ADDED
Binary file (4.29 kB). View file
 
python_env/lib/site-packages/safetensors/__pycache__/mlx.cpython-310.pyc ADDED
Binary file (4.33 kB). View file
 
python_env/lib/site-packages/safetensors/__pycache__/numpy.cpython-310.pyc ADDED
Binary file (5.51 kB). View file
 
python_env/lib/site-packages/safetensors/__pycache__/paddle.cpython-310.pyc ADDED
Binary file (7.95 kB). View file
 
python_env/lib/site-packages/safetensors/__pycache__/tensorflow.cpython-310.pyc ADDED
Binary file (4.39 kB). View file
 
python_env/lib/site-packages/safetensors/__pycache__/torch.cpython-310.pyc ADDED
Binary file (15.7 kB). View file
 
python_env/lib/site-packages/safetensors/_safetensors_rust.pyd ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f203cb23bd0e572173eb37bc53faa5487d500f9bc2540901d0da466c5abadaf0
3
+ size 738304
python_env/lib/site-packages/safetensors/flax.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Dict, Optional, Union
3
+
4
+ import numpy as np
5
+
6
+ import jax.numpy as jnp
7
+ from jax import Array
8
+ from safetensors import numpy, safe_open
9
+
10
+
11
+ def save(tensors: Dict[str, Array], metadata: Optional[Dict[str, str]] = None) -> bytes:
12
+ """
13
+ Saves a dictionary of tensors into raw bytes in safetensors format.
14
+
15
+ Args:
16
+ tensors (`Dict[str, Array]`):
17
+ The incoming tensors. Tensors need to be contiguous and dense.
18
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
19
+ Optional text only metadata you might want to save in your header.
20
+ For instance it can be useful to specify more about the underlying
21
+ tensors. This is purely informative and does not affect tensor loading.
22
+
23
+ Returns:
24
+ `bytes`: The raw bytes representing the format
25
+
26
+ Example:
27
+
28
+ ```python
29
+ from safetensors.flax import save
30
+ from jax import numpy as jnp
31
+
32
+ tensors = {"embedding": jnp.zeros((512, 1024)), "attention": jnp.zeros((256, 256))}
33
+ byte_data = save(tensors)
34
+ ```
35
+ """
36
+ np_tensors = _jnp2np(tensors)
37
+ return numpy.save(np_tensors, metadata=metadata)
38
+
39
+
40
+ def save_file(
41
+ tensors: Dict[str, Array],
42
+ filename: Union[str, os.PathLike],
43
+ metadata: Optional[Dict[str, str]] = None,
44
+ ) -> None:
45
+ """
46
+ Saves a dictionary of tensors into raw bytes in safetensors format.
47
+
48
+ Args:
49
+ tensors (`Dict[str, Array]`):
50
+ The incoming tensors. Tensors need to be contiguous and dense.
51
+ filename (`str`, or `os.PathLike`)):
52
+ The filename we're saving into.
53
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
54
+ Optional text only metadata you might want to save in your header.
55
+ For instance it can be useful to specify more about the underlying
56
+ tensors. This is purely informative and does not affect tensor loading.
57
+
58
+ Returns:
59
+ `None`
60
+
61
+ Example:
62
+
63
+ ```python
64
+ from safetensors.flax import save_file
65
+ from jax import numpy as jnp
66
+
67
+ tensors = {"embedding": jnp.zeros((512, 1024)), "attention": jnp.zeros((256, 256))}
68
+ save_file(tensors, "model.safetensors")
69
+ ```
70
+ """
71
+ np_tensors = _jnp2np(tensors)
72
+ return numpy.save_file(np_tensors, filename, metadata=metadata)
73
+
74
+
75
+ def load(data: bytes) -> Dict[str, Array]:
76
+ """
77
+ Loads a safetensors file into flax format from pure bytes.
78
+
79
+ Args:
80
+ data (`bytes`):
81
+ The content of a safetensors file
82
+
83
+ Returns:
84
+ `Dict[str, Array]`: dictionary that contains name as key, value as `Array` on cpu
85
+
86
+ Example:
87
+
88
+ ```python
89
+ from safetensors.flax import load
90
+
91
+ file_path = "./my_folder/bert.safetensors"
92
+ with open(file_path, "rb") as f:
93
+ data = f.read()
94
+
95
+ loaded = load(data)
96
+ ```
97
+ """
98
+ flat = numpy.load(data)
99
+ return _np2jnp(flat)
100
+
101
+
102
+ def load_file(filename: Union[str, os.PathLike]) -> Dict[str, Array]:
103
+ """
104
+ Loads a safetensors file into flax format.
105
+
106
+ Args:
107
+ filename (`str`, or `os.PathLike`)):
108
+ The name of the file which contains the tensors
109
+
110
+ Returns:
111
+ `Dict[str, Array]`: dictionary that contains name as key, value as `Array`
112
+
113
+ Example:
114
+
115
+ ```python
116
+ from safetensors.flax import load_file
117
+
118
+ file_path = "./my_folder/bert.safetensors"
119
+ loaded = load_file(file_path)
120
+ ```
121
+ """
122
+ result = {}
123
+ with safe_open(filename, framework="flax") as f:
124
+ for k in f.offset_keys():
125
+ result[k] = f.get_tensor(k)
126
+ return result
127
+
128
+
129
+ def _np2jnp(numpy_dict: Dict[str, np.ndarray]) -> Dict[str, Array]:
130
+ for k, v in numpy_dict.items():
131
+ numpy_dict[k] = jnp.array(v)
132
+ return numpy_dict
133
+
134
+
135
+ def _jnp2np(jnp_dict: Dict[str, Array]) -> Dict[str, np.array]:
136
+ for k, v in jnp_dict.items():
137
+ jnp_dict[k] = np.asarray(v)
138
+ return jnp_dict
python_env/lib/site-packages/safetensors/mlx.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Dict, Optional, Union
3
+
4
+ import numpy as np
5
+
6
+ import mlx.core as mx
7
+ from safetensors import numpy, safe_open
8
+
9
+
10
+ def save(
11
+ tensors: Dict[str, mx.array], metadata: Optional[Dict[str, str]] = None
12
+ ) -> bytes:
13
+ """
14
+ Saves a dictionary of tensors into raw bytes in safetensors format.
15
+
16
+ Args:
17
+ tensors (`Dict[str, mx.array]`):
18
+ The incoming tensors. Tensors need to be contiguous and dense.
19
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
20
+ Optional text only metadata you might want to save in your header.
21
+ For instance it can be useful to specify more about the underlying
22
+ tensors. This is purely informative and does not affect tensor loading.
23
+
24
+ Returns:
25
+ `bytes`: The raw bytes representing the format
26
+
27
+ Example:
28
+
29
+ ```python
30
+ from safetensors.mlx import save
31
+ import mlx.core as mx
32
+
33
+ tensors = {"embedding": mx.zeros((512, 1024)), "attention": mx.zeros((256, 256))}
34
+ byte_data = save(tensors)
35
+ ```
36
+ """
37
+ np_tensors = _mx2np(tensors)
38
+ return numpy.save(np_tensors, metadata=metadata)
39
+
40
+
41
+ def save_file(
42
+ tensors: Dict[str, mx.array],
43
+ filename: Union[str, os.PathLike],
44
+ metadata: Optional[Dict[str, str]] = None,
45
+ ) -> None:
46
+ """
47
+ Saves a dictionary of tensors into raw bytes in safetensors format.
48
+
49
+ Args:
50
+ tensors (`Dict[str, mx.array]`):
51
+ The incoming tensors. Tensors need to be contiguous and dense.
52
+ filename (`str`, or `os.PathLike`)):
53
+ The filename we're saving into.
54
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
55
+ Optional text only metadata you might want to save in your header.
56
+ For instance it can be useful to specify more about the underlying
57
+ tensors. This is purely informative and does not affect tensor loading.
58
+
59
+ Returns:
60
+ `None`
61
+
62
+ Example:
63
+
64
+ ```python
65
+ from safetensors.mlx import save_file
66
+ import mlx.core as mx
67
+
68
+ tensors = {"embedding": mx.zeros((512, 1024)), "attention": mx.zeros((256, 256))}
69
+ save_file(tensors, "model.safetensors")
70
+ ```
71
+ """
72
+ np_tensors = _mx2np(tensors)
73
+ return numpy.save_file(np_tensors, filename, metadata=metadata)
74
+
75
+
76
+ def load(data: bytes) -> Dict[str, mx.array]:
77
+ """
78
+ Loads a safetensors file into MLX format from pure bytes.
79
+
80
+ Args:
81
+ data (`bytes`):
82
+ The content of a safetensors file
83
+
84
+ Returns:
85
+ `Dict[str, mx.array]`: dictionary that contains name as key, value as `mx.array`
86
+
87
+ Example:
88
+
89
+ ```python
90
+ from safetensors.mlx import load
91
+
92
+ file_path = "./my_folder/bert.safetensors"
93
+ with open(file_path, "rb") as f:
94
+ data = f.read()
95
+
96
+ loaded = load(data)
97
+ ```
98
+ """
99
+ flat = numpy.load(data)
100
+ return _np2mx(flat)
101
+
102
+
103
+ def load_file(filename: Union[str, os.PathLike]) -> Dict[str, mx.array]:
104
+ """
105
+ Loads a safetensors file into MLX format.
106
+
107
+ Args:
108
+ filename (`str`, or `os.PathLike`)):
109
+ The name of the file which contains the tensors
110
+
111
+ Returns:
112
+ `Dict[str, mx.array]`: dictionary that contains name as key, value as `mx.array`
113
+
114
+ Example:
115
+
116
+ ```python
117
+ from safetensors.flax import load_file
118
+
119
+ file_path = "./my_folder/bert.safetensors"
120
+ loaded = load_file(file_path)
121
+ ```
122
+ """
123
+ result = {}
124
+ with safe_open(filename, framework="mlx") as f:
125
+ for k in f.offset_keys():
126
+ result[k] = f.get_tensor(k)
127
+ return result
128
+
129
+
130
+ def _np2mx(numpy_dict: Dict[str, np.ndarray]) -> Dict[str, mx.array]:
131
+ for k, v in numpy_dict.items():
132
+ numpy_dict[k] = mx.array(v)
133
+ return numpy_dict
134
+
135
+
136
+ def _mx2np(mx_dict: Dict[str, mx.array]) -> Dict[str, np.array]:
137
+ new_dict = {}
138
+ for k, v in mx_dict.items():
139
+ new_dict[k] = np.asarray(v)
140
+ return new_dict
python_env/lib/site-packages/safetensors/numpy.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ from typing import Dict, Optional, Union
4
+
5
+ import numpy as np
6
+
7
+ from safetensors import deserialize, safe_open, serialize, serialize_file
8
+
9
+
10
+ def _tobytes(tensor: np.ndarray) -> bytes:
11
+ if not _is_little_endian(tensor):
12
+ tensor = tensor.byteswap(inplace=False)
13
+ return tensor.tobytes()
14
+
15
+
16
+ def save(
17
+ tensor_dict: Dict[str, np.ndarray], metadata: Optional[Dict[str, str]] = None
18
+ ) -> bytes:
19
+ """
20
+ Saves a dictionary of tensors into raw bytes in safetensors format.
21
+
22
+ Args:
23
+ tensor_dict (`Dict[str, np.ndarray]`):
24
+ The incoming tensors. Tensors need to be contiguous and dense.
25
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
26
+ Optional text only metadata you might want to save in your header.
27
+ For instance it can be useful to specify more about the underlying
28
+ tensors. This is purely informative and does not affect tensor loading.
29
+
30
+ Returns:
31
+ `bytes`: The raw bytes representing the format
32
+
33
+ Example:
34
+
35
+ ```python
36
+ from safetensors.numpy import save
37
+ import numpy as np
38
+
39
+ tensors = {"embedding": np.zeros((512, 1024)), "attention": np.zeros((256, 256))}
40
+ byte_data = save(tensors)
41
+ ```
42
+ """
43
+ flattened = {
44
+ k: {"dtype": v.dtype.name, "shape": v.shape, "data": _tobytes(v)}
45
+ for k, v in tensor_dict.items()
46
+ }
47
+ serialized = serialize(flattened, metadata=metadata)
48
+ result = bytes(serialized)
49
+ return result
50
+
51
+
52
+ def save_file(
53
+ tensor_dict: Dict[str, np.ndarray],
54
+ filename: Union[str, os.PathLike],
55
+ metadata: Optional[Dict[str, str]] = None,
56
+ ) -> None:
57
+ """
58
+ Saves a dictionary of tensors into raw bytes in safetensors format.
59
+
60
+ Args:
61
+ tensor_dict (`Dict[str, np.ndarray]`):
62
+ The incoming tensors. Tensors need to be contiguous and dense.
63
+ filename (`str`, or `os.PathLike`)):
64
+ The filename we're saving into.
65
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
66
+ Optional text only metadata you might want to save in your header.
67
+ For instance it can be useful to specify more about the underlying
68
+ tensors. This is purely informative and does not affect tensor loading.
69
+
70
+ Returns:
71
+ `None`
72
+
73
+ Example:
74
+
75
+ ```python
76
+ from safetensors.numpy import save_file
77
+ import numpy as np
78
+
79
+ tensors = {"embedding": np.zeros((512, 1024)), "attention": np.zeros((256, 256))}
80
+ save_file(tensors, "model.safetensors")
81
+ ```
82
+ """
83
+ flattened = {
84
+ k: {"dtype": v.dtype.name, "shape": v.shape, "data": _tobytes(v)}
85
+ for k, v in tensor_dict.items()
86
+ }
87
+ serialize_file(flattened, filename, metadata=metadata)
88
+
89
+
90
+ def load(data: bytes) -> Dict[str, np.ndarray]:
91
+ """
92
+ Loads a safetensors file into numpy format from pure bytes.
93
+
94
+ Args:
95
+ data (`bytes`):
96
+ The content of a safetensors file
97
+
98
+ Returns:
99
+ `Dict[str, np.ndarray]`: dictionary that contains name as key, value as `np.ndarray` on cpu
100
+
101
+ Example:
102
+
103
+ ```python
104
+ from safetensors.numpy import load
105
+
106
+ file_path = "./my_folder/bert.safetensors"
107
+ with open(file_path, "rb") as f:
108
+ data = f.read()
109
+
110
+ loaded = load(data)
111
+ ```
112
+ """
113
+ flat = deserialize(data)
114
+ return _view2np(flat)
115
+
116
+
117
+ def load_file(filename: Union[str, os.PathLike]) -> Dict[str, np.ndarray]:
118
+ """
119
+ Loads a safetensors file into numpy format.
120
+
121
+ Args:
122
+ filename (`str`, or `os.PathLike`)):
123
+ The name of the file which contains the tensors
124
+
125
+ Returns:
126
+ `Dict[str, np.ndarray]`: dictionary that contains name as key, value as `np.ndarray`
127
+
128
+ Example:
129
+
130
+ ```python
131
+ from safetensors.numpy import load_file
132
+
133
+ file_path = "./my_folder/bert.safetensors"
134
+ loaded = load_file(file_path)
135
+ ```
136
+ """
137
+ result = {}
138
+ with safe_open(filename, framework="np") as f:
139
+ for k in f.offset_keys():
140
+ result[k] = f.get_tensor(k)
141
+ return result
142
+
143
+
144
+ _TYPES = {
145
+ "F64": np.float64,
146
+ "F32": np.float32,
147
+ "F16": np.float16,
148
+ "I64": np.int64,
149
+ "U64": np.uint64,
150
+ "I32": np.int32,
151
+ "U32": np.uint32,
152
+ "I16": np.int16,
153
+ "U16": np.uint16,
154
+ "I8": np.int8,
155
+ "U8": np.uint8,
156
+ "BOOL": bool,
157
+ "C64": np.complex64,
158
+ }
159
+
160
+
161
+ def _getdtype(dtype_str: str) -> np.dtype:
162
+ return _TYPES[dtype_str]
163
+
164
+
165
+ def _view2np(safeview) -> Dict[str, np.ndarray]:
166
+ result = {}
167
+ for k, v in safeview:
168
+ dtype = _getdtype(v["dtype"])
169
+ arr = np.frombuffer(v["data"], dtype=dtype).reshape(v["shape"])
170
+ result[k] = arr
171
+ return result
172
+
173
+
174
+ def _is_little_endian(tensor: np.ndarray) -> bool:
175
+ byteorder = tensor.dtype.byteorder
176
+ if byteorder == "=":
177
+ if sys.byteorder == "little":
178
+ return True
179
+ else:
180
+ return False
181
+ elif byteorder == "|":
182
+ return True
183
+ elif byteorder == "<":
184
+ return True
185
+ elif byteorder == ">":
186
+ return False
187
+ raise ValueError(f"Unexpected byte order {byteorder}")
python_env/lib/site-packages/safetensors/paddle.py ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ from typing import Any, Dict, Optional, Union
4
+
5
+ import numpy as np
6
+ import paddle
7
+
8
+ from safetensors import numpy, deserialize, safe_open, serialize, serialize_file
9
+
10
+
11
+ def save(
12
+ tensors: Dict[str, paddle.Tensor], metadata: Optional[Dict[str, str]] = None
13
+ ) -> bytes:
14
+ """
15
+ Saves a dictionary of tensors into raw bytes in safetensors format.
16
+
17
+ Args:
18
+ tensors (`Dict[str, paddle.Tensor]`):
19
+ The incoming tensors. Tensors need to be contiguous and dense.
20
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
21
+ Optional text only metadata you might want to save in your header.
22
+ For instance it can be useful to specify more about the underlying
23
+ tensors. This is purely informative and does not affect tensor loading.
24
+
25
+ Returns:
26
+ `bytes`: The raw bytes representing the format
27
+
28
+ Example:
29
+
30
+ ```python
31
+ from safetensors.paddle import save
32
+ import paddle
33
+
34
+ tensors = {"embedding": paddle.zeros((512, 1024)), "attention": paddle.zeros((256, 256))}
35
+ byte_data = save(tensors)
36
+ ```
37
+ """
38
+ serialized = serialize(_flatten(tensors), metadata=metadata)
39
+ result = bytes(serialized)
40
+ return result
41
+
42
+
43
+ def save_file(
44
+ tensors: Dict[str, paddle.Tensor],
45
+ filename: Union[str, os.PathLike],
46
+ metadata: Optional[Dict[str, str]] = None,
47
+ ) -> None:
48
+ """
49
+ Saves a dictionary of tensors into raw bytes in safetensors format.
50
+
51
+ Args:
52
+ tensors (`Dict[str, paddle.Tensor]`):
53
+ The incoming tensors. Tensors need to be contiguous and dense.
54
+ filename (`str`, or `os.PathLike`)):
55
+ The filename we're saving into.
56
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
57
+ Optional text only metadata you might want to save in your header.
58
+ For instance it can be useful to specify more about the underlying
59
+ tensors. This is purely informative and does not affect tensor loading.
60
+
61
+ Returns:
62
+ `None`
63
+
64
+ Example:
65
+
66
+ ```python
67
+ from safetensors.paddle import save_file
68
+ import paddle
69
+
70
+ tensors = {"embedding": paddle.zeros((512, 1024)), "attention": paddle.zeros((256, 256))}
71
+ save_file(tensors, "model.safetensors")
72
+ ```
73
+ """
74
+ serialize_file(_flatten(tensors), filename, metadata=metadata)
75
+
76
+
77
+ def load(data: bytes, device: str = "cpu") -> Dict[str, paddle.Tensor]:
78
+ """
79
+ Loads a safetensors file into paddle format from pure bytes.
80
+
81
+ Args:
82
+ data (`bytes`):
83
+ The content of a safetensors file
84
+
85
+ Returns:
86
+ `Dict[str, paddle.Tensor]`: dictionary that contains name as key, value as `paddle.Tensor` on cpu
87
+
88
+ Example:
89
+
90
+ ```python
91
+ from safetensors.paddle import load
92
+
93
+ file_path = "./my_folder/bert.safetensors"
94
+ with open(file_path, "rb") as f:
95
+ data = f.read()
96
+
97
+ loaded = load(data)
98
+ ```
99
+ """
100
+ if paddle.__version__ >= "3.2.0":
101
+ flat = deserialize(data)
102
+ return _view2paddle(flat, device)
103
+ else:
104
+ flat = numpy.load(data)
105
+ return _np2paddle(flat, device)
106
+
107
+
108
+ def load_file(
109
+ filename: Union[str, os.PathLike], device="cpu"
110
+ ) -> Dict[str, paddle.Tensor]:
111
+ """
112
+ Loads a safetensors file into paddle format.
113
+
114
+ Args:
115
+ filename (`str`, or `os.PathLike`)):
116
+ The name of the file which contains the tensors
117
+ device (`Union[Dict[str, any], str]`, *optional*, defaults to `cpu`):
118
+ The device where the tensors need to be located after load.
119
+ available options are all regular paddle device locations
120
+
121
+ Returns:
122
+ `Dict[str, paddle.Tensor]`: dictionary that contains name as key, value as `paddle.Tensor`
123
+
124
+ Example:
125
+
126
+ ```python
127
+ from safetensors.paddle import load_file
128
+
129
+ file_path = "./my_folder/bert.safetensors"
130
+ loaded = load_file(file_path)
131
+ ```
132
+ """
133
+ result = {}
134
+ if paddle.__version__ >= "3.2.0":
135
+ with safe_open(filename, framework="paddle", device=device) as f:
136
+ for k in f.offset_keys():
137
+ result[k] = f.get_tensor(k)
138
+ else:
139
+ flat = numpy.load_file(filename)
140
+ result = _np2paddle(flat, device)
141
+ return result
142
+
143
+
144
+ def _np2paddle(
145
+ numpy_dict: Dict[str, np.ndarray], device: str = "cpu"
146
+ ) -> Dict[str, paddle.Tensor]:
147
+ for k, v in numpy_dict.items():
148
+ numpy_dict[k] = paddle.to_tensor(v, place=device)
149
+ return numpy_dict
150
+
151
+
152
+ def _paddle2np(paddle_dict: Dict[str, paddle.Tensor]) -> Dict[str, np.array]:
153
+ for k, v in paddle_dict.items():
154
+ paddle_dict[k] = v.detach().cpu().numpy()
155
+ return paddle_dict
156
+
157
+
158
+ _SIZE = {
159
+ paddle.int64: 8,
160
+ paddle.float32: 4,
161
+ paddle.int32: 4,
162
+ paddle.bfloat16: 2,
163
+ paddle.float16: 2,
164
+ paddle.int16: 2,
165
+ paddle.uint8: 1,
166
+ paddle.int8: 1,
167
+ paddle.bool: 1,
168
+ paddle.float64: 8,
169
+ paddle.float8_e4m3fn: 1,
170
+ paddle.float8_e5m2: 1,
171
+ paddle.complex64: 8,
172
+ # XXX: These are not supported yet in paddle
173
+ # paddle.uint64: 8,
174
+ # paddle.uint32: 4,
175
+ # paddle.uint16: 2,
176
+ # paddle.float8_e8m0: 1,
177
+ # paddle.float4_e2m1_x2: 1,
178
+ }
179
+
180
+ _TYPES = {
181
+ "F64": paddle.float64,
182
+ "F32": paddle.float32,
183
+ "F16": paddle.float16,
184
+ "BF16": paddle.bfloat16,
185
+ "I64": paddle.int64,
186
+ "I32": paddle.int32,
187
+ "I16": paddle.int16,
188
+ "I8": paddle.int8,
189
+ "U8": paddle.uint8,
190
+ "BOOL": paddle.bool,
191
+ "F8_E4M3": paddle.float8_e4m3fn,
192
+ "F8_E5M2": paddle.float8_e5m2,
193
+ }
194
+
195
+ NPDTYPES = {
196
+ paddle.int64: np.int64,
197
+ paddle.float32: np.float32,
198
+ paddle.int32: np.int32,
199
+ # XXX: This is ok because both have the same width
200
+ paddle.bfloat16: np.float16,
201
+ paddle.float16: np.float16,
202
+ paddle.int16: np.int16,
203
+ paddle.uint8: np.uint8,
204
+ paddle.int8: np.int8,
205
+ paddle.bool: bool,
206
+ paddle.float64: np.float64,
207
+ # XXX: This is ok because both have the same width and byteswap is a no-op anyway
208
+ paddle.float8_e4m3fn: np.uint8,
209
+ paddle.float8_e5m2: np.uint8,
210
+ }
211
+
212
+
213
+ def _getdtype(dtype_str: str) -> paddle.dtype:
214
+ return _TYPES[dtype_str]
215
+
216
+
217
+ def _view2paddle(safeview, device) -> Dict[str, paddle.Tensor]:
218
+ result = {}
219
+ for k, v in safeview:
220
+ dtype = _getdtype(v["dtype"])
221
+ if len(v["data"]) == 0:
222
+ # Workaround because frombuffer doesn't accept zero-size tensors
223
+ assert any(x == 0 for x in v["shape"])
224
+ arr = paddle.empty(v["shape"], dtype=dtype)
225
+ else:
226
+ arr = paddle.base.core.frombuffer(v["data"], dtype).reshape(v["shape"])
227
+ if device != "cpu":
228
+ arr = arr.to(device)
229
+ if sys.byteorder == "big":
230
+ arr = paddle.to_tensor(arr.numpy().byteswap(inplace=False), place=device)
231
+ result[k] = arr
232
+
233
+ return result
234
+
235
+
236
+ def _tobytes(tensor: paddle.Tensor, name: str) -> bytes:
237
+ if not tensor.is_contiguous():
238
+ raise ValueError(
239
+ f"You are trying to save a non contiguous tensor: `{name}` which is not allowed. It either means you"
240
+ " are trying to save tensors which are reference of each other in which case it's recommended to save"
241
+ " only the full tensors, and reslice at load time, or simply call `.contiguous()` on your tensor to"
242
+ " pack it before saving."
243
+ )
244
+ if not tensor.place.is_cpu_place():
245
+ # Moving tensor to cpu before saving
246
+ tensor = tensor.cpu()
247
+
248
+ import ctypes
249
+
250
+ import numpy as np
251
+
252
+ # When shape is empty (scalar), np.prod returns a float
253
+ # we need a int for the following calculations
254
+ length = int(np.prod(tensor.shape).item())
255
+ bytes_per_item = _SIZE[tensor.dtype]
256
+
257
+ total_bytes = length * bytes_per_item
258
+
259
+ ptr = tensor.data_ptr()
260
+ if ptr == 0:
261
+ return b""
262
+ newptr = ctypes.cast(ptr, ctypes.POINTER(ctypes.c_ubyte))
263
+ data = np.ctypeslib.as_array(newptr, (total_bytes,)) # no internal copy
264
+ if sys.byteorder == "big":
265
+ npdtype = NPDTYPES[tensor.dtype]
266
+ # Not in place as that would potentially modify a live running model
267
+ data = data.view(npdtype).byteswap(inplace=False)
268
+ return data.tobytes()
269
+
270
+
271
+ def _flatten(tensors: Dict[str, paddle.Tensor]) -> Dict[str, Dict[str, Any]]:
272
+ if not isinstance(tensors, dict):
273
+ raise ValueError(
274
+ f"Expected a dict of [str, paddle.Tensor] but received {type(tensors)}"
275
+ )
276
+
277
+ for k, v in tensors.items():
278
+ if not isinstance(v, paddle.Tensor):
279
+ raise ValueError(
280
+ f"Key `{k}` is invalid, expected paddle.Tensor but received {type(v)}"
281
+ )
282
+
283
+ return {
284
+ k: {
285
+ "dtype": str(v.dtype).split(".")[-1],
286
+ "shape": v.shape,
287
+ "data": _tobytes(v, k),
288
+ }
289
+ for k, v in tensors.items()
290
+ }
python_env/lib/site-packages/safetensors/py.typed ADDED
File without changes
python_env/lib/site-packages/safetensors/tensorflow.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Dict, Optional, Union
3
+
4
+ import numpy as np
5
+ import tensorflow as tf
6
+
7
+ from safetensors import numpy, safe_open
8
+
9
+
10
+ def save(
11
+ tensors: Dict[str, tf.Tensor], metadata: Optional[Dict[str, str]] = None
12
+ ) -> bytes:
13
+ """
14
+ Saves a dictionary of tensors into raw bytes in safetensors format.
15
+
16
+ Args:
17
+ tensors (`Dict[str, tf.Tensor]`):
18
+ The incoming tensors. Tensors need to be contiguous and dense.
19
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
20
+ Optional text only metadata you might want to save in your header.
21
+ For instance it can be useful to specify more about the underlying
22
+ tensors. This is purely informative and does not affect tensor loading.
23
+
24
+ Returns:
25
+ `bytes`: The raw bytes representing the format
26
+
27
+ Example:
28
+
29
+ ```python
30
+ from safetensors.tensorflow import save
31
+ import tensorflow as tf
32
+
33
+ tensors = {"embedding": tf.zeros((512, 1024)), "attention": tf.zeros((256, 256))}
34
+ byte_data = save(tensors)
35
+ ```
36
+ """
37
+ np_tensors = _tf2np(tensors)
38
+ return numpy.save(np_tensors, metadata=metadata)
39
+
40
+
41
+ def save_file(
42
+ tensors: Dict[str, tf.Tensor],
43
+ filename: Union[str, os.PathLike],
44
+ metadata: Optional[Dict[str, str]] = None,
45
+ ) -> None:
46
+ """
47
+ Saves a dictionary of tensors into raw bytes in safetensors format.
48
+
49
+ Args:
50
+ tensors (`Dict[str, tf.Tensor]`):
51
+ The incoming tensors. Tensors need to be contiguous and dense.
52
+ filename (`str`, or `os.PathLike`)):
53
+ The filename we're saving into.
54
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
55
+ Optional text only metadata you might want to save in your header.
56
+ For instance it can be useful to specify more about the underlying
57
+ tensors. This is purely informative and does not affect tensor loading.
58
+
59
+ Returns:
60
+ `None`
61
+
62
+ Example:
63
+
64
+ ```python
65
+ from safetensors.tensorflow import save_file
66
+ import tensorflow as tf
67
+
68
+ tensors = {"embedding": tf.zeros((512, 1024)), "attention": tf.zeros((256, 256))}
69
+ save_file(tensors, "model.safetensors")
70
+ ```
71
+ """
72
+ np_tensors = _tf2np(tensors)
73
+ return numpy.save_file(np_tensors, filename, metadata=metadata)
74
+
75
+
76
+ def load(data: bytes) -> Dict[str, tf.Tensor]:
77
+ """
78
+ Loads a safetensors file into tensorflow format from pure bytes.
79
+
80
+ Args:
81
+ data (`bytes`):
82
+ The content of a safetensors file
83
+
84
+ Returns:
85
+ `Dict[str, tf.Tensor]`: dictionary that contains name as key, value as `tf.Tensor` on cpu
86
+
87
+ Example:
88
+
89
+ ```python
90
+ from safetensors.tensorflow import load
91
+
92
+ file_path = "./my_folder/bert.safetensors"
93
+ with open(file_path, "rb") as f:
94
+ data = f.read()
95
+
96
+ loaded = load(data)
97
+ ```
98
+ """
99
+ flat = numpy.load(data)
100
+ return _np2tf(flat)
101
+
102
+
103
+ def load_file(filename: Union[str, os.PathLike]) -> Dict[str, tf.Tensor]:
104
+ """
105
+ Loads a safetensors file into tensorflow format.
106
+
107
+ Args:
108
+ filename (`str`, or `os.PathLike`)):
109
+ The name of the file which contains the tensors
110
+
111
+ Returns:
112
+ `Dict[str, tf.Tensor]`: dictionary that contains name as key, value as `tf.Tensor`
113
+
114
+ Example:
115
+
116
+ ```python
117
+ from safetensors.tensorflow import load_file
118
+
119
+ file_path = "./my_folder/bert.safetensors"
120
+ loaded = load_file(file_path)
121
+ ```
122
+ """
123
+ result = {}
124
+ with safe_open(filename, framework="tf") as f:
125
+ for k in f.offset_keys():
126
+ result[k] = f.get_tensor(k)
127
+ return result
128
+
129
+
130
+ def _np2tf(numpy_dict: Dict[str, np.ndarray]) -> Dict[str, tf.Tensor]:
131
+ for k, v in numpy_dict.items():
132
+ numpy_dict[k] = tf.convert_to_tensor(v)
133
+ return numpy_dict
134
+
135
+
136
+ def _tf2np(tf_dict: Dict[str, tf.Tensor]) -> Dict[str, np.array]:
137
+ for k, v in tf_dict.items():
138
+ tf_dict[k] = v.numpy()
139
+ return tf_dict
python_env/lib/site-packages/safetensors/torch.py ADDED
@@ -0,0 +1,550 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ from collections import defaultdict
4
+ from typing import Any, Dict, List, Optional, Set, Tuple, Union
5
+ from packaging.version import Version
6
+
7
+ import torch
8
+
9
+ from safetensors import deserialize, safe_open, serialize, serialize_file
10
+
11
+
12
+ def storage_ptr(tensor: torch.Tensor) -> int:
13
+ try:
14
+ return tensor.untyped_storage().data_ptr()
15
+ except Exception:
16
+ # Fallback for torch==1.10
17
+ try:
18
+ return tensor.storage().data_ptr()
19
+ except NotImplementedError:
20
+ # Fallback for meta storage
21
+ return 0
22
+
23
+
24
+ def _end_ptr(tensor: torch.Tensor) -> int:
25
+ if tensor.nelement():
26
+ stop = tensor.view(-1)[-1].data_ptr() + _SIZE[tensor.dtype]
27
+ else:
28
+ stop = tensor.data_ptr()
29
+ return stop
30
+
31
+
32
+ def storage_size(tensor: torch.Tensor) -> int:
33
+ try:
34
+ return tensor.untyped_storage().nbytes()
35
+ except AttributeError:
36
+ # Fallback for torch==1.10
37
+ try:
38
+ return tensor.storage().size() * _SIZE[tensor.dtype]
39
+ except NotImplementedError:
40
+ # Fallback for meta storage
41
+ # On torch >=2.0 this is the tensor size
42
+ return tensor.nelement() * _SIZE[tensor.dtype]
43
+
44
+
45
+ def _filter_shared_not_shared(
46
+ tensors: List[Set[str]], state_dict: Dict[str, torch.Tensor]
47
+ ) -> List[Set[str]]:
48
+ filtered_tensors = []
49
+ for shared in tensors:
50
+ if len(shared) < 2:
51
+ filtered_tensors.append(shared)
52
+ continue
53
+
54
+ areas = []
55
+ for name in shared:
56
+ tensor = state_dict[name]
57
+ areas.append((tensor.data_ptr(), _end_ptr(tensor), name))
58
+ areas.sort()
59
+
60
+ _, last_stop, last_name = areas[0]
61
+ filtered_tensors.append({last_name})
62
+ for start, stop, name in areas[1:]:
63
+ if start >= last_stop:
64
+ filtered_tensors.append({name})
65
+ else:
66
+ filtered_tensors[-1].add(name)
67
+ last_stop = stop
68
+
69
+ return filtered_tensors
70
+
71
+
72
+ def _find_shared_tensors(state_dict: Dict[str, torch.Tensor]) -> List[Set[str]]:
73
+ tensors = defaultdict(set)
74
+ for k, v in state_dict.items():
75
+ if (
76
+ v.device != torch.device("meta")
77
+ and storage_ptr(v) != 0
78
+ and storage_size(v) != 0
79
+ ):
80
+ # Need to add device as key because of multiple GPU.
81
+ tensors[(v.device, storage_ptr(v), storage_size(v))].add(k)
82
+ tensors = list(sorted(tensors.values()))
83
+ tensors = _filter_shared_not_shared(tensors, state_dict)
84
+ return tensors
85
+
86
+
87
+ def _is_complete(tensor: torch.Tensor) -> bool:
88
+ return tensor.data_ptr() == storage_ptr(tensor) and tensor.nelement() * _SIZE[
89
+ tensor.dtype
90
+ ] == storage_size(tensor)
91
+
92
+
93
+ def _remove_duplicate_names(
94
+ state_dict: Dict[str, torch.Tensor],
95
+ *,
96
+ preferred_names: Optional[List[str]] = None,
97
+ discard_names: Optional[List[str]] = None,
98
+ ) -> Dict[str, List[str]]:
99
+ if preferred_names is None:
100
+ preferred_names = []
101
+ preferred_names = set(preferred_names)
102
+ if discard_names is None:
103
+ discard_names = []
104
+ discard_names = set(discard_names)
105
+
106
+ shareds = _find_shared_tensors(state_dict)
107
+ to_remove = defaultdict(list)
108
+ for shared in shareds:
109
+ complete_names = set(
110
+ [name for name in shared if _is_complete(state_dict[name])]
111
+ )
112
+ if not complete_names:
113
+ raise RuntimeError(
114
+ "Error while trying to find names to remove to save state dict, but found no suitable name to keep"
115
+ f" for saving amongst: {shared}. None is covering the entire storage.Refusing to save/load the model"
116
+ " since you could be storing much more memory than needed. Please refer to"
117
+ " https://huggingface.co/docs/safetensors/torch_shared_tensors for more information. Or open an"
118
+ " issue."
119
+ )
120
+
121
+ keep_name = sorted(list(complete_names))[0]
122
+
123
+ # Mechanism to preferentially select keys to keep
124
+ # coming from the on-disk file to allow
125
+ # loading models saved with a different choice
126
+ # of keep_name
127
+ preferred = complete_names.difference(discard_names)
128
+ if preferred:
129
+ keep_name = sorted(list(preferred))[0]
130
+
131
+ if preferred_names:
132
+ preferred = preferred_names.intersection(complete_names)
133
+ if preferred:
134
+ keep_name = sorted(list(preferred))[0]
135
+ for name in sorted(shared):
136
+ if name != keep_name:
137
+ to_remove[keep_name].append(name)
138
+ return to_remove
139
+
140
+
141
+ def save_model(
142
+ model: torch.nn.Module,
143
+ filename: str,
144
+ metadata: Optional[Dict[str, str]] = None,
145
+ force_contiguous: bool = True,
146
+ ):
147
+ """
148
+ Saves a given torch model to specified filename.
149
+ This method exists specifically to avoid tensor sharing issues which are
150
+ not allowed in `safetensors`. [More information on tensor sharing](../torch_shared_tensors)
151
+
152
+ Args:
153
+ model (`torch.nn.Module`):
154
+ The model to save on disk.
155
+ filename (`str`):
156
+ The filename location to save the file
157
+ metadata (`Dict[str, str]`, *optional*):
158
+ Extra information to save along with the file.
159
+ Some metadata will be added for each dropped tensors.
160
+ This information will not be enough to recover the entire
161
+ shared structure but might help understanding things
162
+ force_contiguous (`boolean`, *optional*, defaults to True):
163
+ Forcing the state_dict to be saved as contiguous tensors.
164
+ This has no effect on the correctness of the model, but it
165
+ could potentially change performance if the layout of the tensor
166
+ was chosen specifically for that reason.
167
+ """
168
+ state_dict = model.state_dict()
169
+ to_removes = _remove_duplicate_names(state_dict)
170
+
171
+ for kept_name, to_remove_group in to_removes.items():
172
+ for to_remove in to_remove_group:
173
+ if metadata is None:
174
+ metadata = {}
175
+
176
+ if to_remove not in metadata:
177
+ # Do not override user data
178
+ metadata[to_remove] = kept_name
179
+ del state_dict[to_remove]
180
+ if force_contiguous:
181
+ state_dict = {k: v.contiguous() for k, v in state_dict.items()}
182
+ try:
183
+ save_file(state_dict, filename, metadata=metadata)
184
+ except ValueError as e:
185
+ msg = str(e)
186
+ msg += " Or use save_model(..., force_contiguous=True), read the docs for potential caveats."
187
+ raise ValueError(msg)
188
+
189
+
190
+ def load_model(
191
+ model: torch.nn.Module,
192
+ filename: Union[str, os.PathLike],
193
+ strict: bool = True,
194
+ device: Union[str, int] = "cpu",
195
+ ) -> Tuple[List[str], List[str]]:
196
+ """
197
+ Loads a given filename onto a torch model.
198
+ This method exists specifically to avoid tensor sharing issues which are
199
+ not allowed in `safetensors`. [More information on tensor sharing](../torch_shared_tensors)
200
+
201
+ Args:
202
+ model (`torch.nn.Module`):
203
+ The model to load onto.
204
+ filename (`str`, or `os.PathLike`):
205
+ The filename location to load the file from.
206
+ strict (`bool`, *optional*, defaults to True):
207
+ Whether to fail if you're missing keys or having unexpected ones.
208
+ When false, the function simply returns missing and unexpected names.
209
+ device (`Union[str, int]`, *optional*, defaults to `cpu`):
210
+ The device where the tensors need to be located after load.
211
+ available options are all regular torch device locations.
212
+
213
+ Returns:
214
+ `(missing, unexpected): (List[str], List[str])`
215
+ `missing` are names in the model which were not modified during loading
216
+ `unexpected` are names that are on the file, but weren't used during
217
+ the load.
218
+ """
219
+ state_dict = load_file(filename, device=device)
220
+ model_state_dict = model.state_dict()
221
+ to_removes = _remove_duplicate_names(
222
+ model_state_dict, preferred_names=state_dict.keys()
223
+ )
224
+ missing, unexpected = model.load_state_dict(state_dict, strict=False)
225
+ missing = set(missing)
226
+ for to_remove_group in to_removes.values():
227
+ for to_remove in to_remove_group:
228
+ if to_remove not in missing:
229
+ unexpected.append(to_remove)
230
+ else:
231
+ missing.remove(to_remove)
232
+ if strict and (missing or unexpected):
233
+ missing_keys = ", ".join([f'"{k}"' for k in sorted(missing)])
234
+ unexpected_keys = ", ".join([f'"{k}"' for k in sorted(unexpected)])
235
+ error = f"Error(s) in loading state_dict for {model.__class__.__name__}:"
236
+ if missing:
237
+ error += f"\n Missing key(s) in state_dict: {missing_keys}"
238
+ if unexpected:
239
+ error += f"\n Unexpected key(s) in state_dict: {unexpected_keys}"
240
+ raise RuntimeError(error)
241
+ return missing, unexpected
242
+
243
+
244
+ def save(
245
+ tensors: Dict[str, torch.Tensor], metadata: Optional[Dict[str, str]] = None
246
+ ) -> bytes:
247
+ """
248
+ Saves a dictionary of tensors into raw bytes in safetensors format.
249
+
250
+ Args:
251
+ tensors (`Dict[str, torch.Tensor]`):
252
+ The incoming tensors. Tensors need to be contiguous and dense.
253
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
254
+ Optional text only metadata you might want to save in your header.
255
+ For instance it can be useful to specify more about the underlying
256
+ tensors. This is purely informative and does not affect tensor loading.
257
+
258
+ Returns:
259
+ `bytes`: The raw bytes representing the format
260
+
261
+ Example:
262
+
263
+ ```python
264
+ from safetensors.torch import save
265
+ import torch
266
+
267
+ tensors = {"embedding": torch.zeros((512, 1024)), "attention": torch.zeros((256, 256))}
268
+ byte_data = save(tensors)
269
+ ```
270
+ """
271
+ serialized = serialize(_flatten(tensors), metadata=metadata)
272
+ result = bytes(serialized)
273
+ return result
274
+
275
+
276
+ def save_file(
277
+ tensors: Dict[str, torch.Tensor],
278
+ filename: Union[str, os.PathLike],
279
+ metadata: Optional[Dict[str, str]] = None,
280
+ ):
281
+ """
282
+ Saves a dictionary of tensors into raw bytes in safetensors format.
283
+
284
+ Args:
285
+ tensors (`Dict[str, torch.Tensor]`):
286
+ The incoming tensors. Tensors need to be contiguous and dense.
287
+ filename (`str`, or `os.PathLike`)):
288
+ The filename we're saving into.
289
+ metadata (`Dict[str, str]`, *optional*, defaults to `None`):
290
+ Optional text only metadata you might want to save in your header.
291
+ For instance it can be useful to specify more about the underlying
292
+ tensors. This is purely informative and does not affect tensor loading.
293
+
294
+ Returns:
295
+ `None`
296
+
297
+ Example:
298
+
299
+ ```python
300
+ from safetensors.torch import save_file
301
+ import torch
302
+
303
+ tensors = {"embedding": torch.zeros((512, 1024)), "attention": torch.zeros((256, 256))}
304
+ save_file(tensors, "model.safetensors")
305
+ ```
306
+ """
307
+ serialize_file(_flatten(tensors), filename, metadata=metadata)
308
+
309
+
310
+ def load_file(
311
+ filename: Union[str, os.PathLike], device: Union[str, int] = "cpu"
312
+ ) -> Dict[str, torch.Tensor]:
313
+ """
314
+ Loads a safetensors file into torch format.
315
+
316
+ Args:
317
+ filename (`str`, or `os.PathLike`):
318
+ The name of the file which contains the tensors
319
+ device (`Union[str, int]`, *optional*, defaults to `cpu`):
320
+ The device where the tensors need to be located after load.
321
+ available options are all regular torch device locations.
322
+
323
+ Returns:
324
+ `Dict[str, torch.Tensor]`: dictionary that contains name as key, value as `torch.Tensor`
325
+
326
+ Example:
327
+
328
+ ```python
329
+ from safetensors.torch import load_file
330
+
331
+ file_path = "./my_folder/bert.safetensors"
332
+ loaded = load_file(file_path)
333
+ ```
334
+ """
335
+ result = {}
336
+ with safe_open(filename, framework="pt", device=device) as f:
337
+ for k in f.offset_keys():
338
+ result[k] = f.get_tensor(k)
339
+ return result
340
+
341
+
342
+ def load(data: bytes) -> Dict[str, torch.Tensor]:
343
+ """
344
+ Loads a safetensors file into torch format from pure bytes.
345
+
346
+ Args:
347
+ data (`bytes`):
348
+ The content of a safetensors file
349
+
350
+ Returns:
351
+ `Dict[str, torch.Tensor]`: dictionary that contains name as key, value as `torch.Tensor` on cpu
352
+
353
+ Example:
354
+
355
+ ```python
356
+ from safetensors.torch import load
357
+
358
+ file_path = "./my_folder/bert.safetensors"
359
+ with open(file_path, "rb") as f:
360
+ data = f.read()
361
+
362
+ loaded = load(data)
363
+ ```
364
+ """
365
+ flat = deserialize(data)
366
+ return _view2torch(flat)
367
+
368
+
369
+ # torch.float8 formats require 2.1; we do not support these dtypes on earlier versions
370
+ _float8_e4m3fn = getattr(torch, "float8_e4m3fn", None)
371
+ _float8_e5m2 = getattr(torch, "float8_e5m2", None)
372
+ _float8_e8m0 = getattr(torch, "float8_e8m0fnu", None)
373
+ _float4_e2m1_x2 = getattr(torch, "float4_e2m1fn_x2", None)
374
+
375
+ _SIZE = {
376
+ torch.int64: 8,
377
+ torch.float32: 4,
378
+ torch.int32: 4,
379
+ torch.bfloat16: 2,
380
+ torch.float16: 2,
381
+ torch.int16: 2,
382
+ torch.uint8: 1,
383
+ torch.int8: 1,
384
+ torch.bool: 1,
385
+ torch.float64: 8,
386
+ torch.complex64: 8,
387
+ _float8_e4m3fn: 1,
388
+ _float8_e5m2: 1,
389
+ _float8_e8m0: 1,
390
+ _float4_e2m1_x2: 1,
391
+ }
392
+ if Version(torch.__version__) >= Version("2.3.0"):
393
+ _SIZE.update(
394
+ {
395
+ torch.uint64: 8,
396
+ torch.uint32: 4,
397
+ torch.uint16: 2,
398
+ }
399
+ )
400
+
401
+ _TYPES = {
402
+ "F64": torch.float64,
403
+ "F32": torch.float32,
404
+ "F16": torch.float16,
405
+ "BF16": torch.bfloat16,
406
+ "I64": torch.int64,
407
+ "I32": torch.int32,
408
+ "I16": torch.int16,
409
+ "I8": torch.int8,
410
+ "U8": torch.uint8,
411
+ "BOOL": torch.bool,
412
+ "F8_E4M3": _float8_e4m3fn,
413
+ "F8_E5M2": _float8_e5m2,
414
+ "C64": torch.complex64,
415
+ }
416
+ if Version(torch.__version__) >= Version("2.3.0"):
417
+ _TYPES.update(
418
+ {
419
+ "U64": torch.uint64,
420
+ "U32": torch.uint32,
421
+ "U16": torch.uint16,
422
+ }
423
+ )
424
+
425
+
426
+ def _getdtype(dtype_str: str) -> torch.dtype:
427
+ return _TYPES[dtype_str]
428
+
429
+
430
+ def _view2torch(safeview) -> Dict[str, torch.Tensor]:
431
+ result = {}
432
+ for k, v in safeview:
433
+ dtype = _getdtype(v["dtype"])
434
+ if len(v["data"]) == 0:
435
+ # Workaround because frombuffer doesn't accept zero-size tensors
436
+ assert any(x == 0 for x in v["shape"])
437
+ arr = torch.empty(v["shape"], dtype=dtype)
438
+ else:
439
+ arr = torch.frombuffer(v["data"], dtype=dtype).reshape(v["shape"])
440
+ if sys.byteorder == "big":
441
+ arr = torch.from_numpy(arr.numpy().byteswap(inplace=False))
442
+ result[k] = arr
443
+
444
+ return result
445
+
446
+
447
+ def _tobytes(tensor: torch.Tensor, name: str) -> bytes:
448
+ if tensor.layout != torch.strided:
449
+ raise ValueError(
450
+ f"You are trying to save a sparse tensor: `{name}` which this library does not support."
451
+ " You can make it a dense tensor before saving with `.to_dense()` but be aware this might"
452
+ " make a much larger file than needed."
453
+ )
454
+
455
+ if not tensor.is_contiguous():
456
+ raise ValueError(
457
+ f"You are trying to save a non contiguous tensor: `{name}` which is not allowed. It either means you"
458
+ " are trying to save tensors which are reference of each other in which case it's recommended to save"
459
+ " only the full tensors, and reslice at load time, or simply call `.contiguous()` on your tensor to"
460
+ " pack it before saving."
461
+ )
462
+ if tensor.device.type != "cpu":
463
+ # Moving tensor to cpu before saving
464
+ tensor = tensor.to("cpu")
465
+
466
+ import ctypes
467
+
468
+ import numpy as np
469
+
470
+ # When shape is empty (scalar), np.prod returns a float
471
+ # we need a int for the following calculations
472
+ length = int(np.prod(tensor.shape).item())
473
+ bytes_per_item = _SIZE[tensor.dtype]
474
+
475
+ total_bytes = length * bytes_per_item
476
+
477
+ ptr = tensor.data_ptr()
478
+ if ptr == 0:
479
+ return b""
480
+ newptr = ctypes.cast(ptr, ctypes.POINTER(ctypes.c_ubyte))
481
+ data = np.ctypeslib.as_array(newptr, (total_bytes,)) # no internal copy
482
+ if sys.byteorder == "big":
483
+ NPDTYPES = {
484
+ torch.int64: np.int64,
485
+ torch.float32: np.float32,
486
+ torch.int32: np.int32,
487
+ # XXX: This is ok because both have the same width
488
+ torch.bfloat16: np.float16,
489
+ torch.float16: np.float16,
490
+ torch.int16: np.int16,
491
+ torch.uint8: np.uint8,
492
+ torch.int8: np.int8,
493
+ torch.bool: bool,
494
+ torch.float64: np.float64,
495
+ # XXX: This is ok because both have the same width and byteswap is a no-op anyway
496
+ _float8_e4m3fn: np.uint8,
497
+ _float8_e5m2: np.uint8,
498
+ torch.complex64: np.complex64,
499
+ }
500
+ npdtype = NPDTYPES[tensor.dtype]
501
+ # Not in place as that would potentially modify a live running model
502
+ data = data.view(npdtype).byteswap(inplace=False)
503
+ return data.tobytes()
504
+
505
+
506
+ def _flatten(tensors: Dict[str, torch.Tensor]) -> Dict[str, Dict[str, Any]]:
507
+ if not isinstance(tensors, dict):
508
+ raise ValueError(
509
+ f"Expected a dict of [str, torch.Tensor] but received {type(tensors)}"
510
+ )
511
+
512
+ invalid_tensors = []
513
+ for k, v in tensors.items():
514
+ if not isinstance(v, torch.Tensor):
515
+ raise ValueError(
516
+ f"Key `{k}` is invalid, expected torch.Tensor but received {type(v)}"
517
+ )
518
+
519
+ if v.layout != torch.strided:
520
+ invalid_tensors.append(k)
521
+ if invalid_tensors:
522
+ raise ValueError(
523
+ f"You are trying to save a sparse tensors: `{invalid_tensors}` which this library does not support."
524
+ " You can make it a dense tensor before saving with `.to_dense()` but be aware this might"
525
+ " make a much larger file than needed."
526
+ )
527
+
528
+ shared_pointers = _find_shared_tensors(tensors)
529
+ failing = []
530
+ for names in shared_pointers:
531
+ if len(names) > 1:
532
+ failing.append(names)
533
+
534
+ if failing:
535
+ raise RuntimeError(
536
+ f"""
537
+ Some tensors share memory, this will lead to duplicate memory on disk and potential differences when loading them again: {failing}.
538
+ A potential way to correctly save your model is to use `save_model`.
539
+ More information at https://huggingface.co/docs/safetensors/torch_shared_tensors
540
+ """
541
+ )
542
+
543
+ return {
544
+ k: {
545
+ "dtype": str(v.dtype).split(".")[-1],
546
+ "shape": v.shape,
547
+ "data": _tobytes(v, k),
548
+ }
549
+ for k, v in tensors.items()
550
+ }