Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- lib/python3.12/site-packages/__pycache__/decorator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/__pycache__/ipython_pygments_lexers.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/__pycache__/isympy.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/__pycache__/pylab.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/__pycache__/six.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/click-8.2.1.dist-info/INSTALLER +1 -0
- lib/python3.12/site-packages/click-8.2.1.dist-info/METADATA +82 -0
- lib/python3.12/site-packages/click-8.2.1.dist-info/RECORD +38 -0
- lib/python3.12/site-packages/click-8.2.1.dist-info/WHEEL +4 -0
- lib/python3.12/site-packages/click-8.2.1.dist-info/licenses/LICENSE.txt +28 -0
- lib/python3.12/site-packages/deepspeed/__init__.py +398 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__init__.py +7 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/__init__.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/abstract_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/cpu_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/cuda_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/hpu_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/mlu_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/mps_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/npu_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/real_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/sdaa_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/xpu_accelerator.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/accelerator/abstract_accelerator.py +306 -0
- lib/python3.12/site-packages/deepspeed/accelerator/cpu_accelerator.py +361 -0
- lib/python3.12/site-packages/deepspeed/accelerator/cuda_accelerator.py +382 -0
- lib/python3.12/site-packages/deepspeed/accelerator/hpu_accelerator.py +331 -0
- lib/python3.12/site-packages/deepspeed/accelerator/mlu_accelerator.py +300 -0
- lib/python3.12/site-packages/deepspeed/accelerator/mps_accelerator.py +281 -0
- lib/python3.12/site-packages/deepspeed/accelerator/npu_accelerator.py +299 -0
- lib/python3.12/site-packages/deepspeed/accelerator/real_accelerator.py +308 -0
- lib/python3.12/site-packages/deepspeed/accelerator/sdaa_accelerator.py +328 -0
- lib/python3.12/site-packages/deepspeed/accelerator/xpu_accelerator.py +337 -0
- lib/python3.12/site-packages/deepspeed/constants.py +21 -0
- lib/python3.12/site-packages/deepspeed/env_report.py +195 -0
- lib/python3.12/site-packages/deepspeed/git_version_info.py +31 -0
- lib/python3.12/site-packages/deepspeed/git_version_info_installed.py +6 -0
- lib/python3.12/site-packages/deepspeed/inference/__init__.py +7 -0
- lib/python3.12/site-packages/deepspeed/inference/__pycache__/__init__.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/__pycache__/config.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/__pycache__/engine.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/config.py +323 -0
- lib/python3.12/site-packages/deepspeed/inference/engine.py +625 -0
- lib/python3.12/site-packages/deepspeed/inference/quantization/__init__.py +4 -0
- lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/__init__.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/layers.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/quantization.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/quantization_context.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/utils.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/deepspeed/inference/quantization/layers.py +114 -0
lib/python3.12/site-packages/__pycache__/decorator.cpython-312.pyc
ADDED
|
Binary file (21.4 kB). View file
|
|
|
lib/python3.12/site-packages/__pycache__/ipython_pygments_lexers.cpython-312.pyc
ADDED
|
Binary file (16.9 kB). View file
|
|
|
lib/python3.12/site-packages/__pycache__/isympy.cpython-312.pyc
ADDED
|
Binary file (11 kB). View file
|
|
|
lib/python3.12/site-packages/__pycache__/pylab.cpython-312.pyc
ADDED
|
Binary file (313 Bytes). View file
|
|
|
lib/python3.12/site-packages/__pycache__/six.cpython-312.pyc
ADDED
|
Binary file (41.3 kB). View file
|
|
|
lib/python3.12/site-packages/click-8.2.1.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
lib/python3.12/site-packages/click-8.2.1.dist-info/METADATA
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: click
|
| 3 |
+
Version: 8.2.1
|
| 4 |
+
Summary: Composable command line interface toolkit
|
| 5 |
+
Maintainer-email: Pallets <contact@palletsprojects.com>
|
| 6 |
+
Requires-Python: >=3.10
|
| 7 |
+
Description-Content-Type: text/markdown
|
| 8 |
+
License-Expression: BSD-3-Clause
|
| 9 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 10 |
+
Classifier: Intended Audience :: Developers
|
| 11 |
+
Classifier: Operating System :: OS Independent
|
| 12 |
+
Classifier: Programming Language :: Python
|
| 13 |
+
Classifier: Typing :: Typed
|
| 14 |
+
License-File: LICENSE.txt
|
| 15 |
+
Requires-Dist: colorama; platform_system == 'Windows'
|
| 16 |
+
Project-URL: Changes, https://click.palletsprojects.com/page/changes/
|
| 17 |
+
Project-URL: Chat, https://discord.gg/pallets
|
| 18 |
+
Project-URL: Documentation, https://click.palletsprojects.com/
|
| 19 |
+
Project-URL: Donate, https://palletsprojects.com/donate
|
| 20 |
+
Project-URL: Source, https://github.com/pallets/click/
|
| 21 |
+
|
| 22 |
+
# $ click_
|
| 23 |
+
|
| 24 |
+
Click is a Python package for creating beautiful command line interfaces
|
| 25 |
+
in a composable way with as little code as necessary. It's the "Command
|
| 26 |
+
Line Interface Creation Kit". It's highly configurable but comes with
|
| 27 |
+
sensible defaults out of the box.
|
| 28 |
+
|
| 29 |
+
It aims to make the process of writing command line tools quick and fun
|
| 30 |
+
while also preventing any frustration caused by the inability to
|
| 31 |
+
implement an intended CLI API.
|
| 32 |
+
|
| 33 |
+
Click in three points:
|
| 34 |
+
|
| 35 |
+
- Arbitrary nesting of commands
|
| 36 |
+
- Automatic help page generation
|
| 37 |
+
- Supports lazy loading of subcommands at runtime
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
## A Simple Example
|
| 41 |
+
|
| 42 |
+
```python
|
| 43 |
+
import click
|
| 44 |
+
|
| 45 |
+
@click.command()
|
| 46 |
+
@click.option("--count", default=1, help="Number of greetings.")
|
| 47 |
+
@click.option("--name", prompt="Your name", help="The person to greet.")
|
| 48 |
+
def hello(count, name):
|
| 49 |
+
"""Simple program that greets NAME for a total of COUNT times."""
|
| 50 |
+
for _ in range(count):
|
| 51 |
+
click.echo(f"Hello, {name}!")
|
| 52 |
+
|
| 53 |
+
if __name__ == '__main__':
|
| 54 |
+
hello()
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
```
|
| 58 |
+
$ python hello.py --count=3
|
| 59 |
+
Your name: Click
|
| 60 |
+
Hello, Click!
|
| 61 |
+
Hello, Click!
|
| 62 |
+
Hello, Click!
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
## Donate
|
| 67 |
+
|
| 68 |
+
The Pallets organization develops and supports Click and other popular
|
| 69 |
+
packages. In order to grow the community of contributors and users, and
|
| 70 |
+
allow the maintainers to devote more time to the projects, [please
|
| 71 |
+
donate today][].
|
| 72 |
+
|
| 73 |
+
[please donate today]: https://palletsprojects.com/donate
|
| 74 |
+
|
| 75 |
+
## Contributing
|
| 76 |
+
|
| 77 |
+
See our [detailed contributing documentation][contrib] for many ways to
|
| 78 |
+
contribute, including reporting issues, requesting features, asking or answering
|
| 79 |
+
questions, and making PRs.
|
| 80 |
+
|
| 81 |
+
[contrib]: https://palletsprojects.com/contributing/
|
| 82 |
+
|
lib/python3.12/site-packages/click-8.2.1.dist-info/RECORD
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
click-8.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 2 |
+
click-8.2.1.dist-info/METADATA,sha256=dI1MbhHTLoKD2tNCCGnx9rK2gok23HDNylFeLKdLSik,2471
|
| 3 |
+
click-8.2.1.dist-info/RECORD,,
|
| 4 |
+
click-8.2.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
| 5 |
+
click-8.2.1.dist-info/licenses/LICENSE.txt,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475
|
| 6 |
+
click/__init__.py,sha256=6YyS1aeyknZ0LYweWozNZy0A9nZ_11wmYIhv3cbQrYo,4473
|
| 7 |
+
click/__pycache__/__init__.cpython-312.pyc,,
|
| 8 |
+
click/__pycache__/_compat.cpython-312.pyc,,
|
| 9 |
+
click/__pycache__/_termui_impl.cpython-312.pyc,,
|
| 10 |
+
click/__pycache__/_textwrap.cpython-312.pyc,,
|
| 11 |
+
click/__pycache__/_winconsole.cpython-312.pyc,,
|
| 12 |
+
click/__pycache__/core.cpython-312.pyc,,
|
| 13 |
+
click/__pycache__/decorators.cpython-312.pyc,,
|
| 14 |
+
click/__pycache__/exceptions.cpython-312.pyc,,
|
| 15 |
+
click/__pycache__/formatting.cpython-312.pyc,,
|
| 16 |
+
click/__pycache__/globals.cpython-312.pyc,,
|
| 17 |
+
click/__pycache__/parser.cpython-312.pyc,,
|
| 18 |
+
click/__pycache__/shell_completion.cpython-312.pyc,,
|
| 19 |
+
click/__pycache__/termui.cpython-312.pyc,,
|
| 20 |
+
click/__pycache__/testing.cpython-312.pyc,,
|
| 21 |
+
click/__pycache__/types.cpython-312.pyc,,
|
| 22 |
+
click/__pycache__/utils.cpython-312.pyc,,
|
| 23 |
+
click/_compat.py,sha256=v3xBZkFbvA1BXPRkFfBJc6-pIwPI7345m-kQEnpVAs4,18693
|
| 24 |
+
click/_termui_impl.py,sha256=ASXhLi9IQIc0Js9KQSS-3-SLZcPet3VqysBf9WgbbpI,26712
|
| 25 |
+
click/_textwrap.py,sha256=BOae0RQ6vg3FkNgSJyOoGzG1meGMxJ_ukWVZKx_v-0o,1400
|
| 26 |
+
click/_winconsole.py,sha256=_vxUuUaxwBhoR0vUWCNuHY8VUefiMdCIyU2SXPqoF-A,8465
|
| 27 |
+
click/core.py,sha256=gUhpNS9cFBGdEXXdisGVG-eRvGf49RTyFagxulqwdFw,117343
|
| 28 |
+
click/decorators.py,sha256=5P7abhJtAQYp_KHgjUvhMv464ERwOzrv2enNknlwHyQ,18461
|
| 29 |
+
click/exceptions.py,sha256=1rdtXgHJ1b3OjGkN-UpXB9t_HCBihJvh_DtpmLmwn9s,9891
|
| 30 |
+
click/formatting.py,sha256=Bhqx4QXdKQ9W4WKknIwj5KPKFmtduGOuGq1yw_THLZ8,9726
|
| 31 |
+
click/globals.py,sha256=gM-Nh6A4M0HB_SgkaF5M4ncGGMDHc_flHXu9_oh4GEU,1923
|
| 32 |
+
click/parser.py,sha256=nU1Ah2p11q29ul1vNdU9swPo_PUuKrxU6YXToi71q1c,18979
|
| 33 |
+
click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 34 |
+
click/shell_completion.py,sha256=CQSGdjgun4ORbOZrXP0CVhEtPx4knsufOkRsDiK64cM,19857
|
| 35 |
+
click/termui.py,sha256=vAYrKC2a7f_NfEIhAThEVYfa__ib5XQbTSCGtJlABRA,30847
|
| 36 |
+
click/testing.py,sha256=2eLdAaCJCGToP5Tw-XN8JjrDb3wbJIfARxg3d0crW5M,18702
|
| 37 |
+
click/types.py,sha256=KBTRxN28cR1VZ5mb9iJX98MQSw_p9SGzljqfEI8z5Tw,38389
|
| 38 |
+
click/utils.py,sha256=b1Mm-usEDBHtEwcPltPIn3zSK4nw2KTp5GC7_oSTlLo,20245
|
lib/python3.12/site-packages/click-8.2.1.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: flit 3.12.0
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
lib/python3.12/site-packages/click-8.2.1.dist-info/licenses/LICENSE.txt
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2014 Pallets
|
| 2 |
+
|
| 3 |
+
Redistribution and use in source and binary forms, with or without
|
| 4 |
+
modification, are permitted provided that the following conditions are
|
| 5 |
+
met:
|
| 6 |
+
|
| 7 |
+
1. Redistributions of source code must retain the above copyright
|
| 8 |
+
notice, this list of conditions and the following disclaimer.
|
| 9 |
+
|
| 10 |
+
2. Redistributions in binary form must reproduce the above copyright
|
| 11 |
+
notice, this list of conditions and the following disclaimer in the
|
| 12 |
+
documentation and/or other materials provided with the distribution.
|
| 13 |
+
|
| 14 |
+
3. Neither the name of the copyright holder nor the names of its
|
| 15 |
+
contributors may be used to endorse or promote products derived from
|
| 16 |
+
this software without specific prior written permission.
|
| 17 |
+
|
| 18 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 19 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 20 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
| 21 |
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 22 |
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 23 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
| 24 |
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
| 25 |
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
| 26 |
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
| 27 |
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
| 28 |
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
lib/python3.12/site-packages/deepspeed/__init__.py
ADDED
|
@@ -0,0 +1,398 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import sys
|
| 7 |
+
import types
|
| 8 |
+
import json
|
| 9 |
+
from typing import Optional, Union
|
| 10 |
+
import torch
|
| 11 |
+
from torch.optim import Optimizer
|
| 12 |
+
from torch.optim.lr_scheduler import _LRScheduler
|
| 13 |
+
from packaging import version as pkg_version
|
| 14 |
+
|
| 15 |
+
# Skip Triton import for AMD due to pytorch-triton-rocm module breaking device API in DeepSpeed
|
| 16 |
+
if not (hasattr(torch.version, 'hip') and torch.version.hip is not None):
|
| 17 |
+
try:
|
| 18 |
+
import triton # noqa: F401 # type: ignore
|
| 19 |
+
HAS_TRITON = True
|
| 20 |
+
except ImportError:
|
| 21 |
+
HAS_TRITON = False
|
| 22 |
+
else:
|
| 23 |
+
HAS_TRITON = False
|
| 24 |
+
|
| 25 |
+
from . import ops
|
| 26 |
+
from . import module_inject
|
| 27 |
+
|
| 28 |
+
from .accelerator import get_accelerator
|
| 29 |
+
from .constants import TORCH_DISTRIBUTED_DEFAULT_PORT
|
| 30 |
+
from .runtime.engine import DeepSpeedEngine, DeepSpeedOptimizerCallable, DeepSpeedSchedulerCallable
|
| 31 |
+
from .runtime.engine import ADAM_OPTIMIZER, LAMB_OPTIMIZER
|
| 32 |
+
from .runtime.hybrid_engine import DeepSpeedHybridEngine
|
| 33 |
+
from .runtime.pipe.engine import PipelineEngine
|
| 34 |
+
from .inference.engine import InferenceEngine
|
| 35 |
+
from .inference.config import DeepSpeedInferenceConfig
|
| 36 |
+
from .runtime.lr_schedules import add_tuning_arguments
|
| 37 |
+
from .runtime.config import DeepSpeedConfig, DeepSpeedConfigError
|
| 38 |
+
from .runtime.activation_checkpointing import checkpointing
|
| 39 |
+
from .ops.transformer import DeepSpeedTransformerLayer, DeepSpeedTransformerConfig
|
| 40 |
+
from .module_inject import replace_transformer_layer, revert_transformer_layer, set_autotp_mode
|
| 41 |
+
|
| 42 |
+
from .utils import log_dist, OnDevice, logger
|
| 43 |
+
from .comm.comm import init_distributed
|
| 44 |
+
|
| 45 |
+
from .runtime import zero, domino
|
| 46 |
+
from .runtime.compiler import is_compile_supported
|
| 47 |
+
|
| 48 |
+
from .pipe import PipelineModule
|
| 49 |
+
|
| 50 |
+
from .git_version_info import version, git_hash, git_branch
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def _parse_version(version_str):
|
| 54 |
+
'''Parse a version string and extract the major, minor, and patch versions.'''
|
| 55 |
+
ver = pkg_version.parse(version_str)
|
| 56 |
+
return ver.major, ver.minor, ver.micro
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
# Export version information
|
| 60 |
+
__version__ = version
|
| 61 |
+
__version_major__, __version_minor__, __version_patch__ = _parse_version(__version__)
|
| 62 |
+
__git_hash__ = git_hash
|
| 63 |
+
__git_branch__ = git_branch
|
| 64 |
+
|
| 65 |
+
# Set to torch's distributed package or deepspeed.comm based inside DeepSpeedEngine init
|
| 66 |
+
dist = None
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def initialize(args=None,
|
| 70 |
+
model: torch.nn.Module = None,
|
| 71 |
+
optimizer: Optional[Union[Optimizer, DeepSpeedOptimizerCallable]] = None,
|
| 72 |
+
model_parameters: Optional[torch.nn.Module] = None,
|
| 73 |
+
training_data: Optional[torch.utils.data.Dataset] = None,
|
| 74 |
+
lr_scheduler: Optional[Union[_LRScheduler, DeepSpeedSchedulerCallable]] = None,
|
| 75 |
+
distributed_port: int = TORCH_DISTRIBUTED_DEFAULT_PORT,
|
| 76 |
+
mpu=None,
|
| 77 |
+
dist_init_required: Optional[bool] = None,
|
| 78 |
+
collate_fn=None,
|
| 79 |
+
config=None,
|
| 80 |
+
mesh_param=None,
|
| 81 |
+
config_params=None):
|
| 82 |
+
"""Initialize the DeepSpeed Engine.
|
| 83 |
+
|
| 84 |
+
Arguments:
|
| 85 |
+
args: an object containing local_rank and deepspeed_config fields.
|
| 86 |
+
This is optional if `config` is passed.
|
| 87 |
+
|
| 88 |
+
model: Required: nn.module class before apply any wrappers
|
| 89 |
+
|
| 90 |
+
optimizer: Optional: a user defined Optimizer or Callable that returns an Optimizer object.
|
| 91 |
+
This overrides any optimizer definition in the DeepSpeed json config.
|
| 92 |
+
|
| 93 |
+
model_parameters: Optional: An iterable of torch.Tensors or dicts.
|
| 94 |
+
Specifies what Tensors should be optimized.
|
| 95 |
+
|
| 96 |
+
training_data: Optional: Dataset of type torch.utils.data.Dataset
|
| 97 |
+
|
| 98 |
+
lr_scheduler: Optional: Learning Rate Scheduler Object or a Callable that takes an Optimizer and returns a Scheduler object.
|
| 99 |
+
The scheduler object should define a get_lr(), step(), state_dict(), and load_state_dict() methods
|
| 100 |
+
|
| 101 |
+
distributed_port: Optional: Master node (rank 0)'s free port that needs to be used for communication during distributed training
|
| 102 |
+
|
| 103 |
+
mpu: Optional: A model parallelism unit object that implements
|
| 104 |
+
get_{model,data}_parallel_{rank,group,world_size}()
|
| 105 |
+
|
| 106 |
+
dist_init_required: Optional: None will auto-initialize torch distributed if needed,
|
| 107 |
+
otherwise the user can force it to be initialized or not via boolean.
|
| 108 |
+
|
| 109 |
+
collate_fn: Optional: Merges a list of samples to form a
|
| 110 |
+
mini-batch of Tensor(s). Used when using batched loading from a
|
| 111 |
+
map-style dataset.
|
| 112 |
+
|
| 113 |
+
config: Optional: Instead of requiring args.deepspeed_config you can pass your deepspeed config
|
| 114 |
+
as an argument instead, as a path or a dictionary.
|
| 115 |
+
|
| 116 |
+
config_params: Optional: Same as `config`, kept for backwards compatibility.
|
| 117 |
+
|
| 118 |
+
Returns:
|
| 119 |
+
A tuple of ``engine``, ``optimizer``, ``training_dataloader``, ``lr_scheduler``
|
| 120 |
+
|
| 121 |
+
* ``engine``: DeepSpeed runtime engine which wraps the client model for distributed training.
|
| 122 |
+
|
| 123 |
+
* ``optimizer``: Wrapped optimizer if a user defined ``optimizer`` is supplied, or if
|
| 124 |
+
optimizer is specified in json config else ``None``.
|
| 125 |
+
|
| 126 |
+
* ``training_dataloader``: DeepSpeed dataloader if ``training_data`` was supplied,
|
| 127 |
+
otherwise ``None``.
|
| 128 |
+
|
| 129 |
+
* ``lr_scheduler``: Wrapped lr scheduler if user ``lr_scheduler`` is passed, or
|
| 130 |
+
if ``lr_scheduler`` specified in JSON configuration. Otherwise ``None``.
|
| 131 |
+
"""
|
| 132 |
+
log_dist("DeepSpeed info: version={}, git-hash={}, git-branch={}".format(__version__, __git_hash__,
|
| 133 |
+
__git_branch__),
|
| 134 |
+
ranks=[0])
|
| 135 |
+
|
| 136 |
+
# Disable zero.Init context if it's currently enabled
|
| 137 |
+
zero.partition_parameters.shutdown_init_context()
|
| 138 |
+
|
| 139 |
+
assert model is not None, "deepspeed.initialize requires a model"
|
| 140 |
+
|
| 141 |
+
global dist
|
| 142 |
+
from deepspeed import comm as dist
|
| 143 |
+
dist_backend = get_accelerator().communication_backend_name()
|
| 144 |
+
dist.init_distributed(dist_backend=dist_backend,
|
| 145 |
+
distributed_port=distributed_port,
|
| 146 |
+
dist_init_required=dist_init_required)
|
| 147 |
+
|
| 148 |
+
##TODO: combine reuse mpu as mesh device and vice versa
|
| 149 |
+
# Set config using config_params for backwards compat
|
| 150 |
+
if config is None and config_params is not None:
|
| 151 |
+
config = config_params
|
| 152 |
+
|
| 153 |
+
mesh_device = None
|
| 154 |
+
if mesh_param:
|
| 155 |
+
logger.info(f"mesh_param to Initialize mesh device: {mesh_param}")
|
| 156 |
+
mesh_device = dist.initialize_mesh_device(mesh_param, ("data_parallel", "sequence_parallel"))
|
| 157 |
+
#if config file has sequence parallelize and data parallelize, then use them to initialize mesh device
|
| 158 |
+
elif config is not None:
|
| 159 |
+
if "sequence_parallel_size" in config and "data_parallel_size" in config:
|
| 160 |
+
logger.info(f"config to Initialize mesh device: {config}")
|
| 161 |
+
mesh_device = dist.initialize_mesh_device((config["data_parallel_size"], config["sequence_parallel_size"]), \
|
| 162 |
+
("data_parallel", "sequence_parallel"))
|
| 163 |
+
|
| 164 |
+
# Check for deepscale_config for backwards compat
|
| 165 |
+
if hasattr(args, "deepscale_config") and args.deepscale_config is not None:
|
| 166 |
+
logger.warning("************ --deepscale_config is deprecated, please use --deepspeed_config ************")
|
| 167 |
+
if hasattr(args, "deepspeed_config"):
|
| 168 |
+
assert (args.deepspeed_config
|
| 169 |
+
is None), "Not sure how to proceed, we were given both a deepscale_config and deepspeed_config"
|
| 170 |
+
args.deepspeed_config = args.deepscale_config
|
| 171 |
+
args.deepscale_config = None
|
| 172 |
+
|
| 173 |
+
# Check that we have only one config passed
|
| 174 |
+
if hasattr(args, "deepspeed_config") and args.deepspeed_config is not None:
|
| 175 |
+
assert config is None, "Not sure how to proceed, we were given deepspeed configs in the deepspeed arguments and deepspeed.initialize() function call"
|
| 176 |
+
config = args.deepspeed_config
|
| 177 |
+
assert config is not None, "DeepSpeed requires --deepspeed_config to specify configuration file"
|
| 178 |
+
if not isinstance(model, PipelineModule):
|
| 179 |
+
config_class = DeepSpeedConfig(config, mpu, mesh_device=mesh_device)
|
| 180 |
+
if config_class.hybrid_engine.enabled:
|
| 181 |
+
engine = DeepSpeedHybridEngine(args=args,
|
| 182 |
+
model=model,
|
| 183 |
+
optimizer=optimizer,
|
| 184 |
+
model_parameters=model_parameters,
|
| 185 |
+
training_data=training_data,
|
| 186 |
+
lr_scheduler=lr_scheduler,
|
| 187 |
+
mpu=mpu,
|
| 188 |
+
dist_init_required=dist_init_required,
|
| 189 |
+
collate_fn=collate_fn,
|
| 190 |
+
config=config,
|
| 191 |
+
config_class=config_class)
|
| 192 |
+
else:
|
| 193 |
+
engine = DeepSpeedEngine(args=args,
|
| 194 |
+
model=model,
|
| 195 |
+
optimizer=optimizer,
|
| 196 |
+
model_parameters=model_parameters,
|
| 197 |
+
training_data=training_data,
|
| 198 |
+
lr_scheduler=lr_scheduler,
|
| 199 |
+
mpu=mpu,
|
| 200 |
+
dist_init_required=dist_init_required,
|
| 201 |
+
collate_fn=collate_fn,
|
| 202 |
+
config=config,
|
| 203 |
+
mesh_device=mesh_device,
|
| 204 |
+
config_class=config_class)
|
| 205 |
+
else:
|
| 206 |
+
assert mpu is None, "mpu must be None with pipeline parallelism"
|
| 207 |
+
mpu = model.mpu()
|
| 208 |
+
config_class = DeepSpeedConfig(config, mpu)
|
| 209 |
+
engine = PipelineEngine(args=args,
|
| 210 |
+
model=model,
|
| 211 |
+
optimizer=optimizer,
|
| 212 |
+
model_parameters=model_parameters,
|
| 213 |
+
training_data=training_data,
|
| 214 |
+
lr_scheduler=lr_scheduler,
|
| 215 |
+
mpu=mpu,
|
| 216 |
+
dist_init_required=dist_init_required,
|
| 217 |
+
collate_fn=collate_fn,
|
| 218 |
+
config=config,
|
| 219 |
+
config_class=config_class)
|
| 220 |
+
|
| 221 |
+
# Restore zero.Init context if necessary
|
| 222 |
+
zero.partition_parameters.restore_init_context()
|
| 223 |
+
|
| 224 |
+
return_items = [
|
| 225 |
+
engine,
|
| 226 |
+
engine.optimizer,
|
| 227 |
+
engine.training_dataloader,
|
| 228 |
+
engine.lr_scheduler,
|
| 229 |
+
]
|
| 230 |
+
return tuple(return_items)
|
| 231 |
+
|
| 232 |
+
|
| 233 |
+
def _add_core_arguments(parser):
|
| 234 |
+
r"""Helper (internal) function to update an argument parser with an argument group of the core DeepSpeed arguments.
|
| 235 |
+
The core set of DeepSpeed arguments include the following:
|
| 236 |
+
1) --deepspeed: boolean flag to enable DeepSpeed
|
| 237 |
+
2) --deepspeed_config <json file path>: path of a json configuration file to configure DeepSpeed runtime.
|
| 238 |
+
|
| 239 |
+
This is a helper function to the public add_config_arguments()
|
| 240 |
+
|
| 241 |
+
Arguments:
|
| 242 |
+
parser: argument parser
|
| 243 |
+
Return:
|
| 244 |
+
parser: Updated Parser
|
| 245 |
+
"""
|
| 246 |
+
group = parser.add_argument_group('DeepSpeed', 'DeepSpeed configurations')
|
| 247 |
+
|
| 248 |
+
group.add_argument('--deepspeed',
|
| 249 |
+
default=False,
|
| 250 |
+
action='store_true',
|
| 251 |
+
help='Enable DeepSpeed (helper flag for user code, no impact on DeepSpeed backend)')
|
| 252 |
+
|
| 253 |
+
group.add_argument('--deepspeed_config', default=None, type=str, help='DeepSpeed json configuration file.')
|
| 254 |
+
|
| 255 |
+
group.add_argument('--deepscale',
|
| 256 |
+
default=False,
|
| 257 |
+
action='store_true',
|
| 258 |
+
help='Deprecated enable DeepSpeed (helper flag for user code, no impact on DeepSpeed backend)')
|
| 259 |
+
|
| 260 |
+
group.add_argument('--deepscale_config',
|
| 261 |
+
default=None,
|
| 262 |
+
type=str,
|
| 263 |
+
help='Deprecated DeepSpeed json configuration file.')
|
| 264 |
+
|
| 265 |
+
return parser
|
| 266 |
+
|
| 267 |
+
|
| 268 |
+
def add_config_arguments(parser):
|
| 269 |
+
r"""Update the argument parser to enabling parsing of DeepSpeed command line arguments.
|
| 270 |
+
The set of DeepSpeed arguments include the following:
|
| 271 |
+
1) --deepspeed: boolean flag to enable DeepSpeed
|
| 272 |
+
2) --deepspeed_config <json file path>: path of a json configuration file to configure DeepSpeed runtime.
|
| 273 |
+
|
| 274 |
+
Arguments:
|
| 275 |
+
parser: argument parser
|
| 276 |
+
Return:
|
| 277 |
+
parser: Updated Parser
|
| 278 |
+
"""
|
| 279 |
+
parser = _add_core_arguments(parser)
|
| 280 |
+
|
| 281 |
+
return parser
|
| 282 |
+
|
| 283 |
+
|
| 284 |
+
def default_inference_config():
|
| 285 |
+
"""
|
| 286 |
+
Return a default DeepSpeed inference configuration dictionary.
|
| 287 |
+
"""
|
| 288 |
+
return DeepSpeedInferenceConfig().dict()
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def init_inference(model, config=None, **kwargs):
|
| 292 |
+
"""Initialize the DeepSpeed InferenceEngine.
|
| 293 |
+
|
| 294 |
+
Description: all four cases are valid and supported in DS init_inference() API.
|
| 295 |
+
|
| 296 |
+
# Case 1: user provides no config and no kwargs. Default config will be used.
|
| 297 |
+
|
| 298 |
+
.. code-block:: python
|
| 299 |
+
|
| 300 |
+
generator.model = deepspeed.init_inference(generator.model)
|
| 301 |
+
string = generator("DeepSpeed is")
|
| 302 |
+
print(string)
|
| 303 |
+
|
| 304 |
+
# Case 2: user provides a config and no kwargs. User supplied config will be used.
|
| 305 |
+
|
| 306 |
+
.. code-block:: python
|
| 307 |
+
|
| 308 |
+
generator.model = deepspeed.init_inference(generator.model, config=config)
|
| 309 |
+
string = generator("DeepSpeed is")
|
| 310 |
+
print(string)
|
| 311 |
+
|
| 312 |
+
# Case 3: user provides no config and uses keyword arguments (kwargs) only.
|
| 313 |
+
|
| 314 |
+
.. code-block:: python
|
| 315 |
+
|
| 316 |
+
generator.model = deepspeed.init_inference(generator.model,
|
| 317 |
+
tensor_parallel={"tp_size": world_size},
|
| 318 |
+
dtype=torch.half,
|
| 319 |
+
replace_with_kernel_inject=True)
|
| 320 |
+
string = generator("DeepSpeed is")
|
| 321 |
+
print(string)
|
| 322 |
+
|
| 323 |
+
# Case 4: user provides config and keyword arguments (kwargs). Both config and kwargs are merged and kwargs take precedence.
|
| 324 |
+
|
| 325 |
+
.. code-block:: python
|
| 326 |
+
|
| 327 |
+
generator.model = deepspeed.init_inference(generator.model, config={"dtype": torch.half}, replace_with_kernel_inject=True)
|
| 328 |
+
string = generator("DeepSpeed is")
|
| 329 |
+
print(string)
|
| 330 |
+
|
| 331 |
+
Arguments:
|
| 332 |
+
model: Required: original nn.module object without any wrappers
|
| 333 |
+
|
| 334 |
+
config: Optional: instead of arguments, you can pass in a DS inference config dict or path to JSON file
|
| 335 |
+
|
| 336 |
+
Returns:
|
| 337 |
+
A deepspeed.InferenceEngine wrapped model.
|
| 338 |
+
"""
|
| 339 |
+
log_dist("DeepSpeed info: version={}, git-hash={}, git-branch={}".format(__version__, __git_hash__,
|
| 340 |
+
__git_branch__),
|
| 341 |
+
ranks=[0])
|
| 342 |
+
|
| 343 |
+
# Load config_dict from config first
|
| 344 |
+
if config is None:
|
| 345 |
+
config = {}
|
| 346 |
+
if isinstance(config, str):
|
| 347 |
+
with open(config, "r") as f:
|
| 348 |
+
config_dict = json.load(f)
|
| 349 |
+
elif isinstance(config, dict):
|
| 350 |
+
config_dict = config
|
| 351 |
+
else:
|
| 352 |
+
raise ValueError(f"'config' argument expected string or dictionary, got {type(config)}")
|
| 353 |
+
|
| 354 |
+
# Update with values from kwargs, ensuring no conflicting overlap between config and kwargs
|
| 355 |
+
overlap_keys = set(config_dict.keys()).intersection(kwargs.keys())
|
| 356 |
+
# If there is overlap, error out if values are different
|
| 357 |
+
for key in overlap_keys:
|
| 358 |
+
if config_dict[key] != kwargs[key]:
|
| 359 |
+
raise ValueError(f"Conflicting argument '{key}' in 'config':{config_dict[key]} and kwargs:{kwargs[key]}")
|
| 360 |
+
config_dict.update(kwargs)
|
| 361 |
+
|
| 362 |
+
ds_inference_config = DeepSpeedInferenceConfig(**config_dict)
|
| 363 |
+
|
| 364 |
+
engine = InferenceEngine(model, config=ds_inference_config)
|
| 365 |
+
|
| 366 |
+
return engine
|
| 367 |
+
|
| 368 |
+
|
| 369 |
+
def tp_model_init(model, tp_size, dtype, config=None, **kwargs):
|
| 370 |
+
"""
|
| 371 |
+
Initialize the model for tensor parallelism.
|
| 372 |
+
|
| 373 |
+
Args:
|
| 374 |
+
model (torch.nn.Module): The model to be initialized.
|
| 375 |
+
tp_size (int): The tensor parallelism size.
|
| 376 |
+
dtype (torch.dtype): The data type to be used for the model.
|
| 377 |
+
|
| 378 |
+
Returns:
|
| 379 |
+
torch.nn.Module: The initialized model with tensor parallelism.
|
| 380 |
+
"""
|
| 381 |
+
# avoid re-entry
|
| 382 |
+
if hasattr(model, 'ds_autotp_parsed'):
|
| 383 |
+
logger.warning("ds_autotp_parsed' attribute already exists in the model, re-entry is not allowed.")
|
| 384 |
+
return
|
| 385 |
+
|
| 386 |
+
set_autotp_mode(training=True)
|
| 387 |
+
|
| 388 |
+
from deepspeed.runtime.tensor_parallel import TpTrainingManager
|
| 389 |
+
# The expected usage here is for it to be invoked by transformers package.
|
| 390 |
+
|
| 391 |
+
#TODO: We should provide a custom TP mapping solution without using autoTP
|
| 392 |
+
#as modifying the autoTP logic may be more difficult for users compared to configuring it
|
| 393 |
+
|
| 394 |
+
model = TpTrainingManager(model=model, tp_size=tp_size, dtype=dtype).module
|
| 395 |
+
|
| 396 |
+
setattr(model, 'ds_autotp_parsed', True)
|
| 397 |
+
|
| 398 |
+
return model
|
lib/python3.12/site-packages/deepspeed/accelerator/__init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 7 |
+
from .real_accelerator import get_accelerator, set_accelerator, is_current_accelerator_supported
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (399 Bytes). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/abstract_accelerator.cpython-312.pyc
ADDED
|
Binary file (14.1 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/cpu_accelerator.cpython-312.pyc
ADDED
|
Binary file (16.6 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/cuda_accelerator.cpython-312.pyc
ADDED
|
Binary file (22.1 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/hpu_accelerator.cpython-312.pyc
ADDED
|
Binary file (19.3 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/mlu_accelerator.cpython-312.pyc
ADDED
|
Binary file (18.8 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/mps_accelerator.cpython-312.pyc
ADDED
|
Binary file (13.9 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/npu_accelerator.cpython-312.pyc
ADDED
|
Binary file (17.7 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/real_accelerator.cpython-312.pyc
ADDED
|
Binary file (7.85 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/sdaa_accelerator.cpython-312.pyc
ADDED
|
Binary file (18.4 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/__pycache__/xpu_accelerator.cpython-312.pyc
ADDED
|
Binary file (19.8 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/accelerator/abstract_accelerator.py
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import abc
|
| 7 |
+
from abc import ABC
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class DeepSpeedAccelerator(ABC):
|
| 11 |
+
|
| 12 |
+
def __init__(self):
|
| 13 |
+
self._name = None
|
| 14 |
+
self._communication_backend_name = None
|
| 15 |
+
self._compile_backend = None
|
| 16 |
+
|
| 17 |
+
@abc.abstractmethod
|
| 18 |
+
def is_synchronized_device(self):
|
| 19 |
+
...
|
| 20 |
+
|
| 21 |
+
@abc.abstractmethod
|
| 22 |
+
def use_host_timers(self):
|
| 23 |
+
...
|
| 24 |
+
|
| 25 |
+
@abc.abstractmethod
|
| 26 |
+
def resolves_data_dependency(self):
|
| 27 |
+
...
|
| 28 |
+
|
| 29 |
+
@abc.abstractmethod
|
| 30 |
+
def handles_memory_backpressure(self):
|
| 31 |
+
...
|
| 32 |
+
|
| 33 |
+
# Device APIs
|
| 34 |
+
@abc.abstractmethod
|
| 35 |
+
def device_name(self, device_index):
|
| 36 |
+
...
|
| 37 |
+
|
| 38 |
+
@abc.abstractmethod
|
| 39 |
+
def device(self, device_index):
|
| 40 |
+
...
|
| 41 |
+
|
| 42 |
+
@abc.abstractmethod
|
| 43 |
+
def set_device(self, device_index):
|
| 44 |
+
...
|
| 45 |
+
|
| 46 |
+
@abc.abstractmethod
|
| 47 |
+
def current_device(self):
|
| 48 |
+
...
|
| 49 |
+
|
| 50 |
+
@abc.abstractmethod
|
| 51 |
+
def current_device_name(self):
|
| 52 |
+
...
|
| 53 |
+
|
| 54 |
+
@abc.abstractmethod
|
| 55 |
+
def device_count(self):
|
| 56 |
+
...
|
| 57 |
+
|
| 58 |
+
@abc.abstractmethod
|
| 59 |
+
def synchronize(self, device_index=None):
|
| 60 |
+
...
|
| 61 |
+
|
| 62 |
+
# RNG APIs
|
| 63 |
+
@abc.abstractmethod
|
| 64 |
+
def random(self):
|
| 65 |
+
...
|
| 66 |
+
|
| 67 |
+
@abc.abstractmethod
|
| 68 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 69 |
+
...
|
| 70 |
+
|
| 71 |
+
@abc.abstractmethod
|
| 72 |
+
def get_rng_state(self, device_index=None):
|
| 73 |
+
...
|
| 74 |
+
|
| 75 |
+
@abc.abstractmethod
|
| 76 |
+
def manual_seed(self, seed):
|
| 77 |
+
...
|
| 78 |
+
|
| 79 |
+
@abc.abstractmethod
|
| 80 |
+
def manual_seed_all(self, seed):
|
| 81 |
+
...
|
| 82 |
+
|
| 83 |
+
@abc.abstractmethod
|
| 84 |
+
def initial_seed(self):
|
| 85 |
+
...
|
| 86 |
+
|
| 87 |
+
@abc.abstractmethod
|
| 88 |
+
def default_generator(self, device_index):
|
| 89 |
+
...
|
| 90 |
+
|
| 91 |
+
# Streams/Events
|
| 92 |
+
@property
|
| 93 |
+
@abc.abstractmethod
|
| 94 |
+
def Stream(self):
|
| 95 |
+
...
|
| 96 |
+
|
| 97 |
+
@abc.abstractmethod
|
| 98 |
+
def stream(self, stream):
|
| 99 |
+
...
|
| 100 |
+
|
| 101 |
+
@abc.abstractmethod
|
| 102 |
+
def current_stream(self, device_index=None):
|
| 103 |
+
...
|
| 104 |
+
|
| 105 |
+
@abc.abstractmethod
|
| 106 |
+
def default_stream(self, device_index=None):
|
| 107 |
+
...
|
| 108 |
+
|
| 109 |
+
@property
|
| 110 |
+
@abc.abstractmethod
|
| 111 |
+
def Event(self):
|
| 112 |
+
...
|
| 113 |
+
|
| 114 |
+
# Memory management
|
| 115 |
+
@abc.abstractmethod
|
| 116 |
+
def empty_cache(self):
|
| 117 |
+
...
|
| 118 |
+
|
| 119 |
+
@abc.abstractmethod
|
| 120 |
+
def memory_allocated(self, device_index=None):
|
| 121 |
+
...
|
| 122 |
+
|
| 123 |
+
@abc.abstractmethod
|
| 124 |
+
def max_memory_allocated(self, device_index=None):
|
| 125 |
+
...
|
| 126 |
+
|
| 127 |
+
@abc.abstractmethod
|
| 128 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 129 |
+
...
|
| 130 |
+
|
| 131 |
+
@abc.abstractmethod
|
| 132 |
+
def memory_cached(self, device_index=None):
|
| 133 |
+
...
|
| 134 |
+
|
| 135 |
+
@abc.abstractmethod
|
| 136 |
+
def max_memory_cached(self, device_index=None):
|
| 137 |
+
...
|
| 138 |
+
|
| 139 |
+
@abc.abstractmethod
|
| 140 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 141 |
+
...
|
| 142 |
+
|
| 143 |
+
@abc.abstractmethod
|
| 144 |
+
def memory_stats(self, device_index=None):
|
| 145 |
+
...
|
| 146 |
+
|
| 147 |
+
@abc.abstractmethod
|
| 148 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 149 |
+
...
|
| 150 |
+
|
| 151 |
+
@abc.abstractmethod
|
| 152 |
+
def memory_reserved(self, device_index=None):
|
| 153 |
+
...
|
| 154 |
+
|
| 155 |
+
@abc.abstractmethod
|
| 156 |
+
def max_memory_reserved(self, device_index=None):
|
| 157 |
+
...
|
| 158 |
+
|
| 159 |
+
@abc.abstractmethod
|
| 160 |
+
def total_memory(self, device_index=None):
|
| 161 |
+
...
|
| 162 |
+
|
| 163 |
+
@abc.abstractmethod
|
| 164 |
+
def available_memory(self, device_index=None):
|
| 165 |
+
...
|
| 166 |
+
|
| 167 |
+
# Data types
|
| 168 |
+
@abc.abstractmethod
|
| 169 |
+
def is_bf16_supported(self):
|
| 170 |
+
...
|
| 171 |
+
|
| 172 |
+
@abc.abstractmethod
|
| 173 |
+
def is_fp16_supported(self):
|
| 174 |
+
...
|
| 175 |
+
|
| 176 |
+
@abc.abstractmethod
|
| 177 |
+
def supported_dtypes(self):
|
| 178 |
+
...
|
| 179 |
+
|
| 180 |
+
# Misc
|
| 181 |
+
@abc.abstractmethod
|
| 182 |
+
def amp(self):
|
| 183 |
+
...
|
| 184 |
+
|
| 185 |
+
@abc.abstractmethod
|
| 186 |
+
def is_available(self):
|
| 187 |
+
...
|
| 188 |
+
|
| 189 |
+
@abc.abstractmethod
|
| 190 |
+
def range_push(self, msg):
|
| 191 |
+
...
|
| 192 |
+
|
| 193 |
+
@abc.abstractmethod
|
| 194 |
+
def range_pop(self):
|
| 195 |
+
...
|
| 196 |
+
|
| 197 |
+
@abc.abstractmethod
|
| 198 |
+
def lazy_call(self, callback):
|
| 199 |
+
...
|
| 200 |
+
|
| 201 |
+
@abc.abstractmethod
|
| 202 |
+
def communication_backend_name(self):
|
| 203 |
+
...
|
| 204 |
+
|
| 205 |
+
@abc.abstractmethod
|
| 206 |
+
def is_triton_supported(self):
|
| 207 |
+
...
|
| 208 |
+
|
| 209 |
+
# Graph operations
|
| 210 |
+
@abc.abstractmethod
|
| 211 |
+
def create_graph(self):
|
| 212 |
+
...
|
| 213 |
+
|
| 214 |
+
@abc.abstractmethod
|
| 215 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 216 |
+
...
|
| 217 |
+
|
| 218 |
+
@abc.abstractmethod
|
| 219 |
+
def replay_graph(self, graph):
|
| 220 |
+
...
|
| 221 |
+
|
| 222 |
+
# Tensor operations
|
| 223 |
+
@property
|
| 224 |
+
@abc.abstractmethod
|
| 225 |
+
def BFloat16Tensor(self):
|
| 226 |
+
...
|
| 227 |
+
|
| 228 |
+
@property
|
| 229 |
+
@abc.abstractmethod
|
| 230 |
+
def ByteTensor(self):
|
| 231 |
+
...
|
| 232 |
+
|
| 233 |
+
@property
|
| 234 |
+
@abc.abstractmethod
|
| 235 |
+
def DoubleTensor(self):
|
| 236 |
+
...
|
| 237 |
+
|
| 238 |
+
@property
|
| 239 |
+
@abc.abstractmethod
|
| 240 |
+
def FloatTensor(self):
|
| 241 |
+
...
|
| 242 |
+
|
| 243 |
+
@property
|
| 244 |
+
@abc.abstractmethod
|
| 245 |
+
def HalfTensor(self):
|
| 246 |
+
...
|
| 247 |
+
|
| 248 |
+
@property
|
| 249 |
+
@abc.abstractmethod
|
| 250 |
+
def IntTensor(self):
|
| 251 |
+
...
|
| 252 |
+
|
| 253 |
+
@property
|
| 254 |
+
@abc.abstractmethod
|
| 255 |
+
def LongTensor(self):
|
| 256 |
+
...
|
| 257 |
+
|
| 258 |
+
@abc.abstractmethod
|
| 259 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 260 |
+
...
|
| 261 |
+
|
| 262 |
+
@abc.abstractmethod
|
| 263 |
+
def is_pinned(self, tensor):
|
| 264 |
+
...
|
| 265 |
+
|
| 266 |
+
@abc.abstractmethod
|
| 267 |
+
def on_accelerator(self, tensor):
|
| 268 |
+
...
|
| 269 |
+
|
| 270 |
+
@abc.abstractmethod
|
| 271 |
+
def op_builder_dir(self):
|
| 272 |
+
...
|
| 273 |
+
|
| 274 |
+
# create an instance of op builder, specified by class_name
|
| 275 |
+
@abc.abstractmethod
|
| 276 |
+
def create_op_builder(self, class_name):
|
| 277 |
+
...
|
| 278 |
+
|
| 279 |
+
# return an op builder class, specified by class_name
|
| 280 |
+
@abc.abstractmethod
|
| 281 |
+
def get_op_builder(self, class_name):
|
| 282 |
+
...
|
| 283 |
+
|
| 284 |
+
@abc.abstractmethod
|
| 285 |
+
def build_extension(self):
|
| 286 |
+
...
|
| 287 |
+
|
| 288 |
+
@abc.abstractmethod
|
| 289 |
+
def export_envs(self):
|
| 290 |
+
...
|
| 291 |
+
|
| 292 |
+
@abc.abstractmethod
|
| 293 |
+
def visible_devices_envs(self):
|
| 294 |
+
...
|
| 295 |
+
|
| 296 |
+
@abc.abstractmethod
|
| 297 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 298 |
+
...
|
| 299 |
+
|
| 300 |
+
@abc.abstractmethod
|
| 301 |
+
def get_compile_backend(self):
|
| 302 |
+
...
|
| 303 |
+
|
| 304 |
+
@abc.abstractmethod
|
| 305 |
+
def set_compile_backend(self, backend):
|
| 306 |
+
...
|
lib/python3.12/site-packages/deepspeed/accelerator/cpu_accelerator.py
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 7 |
+
|
| 8 |
+
# During setup stage torch may not be installed, pass on no torch will
|
| 9 |
+
# allow op builder related API to be executed.
|
| 10 |
+
try:
|
| 11 |
+
import torch
|
| 12 |
+
except ImportError as e:
|
| 13 |
+
pass
|
| 14 |
+
|
| 15 |
+
try:
|
| 16 |
+
import oneccl_bindings_for_pytorch # noqa: F401 # type: ignore
|
| 17 |
+
oneccl_imported_p = True
|
| 18 |
+
except ImportError as e:
|
| 19 |
+
oneccl_imported_p = False
|
| 20 |
+
|
| 21 |
+
import os
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
# accelerator for Intel CPU
|
| 25 |
+
class CPU_Accelerator(DeepSpeedAccelerator):
|
| 26 |
+
|
| 27 |
+
def __init__(self):
|
| 28 |
+
self._name = 'cpu'
|
| 29 |
+
self._compile_backend = "inductor"
|
| 30 |
+
if oneccl_imported_p:
|
| 31 |
+
self._communication_backend_name = 'ccl'
|
| 32 |
+
else:
|
| 33 |
+
# fallback to gloo if oneccl_binding_for_pytorch is not installed
|
| 34 |
+
self._communication_backend_name = 'gloo'
|
| 35 |
+
try:
|
| 36 |
+
import psutil
|
| 37 |
+
mem = psutil.Process().memory_info().rss
|
| 38 |
+
self.max_mem = mem
|
| 39 |
+
except ImportError as e:
|
| 40 |
+
self.max_mem = 0
|
| 41 |
+
|
| 42 |
+
def is_synchronized_device(self):
|
| 43 |
+
return True
|
| 44 |
+
|
| 45 |
+
def use_host_timers(self):
|
| 46 |
+
return self.is_synchronized_device()
|
| 47 |
+
|
| 48 |
+
def resolves_data_dependency(self):
|
| 49 |
+
return self.is_synchronized_device()
|
| 50 |
+
|
| 51 |
+
def handles_memory_backpressure(self):
|
| 52 |
+
return self.is_synchronized_device()
|
| 53 |
+
|
| 54 |
+
# Device APIs
|
| 55 |
+
def device_name(self, device_index=None):
|
| 56 |
+
return 'cpu'
|
| 57 |
+
|
| 58 |
+
def device(self, device_index=None):
|
| 59 |
+
return None
|
| 60 |
+
|
| 61 |
+
def set_device(self, device_index):
|
| 62 |
+
return
|
| 63 |
+
|
| 64 |
+
def current_device(self):
|
| 65 |
+
return os.environ.get('LOCAL_RANK', 0)
|
| 66 |
+
|
| 67 |
+
def current_device_name(self):
|
| 68 |
+
return 'cpu'
|
| 69 |
+
|
| 70 |
+
def device_count(self):
|
| 71 |
+
device_count = int(os.environ.get('LOCAL_SIZE', 0))
|
| 72 |
+
if device_count > 0:
|
| 73 |
+
return device_count
|
| 74 |
+
else:
|
| 75 |
+
from deepspeed.utils.numa import get_numa_cores
|
| 76 |
+
# Count NUMA node for number of cpu accelerators. On machine with HBM
|
| 77 |
+
# In flat mode, HBM is in separate NUMA node with no cores on this node.
|
| 78 |
+
# Ignore these NUMA nodes with no cores.
|
| 79 |
+
numa_core_lists = get_numa_cores()
|
| 80 |
+
if not numa_core_lists:
|
| 81 |
+
return 1
|
| 82 |
+
numa_count = 0
|
| 83 |
+
prev_core_list = []
|
| 84 |
+
for core_list in numa_core_lists:
|
| 85 |
+
if len(core_list) > 0 and core_list != prev_core_list:
|
| 86 |
+
numa_count += 1
|
| 87 |
+
prev_core_list = core_list
|
| 88 |
+
return numa_count
|
| 89 |
+
|
| 90 |
+
def synchronize(self, device_index=None):
|
| 91 |
+
return
|
| 92 |
+
|
| 93 |
+
# RNG APIs
|
| 94 |
+
def random(self):
|
| 95 |
+
return torch.random
|
| 96 |
+
|
| 97 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 98 |
+
if device_index is None:
|
| 99 |
+
return torch.set_rng_state(new_state)
|
| 100 |
+
return torch.set_rng_state(new_state, device_index)
|
| 101 |
+
|
| 102 |
+
def get_rng_state(self, device_index=None):
|
| 103 |
+
return torch.get_rng_state()
|
| 104 |
+
|
| 105 |
+
def manual_seed(self, seed):
|
| 106 |
+
return torch.manual_seed(seed)
|
| 107 |
+
|
| 108 |
+
def manual_seed_all(self, seed):
|
| 109 |
+
return torch.manual_seed(seed)
|
| 110 |
+
|
| 111 |
+
def initial_seed(self):
|
| 112 |
+
return torch.initial_seed()
|
| 113 |
+
|
| 114 |
+
def default_generator(self, device_index):
|
| 115 |
+
return torch.default_generator
|
| 116 |
+
|
| 117 |
+
# Streams/Events
|
| 118 |
+
@property
|
| 119 |
+
def Stream(self):
|
| 120 |
+
return None
|
| 121 |
+
|
| 122 |
+
def stream(self, stream):
|
| 123 |
+
from deepspeed.runtime.utils import noop_context
|
| 124 |
+
return noop_context()
|
| 125 |
+
|
| 126 |
+
def current_stream(self, device_index=None):
|
| 127 |
+
return None
|
| 128 |
+
|
| 129 |
+
def default_stream(self, device_index=None):
|
| 130 |
+
return None
|
| 131 |
+
|
| 132 |
+
@property
|
| 133 |
+
def Event(self):
|
| 134 |
+
return None
|
| 135 |
+
|
| 136 |
+
# Memory management
|
| 137 |
+
def empty_cache(self):
|
| 138 |
+
return
|
| 139 |
+
|
| 140 |
+
def get_rss(self):
|
| 141 |
+
import psutil
|
| 142 |
+
mem = psutil.Process().memory_info().rss
|
| 143 |
+
if mem > self.max_mem:
|
| 144 |
+
self.max_mem = mem
|
| 145 |
+
return mem
|
| 146 |
+
|
| 147 |
+
def reset_rss(self):
|
| 148 |
+
import psutil
|
| 149 |
+
mem = psutil.Process().memory_info().rss
|
| 150 |
+
self.max_mem = mem
|
| 151 |
+
return mem
|
| 152 |
+
|
| 153 |
+
def memory_allocated(self, device_index=None):
|
| 154 |
+
return self.get_rss()
|
| 155 |
+
|
| 156 |
+
def max_memory_allocated(self, device_index=None):
|
| 157 |
+
self.get_rss()
|
| 158 |
+
return self.max_mem
|
| 159 |
+
|
| 160 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 161 |
+
self.reset_rss()
|
| 162 |
+
return
|
| 163 |
+
|
| 164 |
+
def memory_cached(self, device_index=None):
|
| 165 |
+
return self.get_rss()
|
| 166 |
+
|
| 167 |
+
def max_memory_cached(self, device_index=None):
|
| 168 |
+
self.get_rss()
|
| 169 |
+
return self.max_mem
|
| 170 |
+
|
| 171 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 172 |
+
self.reset_rss()
|
| 173 |
+
return
|
| 174 |
+
|
| 175 |
+
def memory_stats(self, device_index=None):
|
| 176 |
+
mem = self.get_rss()
|
| 177 |
+
mem_stat = {}
|
| 178 |
+
mem_stat['allocated_bytes.all.current'] = mem
|
| 179 |
+
mem_stat['allocated_bytes.all.peak'] = self.max_mem
|
| 180 |
+
return mem_stat
|
| 181 |
+
|
| 182 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 183 |
+
self.reset_rss()
|
| 184 |
+
return
|
| 185 |
+
|
| 186 |
+
def memory_reserved(self, device_index=None):
|
| 187 |
+
return self.get_rss()
|
| 188 |
+
|
| 189 |
+
def max_memory_reserved(self, device_index=None):
|
| 190 |
+
self.get_rss()
|
| 191 |
+
return self.max_mem
|
| 192 |
+
|
| 193 |
+
def total_memory(self, device_index=None):
|
| 194 |
+
import psutil
|
| 195 |
+
return psutil.virtual_memory().total
|
| 196 |
+
|
| 197 |
+
def available_memory(self, device_index=None):
|
| 198 |
+
import psutil
|
| 199 |
+
return psutil.virtual_memory().available
|
| 200 |
+
|
| 201 |
+
# Misc
|
| 202 |
+
def amp(self):
|
| 203 |
+
return torch.cpu.amp
|
| 204 |
+
|
| 205 |
+
def is_available(self):
|
| 206 |
+
return True
|
| 207 |
+
|
| 208 |
+
def range_push(self, msg):
|
| 209 |
+
# TODO itt is currently not supported yet
|
| 210 |
+
# return torch.profiler.itt.range_push(msg)
|
| 211 |
+
return
|
| 212 |
+
|
| 213 |
+
def range_pop(self):
|
| 214 |
+
# TODO itt is currently not supported yet
|
| 215 |
+
# return torch.profiler.itt.range_pop()
|
| 216 |
+
return
|
| 217 |
+
|
| 218 |
+
def lazy_call(self, callback):
|
| 219 |
+
return callback()
|
| 220 |
+
|
| 221 |
+
def communication_backend_name(self):
|
| 222 |
+
return self._communication_backend_name
|
| 223 |
+
|
| 224 |
+
def is_triton_supported(self):
|
| 225 |
+
return False
|
| 226 |
+
|
| 227 |
+
# Data types
|
| 228 |
+
def is_bf16_supported(self):
|
| 229 |
+
return True
|
| 230 |
+
|
| 231 |
+
def is_fp16_supported(self):
|
| 232 |
+
try:
|
| 233 |
+
if torch.ops.mkldnn._is_mkldnn_fp16_supported():
|
| 234 |
+
return True
|
| 235 |
+
except:
|
| 236 |
+
return False
|
| 237 |
+
|
| 238 |
+
def supported_dtypes(self):
|
| 239 |
+
supported_dtypes = [torch.float, torch.bfloat16]
|
| 240 |
+
if self.is_fp16_supported():
|
| 241 |
+
supported_dtypes.append(torch.float16)
|
| 242 |
+
return supported_dtypes
|
| 243 |
+
|
| 244 |
+
# Graph operations
|
| 245 |
+
def create_graph(self):
|
| 246 |
+
return None
|
| 247 |
+
|
| 248 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 249 |
+
from deepspeed.runtime.utils import noop_context
|
| 250 |
+
return noop_context()
|
| 251 |
+
|
| 252 |
+
def replay_graph(self, graph):
|
| 253 |
+
return
|
| 254 |
+
|
| 255 |
+
# Tensor operations
|
| 256 |
+
@property
|
| 257 |
+
def BFloat16Tensor(self):
|
| 258 |
+
return torch.BFloat16Tensor
|
| 259 |
+
|
| 260 |
+
@property
|
| 261 |
+
def ByteTensor(self):
|
| 262 |
+
return torch.ByteTensor
|
| 263 |
+
|
| 264 |
+
@property
|
| 265 |
+
def DoubleTensor(self):
|
| 266 |
+
return torch.DoubleTensor
|
| 267 |
+
|
| 268 |
+
@property
|
| 269 |
+
def FloatTensor(self):
|
| 270 |
+
return torch.FloatTensor
|
| 271 |
+
|
| 272 |
+
@property
|
| 273 |
+
def HalfTensor(self):
|
| 274 |
+
return torch.HalfTensor
|
| 275 |
+
|
| 276 |
+
@property
|
| 277 |
+
def IntTensor(self):
|
| 278 |
+
return torch.IntTensor
|
| 279 |
+
|
| 280 |
+
@property
|
| 281 |
+
def LongTensor(self):
|
| 282 |
+
return torch.LongTensor
|
| 283 |
+
|
| 284 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 285 |
+
return tensor
|
| 286 |
+
|
| 287 |
+
def is_pinned(self, tensor):
|
| 288 |
+
return tensor.is_pinned()
|
| 289 |
+
|
| 290 |
+
def op_builder_dir(self):
|
| 291 |
+
try:
|
| 292 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 293 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 294 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 295 |
+
return "op_builder.cpu"
|
| 296 |
+
except ImportError:
|
| 297 |
+
return "deepspeed.ops.op_builder.cpu"
|
| 298 |
+
|
| 299 |
+
def on_accelerator(self, tensor):
|
| 300 |
+
device_str = str(tensor.device)
|
| 301 |
+
if device_str.startswith('cpu'):
|
| 302 |
+
return True
|
| 303 |
+
else:
|
| 304 |
+
return False
|
| 305 |
+
|
| 306 |
+
# create an instance of op builder and return, name specified by class_name
|
| 307 |
+
def create_op_builder(self, op_name):
|
| 308 |
+
builder_class = self.get_op_builder(op_name)
|
| 309 |
+
if builder_class is not None:
|
| 310 |
+
return builder_class()
|
| 311 |
+
return None
|
| 312 |
+
|
| 313 |
+
# return an op builder class, name specified by class_name
|
| 314 |
+
def get_op_builder(self, class_name):
|
| 315 |
+
try:
|
| 316 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 317 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 318 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 319 |
+
from op_builder.cpu import AsyncIOBuilder, CCLCommBuilder, ShareMemCommBuilder, FusedAdamBuilder, CPUAdamBuilder, NotImplementedBuilder
|
| 320 |
+
except ImportError:
|
| 321 |
+
from deepspeed.ops.op_builder.cpu import AsyncIOBuilder, CCLCommBuilder, ShareMemCommBuilder, FusedAdamBuilder, CPUAdamBuilder, NotImplementedBuilder
|
| 322 |
+
|
| 323 |
+
if class_name == "CCLCommBuilder":
|
| 324 |
+
return CCLCommBuilder
|
| 325 |
+
elif class_name == "ShareMemCommBuilder":
|
| 326 |
+
return ShareMemCommBuilder
|
| 327 |
+
elif class_name == "FusedAdamBuilder":
|
| 328 |
+
return FusedAdamBuilder
|
| 329 |
+
elif class_name == "CPUAdamBuilder":
|
| 330 |
+
return CPUAdamBuilder
|
| 331 |
+
elif class_name == "AsyncIOBuilder":
|
| 332 |
+
return AsyncIOBuilder
|
| 333 |
+
else:
|
| 334 |
+
# return a NotImplementedBuilder to avoid get NoneType[Name] in unit tests
|
| 335 |
+
return NotImplementedBuilder
|
| 336 |
+
|
| 337 |
+
def build_extension(self):
|
| 338 |
+
from torch.utils.cpp_extension import BuildExtension
|
| 339 |
+
return BuildExtension
|
| 340 |
+
|
| 341 |
+
def export_envs(self):
|
| 342 |
+
return []
|
| 343 |
+
|
| 344 |
+
# TODO: cpu's visible envs is confirmed, keep as CUDA_VISIBLE_DEVICES
|
| 345 |
+
def visible_devices_envs(self):
|
| 346 |
+
return ['CUDA_VISIBLE_DEVICES']
|
| 347 |
+
|
| 348 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 349 |
+
for env in self.visible_devices_envs():
|
| 350 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 351 |
+
|
| 352 |
+
def get_compile_backend(self):
|
| 353 |
+
return self._compile_backend
|
| 354 |
+
|
| 355 |
+
def set_compile_backend(self, backend):
|
| 356 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 357 |
+
if backend in supported_backends:
|
| 358 |
+
self._compile_backend = backend
|
| 359 |
+
else:
|
| 360 |
+
raise ValueError(
|
| 361 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends}")
|
lib/python3.12/site-packages/deepspeed/accelerator/cuda_accelerator.py
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import functools
|
| 7 |
+
import os
|
| 8 |
+
import pkgutil
|
| 9 |
+
import importlib
|
| 10 |
+
import sys
|
| 11 |
+
|
| 12 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 13 |
+
# During setup stage torch may not be installed, pass on no torch will
|
| 14 |
+
# allow op builder related API to be executed.
|
| 15 |
+
try:
|
| 16 |
+
import torch.cuda
|
| 17 |
+
except ImportError:
|
| 18 |
+
pass
|
| 19 |
+
|
| 20 |
+
# Delay import pynvml to avoid import error when CUDA is not available
|
| 21 |
+
pynvml = None
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class CUDA_Accelerator(DeepSpeedAccelerator):
|
| 25 |
+
|
| 26 |
+
def __init__(self):
|
| 27 |
+
self._name = 'cuda'
|
| 28 |
+
self._communication_backend_name = 'nccl' if sys.platform != 'win32' else 'gloo'
|
| 29 |
+
self._compile_backend = "inductor"
|
| 30 |
+
if pynvml is None:
|
| 31 |
+
self._init_pynvml()
|
| 32 |
+
|
| 33 |
+
def _init_pynvml(self):
|
| 34 |
+
global pynvml
|
| 35 |
+
try:
|
| 36 |
+
import pynvml
|
| 37 |
+
except ImportError:
|
| 38 |
+
return
|
| 39 |
+
try:
|
| 40 |
+
pynvml.nvmlInit()
|
| 41 |
+
except pynvml.NVMLError:
|
| 42 |
+
pynvml = None
|
| 43 |
+
return
|
| 44 |
+
|
| 45 |
+
def is_synchronized_device(self):
|
| 46 |
+
return False
|
| 47 |
+
|
| 48 |
+
def use_host_timers(self):
|
| 49 |
+
return self.is_synchronized_device()
|
| 50 |
+
|
| 51 |
+
def resolves_data_dependency(self):
|
| 52 |
+
return self.is_synchronized_device()
|
| 53 |
+
|
| 54 |
+
def handles_memory_backpressure(self):
|
| 55 |
+
return self.is_synchronized_device()
|
| 56 |
+
|
| 57 |
+
# Device APIs
|
| 58 |
+
def device_name(self, device_index=None):
|
| 59 |
+
if device_index is None:
|
| 60 |
+
return 'cuda'
|
| 61 |
+
return 'cuda:{}'.format(device_index)
|
| 62 |
+
|
| 63 |
+
def device(self, device_index=None):
|
| 64 |
+
return torch.cuda.device(device_index)
|
| 65 |
+
|
| 66 |
+
def set_device(self, device_index):
|
| 67 |
+
torch.cuda.set_device(device_index)
|
| 68 |
+
|
| 69 |
+
def current_device(self):
|
| 70 |
+
return torch.cuda.current_device()
|
| 71 |
+
|
| 72 |
+
def current_device_name(self):
|
| 73 |
+
return 'cuda:{}'.format(torch.cuda.current_device())
|
| 74 |
+
|
| 75 |
+
def device_count(self):
|
| 76 |
+
return torch.cuda.device_count()
|
| 77 |
+
|
| 78 |
+
def synchronize(self, device_index=None):
|
| 79 |
+
return torch.cuda.synchronize(device_index)
|
| 80 |
+
|
| 81 |
+
# RNG APIs
|
| 82 |
+
def random(self):
|
| 83 |
+
return torch.random
|
| 84 |
+
|
| 85 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 86 |
+
if device_index is None:
|
| 87 |
+
return torch.cuda.set_rng_state(new_state)
|
| 88 |
+
|
| 89 |
+
return torch.cuda.set_rng_state(new_state, device_index)
|
| 90 |
+
|
| 91 |
+
def get_rng_state(self, device_index=None):
|
| 92 |
+
if device_index is None:
|
| 93 |
+
return torch.cuda.get_rng_state()
|
| 94 |
+
|
| 95 |
+
return torch.cuda.get_rng_state(device_index)
|
| 96 |
+
|
| 97 |
+
def manual_seed(self, seed):
|
| 98 |
+
return torch.cuda.manual_seed(seed)
|
| 99 |
+
|
| 100 |
+
def manual_seed_all(self, seed):
|
| 101 |
+
return torch.cuda.manual_seed_all(seed)
|
| 102 |
+
|
| 103 |
+
def initial_seed(self):
|
| 104 |
+
return torch.cuda.initial_seed()
|
| 105 |
+
|
| 106 |
+
def default_generator(self, device_index):
|
| 107 |
+
return torch.cuda.default_generators[device_index]
|
| 108 |
+
|
| 109 |
+
# Streams/Events
|
| 110 |
+
@property
|
| 111 |
+
def Stream(self):
|
| 112 |
+
return torch.cuda.Stream
|
| 113 |
+
|
| 114 |
+
def stream(self, stream):
|
| 115 |
+
return torch.cuda.stream(stream)
|
| 116 |
+
|
| 117 |
+
def current_stream(self, device_index=None):
|
| 118 |
+
return torch.cuda.current_stream(device_index)
|
| 119 |
+
|
| 120 |
+
def default_stream(self, device_index=None):
|
| 121 |
+
return torch.cuda.default_stream(device_index)
|
| 122 |
+
|
| 123 |
+
@property
|
| 124 |
+
def Event(self):
|
| 125 |
+
return torch.cuda.Event
|
| 126 |
+
|
| 127 |
+
# Memory management
|
| 128 |
+
def empty_cache(self):
|
| 129 |
+
return torch.cuda.empty_cache()
|
| 130 |
+
|
| 131 |
+
def memory_allocated(self, device_index=None):
|
| 132 |
+
return torch.cuda.memory_allocated(device_index)
|
| 133 |
+
|
| 134 |
+
def max_memory_allocated(self, device_index=None):
|
| 135 |
+
return torch.cuda.max_memory_allocated(device_index)
|
| 136 |
+
|
| 137 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 138 |
+
return torch.cuda.reset_max_memory_allocated(device_index)
|
| 139 |
+
|
| 140 |
+
def memory_cached(self, device_index=None):
|
| 141 |
+
return torch.cuda.memory_cached(device_index)
|
| 142 |
+
|
| 143 |
+
def max_memory_cached(self, device_index=None):
|
| 144 |
+
return torch.cuda.max_memory_cached(device_index)
|
| 145 |
+
|
| 146 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 147 |
+
return torch.cuda.reset_max_memory_cached(device_index)
|
| 148 |
+
|
| 149 |
+
def memory_stats(self, device_index=None):
|
| 150 |
+
if hasattr(torch.cuda, 'memory_stats'):
|
| 151 |
+
return torch.cuda.memory_stats(device_index)
|
| 152 |
+
|
| 153 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 154 |
+
if hasattr(torch.cuda, 'reset_peak_memory_stats'):
|
| 155 |
+
return torch.cuda.reset_peak_memory_stats(device_index)
|
| 156 |
+
|
| 157 |
+
def memory_reserved(self, device_index=None):
|
| 158 |
+
if hasattr(torch.cuda, 'memory_reserved'):
|
| 159 |
+
return torch.cuda.memory_reserved(device_index)
|
| 160 |
+
|
| 161 |
+
def max_memory_reserved(self, device_index=None):
|
| 162 |
+
if hasattr(torch.cuda, 'max_memory_reserved'):
|
| 163 |
+
return torch.cuda.max_memory_reserved(device_index)
|
| 164 |
+
|
| 165 |
+
def total_memory(self, device_index=None):
|
| 166 |
+
return torch.cuda.get_device_properties(device_index).total_memory
|
| 167 |
+
|
| 168 |
+
def _get_nvml_gpu_id(self, torch_gpu_id):
|
| 169 |
+
"""
|
| 170 |
+
credit: https://discuss.pytorch.org/t/making-pynvml-match-torch-device-ids-cuda-visible-devices/103020
|
| 171 |
+
|
| 172 |
+
Remap torch device id to nvml device id, respecting CUDA_VISIBLE_DEVICES.
|
| 173 |
+
|
| 174 |
+
If the latter isn't set return the same id
|
| 175 |
+
"""
|
| 176 |
+
# if CUDA_VISIBLE_DEVICES is used automagically remap the id since pynvml ignores this env var
|
| 177 |
+
if "CUDA_VISIBLE_DEVICES" in os.environ:
|
| 178 |
+
ids = list(map(int, os.environ.get("CUDA_VISIBLE_DEVICES", "").split(",")))
|
| 179 |
+
return ids[torch_gpu_id] # remap
|
| 180 |
+
else:
|
| 181 |
+
return torch_gpu_id
|
| 182 |
+
|
| 183 |
+
def available_memory(self, device_index=None):
|
| 184 |
+
if pynvml:
|
| 185 |
+
if device_index is None:
|
| 186 |
+
device_index = self.current_device()
|
| 187 |
+
handle = pynvml.nvmlDeviceGetHandleByIndex(self._get_nvml_gpu_id(device_index))
|
| 188 |
+
info = pynvml.nvmlDeviceGetMemoryInfo(handle)
|
| 189 |
+
return info.free
|
| 190 |
+
else:
|
| 191 |
+
return self.total_memory(device_index) - self.memory_allocated(device_index)
|
| 192 |
+
|
| 193 |
+
# Data types
|
| 194 |
+
def is_bf16_supported(self):
|
| 195 |
+
if not torch.cuda.is_available():
|
| 196 |
+
return True
|
| 197 |
+
return torch.cuda.is_bf16_supported()
|
| 198 |
+
|
| 199 |
+
def is_fp16_supported(self):
|
| 200 |
+
if not torch.cuda.is_available():
|
| 201 |
+
return True
|
| 202 |
+
# See https://docs.nvidia.com/deeplearning/tensorrt/support-matrix/index.html#hardware-precision-matrix
|
| 203 |
+
# FP16 on compute capability 6.x is deprecated
|
| 204 |
+
allow_deprecated_fp16 = os.environ.get('DS_ALLOW_DEPRECATED_FP16', '0') == '1'
|
| 205 |
+
major, _ = torch.cuda.get_device_capability()
|
| 206 |
+
if major >= 7:
|
| 207 |
+
return True
|
| 208 |
+
elif major == 6 and allow_deprecated_fp16:
|
| 209 |
+
return True
|
| 210 |
+
else:
|
| 211 |
+
return False
|
| 212 |
+
|
| 213 |
+
def supported_dtypes(self):
|
| 214 |
+
supported_dtypes = [torch.float]
|
| 215 |
+
if self.is_fp16_supported():
|
| 216 |
+
supported_dtypes.append(torch.half)
|
| 217 |
+
if self.is_bf16_supported():
|
| 218 |
+
supported_dtypes.append(torch.bfloat16)
|
| 219 |
+
return supported_dtypes
|
| 220 |
+
|
| 221 |
+
# Misc
|
| 222 |
+
def amp(self):
|
| 223 |
+
if hasattr(torch.cuda, 'amp'):
|
| 224 |
+
return torch.cuda.amp
|
| 225 |
+
return None
|
| 226 |
+
|
| 227 |
+
def is_available(self):
|
| 228 |
+
return torch.cuda.is_available()
|
| 229 |
+
|
| 230 |
+
def range_push(self, msg):
|
| 231 |
+
if hasattr(torch.cuda.nvtx, 'range_push'):
|
| 232 |
+
return torch.cuda.nvtx.range_push(msg)
|
| 233 |
+
|
| 234 |
+
def range_pop(self):
|
| 235 |
+
if hasattr(torch.cuda.nvtx, 'range_pop'):
|
| 236 |
+
return torch.cuda.nvtx.range_pop()
|
| 237 |
+
|
| 238 |
+
def lazy_call(self, callback):
|
| 239 |
+
return torch.cuda._lazy_call(callback)
|
| 240 |
+
|
| 241 |
+
def communication_backend_name(self):
|
| 242 |
+
return self._communication_backend_name
|
| 243 |
+
|
| 244 |
+
def is_triton_supported(self):
|
| 245 |
+
major, _ = torch.cuda.get_device_capability()
|
| 246 |
+
if major >= 8:
|
| 247 |
+
return True
|
| 248 |
+
else:
|
| 249 |
+
return False
|
| 250 |
+
|
| 251 |
+
# Graph operations
|
| 252 |
+
def create_graph(self):
|
| 253 |
+
return torch.cuda.CUDAGraph()
|
| 254 |
+
|
| 255 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 256 |
+
return torch.cuda.graph(graph, pool, stream)
|
| 257 |
+
|
| 258 |
+
def replay_graph(self, graph):
|
| 259 |
+
graph.replay()
|
| 260 |
+
return
|
| 261 |
+
|
| 262 |
+
# Tensor operations
|
| 263 |
+
|
| 264 |
+
@property
|
| 265 |
+
def BFloat16Tensor(self):
|
| 266 |
+
return functools.partial(torch.tensor, dtype=torch.bfloat16, device='cuda')
|
| 267 |
+
|
| 268 |
+
@property
|
| 269 |
+
def ByteTensor(self):
|
| 270 |
+
return functools.partial(torch.tensor, dtype=torch.uint8, device='cuda')
|
| 271 |
+
|
| 272 |
+
@property
|
| 273 |
+
def DoubleTensor(self):
|
| 274 |
+
return functools.partial(torch.tensor, dtype=torch.double, device='cuda')
|
| 275 |
+
|
| 276 |
+
@property
|
| 277 |
+
def FloatTensor(self):
|
| 278 |
+
return functools.partial(torch.tensor, dtype=torch.float, device='cuda')
|
| 279 |
+
|
| 280 |
+
@property
|
| 281 |
+
def HalfTensor(self):
|
| 282 |
+
return functools.partial(torch.tensor, dtype=torch.half, device='cuda')
|
| 283 |
+
|
| 284 |
+
@property
|
| 285 |
+
def IntTensor(self):
|
| 286 |
+
return functools.partial(torch.tensor, dtype=torch.int, device='cuda')
|
| 287 |
+
|
| 288 |
+
@property
|
| 289 |
+
def LongTensor(self):
|
| 290 |
+
return functools.partial(torch.tensor, dtype=torch.long, device='cuda')
|
| 291 |
+
|
| 292 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 293 |
+
return tensor.pin_memory()
|
| 294 |
+
|
| 295 |
+
def is_pinned(self, tensor):
|
| 296 |
+
return tensor.is_pinned()
|
| 297 |
+
|
| 298 |
+
def on_accelerator(self, tensor):
|
| 299 |
+
device_str = str(tensor.device)
|
| 300 |
+
if device_str.startswith('cuda:'):
|
| 301 |
+
return True
|
| 302 |
+
else:
|
| 303 |
+
return False
|
| 304 |
+
|
| 305 |
+
def op_builder_dir(self):
|
| 306 |
+
try:
|
| 307 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 308 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 309 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 310 |
+
return "op_builder"
|
| 311 |
+
except ImportError:
|
| 312 |
+
return "deepspeed.ops.op_builder"
|
| 313 |
+
|
| 314 |
+
# dict that holds class name <--> class type mapping i.e.
|
| 315 |
+
# 'AsyncIOBuilder': <class 'op_builder.async_io.AsyncIOBuilder'>
|
| 316 |
+
# this dict will be filled at init stage
|
| 317 |
+
class_dict = None
|
| 318 |
+
|
| 319 |
+
def _lazy_init_class_dict(self):
|
| 320 |
+
if self.class_dict is not None:
|
| 321 |
+
return
|
| 322 |
+
else:
|
| 323 |
+
self.class_dict = {}
|
| 324 |
+
# begin initialize for create_op_builder()
|
| 325 |
+
# put all valid class name <--> class type mapping into class_dict
|
| 326 |
+
op_builder_dir = self.op_builder_dir()
|
| 327 |
+
op_builder_module = importlib.import_module(op_builder_dir)
|
| 328 |
+
op_builder_absolute_path = os.path.dirname(op_builder_module.__file__)
|
| 329 |
+
for _, module_name, _ in pkgutil.iter_modules([op_builder_absolute_path]):
|
| 330 |
+
# avoid self references,
|
| 331 |
+
# skip sub_directories which contains ops for other backend(cpu, npu, etc.).
|
| 332 |
+
if module_name != 'all_ops' and module_name != 'builder' and not os.path.isdir(
|
| 333 |
+
os.path.join(op_builder_absolute_path, module_name)):
|
| 334 |
+
module = importlib.import_module("{}.{}".format(op_builder_dir, module_name))
|
| 335 |
+
for member_name in module.__dir__():
|
| 336 |
+
if member_name.endswith(
|
| 337 |
+
'Builder'
|
| 338 |
+
) and member_name != "OpBuilder" and member_name != "CUDAOpBuilder" and member_name != "TorchCPUOpBuilder": # avoid abstract classes
|
| 339 |
+
if not member_name in self.class_dict:
|
| 340 |
+
self.class_dict[member_name] = getattr(module, member_name)
|
| 341 |
+
# end initialize for create_op_builder()
|
| 342 |
+
|
| 343 |
+
# create an instance of op builder and return, name specified by class_name
|
| 344 |
+
def create_op_builder(self, class_name):
|
| 345 |
+
self._lazy_init_class_dict()
|
| 346 |
+
if class_name in self.class_dict:
|
| 347 |
+
return self.class_dict[class_name]()
|
| 348 |
+
else:
|
| 349 |
+
return None
|
| 350 |
+
|
| 351 |
+
# return an op builder class, name specified by class_name
|
| 352 |
+
def get_op_builder(self, class_name):
|
| 353 |
+
self._lazy_init_class_dict()
|
| 354 |
+
if class_name in self.class_dict:
|
| 355 |
+
return self.class_dict[class_name]
|
| 356 |
+
else:
|
| 357 |
+
return None
|
| 358 |
+
|
| 359 |
+
def build_extension(self):
|
| 360 |
+
from torch.utils.cpp_extension import BuildExtension
|
| 361 |
+
return BuildExtension
|
| 362 |
+
|
| 363 |
+
def export_envs(self):
|
| 364 |
+
return ['NCCL']
|
| 365 |
+
|
| 366 |
+
def visible_devices_envs(self):
|
| 367 |
+
return ['CUDA_VISIBLE_DEVICES']
|
| 368 |
+
|
| 369 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 370 |
+
for env in self.visible_devices_envs():
|
| 371 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 372 |
+
|
| 373 |
+
def get_compile_backend(self):
|
| 374 |
+
return self._compile_backend
|
| 375 |
+
|
| 376 |
+
def set_compile_backend(self, backend):
|
| 377 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 378 |
+
if backend in supported_backends:
|
| 379 |
+
self._compile_backend = backend
|
| 380 |
+
else:
|
| 381 |
+
raise ValueError(
|
| 382 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends}")
|
lib/python3.12/site-packages/deepspeed/accelerator/hpu_accelerator.py
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import functools
|
| 7 |
+
import os
|
| 8 |
+
import pkgutil
|
| 9 |
+
import importlib
|
| 10 |
+
import torch
|
| 11 |
+
|
| 12 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class HPU_Accelerator(DeepSpeedAccelerator):
|
| 16 |
+
|
| 17 |
+
def __init__(self):
|
| 18 |
+
self._name = 'hpu'
|
| 19 |
+
self._communication_backend_name = 'hccl'
|
| 20 |
+
self._compile_backend = "hpu_backend"
|
| 21 |
+
self.apply_hpu_workarounds()
|
| 22 |
+
try:
|
| 23 |
+
import habana_frameworks.torch.hpu as hpu
|
| 24 |
+
self.hpu = hpu
|
| 25 |
+
torch.use_deterministic_algorithms(True)
|
| 26 |
+
# TODO: remove this WA when memory mapping break is resolved.
|
| 27 |
+
torch.utils.deterministic.fill_uninitialized_memory = False
|
| 28 |
+
except ImportError as e:
|
| 29 |
+
raise ValueError(
|
| 30 |
+
f"HPU_Accelerator requires habana_frameworks.torch.hpu, which is not installed on this system.")
|
| 31 |
+
|
| 32 |
+
self.fp16_supported = None
|
| 33 |
+
|
| 34 |
+
def apply_hpu_workarounds(self):
|
| 35 |
+
|
| 36 |
+
def update_wa_env_var(key, value):
|
| 37 |
+
if key not in os.environ.keys():
|
| 38 |
+
os.environ[key] = value
|
| 39 |
+
|
| 40 |
+
update_wa_env_var("PT_HPU_LAZY_ACC_PAR_MODE", "0")
|
| 41 |
+
update_wa_env_var("PT_HPU_ENABLE_REFINE_DYNAMIC_SHAPES", "0")
|
| 42 |
+
|
| 43 |
+
# Device APIs
|
| 44 |
+
def is_synchronized_device(self):
|
| 45 |
+
return False
|
| 46 |
+
|
| 47 |
+
def use_host_timers(self):
|
| 48 |
+
return False
|
| 49 |
+
|
| 50 |
+
def resolves_data_dependency(self):
|
| 51 |
+
return True
|
| 52 |
+
|
| 53 |
+
def handles_memory_backpressure(self):
|
| 54 |
+
return True
|
| 55 |
+
|
| 56 |
+
def device_name(self, device_index=None):
|
| 57 |
+
# ignoring device_index.
|
| 58 |
+
return 'hpu'
|
| 59 |
+
|
| 60 |
+
def device(self, device_index=None):
|
| 61 |
+
return torch.device(self.device_name(device_index))
|
| 62 |
+
|
| 63 |
+
def set_device(self, device_index):
|
| 64 |
+
self.hpu.set_device(device_index)
|
| 65 |
+
|
| 66 |
+
def current_device(self):
|
| 67 |
+
return (self.hpu.current_device())
|
| 68 |
+
|
| 69 |
+
def current_device_name(self):
|
| 70 |
+
return 'hpu:{}'.format(self.current_device())
|
| 71 |
+
|
| 72 |
+
def device_count(self):
|
| 73 |
+
return self.hpu.device_count()
|
| 74 |
+
|
| 75 |
+
def synchronize(self, device_index=None):
|
| 76 |
+
return self.hpu.synchronize()
|
| 77 |
+
|
| 78 |
+
# RNG APIs
|
| 79 |
+
def random(self):
|
| 80 |
+
return torch.random
|
| 81 |
+
|
| 82 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 83 |
+
self.hpu.random.set_rng_state(new_state)
|
| 84 |
+
|
| 85 |
+
def get_rng_state(self, device_index=None):
|
| 86 |
+
return self.hpu.random.get_rng_state()
|
| 87 |
+
|
| 88 |
+
def manual_seed(self, seed):
|
| 89 |
+
return self.hpu.random.manual_seed(seed)
|
| 90 |
+
|
| 91 |
+
def manual_seed_all(self, seed):
|
| 92 |
+
self.hpu.random.manual_seed_all(seed)
|
| 93 |
+
|
| 94 |
+
def initial_seed(self):
|
| 95 |
+
return self.hpu.random.initial_seed()
|
| 96 |
+
|
| 97 |
+
def default_generator(self, device_index):
|
| 98 |
+
return self.hpu.random.default_generators[device_index]
|
| 99 |
+
|
| 100 |
+
# Streams/Events
|
| 101 |
+
@property
|
| 102 |
+
def Stream(self):
|
| 103 |
+
return self.hpu.Stream
|
| 104 |
+
|
| 105 |
+
def stream(self, stream):
|
| 106 |
+
return self.hpu.stream(stream)
|
| 107 |
+
|
| 108 |
+
def current_stream(self, device_index=None):
|
| 109 |
+
return self.hpu.current_stream()
|
| 110 |
+
|
| 111 |
+
def default_stream(self, device_index=None):
|
| 112 |
+
return self.hpu.default_stream()
|
| 113 |
+
|
| 114 |
+
@property
|
| 115 |
+
def Event(self):
|
| 116 |
+
import habana_frameworks.torch.core as htcore
|
| 117 |
+
return htcore.hpu.Event
|
| 118 |
+
|
| 119 |
+
# Memory management
|
| 120 |
+
def empty_cache(self):
|
| 121 |
+
return
|
| 122 |
+
|
| 123 |
+
def memory_allocated(self, device_index=None):
|
| 124 |
+
return self.hpu.memory_allocated()
|
| 125 |
+
|
| 126 |
+
def max_memory_allocated(self, device_index=None):
|
| 127 |
+
return self.hpu.max_memory_allocated()
|
| 128 |
+
|
| 129 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 130 |
+
return self.hpu.reset_max_memory_allocated()
|
| 131 |
+
|
| 132 |
+
def memory_cached(self, device_index=None):
|
| 133 |
+
return self.hpu.memory_cached(device_index)
|
| 134 |
+
|
| 135 |
+
def max_memory_cached(self, device_index=None):
|
| 136 |
+
return self.hpu.max_memory_cached(device_index)
|
| 137 |
+
|
| 138 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 139 |
+
return None
|
| 140 |
+
|
| 141 |
+
def memory_stats(self, device_index=None):
|
| 142 |
+
return self.hpu.memory_stats(device_index)
|
| 143 |
+
|
| 144 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 145 |
+
self.hpu.reset_peak_memory_stats(device_index)
|
| 146 |
+
|
| 147 |
+
def memory_reserved(self, device_index=None):
|
| 148 |
+
return self.hpu.memory_reserved(device_index)
|
| 149 |
+
|
| 150 |
+
def max_memory_reserved(self, device_index=None):
|
| 151 |
+
return self.hpu.max_memory_reserved(device_index)
|
| 152 |
+
|
| 153 |
+
def total_memory(self, device_index=None):
|
| 154 |
+
return self.memory_stats(device_index)['Limit']
|
| 155 |
+
|
| 156 |
+
def available_memory(self, device_index=None):
|
| 157 |
+
return self.total_memory(device_index) - self.memory_allocated(device_index)
|
| 158 |
+
|
| 159 |
+
# Data types
|
| 160 |
+
def is_bf16_supported(self):
|
| 161 |
+
return True
|
| 162 |
+
|
| 163 |
+
def is_fp16_supported(self):
|
| 164 |
+
if self.fp16_supported is None:
|
| 165 |
+
import habana_frameworks.torch.utils.experimental as htexp
|
| 166 |
+
self.fp16_supported = htexp._is_fp16_supported()
|
| 167 |
+
return self.fp16_supported
|
| 168 |
+
|
| 169 |
+
def supported_dtypes(self):
|
| 170 |
+
supported_dtypes = [torch.float, torch.bfloat16]
|
| 171 |
+
if self.is_fp16_supported():
|
| 172 |
+
supported_dtypes.append(torch.half)
|
| 173 |
+
return supported_dtypes
|
| 174 |
+
|
| 175 |
+
# Misc
|
| 176 |
+
def amp(self):
|
| 177 |
+
return None
|
| 178 |
+
|
| 179 |
+
def is_available(self):
|
| 180 |
+
return self.hpu.is_available()
|
| 181 |
+
|
| 182 |
+
def range_push(self, msg):
|
| 183 |
+
return
|
| 184 |
+
|
| 185 |
+
def range_pop(self):
|
| 186 |
+
return
|
| 187 |
+
|
| 188 |
+
def lazy_call(self, callback):
|
| 189 |
+
callback()
|
| 190 |
+
|
| 191 |
+
def communication_backend_name(self):
|
| 192 |
+
return self._communication_backend_name
|
| 193 |
+
|
| 194 |
+
def is_triton_supported(self):
|
| 195 |
+
return False
|
| 196 |
+
|
| 197 |
+
# Graph operations
|
| 198 |
+
def create_graph(self):
|
| 199 |
+
return self.hpu.HPUGraph()
|
| 200 |
+
|
| 201 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 202 |
+
return self.hpu.graph(graph, stream=stream)
|
| 203 |
+
|
| 204 |
+
def replay_graph(self, graph):
|
| 205 |
+
graph.replay()
|
| 206 |
+
return
|
| 207 |
+
|
| 208 |
+
# Tensor operations
|
| 209 |
+
@property
|
| 210 |
+
def BFloat16Tensor(self):
|
| 211 |
+
return functools.partial(torch.tensor, dtype=torch.bfloat16, device='hpu')
|
| 212 |
+
|
| 213 |
+
@property
|
| 214 |
+
def ByteTensor(self):
|
| 215 |
+
return functools.partial(torch.tensor, dtype=torch.uint8, device='hpu')
|
| 216 |
+
|
| 217 |
+
@property
|
| 218 |
+
def DoubleTensor(self):
|
| 219 |
+
return functools.partial(torch.tensor, dtype=torch.double, device='hpu')
|
| 220 |
+
|
| 221 |
+
@property
|
| 222 |
+
def FloatTensor(self):
|
| 223 |
+
return functools.partial(torch.tensor, dtype=torch.float, device='hpu')
|
| 224 |
+
|
| 225 |
+
@property
|
| 226 |
+
def HalfTensor(self):
|
| 227 |
+
return functools.partial(torch.tensor, dtype=torch.half, device='hpu')
|
| 228 |
+
|
| 229 |
+
@property
|
| 230 |
+
def IntTensor(self):
|
| 231 |
+
return functools.partial(torch.tensor, dtype=torch.int, device='hpu')
|
| 232 |
+
|
| 233 |
+
@property
|
| 234 |
+
def LongTensor(self):
|
| 235 |
+
return functools.partial(torch.tensor, dtype=torch.long, device='hpu')
|
| 236 |
+
|
| 237 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 238 |
+
return tensor.pin_memory(self.device())
|
| 239 |
+
|
| 240 |
+
def is_pinned(self, tensor):
|
| 241 |
+
return tensor.is_pinned()
|
| 242 |
+
|
| 243 |
+
def on_accelerator(self, tensor):
|
| 244 |
+
device_str = str(tensor.device)
|
| 245 |
+
if device_str.startswith('hpu:'):
|
| 246 |
+
return True
|
| 247 |
+
else:
|
| 248 |
+
return False
|
| 249 |
+
|
| 250 |
+
def op_builder_dir(self):
|
| 251 |
+
try:
|
| 252 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 253 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 254 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 255 |
+
return "op_builder.hpu"
|
| 256 |
+
except ImportError:
|
| 257 |
+
return "deepspeed.ops.op_builder.hpu"
|
| 258 |
+
|
| 259 |
+
# dict that holds class name <--> class type mapping i.e.
|
| 260 |
+
# 'AsyncIOBuilder': <class 'op_builder.async_io.AsyncIOBuilder'>
|
| 261 |
+
# this dict will be filled at init stage
|
| 262 |
+
class_dict = None
|
| 263 |
+
|
| 264 |
+
def _lazy_init_class_dict(self):
|
| 265 |
+
if self.class_dict is not None:
|
| 266 |
+
return
|
| 267 |
+
else:
|
| 268 |
+
self.class_dict = {}
|
| 269 |
+
# begin initialize for create_op_builder()
|
| 270 |
+
# put all valid class name <--> class type mapping into class_dict
|
| 271 |
+
op_builder_dir = self.op_builder_dir()
|
| 272 |
+
op_builder_module = importlib.import_module(op_builder_dir)
|
| 273 |
+
op_builder_absolute_path = os.path.dirname(op_builder_module.__file__)
|
| 274 |
+
for _, module_name, _ in pkgutil.iter_modules([op_builder_absolute_path]):
|
| 275 |
+
# avoid self references,
|
| 276 |
+
# skip sub_directories which contains ops for other backend(cpu, npu, etc.).
|
| 277 |
+
if module_name != 'all_ops' and module_name != 'builder' and not os.path.isdir(
|
| 278 |
+
os.path.join(op_builder_absolute_path, module_name)):
|
| 279 |
+
module = importlib.import_module("{}.{}".format(op_builder_dir, module_name))
|
| 280 |
+
for member_name in module.__dir__():
|
| 281 |
+
if member_name.endswith(
|
| 282 |
+
'Builder'
|
| 283 |
+
) and member_name != "OpBuilder" and member_name != "CPUOpBuilder" and member_name != "TorchCPUOpBuilder": # avoid abstract classes
|
| 284 |
+
if not member_name in self.class_dict:
|
| 285 |
+
self.class_dict[member_name] = getattr(module, member_name)
|
| 286 |
+
# end initialize for create_op_builder()
|
| 287 |
+
|
| 288 |
+
# create an instance of op builder and return, name specified by class_name
|
| 289 |
+
def create_op_builder(self, class_name):
|
| 290 |
+
self._lazy_init_class_dict()
|
| 291 |
+
if class_name in self.class_dict:
|
| 292 |
+
return self.class_dict[class_name]()
|
| 293 |
+
else:
|
| 294 |
+
return None
|
| 295 |
+
|
| 296 |
+
# return an op builder class, name specified by class_name
|
| 297 |
+
def get_op_builder(self, class_name):
|
| 298 |
+
self._lazy_init_class_dict()
|
| 299 |
+
if class_name in self.class_dict:
|
| 300 |
+
return self.class_dict[class_name]
|
| 301 |
+
else:
|
| 302 |
+
return self.class_dict['NotImplementedBuilder'] if 'NotImplementedBuilder' in self.class_dict else None
|
| 303 |
+
|
| 304 |
+
def build_extension(self):
|
| 305 |
+
from torch.utils.cpp_extension import BuildExtension
|
| 306 |
+
return BuildExtension
|
| 307 |
+
|
| 308 |
+
def export_envs(self):
|
| 309 |
+
return []
|
| 310 |
+
|
| 311 |
+
def visible_devices_envs(self):
|
| 312 |
+
# Current way deepspeed set this env var is not applicable with all HPU instances
|
| 313 |
+
# User has to follow instructions in:
|
| 314 |
+
# https://docs.habana.ai/en/latest/PyTorch/Reference/PT_Multiple_Tenants_on_HPU/Multiple_Workloads_Single_Docker.html
|
| 315 |
+
# keeping CUDA_VISIBLE_DEVICES
|
| 316 |
+
return ['CUDA_VISIBLE_DEVICES'] #['HABANA_VISIBLE_MODULES']
|
| 317 |
+
|
| 318 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 319 |
+
for env in self.visible_devices_envs():
|
| 320 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 321 |
+
|
| 322 |
+
def get_compile_backend(self):
|
| 323 |
+
return self._compile_backend
|
| 324 |
+
|
| 325 |
+
def set_compile_backend(self, backend):
|
| 326 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 327 |
+
if backend in supported_backends:
|
| 328 |
+
self._compile_backend = backend
|
| 329 |
+
else:
|
| 330 |
+
raise ValueError(
|
| 331 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends}")
|
lib/python3.12/site-packages/deepspeed/accelerator/mlu_accelerator.py
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
import importlib
|
| 6 |
+
import inspect
|
| 7 |
+
import functools
|
| 8 |
+
|
| 9 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 10 |
+
import torch
|
| 11 |
+
# During setup stage torch may not be installed, pass on no torch will
|
| 12 |
+
# allow op builder related API to be executed.
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class MLU_Accelerator(DeepSpeedAccelerator):
|
| 16 |
+
|
| 17 |
+
def __init__(self):
|
| 18 |
+
self._name = 'mlu'
|
| 19 |
+
self._communication_backend_name = 'cncl'
|
| 20 |
+
self._compile_backend = "inductor"
|
| 21 |
+
self.class_dict = None
|
| 22 |
+
|
| 23 |
+
def is_synchronized_device(self):
|
| 24 |
+
return False
|
| 25 |
+
|
| 26 |
+
def use_host_timers(self):
|
| 27 |
+
return self.is_synchronized_device()
|
| 28 |
+
|
| 29 |
+
def resolves_data_dependency(self):
|
| 30 |
+
return self.is_synchronized_device()
|
| 31 |
+
|
| 32 |
+
def handles_memory_backpressure(self):
|
| 33 |
+
return self.is_synchronized_device()
|
| 34 |
+
|
| 35 |
+
# Device APIs
|
| 36 |
+
def device_name(self, device_index=None):
|
| 37 |
+
if device_index == None:
|
| 38 |
+
return 'mlu'
|
| 39 |
+
return 'mlu:{}'.format(device_index)
|
| 40 |
+
|
| 41 |
+
def device(self, device_index=None):
|
| 42 |
+
return torch.mlu.device(device_index)
|
| 43 |
+
|
| 44 |
+
def set_device(self, device_index):
|
| 45 |
+
torch.mlu.set_device(device_index)
|
| 46 |
+
|
| 47 |
+
def current_device(self):
|
| 48 |
+
return torch.mlu.current_device()
|
| 49 |
+
|
| 50 |
+
def current_device_name(self):
|
| 51 |
+
return 'mlu:{}'.format(torch.mlu.current_device())
|
| 52 |
+
|
| 53 |
+
def device_count(self):
|
| 54 |
+
return torch.mlu.device_count()
|
| 55 |
+
|
| 56 |
+
def synchronize(self, device_index=None):
|
| 57 |
+
return torch.mlu.synchronize(device_index)
|
| 58 |
+
|
| 59 |
+
# RNG APIs
|
| 60 |
+
def random(self):
|
| 61 |
+
return torch.random
|
| 62 |
+
|
| 63 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 64 |
+
if device_index is None:
|
| 65 |
+
return torch.mlu.set_rng_state(new_state)
|
| 66 |
+
|
| 67 |
+
return torch.mlu.set_rng_state(new_state, device_index)
|
| 68 |
+
|
| 69 |
+
def get_rng_state(self, device_index=None):
|
| 70 |
+
if device_index is None:
|
| 71 |
+
return torch.mlu.get_rng_state()
|
| 72 |
+
|
| 73 |
+
return torch.mlu.get_rng_state(device_index)
|
| 74 |
+
|
| 75 |
+
def manual_seed(self, seed):
|
| 76 |
+
return torch.mlu.manual_seed(seed)
|
| 77 |
+
|
| 78 |
+
def manual_seed_all(self, seed):
|
| 79 |
+
return torch.mlu.manual_seed_all(seed)
|
| 80 |
+
|
| 81 |
+
def initial_seed(self, seed):
|
| 82 |
+
return torch.mlu.initial_seed(seed)
|
| 83 |
+
|
| 84 |
+
def default_generator(self, device_index):
|
| 85 |
+
return torch.mlu.default_generators[device_index]
|
| 86 |
+
|
| 87 |
+
# Streams/Events
|
| 88 |
+
@property
|
| 89 |
+
def Stream(self):
|
| 90 |
+
return torch.mlu.Stream
|
| 91 |
+
|
| 92 |
+
def stream(self, stream):
|
| 93 |
+
return torch.mlu.stream(stream)
|
| 94 |
+
|
| 95 |
+
def current_stream(self, device_index=None):
|
| 96 |
+
return torch.mlu.current_stream(device_index)
|
| 97 |
+
|
| 98 |
+
def default_stream(self, device_index=None):
|
| 99 |
+
return torch.mlu.default_stream(device_index)
|
| 100 |
+
|
| 101 |
+
@property
|
| 102 |
+
def Event(self):
|
| 103 |
+
return torch.mlu.Event
|
| 104 |
+
|
| 105 |
+
# Memory management
|
| 106 |
+
def empty_cache(self):
|
| 107 |
+
return torch.mlu.empty_cache()
|
| 108 |
+
|
| 109 |
+
def memory_allocated(self, device_index=None):
|
| 110 |
+
return torch.mlu.memory_allocated(device_index)
|
| 111 |
+
|
| 112 |
+
def max_memory_allocated(self, device_index=None):
|
| 113 |
+
return torch.mlu.max_memory_allocated(device_index)
|
| 114 |
+
|
| 115 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 116 |
+
return torch.mlu.reset_max_memory_allocated(device_index)
|
| 117 |
+
|
| 118 |
+
def memory_cached(self, device_index=None):
|
| 119 |
+
return torch.mlu.memory_cached(device_index)
|
| 120 |
+
|
| 121 |
+
def max_memory_cached(self, device_index=None):
|
| 122 |
+
return torch.mlu.max_memory_cached(device_index)
|
| 123 |
+
|
| 124 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 125 |
+
return torch.mlu.reset_max_memory_cached(device_index)
|
| 126 |
+
|
| 127 |
+
def memory_stats(self, device_index=None):
|
| 128 |
+
if hasattr(torch.mlu, 'memory_stats'):
|
| 129 |
+
return torch.mlu.memory_stats(device_index)
|
| 130 |
+
|
| 131 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 132 |
+
if hasattr(torch.mlu, 'reset_peak_memory_stats'):
|
| 133 |
+
return torch.mlu.reset_peak_memory_stats(device_index)
|
| 134 |
+
|
| 135 |
+
def memory_reserved(self, device_index=None):
|
| 136 |
+
if hasattr(torch.mlu, 'memory_reserved'):
|
| 137 |
+
return torch.mlu.memory_reserved(device_index)
|
| 138 |
+
|
| 139 |
+
def max_memory_reserved(self, device_index=None):
|
| 140 |
+
if hasattr(torch.mlu, 'max_memory_reserved'):
|
| 141 |
+
return torch.mlu.max_memory_reserved(device_index)
|
| 142 |
+
|
| 143 |
+
def total_memory(self, device_index=None):
|
| 144 |
+
return torch.mlu.get_device_properties(device_index).total_memory
|
| 145 |
+
|
| 146 |
+
def available_memory(self, device_index=None):
|
| 147 |
+
return self.total_memory(device_index) - self.memory_allocated(device_index)
|
| 148 |
+
|
| 149 |
+
# Data types
|
| 150 |
+
def is_bf16_supported(self):
|
| 151 |
+
return torch.mlu.is_bf16_supported()
|
| 152 |
+
|
| 153 |
+
def is_fp16_supported(self):
|
| 154 |
+
return True
|
| 155 |
+
|
| 156 |
+
def supported_dtypes(self):
|
| 157 |
+
supported_dtypes = [torch.float]
|
| 158 |
+
if self.is_fp16_supported():
|
| 159 |
+
supported_dtypes.append(torch.half)
|
| 160 |
+
if self.is_bf16_supported():
|
| 161 |
+
supported_dtypes.append(torch.bfloat16)
|
| 162 |
+
return supported_dtypes
|
| 163 |
+
|
| 164 |
+
# Misc
|
| 165 |
+
def amp(self):
|
| 166 |
+
if hasattr(torch.mlu, 'amp'):
|
| 167 |
+
return torch.mlu.amp
|
| 168 |
+
return None
|
| 169 |
+
|
| 170 |
+
def is_available(self):
|
| 171 |
+
return torch.mlu.is_available()
|
| 172 |
+
|
| 173 |
+
def range_push(self, msg):
|
| 174 |
+
if hasattr(torch.mlu.cnpx, 'range_push'):
|
| 175 |
+
return torch.mlu.cnpx.range_push(msg)
|
| 176 |
+
|
| 177 |
+
def range_pop(self):
|
| 178 |
+
if hasattr(torch.mlu.cnpx, 'range_pop'):
|
| 179 |
+
return torch.mlu.cnpx.range_pop()
|
| 180 |
+
|
| 181 |
+
def lazy_call(self, callback):
|
| 182 |
+
return torch.mlu._lazy_call(callback)
|
| 183 |
+
|
| 184 |
+
def communication_backend_name(self):
|
| 185 |
+
return self._communication_backend_name
|
| 186 |
+
|
| 187 |
+
def is_triton_supported(self):
|
| 188 |
+
return True
|
| 189 |
+
|
| 190 |
+
# Graph operations
|
| 191 |
+
def create_graph(self):
|
| 192 |
+
torch.mlu.MLUGraph()
|
| 193 |
+
|
| 194 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 195 |
+
return torch.mlu.graph(graph, pool, stream)
|
| 196 |
+
|
| 197 |
+
def replay_graph(self, graph):
|
| 198 |
+
graph.replay()
|
| 199 |
+
return
|
| 200 |
+
|
| 201 |
+
# Tensor operations
|
| 202 |
+
|
| 203 |
+
@property
|
| 204 |
+
def BFloat16Tensor(self):
|
| 205 |
+
return functools.partial(torch.tensor, dtype=torch.bfloat16, device='mlu')
|
| 206 |
+
|
| 207 |
+
@property
|
| 208 |
+
def ByteTensor(self):
|
| 209 |
+
return functools.partial(torch.tensor, dtype=torch.uint8, device='mlu')
|
| 210 |
+
|
| 211 |
+
@property
|
| 212 |
+
def DoubleTensor(self):
|
| 213 |
+
return functools.partial(torch.tensor, dtype=torch.double, device='mlu')
|
| 214 |
+
|
| 215 |
+
@property
|
| 216 |
+
def FloatTensor(self):
|
| 217 |
+
return functools.partial(torch.tensor, dtype=torch.float, device='mlu')
|
| 218 |
+
|
| 219 |
+
@property
|
| 220 |
+
def HalfTensor(self):
|
| 221 |
+
return functools.partial(torch.tensor, dtype=torch.half, device='mlu')
|
| 222 |
+
|
| 223 |
+
@property
|
| 224 |
+
def IntTensor(self):
|
| 225 |
+
return functools.partial(torch.tensor, dtype=torch.int, device='mlu')
|
| 226 |
+
|
| 227 |
+
@property
|
| 228 |
+
def LongTensor(self):
|
| 229 |
+
return functools.partial(torch.tensor, dtype=torch.long, device='mlu')
|
| 230 |
+
|
| 231 |
+
def pin_memory(self, tensor):
|
| 232 |
+
return tensor.pin_memory()
|
| 233 |
+
|
| 234 |
+
def is_pinned(self, tensor):
|
| 235 |
+
return tensor.is_pinned()
|
| 236 |
+
|
| 237 |
+
def on_accelerator(self, tensor):
|
| 238 |
+
device_str = str(tensor.device)
|
| 239 |
+
if device_str.startswith('mlu:'):
|
| 240 |
+
return True
|
| 241 |
+
else:
|
| 242 |
+
return False
|
| 243 |
+
|
| 244 |
+
def op_builder_dir(self):
|
| 245 |
+
try:
|
| 246 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 247 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 248 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 249 |
+
return "op_builder.mlu"
|
| 250 |
+
except ImportError:
|
| 251 |
+
return "deepspeed.ops.op_builder.mlu"
|
| 252 |
+
|
| 253 |
+
def _lazy_init_class_dict(self):
|
| 254 |
+
if self.class_dict:
|
| 255 |
+
return
|
| 256 |
+
|
| 257 |
+
op_builder_module = importlib.import_module(self.op_builder_dir())
|
| 258 |
+
|
| 259 |
+
# get op builder class from op_builder/mlu/__init__.py
|
| 260 |
+
self.class_dict = {}
|
| 261 |
+
for class_name, class_obj in inspect.getmembers(op_builder_module, inspect.isclass):
|
| 262 |
+
self.class_dict[class_name] = class_obj
|
| 263 |
+
|
| 264 |
+
# create an instance of op builder and return, name specified by class_name
|
| 265 |
+
def create_op_builder(self, class_name):
|
| 266 |
+
builder_class = self.get_op_builder(class_name)
|
| 267 |
+
return builder_class()
|
| 268 |
+
|
| 269 |
+
# return an op builder class, name specified by class_name
|
| 270 |
+
def get_op_builder(self, class_name):
|
| 271 |
+
self._lazy_init_class_dict()
|
| 272 |
+
if class_name in self.class_dict:
|
| 273 |
+
return self.class_dict[class_name]
|
| 274 |
+
else:
|
| 275 |
+
return self.class_dict['NotImplementedBuilder']
|
| 276 |
+
|
| 277 |
+
def build_extension(self):
|
| 278 |
+
from torch.utils.cpp_extension import BuildExtension
|
| 279 |
+
return BuildExtension
|
| 280 |
+
|
| 281 |
+
def export_envs(self):
|
| 282 |
+
return ['NEUWARE_HOME', 'CNCL', 'LD_LIBRARY', 'PATH']
|
| 283 |
+
|
| 284 |
+
def visible_devices_envs(self):
|
| 285 |
+
return ['MLU_VISIBLE_DEVICES']
|
| 286 |
+
|
| 287 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 288 |
+
for env in self.visible_devices_envs():
|
| 289 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 290 |
+
|
| 291 |
+
def get_compile_backend(self):
|
| 292 |
+
return self._compile_backend
|
| 293 |
+
|
| 294 |
+
def set_compile_backend(self, backend):
|
| 295 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 296 |
+
if backend in supported_backends:
|
| 297 |
+
self._compile_backend = backend
|
| 298 |
+
else:
|
| 299 |
+
raise ValueError(
|
| 300 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends }")
|
lib/python3.12/site-packages/deepspeed/accelerator/mps_accelerator.py
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
|
| 8 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 9 |
+
|
| 10 |
+
# During setup stage torch may not be installed, pass on no torch will
|
| 11 |
+
# allow op builder related API to be executed.
|
| 12 |
+
try:
|
| 13 |
+
import torch.mps
|
| 14 |
+
except ImportError:
|
| 15 |
+
pass
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class MPS_Accelerator(DeepSpeedAccelerator):
|
| 19 |
+
|
| 20 |
+
def __init__(self):
|
| 21 |
+
self._name = "mps"
|
| 22 |
+
self._communication_backend_name = None
|
| 23 |
+
self._compile_backend = "inductor"
|
| 24 |
+
|
| 25 |
+
def is_synchronized_device(self):
|
| 26 |
+
return False
|
| 27 |
+
|
| 28 |
+
def use_host_timers(self):
|
| 29 |
+
return self.is_synchronized_device()
|
| 30 |
+
|
| 31 |
+
def resolves_data_dependency(self):
|
| 32 |
+
return self.is_synchronized_device()
|
| 33 |
+
|
| 34 |
+
def handles_memory_backpressure(self):
|
| 35 |
+
return self.is_synchronized_device()
|
| 36 |
+
|
| 37 |
+
# Device APIs
|
| 38 |
+
def device_name(self, device_index=None):
|
| 39 |
+
if device_index is None:
|
| 40 |
+
return "mps"
|
| 41 |
+
return "mps:{}".format(device_index)
|
| 42 |
+
|
| 43 |
+
def device(self, device_index):
|
| 44 |
+
return torch.device("mps", index=0)
|
| 45 |
+
|
| 46 |
+
def set_device(self, device_index):
|
| 47 |
+
return
|
| 48 |
+
|
| 49 |
+
def current_device(self):
|
| 50 |
+
return torch.device("mps", index=0)
|
| 51 |
+
|
| 52 |
+
def current_device_name(self):
|
| 53 |
+
return "mps:0"
|
| 54 |
+
|
| 55 |
+
def device_count(self):
|
| 56 |
+
return 1
|
| 57 |
+
|
| 58 |
+
def synchronize(self, device_index=None):
|
| 59 |
+
return torch.mps.synchronize()
|
| 60 |
+
|
| 61 |
+
# RNG APIs
|
| 62 |
+
def random(self):
|
| 63 |
+
return torch.random
|
| 64 |
+
|
| 65 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 66 |
+
return torch.mps.set_rng_state(new_state)
|
| 67 |
+
|
| 68 |
+
def get_rng_state(self, device_index=None):
|
| 69 |
+
return torch.mps.get_rng_state()
|
| 70 |
+
|
| 71 |
+
def manual_seed(self, seed):
|
| 72 |
+
return torch.mps.manual_seed(seed)
|
| 73 |
+
|
| 74 |
+
def manual_seed_all(self, seed):
|
| 75 |
+
return torch.mps.manual_seed(seed)
|
| 76 |
+
|
| 77 |
+
def seed(self):
|
| 78 |
+
return torch.mps.seed()
|
| 79 |
+
|
| 80 |
+
def initial_seed(self):
|
| 81 |
+
return
|
| 82 |
+
|
| 83 |
+
def default_generator(self, device_index):
|
| 84 |
+
return
|
| 85 |
+
|
| 86 |
+
# Streams/Events
|
| 87 |
+
@property
|
| 88 |
+
def Stream(self):
|
| 89 |
+
return None
|
| 90 |
+
|
| 91 |
+
def stream(self, stream):
|
| 92 |
+
return None
|
| 93 |
+
|
| 94 |
+
def current_stream(self, device_index=None):
|
| 95 |
+
return None
|
| 96 |
+
|
| 97 |
+
def default_stream(self, device_index=None):
|
| 98 |
+
return None
|
| 99 |
+
|
| 100 |
+
@property
|
| 101 |
+
def Event(self):
|
| 102 |
+
return None
|
| 103 |
+
|
| 104 |
+
# Memory management
|
| 105 |
+
def empty_cache(self):
|
| 106 |
+
return torch.mps.empty_cache()
|
| 107 |
+
|
| 108 |
+
def memory_allocated(self, device_index=None):
|
| 109 |
+
return torch.mps.current_allocated_memory()
|
| 110 |
+
|
| 111 |
+
def max_memory_allocated(self, device_index=None):
|
| 112 |
+
return torch.mps.driver_allocated_memory()
|
| 113 |
+
|
| 114 |
+
def set_per_process_memory_fraction(self, fraction):
|
| 115 |
+
return torch.mps.set_per_process_memory_fraction(fraction)
|
| 116 |
+
|
| 117 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 118 |
+
return
|
| 119 |
+
|
| 120 |
+
def memory_cached(self, device_index=None):
|
| 121 |
+
return
|
| 122 |
+
|
| 123 |
+
def max_memory_cached(self, device_index=None):
|
| 124 |
+
return
|
| 125 |
+
|
| 126 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 127 |
+
return
|
| 128 |
+
|
| 129 |
+
def memory_stats(self, device_index=None):
|
| 130 |
+
return
|
| 131 |
+
|
| 132 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 133 |
+
return
|
| 134 |
+
|
| 135 |
+
def memory_reserved(self, device_index=None):
|
| 136 |
+
return
|
| 137 |
+
|
| 138 |
+
def max_memory_reserved(self, device_index=None):
|
| 139 |
+
return
|
| 140 |
+
|
| 141 |
+
def total_memory(self, device_index=None):
|
| 142 |
+
return
|
| 143 |
+
|
| 144 |
+
def available_memory(self, device_index=None):
|
| 145 |
+
return
|
| 146 |
+
|
| 147 |
+
# Data types
|
| 148 |
+
def is_bf16_supported(self):
|
| 149 |
+
return False
|
| 150 |
+
|
| 151 |
+
def is_fp16_supported(self):
|
| 152 |
+
return False
|
| 153 |
+
|
| 154 |
+
def supported_dtypes(self):
|
| 155 |
+
return [torch.float]
|
| 156 |
+
|
| 157 |
+
# Misc
|
| 158 |
+
def amp(self):
|
| 159 |
+
return
|
| 160 |
+
|
| 161 |
+
def is_available(self):
|
| 162 |
+
return hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
|
| 163 |
+
|
| 164 |
+
def range_push(self, msg):
|
| 165 |
+
return
|
| 166 |
+
|
| 167 |
+
def range_pop(self):
|
| 168 |
+
return
|
| 169 |
+
|
| 170 |
+
def lazy_call(self, callback):
|
| 171 |
+
return
|
| 172 |
+
|
| 173 |
+
def communication_backend_name(self):
|
| 174 |
+
return self._communication_backend_name
|
| 175 |
+
|
| 176 |
+
def is_triton_supported(self):
|
| 177 |
+
return False
|
| 178 |
+
|
| 179 |
+
# Graph operations
|
| 180 |
+
def create_graph(self):
|
| 181 |
+
return None
|
| 182 |
+
|
| 183 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 184 |
+
from deepspeed.runtime.utils import noop_context
|
| 185 |
+
return noop_context()
|
| 186 |
+
|
| 187 |
+
def replay_graph(self, graph):
|
| 188 |
+
return
|
| 189 |
+
|
| 190 |
+
# Tensor operations
|
| 191 |
+
@property
|
| 192 |
+
def BFloat16Tensor(self):
|
| 193 |
+
return
|
| 194 |
+
|
| 195 |
+
@property
|
| 196 |
+
def ByteTensor(self):
|
| 197 |
+
return
|
| 198 |
+
|
| 199 |
+
@property
|
| 200 |
+
def DoubleTensor(self):
|
| 201 |
+
return
|
| 202 |
+
|
| 203 |
+
@property
|
| 204 |
+
def FloatTensor(self):
|
| 205 |
+
return
|
| 206 |
+
|
| 207 |
+
@property
|
| 208 |
+
def HalfTensor(self):
|
| 209 |
+
return
|
| 210 |
+
|
| 211 |
+
@property
|
| 212 |
+
def IntTensor(self):
|
| 213 |
+
return
|
| 214 |
+
|
| 215 |
+
@property
|
| 216 |
+
def LongTensor(self):
|
| 217 |
+
return
|
| 218 |
+
|
| 219 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 220 |
+
return tensor.pin_memory()
|
| 221 |
+
|
| 222 |
+
def is_pinned(self, tensor):
|
| 223 |
+
return tensor.is_pinned()
|
| 224 |
+
|
| 225 |
+
def on_accelerator(self, tensor):
|
| 226 |
+
device_str = str(tensor.device)
|
| 227 |
+
if device_str.startswith("mps"):
|
| 228 |
+
return True
|
| 229 |
+
else:
|
| 230 |
+
return False
|
| 231 |
+
|
| 232 |
+
def op_builder_dir(self):
|
| 233 |
+
try:
|
| 234 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 235 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 236 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 237 |
+
|
| 238 |
+
return "op_builder"
|
| 239 |
+
except ImportError:
|
| 240 |
+
return "deepspeed.ops.op_builder"
|
| 241 |
+
|
| 242 |
+
# create an instance of op builder, specified by class_name
|
| 243 |
+
def create_op_builder(self, op_name):
|
| 244 |
+
builder_class = self.get_op_builder(op_name)
|
| 245 |
+
if builder_class is not None:
|
| 246 |
+
return builder_class()
|
| 247 |
+
return None
|
| 248 |
+
|
| 249 |
+
# return an op builder class, specified by class_name
|
| 250 |
+
def get_op_builder(self, class_name):
|
| 251 |
+
from deepspeed.ops.op_builder.cpu import NotImplementedBuilder
|
| 252 |
+
|
| 253 |
+
return NotImplementedBuilder
|
| 254 |
+
|
| 255 |
+
def build_extension(self):
|
| 256 |
+
from torch.utils.cpp_extension import BuildExtension
|
| 257 |
+
|
| 258 |
+
return BuildExtension
|
| 259 |
+
|
| 260 |
+
def export_envs(self):
|
| 261 |
+
return []
|
| 262 |
+
|
| 263 |
+
# TODO: mpu's visible envs is confirmed, keep as CUDA_VISIBLE_DEVICES
|
| 264 |
+
def visible_devices_envs(self):
|
| 265 |
+
# TODO: could not find visible devices env for mps
|
| 266 |
+
return ['CUDA_VISIBLE_DEVICES']
|
| 267 |
+
|
| 268 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 269 |
+
for env in self.visible_devices_envs():
|
| 270 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 271 |
+
|
| 272 |
+
def get_compile_backend(self):
|
| 273 |
+
return self._compile_backend
|
| 274 |
+
|
| 275 |
+
def set_compile_backend(self, backend):
|
| 276 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 277 |
+
if backend in supported_backends:
|
| 278 |
+
self._compile_backend = backend
|
| 279 |
+
else:
|
| 280 |
+
raise ValueError(
|
| 281 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends}")
|
lib/python3.12/site-packages/deepspeed/accelerator/npu_accelerator.py
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
import importlib
|
| 6 |
+
import inspect
|
| 7 |
+
|
| 8 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 9 |
+
# During setup stage torch may not be installed, pass on no torch will
|
| 10 |
+
# allow op builder related API to be executed.
|
| 11 |
+
try:
|
| 12 |
+
import torch.npu
|
| 13 |
+
except ImportError:
|
| 14 |
+
pass
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class NPU_Accelerator(DeepSpeedAccelerator):
|
| 18 |
+
|
| 19 |
+
def __init__(self):
|
| 20 |
+
super().__init__()
|
| 21 |
+
self._name = 'npu'
|
| 22 |
+
self._communication_backend_name = 'hccl'
|
| 23 |
+
self._compile_backend = "inductor"
|
| 24 |
+
# dict that holds class name <--> class type mapping i.e.
|
| 25 |
+
# 'AsyncIOBuilder': <class 'op_builder.async_io.AsyncIOBuilder'>
|
| 26 |
+
# this dict will be filled at init stage
|
| 27 |
+
self.class_dict = None
|
| 28 |
+
|
| 29 |
+
def is_synchronized_device(self):
|
| 30 |
+
return False
|
| 31 |
+
|
| 32 |
+
def use_host_timers(self):
|
| 33 |
+
return self.is_synchronized_device()
|
| 34 |
+
|
| 35 |
+
def resolves_data_dependency(self):
|
| 36 |
+
return self.is_synchronized_device()
|
| 37 |
+
|
| 38 |
+
def handles_memory_backpressure(self):
|
| 39 |
+
return self.is_synchronized_device()
|
| 40 |
+
|
| 41 |
+
# Device APIs
|
| 42 |
+
def device_name(self, device_index=None):
|
| 43 |
+
if device_index is None:
|
| 44 |
+
return 'npu'
|
| 45 |
+
return 'npu:{}'.format(device_index)
|
| 46 |
+
|
| 47 |
+
def device(self, device_index=None):
|
| 48 |
+
return torch.npu.device(device_index)
|
| 49 |
+
|
| 50 |
+
def set_device(self, device_index):
|
| 51 |
+
torch.npu.set_device(device_index)
|
| 52 |
+
|
| 53 |
+
def current_device(self):
|
| 54 |
+
return torch.npu.current_device()
|
| 55 |
+
|
| 56 |
+
def current_device_name(self):
|
| 57 |
+
return 'npu:{}'.format(torch.npu.current_device())
|
| 58 |
+
|
| 59 |
+
def device_count(self):
|
| 60 |
+
return torch.npu.device_count()
|
| 61 |
+
|
| 62 |
+
def synchronize(self, device_index=None):
|
| 63 |
+
return torch.npu.synchronize(device_index)
|
| 64 |
+
|
| 65 |
+
# RNG APIs
|
| 66 |
+
def random(self):
|
| 67 |
+
return torch.random
|
| 68 |
+
|
| 69 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 70 |
+
if device_index is None:
|
| 71 |
+
return torch.npu.set_rng_state(new_state)
|
| 72 |
+
|
| 73 |
+
return torch.npu.set_rng_state(new_state, device_index)
|
| 74 |
+
|
| 75 |
+
def get_rng_state(self, device_index=None):
|
| 76 |
+
if device_index is None:
|
| 77 |
+
return torch.npu.get_rng_state()
|
| 78 |
+
|
| 79 |
+
return torch.npu.get_rng_state(device_index)
|
| 80 |
+
|
| 81 |
+
def manual_seed(self, seed):
|
| 82 |
+
return torch.npu.manual_seed(seed)
|
| 83 |
+
|
| 84 |
+
def manual_seed_all(self, seed):
|
| 85 |
+
return torch.npu.manual_seed_all(seed)
|
| 86 |
+
|
| 87 |
+
def initial_seed(self):
|
| 88 |
+
return torch.npu.initial_seed()
|
| 89 |
+
|
| 90 |
+
def default_generator(self, device_index):
|
| 91 |
+
return torch.npu.default_generators[device_index]
|
| 92 |
+
|
| 93 |
+
# Streams/Events
|
| 94 |
+
@property
|
| 95 |
+
def Stream(self):
|
| 96 |
+
return torch.npu.Stream
|
| 97 |
+
|
| 98 |
+
def stream(self, stream):
|
| 99 |
+
return torch.npu.stream(stream)
|
| 100 |
+
|
| 101 |
+
def current_stream(self, device_index=None):
|
| 102 |
+
return torch.npu.current_stream(device_index)
|
| 103 |
+
|
| 104 |
+
def default_stream(self, device_index=None):
|
| 105 |
+
return torch.npu.default_stream(device_index)
|
| 106 |
+
|
| 107 |
+
@property
|
| 108 |
+
def Event(self):
|
| 109 |
+
return torch.npu.Event
|
| 110 |
+
|
| 111 |
+
# Memory management
|
| 112 |
+
def empty_cache(self):
|
| 113 |
+
return torch.npu.empty_cache()
|
| 114 |
+
|
| 115 |
+
def memory_allocated(self, device_index=None):
|
| 116 |
+
return torch.npu.memory_allocated(device_index)
|
| 117 |
+
|
| 118 |
+
def max_memory_allocated(self, device_index=None):
|
| 119 |
+
return torch.npu.max_memory_allocated(device_index)
|
| 120 |
+
|
| 121 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 122 |
+
return torch.npu.reset_max_memory_allocated(device_index)
|
| 123 |
+
|
| 124 |
+
def memory_cached(self, device_index=None):
|
| 125 |
+
return torch.npu.memory_cached(device_index)
|
| 126 |
+
|
| 127 |
+
def max_memory_cached(self, device_index=None):
|
| 128 |
+
return torch.npu.max_memory_cached(device_index)
|
| 129 |
+
|
| 130 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 131 |
+
return torch.npu.reset_max_memory_cached(device_index)
|
| 132 |
+
|
| 133 |
+
def memory_stats(self, device_index=None):
|
| 134 |
+
if hasattr(torch.npu, 'memory_stats'):
|
| 135 |
+
return torch.npu.memory_stats(device_index)
|
| 136 |
+
|
| 137 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 138 |
+
if hasattr(torch.npu, 'reset_peak_memory_stats'):
|
| 139 |
+
return torch.npu.reset_peak_memory_stats(device_index)
|
| 140 |
+
|
| 141 |
+
def memory_reserved(self, device_index=None):
|
| 142 |
+
if hasattr(torch.npu, 'memory_reserved'):
|
| 143 |
+
return torch.npu.memory_reserved(device_index)
|
| 144 |
+
|
| 145 |
+
def max_memory_reserved(self, device_index=None):
|
| 146 |
+
if hasattr(torch.npu, 'max_memory_reserved'):
|
| 147 |
+
return torch.npu.max_memory_reserved(device_index)
|
| 148 |
+
|
| 149 |
+
def total_memory(self, device_index=None):
|
| 150 |
+
return torch.npu.get_device_properties(device_index).total_memory
|
| 151 |
+
|
| 152 |
+
def available_memory(self, device_index=None):
|
| 153 |
+
return self.total_memory(device_index) - self.memory_allocated(device_index)
|
| 154 |
+
|
| 155 |
+
# Data types
|
| 156 |
+
def is_bf16_supported(self):
|
| 157 |
+
return torch.npu.is_bf16_supported()
|
| 158 |
+
|
| 159 |
+
def is_fp16_supported(self):
|
| 160 |
+
return True
|
| 161 |
+
|
| 162 |
+
def supported_dtypes(self):
|
| 163 |
+
return [torch.float, torch.half, torch.bfloat16]
|
| 164 |
+
|
| 165 |
+
# Misc
|
| 166 |
+
def amp(self):
|
| 167 |
+
if hasattr(torch.npu, 'amp'):
|
| 168 |
+
return torch.npu.amp
|
| 169 |
+
return None
|
| 170 |
+
|
| 171 |
+
def is_available(self):
|
| 172 |
+
return torch.npu.is_available()
|
| 173 |
+
|
| 174 |
+
def range_push(self, msg):
|
| 175 |
+
return
|
| 176 |
+
|
| 177 |
+
def range_pop(self):
|
| 178 |
+
return
|
| 179 |
+
|
| 180 |
+
def lazy_call(self, callback):
|
| 181 |
+
return torch.npu._lazy_call(callback)
|
| 182 |
+
|
| 183 |
+
def communication_backend_name(self):
|
| 184 |
+
return self._communication_backend_name
|
| 185 |
+
|
| 186 |
+
def is_triton_supported(self):
|
| 187 |
+
return False
|
| 188 |
+
|
| 189 |
+
# Graph operations
|
| 190 |
+
def create_graph(self):
|
| 191 |
+
return None
|
| 192 |
+
|
| 193 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 194 |
+
from deepspeed.runtime.utils import noop_context
|
| 195 |
+
return noop_context()
|
| 196 |
+
|
| 197 |
+
def replay_graph(self, graph):
|
| 198 |
+
return
|
| 199 |
+
|
| 200 |
+
# Tensor operations
|
| 201 |
+
|
| 202 |
+
@property
|
| 203 |
+
def BFloat16Tensor(self):
|
| 204 |
+
return torch.npu.BFloat16Tensor
|
| 205 |
+
|
| 206 |
+
@property
|
| 207 |
+
def ByteTensor(self):
|
| 208 |
+
return torch.npu.ByteTensor
|
| 209 |
+
|
| 210 |
+
@property
|
| 211 |
+
def DoubleTensor(self):
|
| 212 |
+
return torch.npu.DoubleTensor
|
| 213 |
+
|
| 214 |
+
@property
|
| 215 |
+
def FloatTensor(self):
|
| 216 |
+
return torch.npu.FloatTensor
|
| 217 |
+
|
| 218 |
+
@property
|
| 219 |
+
def HalfTensor(self):
|
| 220 |
+
return torch.npu.HalfTensor
|
| 221 |
+
|
| 222 |
+
@property
|
| 223 |
+
def IntTensor(self):
|
| 224 |
+
return torch.npu.IntTensor
|
| 225 |
+
|
| 226 |
+
@property
|
| 227 |
+
def LongTensor(self):
|
| 228 |
+
return torch.npu.LongTensor
|
| 229 |
+
|
| 230 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 231 |
+
return tensor.pin_memory()
|
| 232 |
+
|
| 233 |
+
def is_pinned(self, tensor):
|
| 234 |
+
return tensor.is_pinned()
|
| 235 |
+
|
| 236 |
+
def on_accelerator(self, tensor):
|
| 237 |
+
device_str = str(tensor.device)
|
| 238 |
+
if device_str.startswith('npu:'):
|
| 239 |
+
return True
|
| 240 |
+
else:
|
| 241 |
+
return False
|
| 242 |
+
|
| 243 |
+
def op_builder_dir(self):
|
| 244 |
+
try:
|
| 245 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 246 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 247 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 248 |
+
return "op_builder.npu"
|
| 249 |
+
except ImportError:
|
| 250 |
+
return "deepspeed.ops.op_builder.npu"
|
| 251 |
+
|
| 252 |
+
def _lazy_init_class_dict(self):
|
| 253 |
+
if self.class_dict:
|
| 254 |
+
return
|
| 255 |
+
|
| 256 |
+
op_builder_module = importlib.import_module(self.op_builder_dir())
|
| 257 |
+
|
| 258 |
+
# get op builder class from op_builder/npu/__init__.py
|
| 259 |
+
self.class_dict = {}
|
| 260 |
+
for class_name, class_obj in inspect.getmembers(op_builder_module, inspect.isclass):
|
| 261 |
+
self.class_dict[class_name] = class_obj
|
| 262 |
+
|
| 263 |
+
# create an instance of op builder and return, name specified by class_name
|
| 264 |
+
def create_op_builder(self, class_name):
|
| 265 |
+
builder_class = self.get_op_builder(class_name)
|
| 266 |
+
return None if builder_class is None else builder_class()
|
| 267 |
+
|
| 268 |
+
# return an op builder class, name specified by class_name
|
| 269 |
+
def get_op_builder(self, class_name):
|
| 270 |
+
self._lazy_init_class_dict()
|
| 271 |
+
if class_name in self.class_dict:
|
| 272 |
+
return self.class_dict[class_name]
|
| 273 |
+
else:
|
| 274 |
+
return self.class_dict['NotImplementedBuilder'] if 'NotImplementedBuilder' in self.class_dict else None
|
| 275 |
+
|
| 276 |
+
def build_extension(self):
|
| 277 |
+
from torch.utils.cpp_extension import BuildExtension
|
| 278 |
+
return BuildExtension
|
| 279 |
+
|
| 280 |
+
def export_envs(self):
|
| 281 |
+
return ['ASCEND', 'HCCL', 'LD_LIBRARY', 'PATH']
|
| 282 |
+
|
| 283 |
+
def visible_devices_envs(self):
|
| 284 |
+
return ['ASCEND_RT_VISIBLE_DEVICES']
|
| 285 |
+
|
| 286 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 287 |
+
for env in self.visible_devices_envs():
|
| 288 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 289 |
+
|
| 290 |
+
def get_compile_backend(self):
|
| 291 |
+
return self._compile_backend
|
| 292 |
+
|
| 293 |
+
def set_compile_backend(self, backend):
|
| 294 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 295 |
+
if backend in supported_backends:
|
| 296 |
+
self._compile_backend = backend
|
| 297 |
+
else:
|
| 298 |
+
raise ValueError(
|
| 299 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends }")
|
lib/python3.12/site-packages/deepspeed/accelerator/real_accelerator.py
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
try:
|
| 8 |
+
# Importing logger currently requires that torch is installed, hence the try...except
|
| 9 |
+
# TODO: Remove logger dependency on torch.
|
| 10 |
+
from deepspeed.utils import logger as accel_logger
|
| 11 |
+
except ImportError as e:
|
| 12 |
+
accel_logger = None
|
| 13 |
+
|
| 14 |
+
try:
|
| 15 |
+
from accelerator.abstract_accelerator import DeepSpeedAccelerator as dsa1
|
| 16 |
+
except ImportError as e:
|
| 17 |
+
dsa1 = None
|
| 18 |
+
try:
|
| 19 |
+
from deepspeed.accelerator.abstract_accelerator import DeepSpeedAccelerator as dsa2
|
| 20 |
+
except ImportError as e:
|
| 21 |
+
dsa2 = None
|
| 22 |
+
|
| 23 |
+
SUPPORTED_ACCELERATOR_LIST = ['cuda', 'cpu', 'xpu', 'xpu.external', 'npu', 'mps', 'hpu', 'mlu', 'sdaa']
|
| 24 |
+
|
| 25 |
+
ds_accelerator = None
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def _validate_accelerator(accel_obj):
|
| 29 |
+
# because abstract_accelerator has different path during
|
| 30 |
+
# build time (accelerator.abstract_accelerator)
|
| 31 |
+
# and run time (deepspeed.accelerator.abstract_accelerator)
|
| 32 |
+
# and extension would import the
|
| 33 |
+
# run time abstract_accelerator/DeepSpeedAccelerator as its base
|
| 34 |
+
# class, so we need to compare accel_obj with both base class.
|
| 35 |
+
# if accel_obj is instance of DeepSpeedAccelerator in one of
|
| 36 |
+
# accelerator.abstractor_accelerator
|
| 37 |
+
# or deepspeed.accelerator.abstract_accelerator, consider accel_obj
|
| 38 |
+
# is a conforming object
|
| 39 |
+
if not ((dsa1 is not None and isinstance(accel_obj, dsa1)) or (dsa2 is not None and isinstance(accel_obj, dsa2))):
|
| 40 |
+
raise AssertionError(f"{accel_obj.__class__.__name__} accelerator is not subclass of DeepSpeedAccelerator")
|
| 41 |
+
|
| 42 |
+
# TODO: turn off is_available test since this breaks tests
|
| 43 |
+
# assert accel_obj.is_available(), \
|
| 44 |
+
# f'{accel_obj.__class__.__name__} accelerator fails is_available() test'
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def is_current_accelerator_supported():
|
| 48 |
+
return get_accelerator().device_name() in SUPPORTED_ACCELERATOR_LIST
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def get_accelerator():
|
| 52 |
+
global ds_accelerator
|
| 53 |
+
if ds_accelerator is not None:
|
| 54 |
+
return ds_accelerator
|
| 55 |
+
|
| 56 |
+
accelerator_name = None
|
| 57 |
+
ds_set_method = None
|
| 58 |
+
# 1. Detect whether there is override of DeepSpeed accelerators from environment variable.
|
| 59 |
+
if "DS_ACCELERATOR" in os.environ.keys():
|
| 60 |
+
accelerator_name = os.environ["DS_ACCELERATOR"]
|
| 61 |
+
if accelerator_name == "xpu":
|
| 62 |
+
try:
|
| 63 |
+
import intel_extension_for_pytorch as ipex
|
| 64 |
+
assert ipex._C._has_xpu(), "XPU_Accelerator requires an intel_extension_for_pytorch that supports XPU."
|
| 65 |
+
except ImportError as e:
|
| 66 |
+
raise ValueError(
|
| 67 |
+
f"XPU_Accelerator requires intel_extension_for_pytorch, which is not installed on this system.")
|
| 68 |
+
elif accelerator_name == "xpu.external":
|
| 69 |
+
try:
|
| 70 |
+
import intel_extension_for_deepspeed # noqa: F401 # type: ignore
|
| 71 |
+
except ImportError as e:
|
| 72 |
+
raise ValueError(
|
| 73 |
+
f"XPU_Accelerator external requires intel_extension_for_deepspeed, which is not installed on this system."
|
| 74 |
+
)
|
| 75 |
+
elif accelerator_name == "cpu":
|
| 76 |
+
pass
|
| 77 |
+
elif accelerator_name == "npu":
|
| 78 |
+
try:
|
| 79 |
+
import torch_npu # noqa: F401 # type: ignore
|
| 80 |
+
except ImportError as e:
|
| 81 |
+
raise ValueError(f"NPU_Accelerator requires torch_npu, which is not installed on this system.")
|
| 82 |
+
pass
|
| 83 |
+
elif accelerator_name == "sdaa":
|
| 84 |
+
try:
|
| 85 |
+
import torch_sdaa # noqa: F401 # type: ignore
|
| 86 |
+
except ImportError as e:
|
| 87 |
+
raise ValueError(f"SDAA_Accelerator requires torch_sdaa, which is not installed on this system.")
|
| 88 |
+
pass
|
| 89 |
+
elif accelerator_name == "mps":
|
| 90 |
+
try:
|
| 91 |
+
import torch.mps
|
| 92 |
+
|
| 93 |
+
# should use torch.mps.is_available() if it exists someday but this is used as proxy
|
| 94 |
+
torch.mps.current_allocated_memory()
|
| 95 |
+
except (RuntimeError, ImportError) as e:
|
| 96 |
+
raise ValueError(f"MPS_Accelerator requires torch.mps, which is not installed on this system.")
|
| 97 |
+
elif accelerator_name == "hpu":
|
| 98 |
+
try:
|
| 99 |
+
import habana_frameworks.torch.hpu # noqa: F401
|
| 100 |
+
except ImportError as e:
|
| 101 |
+
raise ValueError(
|
| 102 |
+
f"HPU_Accelerator requires habana_frameworks.torch.hpu, which is not installed on this system.")
|
| 103 |
+
elif accelerator_name == "mlu":
|
| 104 |
+
try:
|
| 105 |
+
import torch_mlu # noqa: F401
|
| 106 |
+
except ImportError as e:
|
| 107 |
+
raise ValueError(f"MLU_Accelerator requires torch_mlu, which is not installed on this system.")
|
| 108 |
+
elif accelerator_name not in SUPPORTED_ACCELERATOR_LIST:
|
| 109 |
+
raise ValueError(f'DS_ACCELERATOR must be one of {SUPPORTED_ACCELERATOR_LIST}. '
|
| 110 |
+
f'Value "{accelerator_name}" is not supported')
|
| 111 |
+
ds_set_method = "override"
|
| 112 |
+
|
| 113 |
+
# 2. If no override, detect which accelerator to use automatically
|
| 114 |
+
if accelerator_name is None:
|
| 115 |
+
# We need a way to choose among different accelerator types.
|
| 116 |
+
# Currently we detect which accelerator extension is installed
|
| 117 |
+
# in the environment and use it if the installing answer is True.
|
| 118 |
+
# An alternative might be detect whether CUDA device is installed on
|
| 119 |
+
# the system but this comes with two pitfalls:
|
| 120 |
+
# 1. the system may not have torch pre-installed, so
|
| 121 |
+
# get_accelerator().is_available() may not work.
|
| 122 |
+
# 2. Some scenario like install on login node (without CUDA device)
|
| 123 |
+
# and run on compute node (with CUDA device) may cause mismatch
|
| 124 |
+
# between installation time and runtime.
|
| 125 |
+
|
| 126 |
+
try:
|
| 127 |
+
from intel_extension_for_deepspeed import XPU_Accelerator # noqa: F401,F811 # type: ignore
|
| 128 |
+
accelerator_name = "xpu.external"
|
| 129 |
+
except ImportError as e:
|
| 130 |
+
pass
|
| 131 |
+
if accelerator_name is None:
|
| 132 |
+
try:
|
| 133 |
+
import intel_extension_for_pytorch as ipex
|
| 134 |
+
|
| 135 |
+
if ipex._C._has_xpu():
|
| 136 |
+
accelerator_name = "xpu"
|
| 137 |
+
except ImportError as e:
|
| 138 |
+
pass
|
| 139 |
+
if accelerator_name is None:
|
| 140 |
+
try:
|
| 141 |
+
import torch
|
| 142 |
+
|
| 143 |
+
# torch.xpu will be supported in upstream pytorch-2.8.
|
| 144 |
+
# Currently we can run on xpu device only using pytorch,
|
| 145 |
+
# also reserve the old path using ipex when the torch version is old.
|
| 146 |
+
if hasattr(torch, 'xpu'):
|
| 147 |
+
if torch.cuda.device_count() == 0: #ignore-cuda
|
| 148 |
+
if torch.xpu.device_count() > 0 and torch.xpu.is_available():
|
| 149 |
+
accelerator_name = "xpu"
|
| 150 |
+
else:
|
| 151 |
+
pass
|
| 152 |
+
except ImportError as e:
|
| 153 |
+
pass
|
| 154 |
+
if accelerator_name is None:
|
| 155 |
+
try:
|
| 156 |
+
import torch_npu # noqa: F401,F811 # type: ignore
|
| 157 |
+
|
| 158 |
+
accelerator_name = "npu"
|
| 159 |
+
except ImportError as e:
|
| 160 |
+
pass
|
| 161 |
+
if accelerator_name is None:
|
| 162 |
+
try:
|
| 163 |
+
import torch_sdaa # noqa: F401,F811 # type: ignore
|
| 164 |
+
|
| 165 |
+
accelerator_name = "sdaa"
|
| 166 |
+
except ImportError as e:
|
| 167 |
+
pass
|
| 168 |
+
if accelerator_name is None:
|
| 169 |
+
try:
|
| 170 |
+
import torch.mps
|
| 171 |
+
|
| 172 |
+
# should use torch.mps.is_available() if it exists someday but this is used as proxy
|
| 173 |
+
torch.mps.current_allocated_memory()
|
| 174 |
+
accelerator_name = "mps"
|
| 175 |
+
except (RuntimeError, ImportError) as e:
|
| 176 |
+
pass
|
| 177 |
+
if accelerator_name is None:
|
| 178 |
+
try:
|
| 179 |
+
import habana_frameworks.torch.hpu # noqa: F401,F811
|
| 180 |
+
|
| 181 |
+
accelerator_name = "hpu"
|
| 182 |
+
except ImportError as e:
|
| 183 |
+
pass
|
| 184 |
+
if accelerator_name is None:
|
| 185 |
+
try:
|
| 186 |
+
import torch_mlu # noqa: F401,F811
|
| 187 |
+
|
| 188 |
+
accelerator_name = "mlu"
|
| 189 |
+
except ImportError as e:
|
| 190 |
+
pass
|
| 191 |
+
if accelerator_name is None:
|
| 192 |
+
try:
|
| 193 |
+
import torch
|
| 194 |
+
|
| 195 |
+
# Determine if we are on a GPU or x86 CPU with torch.
|
| 196 |
+
# "torch.cuda.is_available()" provides a stronger guarantee, #ignore-cuda
|
| 197 |
+
# ensuring that we are free from CUDA initialization errors.
|
| 198 |
+
# While "torch.cuda.device_count() > 0" check ensures that #ignore-cuda
|
| 199 |
+
# we won't try to do any CUDA calls when no device is available
|
| 200 |
+
# For reference: https://github.com/deepspeedai/DeepSpeed/pull/6810
|
| 201 |
+
if torch.cuda.device_count() > 0 and torch.cuda.is_available(): #ignore-cuda
|
| 202 |
+
accelerator_name = "cuda"
|
| 203 |
+
except (RuntimeError, ImportError) as e:
|
| 204 |
+
# TODO need a more decent way to detect which accelerator to use, consider using nvidia-smi command for detection
|
| 205 |
+
pass
|
| 206 |
+
if accelerator_name is None:
|
| 207 |
+
# borrow this log from PR#5084
|
| 208 |
+
if accel_logger is not None:
|
| 209 |
+
accel_logger.warning(
|
| 210 |
+
"Setting accelerator to CPU. If you have GPU or other accelerator, we were unable to detect it.")
|
| 211 |
+
# cpu added as catch-all when accelerator detection fails
|
| 212 |
+
accelerator_name = "cpu"
|
| 213 |
+
|
| 214 |
+
ds_set_method = "auto detect"
|
| 215 |
+
|
| 216 |
+
# 3. Set ds_accelerator accordingly
|
| 217 |
+
if accelerator_name == "cuda":
|
| 218 |
+
from .cuda_accelerator import CUDA_Accelerator
|
| 219 |
+
|
| 220 |
+
ds_accelerator = CUDA_Accelerator()
|
| 221 |
+
elif accelerator_name == "cpu":
|
| 222 |
+
from .cpu_accelerator import CPU_Accelerator
|
| 223 |
+
|
| 224 |
+
ds_accelerator = CPU_Accelerator()
|
| 225 |
+
elif accelerator_name == "xpu.external":
|
| 226 |
+
# XPU_Accelerator is already imported in detection stage
|
| 227 |
+
ds_accelerator = XPU_Accelerator()
|
| 228 |
+
elif accelerator_name == "xpu":
|
| 229 |
+
from .xpu_accelerator import XPU_Accelerator
|
| 230 |
+
|
| 231 |
+
ds_accelerator = XPU_Accelerator()
|
| 232 |
+
elif accelerator_name == "npu":
|
| 233 |
+
from .npu_accelerator import NPU_Accelerator
|
| 234 |
+
|
| 235 |
+
ds_accelerator = NPU_Accelerator()
|
| 236 |
+
elif accelerator_name == "sdaa":
|
| 237 |
+
from .sdaa_accelerator import SDAA_Accelerator
|
| 238 |
+
|
| 239 |
+
ds_accelerator = SDAA_Accelerator()
|
| 240 |
+
elif accelerator_name == "mps":
|
| 241 |
+
from .mps_accelerator import MPS_Accelerator
|
| 242 |
+
|
| 243 |
+
ds_accelerator = MPS_Accelerator()
|
| 244 |
+
elif accelerator_name == 'hpu':
|
| 245 |
+
from .hpu_accelerator import HPU_Accelerator
|
| 246 |
+
|
| 247 |
+
ds_accelerator = HPU_Accelerator()
|
| 248 |
+
elif accelerator_name == 'mlu':
|
| 249 |
+
from .mlu_accelerator import MLU_Accelerator
|
| 250 |
+
|
| 251 |
+
ds_accelerator = MLU_Accelerator()
|
| 252 |
+
_validate_accelerator(ds_accelerator)
|
| 253 |
+
if accel_logger is not None:
|
| 254 |
+
accel_logger.info(f"Setting ds_accelerator to {ds_accelerator._name} ({ds_set_method})")
|
| 255 |
+
return ds_accelerator
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
def set_accelerator(accel_obj):
|
| 259 |
+
global ds_accelerator
|
| 260 |
+
_validate_accelerator(accel_obj)
|
| 261 |
+
if accel_logger is not None:
|
| 262 |
+
accel_logger.info(f"Setting ds_accelerator to {accel_obj._name} (model specified)")
|
| 263 |
+
ds_accelerator = accel_obj
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
"""
|
| 267 |
+
-----------[code] test_get.py -----------
|
| 268 |
+
from deepspeed.accelerator import get_accelerator
|
| 269 |
+
my_accelerator = get_accelerator()
|
| 270 |
+
logger.info(f'{my_accelerator._name=}')
|
| 271 |
+
logger.info(f'{my_accelerator._communication_backend=}')
|
| 272 |
+
logger.info(f'{my_accelerator.HalfTensor().device=}')
|
| 273 |
+
logger.info(f'{my_accelerator.total_memory()=}')
|
| 274 |
+
-----------[code] test_get.py -----------
|
| 275 |
+
|
| 276 |
+
---[output] python test_get.py---------
|
| 277 |
+
my_accelerator.name()='cuda'
|
| 278 |
+
my_accelerator.communication_backend='nccl'
|
| 279 |
+
my_accelerator.HalfTensor().device=device(type='cuda', index=0)
|
| 280 |
+
my_accelerator.total_memory()=34089730048
|
| 281 |
+
---[output] python test_get.py---------
|
| 282 |
+
|
| 283 |
+
**************************************************************************
|
| 284 |
+
-----------[code] test_set.py -----------
|
| 285 |
+
from deepspeed.accelerator.cuda_accelerator import CUDA_Accelerator
|
| 286 |
+
cu_accel = CUDA_Accelerator()
|
| 287 |
+
logger.info(f'{id(cu_accel)=}')
|
| 288 |
+
from deepspeed.accelerator import set_accelerator, get_accelerator
|
| 289 |
+
set_accelerator(cu_accel)
|
| 290 |
+
|
| 291 |
+
my_accelerator = get_accelerator()
|
| 292 |
+
logger.info(f'{id(my_accelerator)=}')
|
| 293 |
+
logger.info(f'{my_accelerator._name=}')
|
| 294 |
+
logger.info(f'{my_accelerator._communication_backend=}')
|
| 295 |
+
logger.info(f'{my_accelerator.HalfTensor().device=}')
|
| 296 |
+
logger.info(f'{my_accelerator.total_memory()=}')
|
| 297 |
+
-----------[code] test_set.py -----------
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
---[output] python test_set.py---------
|
| 301 |
+
id(cu_accel)=139648165478304
|
| 302 |
+
my_accelerator=<deepspeed.accelerator.cuda_accelerator.CUDA_Accelerator object at 0x7f025f4bffa0>
|
| 303 |
+
my_accelerator.name='cuda'
|
| 304 |
+
my_accelerator.communication_backend='nccl'
|
| 305 |
+
my_accelerator.HalfTensor().device=device(type='cuda', index=0)
|
| 306 |
+
my_accelerator.total_memory()=34089730048
|
| 307 |
+
---[output] python test_set.py---------
|
| 308 |
+
"""
|
lib/python3.12/site-packages/deepspeed/accelerator/sdaa_accelerator.py
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# BSD 3- Clause License Copyright (c) 2023, Tecorigin Co., Ltd. All rights
|
| 5 |
+
# reserved.
|
| 6 |
+
# Redistribution and use in source and binary forms, with or without
|
| 7 |
+
# modification, are permitted provided that the following conditions are met:
|
| 8 |
+
# Redistributions of source code must retain the above copyright notice,
|
| 9 |
+
# this list of conditions and the following disclaimer.
|
| 10 |
+
# Redistributions in binary form must reproduce the above copyright notice,
|
| 11 |
+
# this list of conditions and the following disclaimer in the documentation
|
| 12 |
+
# and/or other materials provided with the distribution.
|
| 13 |
+
# Neither the name of the copyright holder nor the names of its contributors
|
| 14 |
+
# may be used to endorse or promote products derived from this software
|
| 15 |
+
# without specific prior written permission.
|
| 16 |
+
#
|
| 17 |
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 18 |
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 19 |
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
| 20 |
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
| 21 |
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| 22 |
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| 23 |
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| 24 |
+
# INTERRUPTION)
|
| 25 |
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
| 26 |
+
# STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
| 27 |
+
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
| 28 |
+
# OF SUCH DAMAGE.
|
| 29 |
+
|
| 30 |
+
# DeepSpeed Team
|
| 31 |
+
|
| 32 |
+
import importlib
|
| 33 |
+
import inspect
|
| 34 |
+
import functools
|
| 35 |
+
|
| 36 |
+
from .abstract_accelerator import DeepSpeedAccelerator
|
| 37 |
+
# During setup stage torch may not be installed, pass on no torch will
|
| 38 |
+
# allow op builder related API to be executed.
|
| 39 |
+
try:
|
| 40 |
+
import torch.sdaa
|
| 41 |
+
except ImportError:
|
| 42 |
+
pass
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class SDAA_Accelerator(DeepSpeedAccelerator):
|
| 46 |
+
|
| 47 |
+
def __init__(self):
|
| 48 |
+
self._name = 'sdaa'
|
| 49 |
+
self._communication_backend_name = 'tccl'
|
| 50 |
+
self._compile_backend = "inductor"
|
| 51 |
+
self.class_dict = None
|
| 52 |
+
|
| 53 |
+
def is_synchronized_device(self):
|
| 54 |
+
return False
|
| 55 |
+
|
| 56 |
+
def use_host_timers(self):
|
| 57 |
+
return self.is_synchronized_device()
|
| 58 |
+
|
| 59 |
+
def resolves_data_dependency(self):
|
| 60 |
+
return self.is_synchronized_device()
|
| 61 |
+
|
| 62 |
+
def handles_memory_backpressure(self):
|
| 63 |
+
return self.is_synchronized_device()
|
| 64 |
+
|
| 65 |
+
# Device APIs
|
| 66 |
+
def device_name(self, device_index=None):
|
| 67 |
+
if device_index is None:
|
| 68 |
+
return 'sdaa'
|
| 69 |
+
return 'sdaa:{}'.format(device_index)
|
| 70 |
+
|
| 71 |
+
def device(self, device_index=None):
|
| 72 |
+
return torch.sdaa.device(device_index)
|
| 73 |
+
|
| 74 |
+
def set_device(self, device_index):
|
| 75 |
+
torch.sdaa.set_device(device_index)
|
| 76 |
+
|
| 77 |
+
def current_device(self):
|
| 78 |
+
return torch.sdaa.current_device()
|
| 79 |
+
|
| 80 |
+
def current_device_name(self):
|
| 81 |
+
return 'sdaa:{}'.format(torch.sdaa.current_device())
|
| 82 |
+
|
| 83 |
+
def device_count(self):
|
| 84 |
+
return torch.sdaa.device_count()
|
| 85 |
+
|
| 86 |
+
def synchronize(self, device_index=None):
|
| 87 |
+
return torch.sdaa.synchronize(device_index)
|
| 88 |
+
|
| 89 |
+
# RNG APIs
|
| 90 |
+
def random(self):
|
| 91 |
+
return torch.random
|
| 92 |
+
|
| 93 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 94 |
+
if device_index is None:
|
| 95 |
+
return torch.sdaa.set_rng_state(new_state)
|
| 96 |
+
|
| 97 |
+
return torch.sdaa.set_rng_state(new_state, device_index)
|
| 98 |
+
|
| 99 |
+
def get_rng_state(self, device_index=None):
|
| 100 |
+
if device_index is None:
|
| 101 |
+
return torch.sdaa.get_rng_state()
|
| 102 |
+
|
| 103 |
+
return torch.sdaa.get_rng_state(device_index)
|
| 104 |
+
|
| 105 |
+
def manual_seed(self, seed):
|
| 106 |
+
return torch.sdaa.manual_seed(seed)
|
| 107 |
+
|
| 108 |
+
def manual_seed_all(self, seed):
|
| 109 |
+
return torch.sdaa.manual_seed_all(seed)
|
| 110 |
+
|
| 111 |
+
def initial_seed(self):
|
| 112 |
+
return torch.sdaa.initial_seed()
|
| 113 |
+
|
| 114 |
+
def default_generator(self, device_index):
|
| 115 |
+
return torch.sdaa.default_generators[device_index]
|
| 116 |
+
|
| 117 |
+
# Streams/Events
|
| 118 |
+
@property
|
| 119 |
+
def Stream(self):
|
| 120 |
+
return torch.sdaa.Stream
|
| 121 |
+
|
| 122 |
+
def stream(self, stream):
|
| 123 |
+
return torch.sdaa.stream(stream)
|
| 124 |
+
|
| 125 |
+
def current_stream(self, device_index=None):
|
| 126 |
+
return torch.sdaa.current_stream(device_index)
|
| 127 |
+
|
| 128 |
+
def default_stream(self, device_index=None):
|
| 129 |
+
return torch.sdaa.default_stream(device_index)
|
| 130 |
+
|
| 131 |
+
@property
|
| 132 |
+
def Event(self):
|
| 133 |
+
return torch.sdaa.Event
|
| 134 |
+
|
| 135 |
+
# Memory management
|
| 136 |
+
def empty_cache(self):
|
| 137 |
+
return torch.sdaa.empty_cache()
|
| 138 |
+
|
| 139 |
+
def memory_allocated(self, device_index=None):
|
| 140 |
+
return torch.sdaa.memory_allocated(device_index)
|
| 141 |
+
|
| 142 |
+
def max_memory_allocated(self, device_index=None):
|
| 143 |
+
return torch.sdaa.max_memory_allocated(device_index)
|
| 144 |
+
|
| 145 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 146 |
+
return torch.sdaa.reset_max_memory_allocated(device_index)
|
| 147 |
+
|
| 148 |
+
def memory_cached(self, device_index=None):
|
| 149 |
+
return torch.sdaa.memory_cached(device_index)
|
| 150 |
+
|
| 151 |
+
def max_memory_cached(self, device_index=None):
|
| 152 |
+
return torch.sdaa.max_memory_cached(device_index)
|
| 153 |
+
|
| 154 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 155 |
+
return torch.sdaa.reset_max_memory_cached(device_index)
|
| 156 |
+
|
| 157 |
+
def memory_stats(self, device_index=None):
|
| 158 |
+
if hasattr(torch.sdaa, 'memory_stats'):
|
| 159 |
+
return torch.sdaa.memory_stats(device_index)
|
| 160 |
+
|
| 161 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 162 |
+
if hasattr(torch.sdaa, 'reset_peak_memory_stats'):
|
| 163 |
+
return torch.sdaa.reset_peak_memory_stats(device_index)
|
| 164 |
+
|
| 165 |
+
def memory_reserved(self, device_index=None):
|
| 166 |
+
if hasattr(torch.sdaa, 'memory_reserved'):
|
| 167 |
+
return torch.sdaa.memory_reserved(device_index)
|
| 168 |
+
|
| 169 |
+
def max_memory_reserved(self, device_index=None):
|
| 170 |
+
if hasattr(torch.sdaa, 'max_memory_reserved'):
|
| 171 |
+
return torch.sdaa.max_memory_reserved(device_index)
|
| 172 |
+
|
| 173 |
+
def total_memory(self, device_index=None):
|
| 174 |
+
return torch.sdaa.get_device_properties(device_index).total_memory
|
| 175 |
+
|
| 176 |
+
def available_memory(self, device_index=None):
|
| 177 |
+
return self.total_memory(device_index) - self.memory_allocated(device_index)
|
| 178 |
+
|
| 179 |
+
# Data types
|
| 180 |
+
def is_bf16_supported(self):
|
| 181 |
+
return torch.sdaa.is_bf16_supported()
|
| 182 |
+
|
| 183 |
+
def is_fp16_supported(self):
|
| 184 |
+
return True
|
| 185 |
+
|
| 186 |
+
def supported_dtypes(self):
|
| 187 |
+
supported_dtypes = [torch.float]
|
| 188 |
+
if self.is_fp16_supported():
|
| 189 |
+
supported_dtypes.append(torch.half)
|
| 190 |
+
if self.is_bf16_supported():
|
| 191 |
+
supported_dtypes.append(torch.bfloat16)
|
| 192 |
+
return supported_dtypes
|
| 193 |
+
|
| 194 |
+
# Misc
|
| 195 |
+
def amp(self):
|
| 196 |
+
if hasattr(torch.sdaa, 'amp'):
|
| 197 |
+
return torch.sdaa.amp
|
| 198 |
+
return None
|
| 199 |
+
|
| 200 |
+
def is_available(self):
|
| 201 |
+
return torch.sdaa.is_available()
|
| 202 |
+
|
| 203 |
+
def range_push(self, msg):
|
| 204 |
+
return
|
| 205 |
+
|
| 206 |
+
def range_pop(self):
|
| 207 |
+
return
|
| 208 |
+
|
| 209 |
+
def lazy_call(self, callback):
|
| 210 |
+
return torch.sdaa._lazy_call(callback)
|
| 211 |
+
|
| 212 |
+
def communication_backend_name(self):
|
| 213 |
+
return self._communication_backend_name
|
| 214 |
+
|
| 215 |
+
def is_triton_supported(self):
|
| 216 |
+
return False
|
| 217 |
+
|
| 218 |
+
# Graph operations
|
| 219 |
+
def create_graph(self):
|
| 220 |
+
return None
|
| 221 |
+
|
| 222 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 223 |
+
from deepspeed.runtime.utils import noop_context
|
| 224 |
+
return noop_context()
|
| 225 |
+
|
| 226 |
+
def replay_graph(self, graph):
|
| 227 |
+
return
|
| 228 |
+
|
| 229 |
+
# Tensor operations
|
| 230 |
+
|
| 231 |
+
@property
|
| 232 |
+
def BFloat16Tensor(self):
|
| 233 |
+
return functools.partial(torch.tensor, dtype=torch.bfloat16, device='sdaa')
|
| 234 |
+
|
| 235 |
+
@property
|
| 236 |
+
def ByteTensor(self):
|
| 237 |
+
return functools.partial(torch.tensor, dtype=torch.uint8, device='sdaa')
|
| 238 |
+
|
| 239 |
+
@property
|
| 240 |
+
def DoubleTensor(self):
|
| 241 |
+
return functools.partial(torch.tensor, dtype=torch.double, device='sdaa')
|
| 242 |
+
|
| 243 |
+
@property
|
| 244 |
+
def FloatTensor(self):
|
| 245 |
+
return functools.partial(torch.tensor, dtype=torch.float, device='sdaa')
|
| 246 |
+
|
| 247 |
+
@property
|
| 248 |
+
def HalfTensor(self):
|
| 249 |
+
return functools.partial(torch.tensor, dtype=torch.half, device='sdaa')
|
| 250 |
+
|
| 251 |
+
@property
|
| 252 |
+
def IntTensor(self):
|
| 253 |
+
return functools.partial(torch.tensor, dtype=torch.int, device='sdaa')
|
| 254 |
+
|
| 255 |
+
@property
|
| 256 |
+
def LongTensor(self):
|
| 257 |
+
return functools.partial(torch.tensor, dtype=torch.long, device='sdaa')
|
| 258 |
+
|
| 259 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 260 |
+
return tensor.pin_memory()
|
| 261 |
+
|
| 262 |
+
def is_pinned(self, tensor):
|
| 263 |
+
return tensor.is_pinned()
|
| 264 |
+
|
| 265 |
+
def on_accelerator(self, tensor):
|
| 266 |
+
device_str = str(tensor.device)
|
| 267 |
+
if device_str.startswith('sdaa:'):
|
| 268 |
+
return True
|
| 269 |
+
else:
|
| 270 |
+
return False
|
| 271 |
+
|
| 272 |
+
def op_builder_dir(self):
|
| 273 |
+
try:
|
| 274 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 275 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 276 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 277 |
+
return "op_builder.sdaa"
|
| 278 |
+
except ImportError:
|
| 279 |
+
return "deepspeed.ops.op_builder.sdaa"
|
| 280 |
+
|
| 281 |
+
def _lazy_init_class_dict(self):
|
| 282 |
+
if self.class_dict:
|
| 283 |
+
return
|
| 284 |
+
|
| 285 |
+
op_builder_module = importlib.import_module(self.op_builder_dir())
|
| 286 |
+
|
| 287 |
+
# get op builder class from op_builder/sdaa/__init__.py
|
| 288 |
+
self.class_dict = {}
|
| 289 |
+
for class_name, class_obj in inspect.getmembers(op_builder_module, inspect.isclass):
|
| 290 |
+
self.class_dict[class_name] = class_obj
|
| 291 |
+
|
| 292 |
+
# create an instance of op builder and return, name specified by class_name
|
| 293 |
+
def create_op_builder(self, class_name):
|
| 294 |
+
builder_class = self.get_op_builder(class_name)
|
| 295 |
+
return builder_class()
|
| 296 |
+
|
| 297 |
+
# return an op builder class, name specified by class_name
|
| 298 |
+
def get_op_builder(self, class_name):
|
| 299 |
+
self._lazy_init_class_dict()
|
| 300 |
+
if class_name in self.class_dict:
|
| 301 |
+
return self.class_dict[class_name]
|
| 302 |
+
else:
|
| 303 |
+
return self.class_dict['NotImplementedBuilder']
|
| 304 |
+
|
| 305 |
+
def build_extension(self):
|
| 306 |
+
from torch.utils.cpp_extension import BuildExtension
|
| 307 |
+
return BuildExtension
|
| 308 |
+
|
| 309 |
+
def export_envs(self):
|
| 310 |
+
return ['NCCL', 'LD_LIBRARY', 'PATH']
|
| 311 |
+
|
| 312 |
+
def visible_devices_envs(self):
|
| 313 |
+
return ['SDAA_VISIBLE_DEVICES']
|
| 314 |
+
|
| 315 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 316 |
+
for env in self.visible_devices_envs():
|
| 317 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 318 |
+
|
| 319 |
+
def get_compile_backend(self):
|
| 320 |
+
return self._compile_backend
|
| 321 |
+
|
| 322 |
+
def set_compile_backend(self, backend):
|
| 323 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 324 |
+
if backend in supported_backends:
|
| 325 |
+
self._compile_backend = backend
|
| 326 |
+
else:
|
| 327 |
+
raise ValueError(
|
| 328 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends}")
|
lib/python3.12/site-packages/deepspeed/accelerator/xpu_accelerator.py
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
from deepspeed.accelerator.abstract_accelerator import DeepSpeedAccelerator
|
| 8 |
+
import functools
|
| 9 |
+
import importlib
|
| 10 |
+
import inspect
|
| 11 |
+
|
| 12 |
+
try:
|
| 13 |
+
import oneccl_bindings_for_pytorch # noqa: F401 # type: ignore
|
| 14 |
+
oneccl_imported_p = True
|
| 15 |
+
except ImportError as e:
|
| 16 |
+
oneccl_imported_p = False
|
| 17 |
+
|
| 18 |
+
try:
|
| 19 |
+
import intel_extension_for_pytorch as ipex # noqa: F401 # type: ignore
|
| 20 |
+
ipex_imported_p = True
|
| 21 |
+
except ImportError as e:
|
| 22 |
+
ipex_imported_p = False
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class XPU_Accelerator(DeepSpeedAccelerator):
|
| 26 |
+
|
| 27 |
+
def __init__(self):
|
| 28 |
+
self._name = 'xpu'
|
| 29 |
+
if oneccl_imported_p:
|
| 30 |
+
self._communication_backend_name = 'ccl'
|
| 31 |
+
else:
|
| 32 |
+
# changed to xccl if not using torch-CCL on XPU device
|
| 33 |
+
self._communication_backend_name = 'xccl'
|
| 34 |
+
self._compile_backend = "inductor"
|
| 35 |
+
self.aligned_tensors = []
|
| 36 |
+
self.class_dict = None
|
| 37 |
+
|
| 38 |
+
def is_synchronized_device(self):
|
| 39 |
+
return False
|
| 40 |
+
|
| 41 |
+
def use_host_timers(self):
|
| 42 |
+
if not ipex_imported_p:
|
| 43 |
+
return self.is_synchronized_device()
|
| 44 |
+
else:
|
| 45 |
+
# WA XPU event will be consolidated in 2.6
|
| 46 |
+
if ipex.__version__ < '2.6':
|
| 47 |
+
return True
|
| 48 |
+
else:
|
| 49 |
+
return self.is_synchronized_device()
|
| 50 |
+
|
| 51 |
+
def resolves_data_dependency(self):
|
| 52 |
+
return self.is_synchronized_device()
|
| 53 |
+
|
| 54 |
+
def handles_memory_backpressure(self):
|
| 55 |
+
return self.is_synchronized_device()
|
| 56 |
+
|
| 57 |
+
# Device APIs
|
| 58 |
+
def device_name(self, device_index=None):
|
| 59 |
+
if device_index == None:
|
| 60 |
+
return 'xpu'
|
| 61 |
+
return 'xpu:{}'.format(device_index)
|
| 62 |
+
|
| 63 |
+
def device(self, device_index=None):
|
| 64 |
+
return torch.xpu.device(device_index)
|
| 65 |
+
|
| 66 |
+
def set_device(self, device_index):
|
| 67 |
+
torch.xpu.set_device(device_index)
|
| 68 |
+
|
| 69 |
+
def current_device(self):
|
| 70 |
+
return torch.xpu.current_device()
|
| 71 |
+
|
| 72 |
+
def current_device_name(self):
|
| 73 |
+
return 'xpu:{}'.format(torch.xpu.current_device())
|
| 74 |
+
|
| 75 |
+
def device_count(self):
|
| 76 |
+
return torch.xpu.device_count()
|
| 77 |
+
|
| 78 |
+
def synchronize(self, device_index=None):
|
| 79 |
+
return torch.xpu.synchronize(device_index)
|
| 80 |
+
|
| 81 |
+
# RNG APIs
|
| 82 |
+
def random(self):
|
| 83 |
+
return torch.xpu.random
|
| 84 |
+
|
| 85 |
+
def set_rng_state(self, new_state, device_index=None):
|
| 86 |
+
if device_index == None:
|
| 87 |
+
return torch.xpu.set_rng_state(new_state)
|
| 88 |
+
return torch.xpu.set_rng_state(new_state, device_index)
|
| 89 |
+
|
| 90 |
+
def get_rng_state(self, device_index=None):
|
| 91 |
+
if device_index == None:
|
| 92 |
+
return torch.xpu.get_rng_state()
|
| 93 |
+
return torch.xpu.get_rng_state(device_index)
|
| 94 |
+
|
| 95 |
+
def manual_seed(self, seed):
|
| 96 |
+
return torch.xpu.manual_seed(seed)
|
| 97 |
+
|
| 98 |
+
def manual_seed_all(self, seed):
|
| 99 |
+
return torch.xpu.manual_seed_all(seed)
|
| 100 |
+
|
| 101 |
+
def initial_seed(self):
|
| 102 |
+
return torch.xpu.initial_seed()
|
| 103 |
+
|
| 104 |
+
def default_generator(self, device_index):
|
| 105 |
+
return torch.xpu.default_generators[device_index]
|
| 106 |
+
|
| 107 |
+
# Streams/Events
|
| 108 |
+
@property
|
| 109 |
+
def Stream(self):
|
| 110 |
+
return torch.xpu.Stream
|
| 111 |
+
|
| 112 |
+
def stream(self, stream):
|
| 113 |
+
return torch.xpu.stream(stream)
|
| 114 |
+
|
| 115 |
+
def current_stream(self, device_index=None):
|
| 116 |
+
return torch.xpu.current_stream(device_index)
|
| 117 |
+
|
| 118 |
+
def default_stream(self, device_index=None):
|
| 119 |
+
# torch.xpu does not support the sync behavior of default stream as cuda
|
| 120 |
+
# use current_stream as workaround
|
| 121 |
+
# see https://pytorch.org/docs/stable/notes/cuda.html#cuda-streams
|
| 122 |
+
return torch.xpu.current_stream(device_index)
|
| 123 |
+
|
| 124 |
+
@property
|
| 125 |
+
def Event(self):
|
| 126 |
+
return torch.xpu.Event
|
| 127 |
+
|
| 128 |
+
# Memory management
|
| 129 |
+
def empty_cache(self):
|
| 130 |
+
return torch.xpu.empty_cache()
|
| 131 |
+
|
| 132 |
+
def memory_allocated(self, device_index=None):
|
| 133 |
+
return torch.xpu.memory_allocated(device_index)
|
| 134 |
+
|
| 135 |
+
def max_memory_allocated(self, device_index=None):
|
| 136 |
+
return torch.xpu.max_memory_allocated(device_index)
|
| 137 |
+
|
| 138 |
+
def reset_max_memory_allocated(self, device_index=None):
|
| 139 |
+
return torch.xpu.reset_max_memory_allocated(device_index)
|
| 140 |
+
|
| 141 |
+
def memory_cached(self, device_index=None):
|
| 142 |
+
return torch.xpu.memory_reserved(device_index)
|
| 143 |
+
|
| 144 |
+
def max_memory_cached(self, device_index=None):
|
| 145 |
+
return torch.xpu.max_memory_reserved(device_index)
|
| 146 |
+
|
| 147 |
+
def reset_max_memory_cached(self, device_index=None):
|
| 148 |
+
return torch.xpu.reset_max_memory_reserved(device_index)
|
| 149 |
+
|
| 150 |
+
def memory_stats(self, device_index=None):
|
| 151 |
+
return torch.xpu.memory_stats(device_index)
|
| 152 |
+
|
| 153 |
+
def reset_peak_memory_stats(self, device_index=None):
|
| 154 |
+
return torch.xpu.reset_peak_memory_stats(device_index)
|
| 155 |
+
|
| 156 |
+
def memory_reserved(self, device_index=None):
|
| 157 |
+
return torch.xpu.memory_reserved(device_index)
|
| 158 |
+
|
| 159 |
+
def max_memory_reserved(self, device_index=None):
|
| 160 |
+
return torch.xpu.max_memory_reserved(device_index)
|
| 161 |
+
|
| 162 |
+
def total_memory(self, device_index=None):
|
| 163 |
+
return torch.xpu.get_device_properties(device_index).total_memory
|
| 164 |
+
|
| 165 |
+
def available_memory(self, device_index=None):
|
| 166 |
+
return self.total_memory(device_index) - self.memory_allocated(device_index)
|
| 167 |
+
|
| 168 |
+
# Misc
|
| 169 |
+
def amp(self):
|
| 170 |
+
return torch.xpu.amp
|
| 171 |
+
|
| 172 |
+
def is_available(self):
|
| 173 |
+
return torch.xpu.is_available()
|
| 174 |
+
|
| 175 |
+
def range_push(self, msg):
|
| 176 |
+
# TODO itt is currently not supported yet
|
| 177 |
+
# return torch.profiler.itt.range_push(msg)
|
| 178 |
+
return
|
| 179 |
+
|
| 180 |
+
def range_pop(self):
|
| 181 |
+
# TODO itt is currently not supported yet
|
| 182 |
+
# return torch.profiler.itt.range_pop()
|
| 183 |
+
return
|
| 184 |
+
|
| 185 |
+
def lazy_call(self, callback):
|
| 186 |
+
if hasattr(torch.xpu, "_lazy_call"):
|
| 187 |
+
return torch.xpu._lazy_call(callback)
|
| 188 |
+
else:
|
| 189 |
+
return torch.xpu.lazy_init._lazy_call(callback)
|
| 190 |
+
|
| 191 |
+
def communication_backend_name(self):
|
| 192 |
+
return self._communication_backend_name
|
| 193 |
+
|
| 194 |
+
def is_triton_supported(self):
|
| 195 |
+
return False
|
| 196 |
+
|
| 197 |
+
# Graph operations
|
| 198 |
+
def create_graph(self):
|
| 199 |
+
return None
|
| 200 |
+
|
| 201 |
+
def capture_to_graph(self, graph, pool=None, stream=None):
|
| 202 |
+
from deepspeed.runtime.utils import noop_context
|
| 203 |
+
return noop_context()
|
| 204 |
+
|
| 205 |
+
def replay_graph(self, graph):
|
| 206 |
+
return
|
| 207 |
+
|
| 208 |
+
# Data types
|
| 209 |
+
def is_bf16_supported(self):
|
| 210 |
+
return True
|
| 211 |
+
|
| 212 |
+
def is_fp16_supported(self):
|
| 213 |
+
return True
|
| 214 |
+
|
| 215 |
+
def supported_dtypes(self):
|
| 216 |
+
return [torch.float, torch.half, torch.bfloat16]
|
| 217 |
+
|
| 218 |
+
# Tensor operations
|
| 219 |
+
|
| 220 |
+
@property
|
| 221 |
+
def BFloat16Tensor(self):
|
| 222 |
+
return functools.partial(torch.tensor, dtype=torch.bfloat16, device=self._name)
|
| 223 |
+
|
| 224 |
+
@property
|
| 225 |
+
def ByteTensor(self):
|
| 226 |
+
return functools.partial(torch.tensor, dtype=torch.uint8, device=self._name)
|
| 227 |
+
|
| 228 |
+
@property
|
| 229 |
+
def DoubleTensor(self):
|
| 230 |
+
return functools.partial(torch.tensor, dtype=torch.double, device=self._name)
|
| 231 |
+
|
| 232 |
+
@property
|
| 233 |
+
def FloatTensor(self):
|
| 234 |
+
return functools.partial(torch.tensor, dtype=torch.float, device=self._name)
|
| 235 |
+
|
| 236 |
+
@property
|
| 237 |
+
def HalfTensor(self):
|
| 238 |
+
return functools.partial(torch.tensor, dtype=torch.half, device=self._name)
|
| 239 |
+
|
| 240 |
+
@property
|
| 241 |
+
def IntTensor(self):
|
| 242 |
+
return functools.partial(torch.tensor, dtype=torch.int, device=self._name)
|
| 243 |
+
|
| 244 |
+
@property
|
| 245 |
+
def LongTensor(self):
|
| 246 |
+
return functools.partial(torch.tensor, dtype=torch.long, device=self._name)
|
| 247 |
+
|
| 248 |
+
def pin_memory(self, tensor, align_bytes=1):
|
| 249 |
+
if align_bytes == 1:
|
| 250 |
+
return tensor.pin_memory(device=self.current_device_name())
|
| 251 |
+
elif align_bytes == 0:
|
| 252 |
+
from deepspeed.ops.op_builder.xpu import AsyncIOBuilder
|
| 253 |
+
self.aio_handle = AsyncIOBuilder().load().aio_handle(128 * 1024, 8, False, False, False)
|
| 254 |
+
aligned_t = self.aio_handle.new_cpu_locked_tensor(tensor.numel(), tensor)
|
| 255 |
+
aligned_t = aligned_t[:tensor.numel()].copy_(tensor)
|
| 256 |
+
self.aligned_tensors.append([aligned_t.data_ptr(), aligned_t[-1].data_ptr()])
|
| 257 |
+
return aligned_t
|
| 258 |
+
|
| 259 |
+
def is_pinned(self, tensor):
|
| 260 |
+
if tensor.is_pinned(device=self.current_device_name()):
|
| 261 |
+
return True
|
| 262 |
+
else:
|
| 263 |
+
for begin, end in self.aligned_tensors:
|
| 264 |
+
if begin <= tensor.data_ptr() and tensor.data_ptr() <= end:
|
| 265 |
+
return True
|
| 266 |
+
return False
|
| 267 |
+
|
| 268 |
+
def op_builder_dir(self):
|
| 269 |
+
try:
|
| 270 |
+
# is op_builder from deepspeed or a 3p version? this should only succeed if it's deepspeed
|
| 271 |
+
# if successful this also means we're doing a local install and not JIT compile path
|
| 272 |
+
from op_builder import __deepspeed__ # noqa: F401 # type: ignore
|
| 273 |
+
return "op_builder.xpu"
|
| 274 |
+
except ImportError:
|
| 275 |
+
return "deepspeed.ops.op_builder.xpu"
|
| 276 |
+
|
| 277 |
+
def on_accelerator(self, tensor):
|
| 278 |
+
device_str = str(tensor.device)
|
| 279 |
+
if device_str.startswith('xpu:'):
|
| 280 |
+
return True
|
| 281 |
+
else:
|
| 282 |
+
return False
|
| 283 |
+
|
| 284 |
+
def _lazy_init_class_dict(self):
|
| 285 |
+
if self.class_dict:
|
| 286 |
+
return
|
| 287 |
+
|
| 288 |
+
op_builder_module = importlib.import_module(self.op_builder_dir())
|
| 289 |
+
|
| 290 |
+
# get op builder class from op_builder/xpu/__init__.py
|
| 291 |
+
self.class_dict = {}
|
| 292 |
+
for class_name, class_obj in inspect.getmembers(op_builder_module, inspect.isclass):
|
| 293 |
+
self.class_dict[class_name] = class_obj
|
| 294 |
+
|
| 295 |
+
# create an instance of op builder and return, name specified by class_name
|
| 296 |
+
def create_op_builder(self, class_name):
|
| 297 |
+
builder_class = self.get_op_builder(class_name)
|
| 298 |
+
return builder_class()
|
| 299 |
+
|
| 300 |
+
# return an op builder class, name specified by class_name
|
| 301 |
+
def get_op_builder(self, class_name):
|
| 302 |
+
self._lazy_init_class_dict()
|
| 303 |
+
if class_name in self.class_dict:
|
| 304 |
+
return self.class_dict[class_name]
|
| 305 |
+
else:
|
| 306 |
+
return self.class_dict['NotImplementedBuilder']
|
| 307 |
+
|
| 308 |
+
def build_extension(self):
|
| 309 |
+
if ipex_imported_p:
|
| 310 |
+
try:
|
| 311 |
+
from intel_extension_for_pytorch.xpu.cpp_extension import DpcppBuildExtension
|
| 312 |
+
except ImportError:
|
| 313 |
+
from intel_extension_for_pytorch.xpu.utils import DpcppBuildExtension
|
| 314 |
+
else:
|
| 315 |
+
from torch.utils.cpp_extension import DpcppBuildExtension
|
| 316 |
+
return DpcppBuildExtension
|
| 317 |
+
|
| 318 |
+
def export_envs(self):
|
| 319 |
+
return []
|
| 320 |
+
|
| 321 |
+
def visible_devices_envs(self):
|
| 322 |
+
return ['ZE_AFFINITY_MASK']
|
| 323 |
+
|
| 324 |
+
def set_visible_devices_envs(self, current_env, local_accelerator_ids):
|
| 325 |
+
for env in self.visible_devices_envs():
|
| 326 |
+
current_env[env] = ",".join(map(str, local_accelerator_ids))
|
| 327 |
+
|
| 328 |
+
def get_compile_backend(self):
|
| 329 |
+
return self._compile_backend
|
| 330 |
+
|
| 331 |
+
def set_compile_backend(self, backend):
|
| 332 |
+
supported_backends = torch._dynamo.list_backends(exclude_tags=())
|
| 333 |
+
if backend in supported_backends:
|
| 334 |
+
self._compile_backend = backend
|
| 335 |
+
else:
|
| 336 |
+
raise ValueError(
|
| 337 |
+
f"{backend} not supported by {self.device_name()}. Supported Backends are {supported_backends}")
|
lib/python3.12/site-packages/deepspeed/constants.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
from datetime import timedelta
|
| 8 |
+
|
| 9 |
+
#############################################
|
| 10 |
+
# Torch distributed constants
|
| 11 |
+
#############################################
|
| 12 |
+
TORCH_DISTRIBUTED_DEFAULT_PORT = 29500
|
| 13 |
+
|
| 14 |
+
# Default process group wide timeout, if applicable.
|
| 15 |
+
# This only applies to the gloo and nccl backends
|
| 16 |
+
# (only if NCCL_BLOCKING_WAIT or NCCL_ASYNC_ERROR_HANDLING is set to 1).
|
| 17 |
+
# To make an attempt at backwards compatibility with THD, we use an
|
| 18 |
+
# extraordinarily high default timeout, given that THD did not have timeouts.
|
| 19 |
+
default_pg_timeout = timedelta(minutes=int(os.getenv("DEEPSPEED_TIMEOUT", default=30)))
|
| 20 |
+
INFERENCE_GENERIC_MODE = 'generic'
|
| 21 |
+
INFERENCE_SPECIALIZED_MODE = 'specialized'
|
lib/python3.12/site-packages/deepspeed/env_report.py
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
import torch
|
| 8 |
+
import deepspeed
|
| 9 |
+
import subprocess
|
| 10 |
+
import argparse
|
| 11 |
+
from .ops.op_builder.all_ops import ALL_OPS
|
| 12 |
+
from .git_version_info import installed_ops, torch_info, accelerator_name
|
| 13 |
+
from deepspeed.accelerator import get_accelerator
|
| 14 |
+
|
| 15 |
+
GREEN = '\033[92m'
|
| 16 |
+
RED = '\033[91m'
|
| 17 |
+
YELLOW = '\033[93m'
|
| 18 |
+
END = '\033[0m'
|
| 19 |
+
SUCCESS = f"{GREEN} [SUCCESS] {END}"
|
| 20 |
+
OKAY = f"{GREEN}[OKAY]{END}"
|
| 21 |
+
WARNING = f"{YELLOW}[WARNING]{END}"
|
| 22 |
+
FAIL = f'{RED}[FAIL]{END}'
|
| 23 |
+
INFO = '[INFO]'
|
| 24 |
+
|
| 25 |
+
color_len = len(GREEN) + len(END)
|
| 26 |
+
okay = f"{GREEN}[OKAY]{END}"
|
| 27 |
+
warning = f"{YELLOW}[WARNING]{END}"
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def op_report(verbose=True):
|
| 31 |
+
max_dots = 23
|
| 32 |
+
max_dots2 = 11
|
| 33 |
+
h = ["op name", "installed", "compatible"]
|
| 34 |
+
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
| 35 |
+
print("DeepSpeed C++/CUDA extension op report")
|
| 36 |
+
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
| 37 |
+
|
| 38 |
+
print("NOTE: Ops not installed will be just-in-time (JIT) compiled at\n"
|
| 39 |
+
" runtime if needed. Op compatibility means that your system\n"
|
| 40 |
+
" meet the required dependencies to JIT install the op.")
|
| 41 |
+
|
| 42 |
+
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
| 43 |
+
print("JIT compiled ops requires ninja")
|
| 44 |
+
ninja_status = OKAY if ninja_installed() else FAIL
|
| 45 |
+
print('ninja', "." * (max_dots - 5), ninja_status)
|
| 46 |
+
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
| 47 |
+
print(h[0], "." * (max_dots - len(h[0])), h[1], "." * (max_dots2 - len(h[1])), h[2])
|
| 48 |
+
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
| 49 |
+
installed = f"{GREEN}[YES]{END}"
|
| 50 |
+
no = f"{YELLOW}[NO]{END}"
|
| 51 |
+
for op_name, builder in ALL_OPS.items():
|
| 52 |
+
dots = "." * (max_dots - len(op_name))
|
| 53 |
+
is_compatible = OKAY if builder.is_compatible(verbose) else no
|
| 54 |
+
is_installed = installed if installed_ops.get(op_name,
|
| 55 |
+
False) and accelerator_name == get_accelerator()._name else no
|
| 56 |
+
dots2 = '.' * ((len(h[1]) + (max_dots2 - len(h[1]))) - (len(is_installed) - color_len))
|
| 57 |
+
print(op_name, dots, is_installed, dots2, is_compatible)
|
| 58 |
+
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
def ninja_installed():
|
| 62 |
+
try:
|
| 63 |
+
import ninja # noqa: F401 # type: ignore
|
| 64 |
+
except ImportError:
|
| 65 |
+
return False
|
| 66 |
+
return True
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def nvcc_version():
|
| 70 |
+
import torch.utils.cpp_extension
|
| 71 |
+
cuda_home = torch.utils.cpp_extension.CUDA_HOME
|
| 72 |
+
if cuda_home is None:
|
| 73 |
+
return f"{RED} [FAIL] cannot find CUDA_HOME via torch.utils.cpp_extension.CUDA_HOME={torch.utils.cpp_extension.CUDA_HOME} {END}"
|
| 74 |
+
try:
|
| 75 |
+
output = subprocess.check_output([cuda_home + "/bin/nvcc", "-V"], universal_newlines=True)
|
| 76 |
+
except FileNotFoundError:
|
| 77 |
+
return f"{RED} [FAIL] nvcc missing {END}"
|
| 78 |
+
output_split = output.split()
|
| 79 |
+
release_idx = output_split.index("release")
|
| 80 |
+
release = output_split[release_idx + 1].replace(',', '').split(".")
|
| 81 |
+
return ".".join(release)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def installed_cann_path():
|
| 85 |
+
if "ASCEND_HOME_PATH" in os.environ or os.path.exists(os.environ["ASCEND_HOME_PATH"]):
|
| 86 |
+
return os.environ["ASCEND_HOME_PATH"]
|
| 87 |
+
return None
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def installed_cann_version():
|
| 91 |
+
import re
|
| 92 |
+
ascend_path = installed_cann_path()
|
| 93 |
+
if ascend_path is None:
|
| 94 |
+
return f"CANN_HOME does not exist, unable to compile NPU op(s)"
|
| 95 |
+
cann_version = ""
|
| 96 |
+
for dirpath, _, filenames in os.walk(os.path.realpath(ascend_path)):
|
| 97 |
+
if cann_version:
|
| 98 |
+
break
|
| 99 |
+
install_files = [file for file in filenames if re.match(r"ascend_.*_install\.info", file)]
|
| 100 |
+
if install_files:
|
| 101 |
+
filepath = os.path.join(dirpath, install_files[0])
|
| 102 |
+
with open(filepath, "r") as f:
|
| 103 |
+
for line in f:
|
| 104 |
+
if line.find("version") != -1:
|
| 105 |
+
cann_version = line.strip().split("=")[-1]
|
| 106 |
+
break
|
| 107 |
+
return cann_version
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def get_shm_size():
|
| 111 |
+
try:
|
| 112 |
+
shm_stats = os.statvfs('/dev/shm')
|
| 113 |
+
except (OSError, FileNotFoundError, ValueError, AttributeError):
|
| 114 |
+
return "UNKNOWN", None
|
| 115 |
+
|
| 116 |
+
shm_size = shm_stats.f_frsize * shm_stats.f_blocks
|
| 117 |
+
shm_hbytes = human_readable_size(shm_size)
|
| 118 |
+
warn = []
|
| 119 |
+
if shm_size < 512 * 1024**2:
|
| 120 |
+
warn.append(
|
| 121 |
+
f" {YELLOW} [WARNING] /dev/shm size might be too small, if running in docker increase to at least --shm-size='1gb' {END}"
|
| 122 |
+
)
|
| 123 |
+
if get_accelerator().communication_backend_name() == "nccl":
|
| 124 |
+
warn.append(
|
| 125 |
+
f" {YELLOW} [WARNING] see more details about NCCL requirements: https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/troubleshooting.html#sharing-data {END}"
|
| 126 |
+
)
|
| 127 |
+
return shm_hbytes, warn
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
def human_readable_size(size):
|
| 131 |
+
units = ['B', 'KB', 'MB', 'GB', 'TB']
|
| 132 |
+
i = 0
|
| 133 |
+
while size >= 1024 and i < len(units) - 1:
|
| 134 |
+
size /= 1024
|
| 135 |
+
i += 1
|
| 136 |
+
return f'{size:.2f} {units[i]}'
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
def debug_report():
|
| 140 |
+
max_dots = 33
|
| 141 |
+
|
| 142 |
+
report = [("torch install path", torch.__path__), ("torch version", torch.__version__),
|
| 143 |
+
("deepspeed install path", deepspeed.__path__),
|
| 144 |
+
("deepspeed info", f"{deepspeed.__version__}, {deepspeed.__git_hash__}, {deepspeed.__git_branch__}")]
|
| 145 |
+
if get_accelerator().device_name() == 'cuda':
|
| 146 |
+
hip_version = getattr(torch.version, "hip", None)
|
| 147 |
+
report.extend([("torch cuda version", torch.version.cuda), ("torch hip version", hip_version),
|
| 148 |
+
("nvcc version", (None if hip_version else nvcc_version())),
|
| 149 |
+
("deepspeed wheel compiled w.", f"torch {torch_info['version']}, " +
|
| 150 |
+
(f"hip {torch_info['hip_version']}" if hip_version else f"cuda {torch_info['cuda_version']}"))
|
| 151 |
+
])
|
| 152 |
+
elif get_accelerator().device_name() == 'npu':
|
| 153 |
+
import torch_npu
|
| 154 |
+
report.extend([("deepspeed wheel compiled w.", f"torch {torch_info['version']}"),
|
| 155 |
+
("torch_npu install path", torch_npu.__path__), ("torch_npu version", torch_npu.__version__),
|
| 156 |
+
("ascend_cann version", installed_cann_version())])
|
| 157 |
+
else:
|
| 158 |
+
report.extend([("deepspeed wheel compiled w.", f"torch {torch_info['version']} ")])
|
| 159 |
+
|
| 160 |
+
report.append(("shared memory (/dev/shm) size", get_shm_size()))
|
| 161 |
+
|
| 162 |
+
print("DeepSpeed general environment info:")
|
| 163 |
+
for name, value in report:
|
| 164 |
+
warns = []
|
| 165 |
+
if isinstance(value, tuple):
|
| 166 |
+
value, warns = value
|
| 167 |
+
print(name, "." * (max_dots - len(name)), value)
|
| 168 |
+
if warns:
|
| 169 |
+
for warn in warns:
|
| 170 |
+
print(warn)
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
def parse_arguments():
|
| 174 |
+
parser = argparse.ArgumentParser()
|
| 175 |
+
parser.add_argument('--hide_operator_status',
|
| 176 |
+
action='store_true',
|
| 177 |
+
help='Suppress display of installation and compatibility statuses of DeepSpeed operators. ')
|
| 178 |
+
parser.add_argument('--hide_errors_and_warnings', action='store_true', help='Suppress warning and error messages.')
|
| 179 |
+
args = parser.parse_args()
|
| 180 |
+
return args
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def main(hide_operator_status=False, hide_errors_and_warnings=False):
|
| 184 |
+
if not hide_operator_status:
|
| 185 |
+
op_report(verbose=not hide_errors_and_warnings)
|
| 186 |
+
debug_report()
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
def cli_main():
|
| 190 |
+
args = parse_arguments()
|
| 191 |
+
main(hide_operator_status=args.hide_operator_status, hide_errors_and_warnings=args.hide_errors_and_warnings)
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
if __name__ == "__main__":
|
| 195 |
+
main()
|
lib/python3.12/site-packages/deepspeed/git_version_info.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
try:
|
| 7 |
+
# This is populated by setup.py
|
| 8 |
+
from .git_version_info_installed import * # noqa: F401 # type: ignore
|
| 9 |
+
except ModuleNotFoundError:
|
| 10 |
+
import os
|
| 11 |
+
if os.path.isfile('version.txt'):
|
| 12 |
+
# Will be missing from checkouts that haven't been installed (e.g., readthedocs)
|
| 13 |
+
version = open('version.txt', 'r').read().strip()
|
| 14 |
+
else:
|
| 15 |
+
version = "0.0.0"
|
| 16 |
+
git_hash = '[none]'
|
| 17 |
+
git_branch = '[none]'
|
| 18 |
+
|
| 19 |
+
from .ops.op_builder.all_ops import ALL_OPS
|
| 20 |
+
installed_ops = dict.fromkeys(ALL_OPS.keys(), False)
|
| 21 |
+
accelerator_name = ""
|
| 22 |
+
torch_info = {'version': "0.0", "cuda_version": "0.0", "hip_version": "0.0"}
|
| 23 |
+
|
| 24 |
+
# compatible_ops list is recreated for each launch
|
| 25 |
+
from .ops.op_builder.all_ops import ALL_OPS
|
| 26 |
+
|
| 27 |
+
compatible_ops = dict.fromkeys(ALL_OPS.keys(), False)
|
| 28 |
+
for op_name, builder in ALL_OPS.items():
|
| 29 |
+
op_compatible = builder.is_compatible()
|
| 30 |
+
compatible_ops[op_name] = op_compatible
|
| 31 |
+
compatible_ops["deepspeed_not_implemented"] = False
|
lib/python3.12/site-packages/deepspeed/git_version_info_installed.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version='0.17.0'
|
| 2 |
+
git_hash='unknown'
|
| 3 |
+
git_branch='unknown'
|
| 4 |
+
installed_ops={'deepspeed_not_implemented': False, 'async_io': False, 'deepspeed_ccl_comm': False, 'deepspeed_shm_comm': False, 'cpu_adam': False, 'fused_adam': False}
|
| 5 |
+
accelerator_name='cpu'
|
| 6 |
+
torch_info={'version': '0.0', 'bf16_support': False, 'cuda_version': '0.0', 'nccl_version': '0.0', 'hip_version': '0.0'}
|
lib/python3.12/site-packages/deepspeed/inference/__init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
from .v2 import RaggedInferenceEngineConfig, DeepSpeedTPConfig
|
| 6 |
+
from .v2.engine_v2 import InferenceEngineV2
|
| 7 |
+
from .v2 import build_hf_engine, build_engine_from_ds_checkpoint
|
lib/python3.12/site-packages/deepspeed/inference/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (424 Bytes). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/__pycache__/config.cpython-312.pyc
ADDED
|
Binary file (9.1 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/__pycache__/engine.cpython-312.pyc
ADDED
|
Binary file (38.1 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/config.py
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
import deepspeed
|
| 8 |
+
from pydantic import Field, field_validator
|
| 9 |
+
from deepspeed.runtime.config_utils import DeepSpeedConfigModel
|
| 10 |
+
from deepspeed.runtime.zero.config import DeepSpeedZeroConfig
|
| 11 |
+
from typing import Dict, Union, Optional
|
| 12 |
+
from enum import Enum
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class DtypeEnum(Enum):
|
| 16 |
+
fp16 = (torch.float16, "torch.float16", "fp16", "float16", "half")
|
| 17 |
+
fp32 = (torch.float32, "torch.float32", "fp32", "float32", "float")
|
| 18 |
+
bf16 = (torch.bfloat16, "torch.bfloat16", "bf16", "bfloat16", "bfloat")
|
| 19 |
+
int8 = (torch.int8, "torch.int8", "int8")
|
| 20 |
+
|
| 21 |
+
@classmethod
|
| 22 |
+
def from_str(cls, value: str):
|
| 23 |
+
for dtype in cls:
|
| 24 |
+
if value in dtype.value:
|
| 25 |
+
return dtype
|
| 26 |
+
raise ValueError(f"'{value}' is not a valid DtypeEnum")
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class MoETypeEnum(str, Enum):
|
| 30 |
+
residual = "residual"
|
| 31 |
+
standard = "standard"
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class DeepSpeedTPConfig(DeepSpeedConfigModel):
|
| 35 |
+
""" Configure tensor parallelism settings """
|
| 36 |
+
|
| 37 |
+
enabled: bool = True
|
| 38 |
+
""" Turn tensor parallelism on/off. """
|
| 39 |
+
|
| 40 |
+
tp_size: int = 1
|
| 41 |
+
""" Number of devices to split the model across using tensor parallelism. """
|
| 42 |
+
|
| 43 |
+
tp_grain_size: int = 64
|
| 44 |
+
"Desired MLP/lm_head tp size granularity. DNN library favors tensor size in granularity of power of 2, we pick 64 as a default size."
|
| 45 |
+
|
| 46 |
+
mpu: object = None
|
| 47 |
+
"""
|
| 48 |
+
A model parallelism unit object that implements
|
| 49 |
+
``get_{model,data}_parallel_{rank,group,world_size}()``.
|
| 50 |
+
"""
|
| 51 |
+
|
| 52 |
+
tp_group: object = None
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
class DeepSpeedMoEConfig(DeepSpeedConfigModel):
|
| 56 |
+
""" Sets parameters for MoE """
|
| 57 |
+
|
| 58 |
+
enabled: bool = True
|
| 59 |
+
ep_size: int = 1
|
| 60 |
+
"""
|
| 61 |
+
The expert-parallelism size which is used for partitioning the experts
|
| 62 |
+
across the GPUs in the expert-parallel group.
|
| 63 |
+
"""
|
| 64 |
+
|
| 65 |
+
moe_experts: list = Field([1], alias="num_experts")
|
| 66 |
+
""" The global number of experts used in an MoE layer. """
|
| 67 |
+
|
| 68 |
+
type: MoETypeEnum = MoETypeEnum.standard
|
| 69 |
+
"""
|
| 70 |
+
Specify the type of MoE layer. We have two types of MoE layer: 'Standard'
|
| 71 |
+
and 'Residual'.
|
| 72 |
+
"""
|
| 73 |
+
|
| 74 |
+
ep_mp_group: object = None
|
| 75 |
+
ep_group: object = Field(None, alias="expert_group")
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
class QuantTypeEnum(str, Enum):
|
| 79 |
+
asym = "asymmetric"
|
| 80 |
+
sym = "symmetric"
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
class BaseQuantConfig(DeepSpeedConfigModel):
|
| 84 |
+
enabled: bool = True
|
| 85 |
+
num_bits: int = 8
|
| 86 |
+
q_type: QuantTypeEnum = QuantTypeEnum.sym
|
| 87 |
+
q_groups: int = 1
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
class WeightQuantConfig(BaseQuantConfig):
|
| 91 |
+
enabled: bool = True
|
| 92 |
+
quantized_initialization: Dict = {}
|
| 93 |
+
post_init_quant: Dict = {}
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
class ActivationQuantConfig(BaseQuantConfig):
|
| 97 |
+
enabled: bool = True
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
class QKVQuantConfig(DeepSpeedConfigModel):
|
| 101 |
+
enabled: bool = True
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
class QuantizationConfig(DeepSpeedConfigModel):
|
| 105 |
+
enabled: bool = True
|
| 106 |
+
activation: ActivationQuantConfig = ActivationQuantConfig()
|
| 107 |
+
weight: WeightQuantConfig = WeightQuantConfig()
|
| 108 |
+
qkv: QKVQuantConfig = QKVQuantConfig()
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
# todo: brainstorm on how to do ckpt loading for DS inference
|
| 112 |
+
class InferenceCheckpointConfig(DeepSpeedConfigModel):
|
| 113 |
+
checkpoint_dir: Optional[str] = None
|
| 114 |
+
save_mp_checkpoint_path: Optional[str] = None
|
| 115 |
+
base_dir: Optional[str] = None
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
class DeepSpeedInferenceConfig(DeepSpeedConfigModel):
|
| 119 |
+
""" Sets parameters for DeepSpeed Inference Engine. """
|
| 120 |
+
|
| 121 |
+
replace_with_kernel_inject: bool = Field(False, alias="kernel_inject")
|
| 122 |
+
"""
|
| 123 |
+
Set to true to inject inference kernels for models such as, Bert, GPT2,
|
| 124 |
+
GPT-Neo and GPT-J. Otherwise, the injection_dict provides the names of two
|
| 125 |
+
linear layers as a tuple:
|
| 126 |
+
`(attention_output projection, transformer output projection)`
|
| 127 |
+
"""
|
| 128 |
+
|
| 129 |
+
dtype: torch.dtype = torch.float16
|
| 130 |
+
"""
|
| 131 |
+
Desired model data type, will convert model to this type.
|
| 132 |
+
Supported target types: `torch.half`, `torch.int8`, `torch.float`
|
| 133 |
+
"""
|
| 134 |
+
|
| 135 |
+
tensor_parallel: DeepSpeedTPConfig = Field({}, alias="tp")
|
| 136 |
+
"""
|
| 137 |
+
Configuration for tensor parallelism used to split the model across several
|
| 138 |
+
GPUs. Expects a dictionary containing values for :any:`DeepSpeedTPConfig`.
|
| 139 |
+
"""
|
| 140 |
+
|
| 141 |
+
enable_cuda_graph: bool = False
|
| 142 |
+
"""
|
| 143 |
+
Use this flag for capturing the CUDA-Graph of the inference ops, so that it
|
| 144 |
+
can run faster using the graph replay method.
|
| 145 |
+
"""
|
| 146 |
+
|
| 147 |
+
use_triton: bool = False
|
| 148 |
+
"""
|
| 149 |
+
Use this flag to use triton kernels for inference ops.
|
| 150 |
+
"""
|
| 151 |
+
|
| 152 |
+
triton_autotune: bool = False
|
| 153 |
+
"""
|
| 154 |
+
Use this flag to enable triton autotuning.
|
| 155 |
+
Turning it on is better for performance but increase the 1st runtime for
|
| 156 |
+
autotuning.
|
| 157 |
+
"""
|
| 158 |
+
|
| 159 |
+
zero: DeepSpeedZeroConfig = {}
|
| 160 |
+
"""
|
| 161 |
+
ZeRO configuration to use with the Inference Engine. Expects a dictionary
|
| 162 |
+
containing values for :any:`DeepSpeedZeroConfig`.
|
| 163 |
+
"""
|
| 164 |
+
|
| 165 |
+
triangular_masking: bool = Field(True, alias="tm")
|
| 166 |
+
"""
|
| 167 |
+
Controls the type of masking for attention scores in transformer layer.
|
| 168 |
+
Note that the masking is application specific.
|
| 169 |
+
"""
|
| 170 |
+
|
| 171 |
+
moe: Union[bool, DeepSpeedMoEConfig] = {}
|
| 172 |
+
"""
|
| 173 |
+
Specify if the type of Transformer is MoE. Expects a dictionary containing
|
| 174 |
+
values for :any:`DeepSpeedMoEConfig`.
|
| 175 |
+
"""
|
| 176 |
+
|
| 177 |
+
keep_module_on_host: bool = False
|
| 178 |
+
"""
|
| 179 |
+
When loading checkpoints to model parameters, they are moved to the device. In very large models
|
| 180 |
+
this might fill the device and cause OOM. Setting this flag to true, will keep checkpoints on
|
| 181 |
+
host and not move them directly to the device (giving an option to quantize checkpoint data before
|
| 182 |
+
moving it to the device for example).
|
| 183 |
+
Set only for models with injection policies and auto TP.
|
| 184 |
+
"""
|
| 185 |
+
|
| 186 |
+
quant: QuantizationConfig = {}
|
| 187 |
+
"""
|
| 188 |
+
NOTE: only works for int8 dtype.
|
| 189 |
+
Quantization settings used for quantizing your model using the MoQ. The
|
| 190 |
+
setting can be one element or a tuple. If one value is passed in, we
|
| 191 |
+
consider it as the number of groups used in quantization. A tuple is passed
|
| 192 |
+
in if we want to mention that there is extra-grouping for the MLP part of a
|
| 193 |
+
Transformer layer (e.g. (True, 8) shows we quantize the model using 8
|
| 194 |
+
groups for all the network except the MLP part that we use 8 extra
|
| 195 |
+
grouping). Expects a dictionary containing values for
|
| 196 |
+
:any:`QuantizationConfig`.
|
| 197 |
+
"""
|
| 198 |
+
|
| 199 |
+
#todo: refactor the following 3 into the new checkpoint_config
|
| 200 |
+
checkpoint: Optional[Union[str, Dict]] = None
|
| 201 |
+
"""
|
| 202 |
+
Path to deepspeed compatible checkpoint or path to JSON with load policy.
|
| 203 |
+
"""
|
| 204 |
+
|
| 205 |
+
base_dir: str = ""
|
| 206 |
+
"""
|
| 207 |
+
This shows the root directory under which all the checkpoint files exists.
|
| 208 |
+
This can be passed through the json config too.
|
| 209 |
+
"""
|
| 210 |
+
|
| 211 |
+
set_empty_params: bool = False
|
| 212 |
+
"""
|
| 213 |
+
specifying whether the inference-module is created with empty or real Tensor
|
| 214 |
+
"""
|
| 215 |
+
|
| 216 |
+
save_mp_checkpoint_path: Optional[str] = None
|
| 217 |
+
"""
|
| 218 |
+
The path for which we want to save the loaded model with a checkpoint. This
|
| 219 |
+
feature is used for adjusting the parallelism degree to help alleviate the
|
| 220 |
+
model loading overhead. It does not save any new checkpoint if no path is
|
| 221 |
+
passed.
|
| 222 |
+
"""
|
| 223 |
+
|
| 224 |
+
checkpoint_config: InferenceCheckpointConfig = Field({}, alias="ckpt_config")
|
| 225 |
+
"""
|
| 226 |
+
TODO: Add docs. Expects a dictionary containing values for
|
| 227 |
+
:any:`InferenceCheckpointConfig`.
|
| 228 |
+
"""
|
| 229 |
+
|
| 230 |
+
return_tuple: bool = True
|
| 231 |
+
"""
|
| 232 |
+
Specify whether or not the transformer layers need to return a tuple or a
|
| 233 |
+
Tensor.
|
| 234 |
+
"""
|
| 235 |
+
|
| 236 |
+
training_mp_size: int = 1
|
| 237 |
+
"""
|
| 238 |
+
If loading a checkpoint this is the mp size that it was trained with, it
|
| 239 |
+
may be different than what the mp size that you want to use during
|
| 240 |
+
inference.
|
| 241 |
+
"""
|
| 242 |
+
|
| 243 |
+
replace_method: str = Field(
|
| 244 |
+
"auto",
|
| 245 |
+
json_schema_extra={
|
| 246 |
+
"deprecated": True,
|
| 247 |
+
"deprecated_msg": "This parameter is no longer needed, please remove from your call to DeepSpeed-inference"
|
| 248 |
+
})
|
| 249 |
+
|
| 250 |
+
injection_policy: Optional[Dict] = Field(None, alias="injection_dict")
|
| 251 |
+
"""
|
| 252 |
+
Dictionary mapping a client nn.Module to its corresponding injection
|
| 253 |
+
policy. e.g., `{BertLayer : deepspeed.inference.HFBertLayerPolicy}`
|
| 254 |
+
"""
|
| 255 |
+
|
| 256 |
+
injection_policy_tuple: Optional[tuple] = None
|
| 257 |
+
""" TODO: Add docs """
|
| 258 |
+
|
| 259 |
+
config: Optional[Dict] = Field(None, alias="args") # todo: really no need for this field if we can refactor
|
| 260 |
+
|
| 261 |
+
max_out_tokens: int = Field(1024, alias="max_tokens")
|
| 262 |
+
"""
|
| 263 |
+
This argument shows the maximum number of tokens inference-engine can work
|
| 264 |
+
with, including the input and output tokens. Please consider increasing it
|
| 265 |
+
to the required token-length required for your use-case.
|
| 266 |
+
"""
|
| 267 |
+
|
| 268 |
+
min_out_tokens: int = Field(1, alias="min_tokens")
|
| 269 |
+
"""
|
| 270 |
+
This argument communicates to the runtime the minimum number of tokens you
|
| 271 |
+
expect you will need to generate. This will cause the runtime to error
|
| 272 |
+
if it unable to provide this and provide context on the memory pressure
|
| 273 |
+
rather than seg-faulting or providing corrupted output.
|
| 274 |
+
"""
|
| 275 |
+
|
| 276 |
+
transposed_mode: bool = Field(False, alias="transposed_mode")
|
| 277 |
+
|
| 278 |
+
mp_size: int = Field(1, json_schema_extra={"deprecated": True, "new_param": "tensor_parallel.tp_size"})
|
| 279 |
+
"""
|
| 280 |
+
Desired model parallel size, default is 1 meaning no model parallelism.
|
| 281 |
+
Deprecated, please use the ``tensor_parallel` config to control model
|
| 282 |
+
parallelism.
|
| 283 |
+
"""
|
| 284 |
+
mpu: object = Field(None, json_schema_extra={"deprecated": True, "new_param": "tensor_parallel.mpu"})
|
| 285 |
+
ep_size: int = Field(1, json_schema_extra={"deprecated": True, "new_param": "moe.ep_size"})
|
| 286 |
+
ep_group: object = Field(None,
|
| 287 |
+
alias="expert_group",
|
| 288 |
+
json_schema_extra={
|
| 289 |
+
"deprecated": True,
|
| 290 |
+
"new_param": "moe.ep_group"
|
| 291 |
+
})
|
| 292 |
+
ep_mp_group: object = Field(None,
|
| 293 |
+
alias="expert_mp_group",
|
| 294 |
+
json_schema_extra={
|
| 295 |
+
"deprecated": True,
|
| 296 |
+
"new_param": "moe.ep_mp_group"
|
| 297 |
+
})
|
| 298 |
+
moe_experts: list = Field([1], json_schema_extra={"deprecated": True, "new_param": "moe.moe_experts"})
|
| 299 |
+
moe_type: MoETypeEnum = Field(MoETypeEnum.standard,
|
| 300 |
+
json_schema_extra={
|
| 301 |
+
"deprecated": True,
|
| 302 |
+
"new_param": "moe.type"
|
| 303 |
+
})
|
| 304 |
+
|
| 305 |
+
@field_validator("dtype", mode="before")
|
| 306 |
+
def validate_dtype(cls, field_value, values):
|
| 307 |
+
if isinstance(field_value, str):
|
| 308 |
+
return DtypeEnum.from_str(field_value).value[0]
|
| 309 |
+
if isinstance(field_value, torch.dtype):
|
| 310 |
+
return field_value
|
| 311 |
+
raise TypeError(f"Invalid type for dtype: {type(field_value)}")
|
| 312 |
+
|
| 313 |
+
@field_validator("moe")
|
| 314 |
+
def moe_backward_compat(cls, field_value, values):
|
| 315 |
+
if isinstance(field_value, bool):
|
| 316 |
+
return DeepSpeedMoEConfig(moe=field_value)
|
| 317 |
+
return field_value
|
| 318 |
+
|
| 319 |
+
@field_validator("use_triton")
|
| 320 |
+
def has_triton(cls, field_value, values):
|
| 321 |
+
if field_value and not deepspeed.HAS_TRITON:
|
| 322 |
+
raise ValueError('Triton needs to be installed to use deepspeed with triton kernels')
|
| 323 |
+
return field_value
|
lib/python3.12/site-packages/deepspeed/inference/engine.py
ADDED
|
@@ -0,0 +1,625 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
import time
|
| 8 |
+
import os
|
| 9 |
+
import deepspeed
|
| 10 |
+
from deepspeed import comm as dist
|
| 11 |
+
from deepspeed.utils.logging import log_dist
|
| 12 |
+
|
| 13 |
+
from torch.nn.modules import Module
|
| 14 |
+
from packaging import version as pkg_version
|
| 15 |
+
from deepspeed.runtime.checkpoint_engine.torch_checkpoint_engine import TorchCheckpointEngine
|
| 16 |
+
from deepspeed.utils.timer import SynchronizedWallClockTimer
|
| 17 |
+
from deepspeed.runtime.compiler import is_compile_supported
|
| 18 |
+
from ..runtime.state_dict_factory import SDLoaderFactory
|
| 19 |
+
from ..runtime.weight_quantizer import WeightQuantization
|
| 20 |
+
from ..module_inject import replace_transformer_layer, generic_injection
|
| 21 |
+
from ..comm.comm import init_distributed
|
| 22 |
+
from ..pipe import PipelineModule
|
| 23 |
+
from ..moe.utils import has_moe_layers
|
| 24 |
+
from ..module_inject import LinearAllreduce, LinearLayer, Normalize, ReplaceWithTensorSlicing
|
| 25 |
+
from deepspeed.accelerator import get_accelerator
|
| 26 |
+
from ..module_inject.policy import TransformerPolicy
|
| 27 |
+
from ..module_inject.auto_tp import AutoTP
|
| 28 |
+
|
| 29 |
+
from ..module_inject.replace_policy import generic_policies
|
| 30 |
+
from ..module_inject.auto_tp_model_utils import build_bloom_alibi_tensor, build_mpt_atten_bias_tensor, build_mpt_alibi_tensor, get_alibi_mask
|
| 31 |
+
from ..ops.transformer.inference.ds_attention import DeepSpeedSelfAttention
|
| 32 |
+
from ..model_implementations.transformers.ds_transformer import DeepSpeedTransformerInference
|
| 33 |
+
|
| 34 |
+
DS_INFERENCE_ENABLED = False
|
| 35 |
+
from torch import nn
|
| 36 |
+
|
| 37 |
+
INFERENCE_MODEL_TIMER = "model-forward-inference"
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class InferenceEngine(Module):
|
| 41 |
+
inference_mp_group = None
|
| 42 |
+
inference_ep_group = None
|
| 43 |
+
expert_mp_group = None
|
| 44 |
+
|
| 45 |
+
def __init__(self, model, config):
|
| 46 |
+
"""
|
| 47 |
+
Args:
|
| 48 |
+
model: torch.nn.Module
|
| 49 |
+
config: DeepSpeedInferenceConfig
|
| 50 |
+
"""
|
| 51 |
+
global DS_INFERENCE_ENABLED
|
| 52 |
+
DS_INFERENCE_ENABLED = True
|
| 53 |
+
|
| 54 |
+
super().__init__()
|
| 55 |
+
if DeepSpeedTransformerInference.workspace is not None:
|
| 56 |
+
self.destroy()
|
| 57 |
+
|
| 58 |
+
self.module = model
|
| 59 |
+
self._config = config
|
| 60 |
+
|
| 61 |
+
self._get_model_config_generate(config) # keep for weird backward compatibility
|
| 62 |
+
|
| 63 |
+
# patch model generate with ours if model uses it
|
| 64 |
+
if hasattr(self.module, "generate"):
|
| 65 |
+
self.generate = self._generate
|
| 66 |
+
|
| 67 |
+
if hasattr(self.module, "config"):
|
| 68 |
+
TransformerPolicy.hf_model_config = self.module.config
|
| 69 |
+
|
| 70 |
+
if config.dtype not in get_accelerator().supported_dtypes():
|
| 71 |
+
raise ValueError(
|
| 72 |
+
f"Data type {config.dtype} is not supported by {get_accelerator().device_name()} accelerator")
|
| 73 |
+
|
| 74 |
+
# todo: keep this self.injection_dict because we don't use to change config.injection_policy API
|
| 75 |
+
# todo: this will get changed when Molly's PR on auto injection dict is merged
|
| 76 |
+
self.injection_dict = config.injection_policy
|
| 77 |
+
|
| 78 |
+
# todo: refactor the mp_group and mp_size related in the next refactor
|
| 79 |
+
self.mp_group = config.tensor_parallel.tp_group
|
| 80 |
+
self.mpu = config.tensor_parallel.mpu
|
| 81 |
+
|
| 82 |
+
self.quantize_merge_count = 1
|
| 83 |
+
self.quantization_scales = None
|
| 84 |
+
|
| 85 |
+
# these are not needed in the config as we are creating them ourselves in the inference engine
|
| 86 |
+
self.ep_group = None # config.moe.ep_group
|
| 87 |
+
self.expert_mp_group = None # config.moe.ep_mp_group
|
| 88 |
+
|
| 89 |
+
self.cuda_graph_created = False
|
| 90 |
+
self.checkpoint_engine = TorchCheckpointEngine()
|
| 91 |
+
quantization_setting = None
|
| 92 |
+
self._init_quantization_setting(
|
| 93 |
+
quantization_setting) # todo: update with the new quant config for weight quant
|
| 94 |
+
self.model_profile_enabled = False
|
| 95 |
+
self._model_times = []
|
| 96 |
+
|
| 97 |
+
if not self.injection_dict and config.replace_with_kernel_inject:
|
| 98 |
+
# This is a hack to remove the prepare_mask function on HF side for BLOOM architecture
|
| 99 |
+
self.remove_mask_prepare_for_bloom()
|
| 100 |
+
|
| 101 |
+
if self.injection_dict or not config.replace_with_kernel_inject:
|
| 102 |
+
# This is a hack to redefine the alibi func due to TP
|
| 103 |
+
if config.tensor_parallel.tp_size > 1:
|
| 104 |
+
self.build_alibi_tensor()
|
| 105 |
+
self.build_attn_bias()
|
| 106 |
+
|
| 107 |
+
if get_accelerator().device_name() == 'cuda' and config.enable_cuda_graph:
|
| 108 |
+
assert pkg_version.parse(torch.__version__) >= pkg_version.parse("1.10"), \
|
| 109 |
+
"If you want to use cuda graph, please upgrade torch to at least v1.10"
|
| 110 |
+
|
| 111 |
+
# convert model to intended dtype
|
| 112 |
+
if config.dtype:
|
| 113 |
+
self._convert_to_dtype(config)
|
| 114 |
+
|
| 115 |
+
if self.mpu:
|
| 116 |
+
config.tensor_parallel.tp_size = dist.get_world_size(group=self.mpu.get_model_parallel_group())
|
| 117 |
+
self.mp_group = self.mpu.get_model_parallel_group()
|
| 118 |
+
elif config.tensor_parallel.tp_size > 1:
|
| 119 |
+
self._create_model_parallel_group(config)
|
| 120 |
+
config.tensor_parallel.tp_group = self.mp_group
|
| 121 |
+
|
| 122 |
+
if isinstance(self.module, torch.nn.Module):
|
| 123 |
+
moe, _ = has_moe_layers(self.module)
|
| 124 |
+
else:
|
| 125 |
+
moe = False
|
| 126 |
+
|
| 127 |
+
if moe and dist.get_world_size() > 1:
|
| 128 |
+
self._create_ep_parallel_group(config.moe.moe_experts)
|
| 129 |
+
|
| 130 |
+
# We only support three modes: 1) user specified policy for tensor-parallelism, 2) kernel injection (replace_with_kernel_inject), and 3) automatic tensor parallelism if tp_size > 1.
|
| 131 |
+
if self.injection_dict:
|
| 132 |
+
# 1. User specified Tensor Parallelism
|
| 133 |
+
assert not config.replace_with_kernel_inject, "Cannot use both user specified injection policy and kernel injection"
|
| 134 |
+
for client_module, injection_policy in self.injection_dict.items():
|
| 135 |
+
|
| 136 |
+
assert issubclass(client_module,
|
| 137 |
+
torch.nn.Module), f"{client_module} is not a subclass of torch.nn.Module"
|
| 138 |
+
|
| 139 |
+
# construct the tuple and pass that instead of a string or dict.
|
| 140 |
+
if isinstance(injection_policy, str):
|
| 141 |
+
config.injection_policy_tuple = (injection_policy, )
|
| 142 |
+
else:
|
| 143 |
+
config.injection_policy_tuple = injection_policy
|
| 144 |
+
|
| 145 |
+
layer_names = [name for name, _ in self.module.named_modules()]
|
| 146 |
+
for policy in config.injection_policy_tuple:
|
| 147 |
+
if not any(name.endswith(policy) for name in layer_names):
|
| 148 |
+
raise ValueError(f"Injection policy layer'{policy}' not valid.")
|
| 149 |
+
|
| 150 |
+
self._apply_injection_policy(config, client_module)
|
| 151 |
+
else:
|
| 152 |
+
if config.replace_with_kernel_inject:
|
| 153 |
+
# 2. DeepSpeed Kernel Injection
|
| 154 |
+
self._apply_injection_policy(config)
|
| 155 |
+
elif config.tensor_parallel.tp_size > 1:
|
| 156 |
+
# 3. Automatic Tensor Parallelism
|
| 157 |
+
parser_dict = AutoTP.tp_parser(model)
|
| 158 |
+
print("AutoTP: ", parser_dict)
|
| 159 |
+
for client_module, injection_policy in parser_dict:
|
| 160 |
+
if isinstance(injection_policy, str):
|
| 161 |
+
config.injection_policy_tuple = (injection_policy, )
|
| 162 |
+
else:
|
| 163 |
+
config.injection_policy_tuple = injection_policy
|
| 164 |
+
self._apply_injection_policy(config, client_module)
|
| 165 |
+
|
| 166 |
+
device = get_accelerator().current_device_name()
|
| 167 |
+
# NOTE: This check assumes a Hugging Face hierarchy for the device type i.e. module.device.type
|
| 168 |
+
is_meta_device = hasattr(self.module, "device") and self.module.device.type == 'meta'
|
| 169 |
+
if is_meta_device:
|
| 170 |
+
self.module.to_empty(device=device)
|
| 171 |
+
elif not config.keep_module_on_host:
|
| 172 |
+
self.module.to(device)
|
| 173 |
+
|
| 174 |
+
if config.tensor_parallel.tp_size > 1:
|
| 175 |
+
_rng_state = get_accelerator().get_rng_state().to(get_accelerator().current_device_name())
|
| 176 |
+
dist.broadcast(_rng_state, 0)
|
| 177 |
+
get_accelerator().set_rng_state(_rng_state.cpu())
|
| 178 |
+
|
| 179 |
+
if config.tensor_parallel.tp_size > 1:
|
| 180 |
+
assert not config.enable_cuda_graph, "Cuda graph is not supported for model parallelism"
|
| 181 |
+
|
| 182 |
+
# Check if local CUDA graphs can be created in replacement modules
|
| 183 |
+
self.local_cuda_graph = self._local_cuda_graph_used(self.module)
|
| 184 |
+
self._is_compiled = False
|
| 185 |
+
|
| 186 |
+
def destroy(self):
|
| 187 |
+
DeepSpeedTransformerInference.layer_id = 0
|
| 188 |
+
DeepSpeedSelfAttention.num_layers = 0
|
| 189 |
+
if DeepSpeedTransformerInference.workspace.is_allocated():
|
| 190 |
+
DeepSpeedTransformerInference.workspace.release_workspace()
|
| 191 |
+
DeepSpeedTransformerInference.workspace = None
|
| 192 |
+
|
| 193 |
+
def profile_model_time(self, use_cuda_events=True):
|
| 194 |
+
if not self.model_profile_enabled and not self._config.enable_cuda_graph:
|
| 195 |
+
self.module.register_forward_pre_hook(self._pre_forward_hook)
|
| 196 |
+
self.module.register_forward_hook(self._post_forward_hook)
|
| 197 |
+
self.model_profile_enabled = True
|
| 198 |
+
self.use_cuda_events = use_cuda_events
|
| 199 |
+
if self.use_cuda_events:
|
| 200 |
+
self.timers = SynchronizedWallClockTimer()
|
| 201 |
+
|
| 202 |
+
# todo: remove this once all the config dicts are centralized from top level pydantic config
|
| 203 |
+
def _get_model_config_generate(self, config):
|
| 204 |
+
# this is being passed to replace_transformer_layer(config=self.user_model_config_dict)
|
| 205 |
+
self.config = getattr(self.module, 'config', None) if config.config is None else config.config
|
| 206 |
+
|
| 207 |
+
def remove_mask_prepare_for_bloom(self):
|
| 208 |
+
if hasattr(self.module, 'transformer'):
|
| 209 |
+
if hasattr(self.module.transformer, '_prepare_attn_mask'):
|
| 210 |
+
self.module.transformer._prepare_attn_mask = lambda attention_mask, *args, **kwargs: attention_mask
|
| 211 |
+
|
| 212 |
+
def build_alibi_tensor(self):
|
| 213 |
+
if hasattr(self.module, 'transformer'):
|
| 214 |
+
if hasattr(self.module.transformer, 'build_alibi_tensor'):
|
| 215 |
+
self.module.transformer.build_alibi_tensor = build_bloom_alibi_tensor
|
| 216 |
+
if hasattr(self.module.transformer, 'build_mpt_alibi_tensor'):
|
| 217 |
+
self.module.transformer.build_mpt_alibi_tensor_orig = self.module.transformer.build_mpt_alibi_tensor
|
| 218 |
+
self.module.transformer.__class__.build_mpt_alibi_tensor = build_mpt_alibi_tensor
|
| 219 |
+
if hasattr(self.module, 'model'):
|
| 220 |
+
if hasattr(self.module.model, 'get_alibi_mask'):
|
| 221 |
+
self.module.model.get_alibi_mask_orig = self.module.model.get_alibi_mask
|
| 222 |
+
self.module.model.__class__.get_alibi_mask = get_alibi_mask
|
| 223 |
+
|
| 224 |
+
def build_attn_bias(self):
|
| 225 |
+
if hasattr(self.module, 'transformer'):
|
| 226 |
+
if hasattr(self.module.transformer, '_attn_bias'):
|
| 227 |
+
self.module.transformer._attn_bias_orig = self.module.transformer._attn_bias
|
| 228 |
+
self.module.transformer.__class__._attn_bias = build_mpt_atten_bias_tensor
|
| 229 |
+
|
| 230 |
+
def _pre_forward_hook(self, module, *inputs, **kwargs):
|
| 231 |
+
if self.use_cuda_events:
|
| 232 |
+
self.timers(INFERENCE_MODEL_TIMER).start()
|
| 233 |
+
else:
|
| 234 |
+
get_accelerator().synchronize()
|
| 235 |
+
self._start = time.time()
|
| 236 |
+
|
| 237 |
+
def _post_forward_hook(self, module, input, output):
|
| 238 |
+
if self.use_cuda_events:
|
| 239 |
+
self.timers(INFERENCE_MODEL_TIMER).stop()
|
| 240 |
+
elapsed_time = self.timers(INFERENCE_MODEL_TIMER).elapsed(reset=True)
|
| 241 |
+
else:
|
| 242 |
+
get_accelerator().synchronize()
|
| 243 |
+
self._end = time.time()
|
| 244 |
+
elapsed_time = (self._end - self._start) * 1e3 # convert seconds to ms
|
| 245 |
+
self._model_times.append(elapsed_time)
|
| 246 |
+
|
| 247 |
+
def _create_model_parallel_group(self, config):
|
| 248 |
+
# Call the init process
|
| 249 |
+
if InferenceEngine.inference_mp_group is None:
|
| 250 |
+
init_distributed()
|
| 251 |
+
local_rank = int(os.getenv('LOCAL_RANK', '0'))
|
| 252 |
+
get_accelerator().set_device(local_rank)
|
| 253 |
+
|
| 254 |
+
ranks = [i for i in range(config.tensor_parallel.tp_size)]
|
| 255 |
+
self.mp_group = dist.new_group(ranks)
|
| 256 |
+
InferenceEngine.inference_mp_group = self.mp_group
|
| 257 |
+
else:
|
| 258 |
+
self.mp_group = InferenceEngine.inference_mp_group
|
| 259 |
+
|
| 260 |
+
def _create_ep_parallel_group(self, moe_experts):
|
| 261 |
+
# Call the init process
|
| 262 |
+
self.ep_group = {}
|
| 263 |
+
self.expert_mp_group = {}
|
| 264 |
+
moe_experts = moe_experts if type(moe_experts) is list else [moe_experts]
|
| 265 |
+
for e in moe_experts:
|
| 266 |
+
self.ep_group.update({e: None})
|
| 267 |
+
self.expert_mp_group.update({e: None})
|
| 268 |
+
for moe_ep_size in self.ep_group.keys():
|
| 269 |
+
num_ep_groups = dist.get_world_size() // moe_ep_size
|
| 270 |
+
for i in range(num_ep_groups):
|
| 271 |
+
ep_cnt = i * moe_ep_size
|
| 272 |
+
size = dist.get_world_size() if moe_ep_size > dist.get_world_size() else moe_ep_size
|
| 273 |
+
ranks = list(range(ep_cnt, ep_cnt + size))
|
| 274 |
+
_ep_group = dist.new_group(ranks)
|
| 275 |
+
if dist.get_rank() in ranks:
|
| 276 |
+
self.ep_group.update({moe_ep_size: _ep_group})
|
| 277 |
+
|
| 278 |
+
if dist.get_world_size() > moe_ep_size:
|
| 279 |
+
num_expert_mp_groups = dist.get_world_size() // num_ep_groups
|
| 280 |
+
expert_mp_size = dist.get_world_size() // moe_ep_size
|
| 281 |
+
for i in range(num_expert_mp_groups):
|
| 282 |
+
expert_mp_comm_ranks = [i + nr * moe_ep_size for nr in range(expert_mp_size)]
|
| 283 |
+
_expert_mp_group = dist.new_group(expert_mp_comm_ranks)
|
| 284 |
+
if dist.get_rank() in expert_mp_comm_ranks:
|
| 285 |
+
self.expert_mp_group.update({moe_ep_size: _expert_mp_group})
|
| 286 |
+
|
| 287 |
+
def _init_quantization_setting(self, quantization_setting):
|
| 288 |
+
self.quantize_bits = 8
|
| 289 |
+
self.mlp_extra_grouping = False
|
| 290 |
+
self.quantize_groups = 1
|
| 291 |
+
if type(quantization_setting) is tuple:
|
| 292 |
+
self.mlp_extra_grouping, \
|
| 293 |
+
self.quantize_groups = quantization_setting
|
| 294 |
+
elif quantization_setting is not None:
|
| 295 |
+
self.quantize_groups = quantization_setting
|
| 296 |
+
log_dist(
|
| 297 |
+
f"quantize_bits = {self.quantize_bits} "
|
| 298 |
+
f"mlp_extra_grouping = {self.mlp_extra_grouping}, "
|
| 299 |
+
f"quantize_groups = {self.quantize_groups}", [0])
|
| 300 |
+
|
| 301 |
+
def load_model_with_checkpoint(self, r_module):
|
| 302 |
+
self.mp_replace = ReplaceWithTensorSlicing(
|
| 303 |
+
mp_group=self.mp_group, mp_size=self._config.tensor_parallel.tp_size) #, out_dim=0, in_dim=1)
|
| 304 |
+
error_msgs = []
|
| 305 |
+
|
| 306 |
+
def load(module, state_dict, prefix):
|
| 307 |
+
args = (state_dict, prefix, {}, True, [], [], error_msgs)
|
| 308 |
+
if hasattr(module, 'weight'):
|
| 309 |
+
if module.weight.data.is_meta:
|
| 310 |
+
# meta tensor cannot be casted or copied to, so we need to replace it with a normal tensor here
|
| 311 |
+
module.weight = torch.nn.parameter.Parameter(data=torch.empty_like(module.weight.data,
|
| 312 |
+
device="cpu"),
|
| 313 |
+
requires_grad=module.weight.data.requires_grad)
|
| 314 |
+
if 'query_key_value' in prefix:
|
| 315 |
+
module.weight = self.mp_replace.strided_copy(module.weight.data,
|
| 316 |
+
state_dict[prefix + 'weight'],
|
| 317 |
+
num_splits=3)
|
| 318 |
+
else:
|
| 319 |
+
module.weight = self.mp_replace.copy(module.weight.data, state_dict[prefix + 'weight'])
|
| 320 |
+
else:
|
| 321 |
+
if module.norm.weight.data.is_meta:
|
| 322 |
+
# meta tensor cannot be casted or copied to, so we need to replace it with a normal tensor here
|
| 323 |
+
module.norm.weight = torch.nn.parameter.Parameter(
|
| 324 |
+
data=torch.empty_like(module.norm.weight.data, device="cpu"),
|
| 325 |
+
requires_grad=module.norm.weight.data.requires_grad)
|
| 326 |
+
module.norm.weight = self.mp_replace.copy(module.norm.weight.data, state_dict[prefix + 'weight'])
|
| 327 |
+
if prefix + 'bias' in self.key_list:
|
| 328 |
+
if hasattr(module, 'norm'):
|
| 329 |
+
if module.norm.bias.data.is_meta:
|
| 330 |
+
# meta tensor cannot be casted or copied to, so we need to replace it with a normal tensor here
|
| 331 |
+
module.norm.bias = torch.nn.parameter.Parameter(
|
| 332 |
+
data=torch.empty_like(module.norm.bias.data, device="cpu"),
|
| 333 |
+
requires_grad=module.norm.bias.data.requires_grad)
|
| 334 |
+
module.norm.bias = self.mp_replace.copy(module.norm.bias, state_dict[prefix + 'bias'])
|
| 335 |
+
else:
|
| 336 |
+
if module.bias.data.is_meta:
|
| 337 |
+
# meta tensor cannot be casted or copied to, so we need to replace it with a normal tensor here
|
| 338 |
+
module.bias = torch.nn.parameter.Parameter(data=torch.empty_like(module.bias.data,
|
| 339 |
+
device="cpu"),
|
| 340 |
+
requires_grad=module.bias.data.requires_grad)
|
| 341 |
+
data = state_dict[prefix + 'bias']
|
| 342 |
+
data = data.to(get_accelerator().current_device_name())
|
| 343 |
+
module.bias = self.mp_replace.copy(module.bias, data)
|
| 344 |
+
|
| 345 |
+
layer_policies = {
|
| 346 |
+
nn.Linear: load,
|
| 347 |
+
nn.Embedding: load,
|
| 348 |
+
nn.LayerNorm: load,
|
| 349 |
+
LinearLayer: load,
|
| 350 |
+
LinearAllreduce: load
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
def load_module_recursive(module, prefix='', level=0):
|
| 354 |
+
for name, child in module.named_children():
|
| 355 |
+
if child.__class__ in layer_policies:
|
| 356 |
+
checking_key = prefix + name + '.'
|
| 357 |
+
if not any(checking_key in item for item in self.key_list):
|
| 358 |
+
continue
|
| 359 |
+
if len(list(child.parameters())) > 0 and list(child.parameters())[0].numel() == 0:
|
| 360 |
+
if len(child.weight.ds_shape) == 1:
|
| 361 |
+
child = Normalize(dim=child.weight.ds_shape[-1], dtype=child.weight.dtype, eps=child.eps)
|
| 362 |
+
setattr(module, name, child)
|
| 363 |
+
load(child, self.sd, prefix + name + '.')
|
| 364 |
+
else:
|
| 365 |
+
load_module_recursive(child, prefix if level == 0 else prefix + name + '.', level + 1)
|
| 366 |
+
|
| 367 |
+
load_module_recursive(r_module)
|
| 368 |
+
|
| 369 |
+
embedding_weight = None
|
| 370 |
+
|
| 371 |
+
for n, p in r_module.named_parameters():
|
| 372 |
+
if "word_embeddings." in n or "embed_tokens." in n or "wte." in n:
|
| 373 |
+
embedding_weight = p
|
| 374 |
+
if embedding_weight is not None and hasattr(r_module, "lm_head") and hasattr(
|
| 375 |
+
r_module.lm_head, "weight") and r_module.lm_head.weight.is_meta:
|
| 376 |
+
r_module.lm_head.weight = embedding_weight
|
| 377 |
+
|
| 378 |
+
def _apply_injection_policy(self, config, client_module=None):
|
| 379 |
+
# client_module is only passed when using the injection_dict method.
|
| 380 |
+
checkpoint_dir = config.checkpoint
|
| 381 |
+
checkpoint = SDLoaderFactory.get_sd_loader_json(checkpoint_dir,
|
| 382 |
+
self.checkpoint_engine) if checkpoint_dir is not None else None
|
| 383 |
+
|
| 384 |
+
generic_injection(self.module, dtype=config.dtype, enable_cuda_graph=config.enable_cuda_graph)
|
| 385 |
+
|
| 386 |
+
if isinstance(self.module, torch.nn.Module):
|
| 387 |
+
# config is our DeepSpeedInferenceConfig and self.config is the HF model config
|
| 388 |
+
replace_transformer_layer(client_module, self.module, checkpoint, config, self.config)
|
| 389 |
+
|
| 390 |
+
def _get_all_ckpt_names(self, checkpoints_path, tag):
|
| 391 |
+
ckpt_file_pattern = self._get_ckpt_name(checkpoints_path, tag, mp_placeholder="*")
|
| 392 |
+
import glob
|
| 393 |
+
|
| 394 |
+
ckpt_files = glob.glob(ckpt_file_pattern)
|
| 395 |
+
ckpt_files.sort()
|
| 396 |
+
return ckpt_files
|
| 397 |
+
|
| 398 |
+
def _get_ckpt_name(self, checkpoints_path, tag, mp_placeholder=None):
|
| 399 |
+
if mp_placeholder is not None:
|
| 400 |
+
mp_rank_str = mp_placeholder
|
| 401 |
+
else:
|
| 402 |
+
mp_rank = 0 if self.mpu is None else self.mpu.get_model_parallel_rank()
|
| 403 |
+
mp_rank_str = "{:02d}".format(mp_rank)
|
| 404 |
+
|
| 405 |
+
ckpt_name = os.path.join(
|
| 406 |
+
checkpoints_path,
|
| 407 |
+
"mp_rank_" + mp_rank_str + "_model_states.pt",
|
| 408 |
+
)
|
| 409 |
+
return ckpt_name
|
| 410 |
+
|
| 411 |
+
def _load_checkpoint(self, load_dir, load_module_strict=True, tag=None):
|
| 412 |
+
is_pipe_parallel = isinstance(self.module, PipelineModule)
|
| 413 |
+
if is_pipe_parallel:
|
| 414 |
+
raise RuntimeError('pipeline parallelism is currently not supported in inference.')
|
| 415 |
+
if not isinstance(load_dir, dict) and os.path.isdir(load_dir):
|
| 416 |
+
if tag is None:
|
| 417 |
+
latest_path = os.path.join(load_dir, "latest")
|
| 418 |
+
if os.path.isfile(latest_path):
|
| 419 |
+
with open(latest_path, "r") as fd:
|
| 420 |
+
tag = fd.read().strip()
|
| 421 |
+
|
| 422 |
+
ckpt_list = self._get_all_ckpt_names(load_dir, tag)
|
| 423 |
+
sd_loader = SDLoaderFactory.get_sd_loader(ckpt_list, self.checkpoint_engine)
|
| 424 |
+
else:
|
| 425 |
+
sd_loader = SDLoaderFactory.get_sd_loader_json(load_dir, self.checkpoint_engine)
|
| 426 |
+
|
| 427 |
+
checkpoint = sd_loader['checkpoints']
|
| 428 |
+
|
| 429 |
+
if type(checkpoint) is list:
|
| 430 |
+
self.sd = torch.load(checkpoint[0], map_location='cpu', weights_only=False)
|
| 431 |
+
self.key_list = list(self.sd.keys())
|
| 432 |
+
|
| 433 |
+
self.load_model_with_checkpoint(self.module)
|
| 434 |
+
|
| 435 |
+
for i in range(1, len(checkpoint)):
|
| 436 |
+
if not dist.is_initialized() or dist.get_rank() == 0:
|
| 437 |
+
print(f"loading checkpoint ({i})")
|
| 438 |
+
self.sd = torch.load(checkpoint[i], map_location=get_accelerator().device_name(), weights_only=False)
|
| 439 |
+
self.key_list = list(self.sd.keys())
|
| 440 |
+
self.load_model_with_checkpoint(self.module)
|
| 441 |
+
else:
|
| 442 |
+
mp_rank = 0 if self.mpu is None else self.mpu.get_model_parallel_rank()
|
| 443 |
+
|
| 444 |
+
load_path, checkpoint, quantize_config = sd_loader.load(self._config.tensor_parallel.tp_size,
|
| 445 |
+
mp_rank,
|
| 446 |
+
is_pipe_parallel=is_pipe_parallel,
|
| 447 |
+
quantize=(self._config.dtype is torch.int8),
|
| 448 |
+
quantize_groups=self.quantize_groups,
|
| 449 |
+
mlp_extra_grouping=self.mlp_extra_grouping)
|
| 450 |
+
|
| 451 |
+
self.quantization_scales, self.quantize_merge_count = quantize_config
|
| 452 |
+
|
| 453 |
+
moe, _ = has_moe_layers(self.module)
|
| 454 |
+
if moe:
|
| 455 |
+
from deepspeed.runtime.engine import DeepSpeedEngine
|
| 456 |
+
old_moe_load = False
|
| 457 |
+
if not isinstance(checkpoint['num_experts'], list):
|
| 458 |
+
old_moe_load = True
|
| 459 |
+
DeepSpeedEngine.load_moe_state_dict(load_dir,
|
| 460 |
+
tag,
|
| 461 |
+
state_dict=checkpoint[self._choose_module_key(checkpoint)],
|
| 462 |
+
old_moe_load=old_moe_load,
|
| 463 |
+
model=self.module,
|
| 464 |
+
mpu=self.mpu,
|
| 465 |
+
checkpoint_engine=self.checkpoint_engine)
|
| 466 |
+
|
| 467 |
+
self.module.load_state_dict(state_dict=checkpoint[self._choose_module_key(checkpoint)],
|
| 468 |
+
strict=load_module_strict)
|
| 469 |
+
|
| 470 |
+
def _choose_module_key(self, sd):
|
| 471 |
+
assert not ('module' in sd
|
| 472 |
+
and 'model' in sd), "checkpoint has both 'model' and 'module' keys, not sure how to proceed"
|
| 473 |
+
assert 'module' in sd or 'model' in sd, "checkpoint contains neither 'model' or 'module' keys, not sure how to proceed"
|
| 474 |
+
if 'module' in sd:
|
| 475 |
+
return 'module'
|
| 476 |
+
elif 'model' in sd:
|
| 477 |
+
return 'model'
|
| 478 |
+
|
| 479 |
+
def _convert_to_dtype(self, config):
|
| 480 |
+
if not isinstance(self.module, torch.nn.Module):
|
| 481 |
+
return
|
| 482 |
+
|
| 483 |
+
if False: #config.dtype is torch.int8 and self.quantization_scales is None:
|
| 484 |
+
quantizer = WeightQuantization(mlp_extra_grouping=self.mlp_extra_grouping)
|
| 485 |
+
model, self.quantization_scales = quantizer.model_quantize(self.module, self.injection_dict,
|
| 486 |
+
self.quantize_bits, self.quantize_groups)
|
| 487 |
+
elif config.dtype == torch.half:
|
| 488 |
+
self.module.half()
|
| 489 |
+
elif config.dtype == torch.bfloat16:
|
| 490 |
+
self.module.bfloat16()
|
| 491 |
+
elif config.dtype == torch.float:
|
| 492 |
+
self.module.float()
|
| 493 |
+
|
| 494 |
+
def _create_cuda_graph(self, *inputs, **kwargs):
|
| 495 |
+
# warmup to create the workspace and cublas handle
|
| 496 |
+
cuda_stream = get_accelerator().Stream()
|
| 497 |
+
cuda_stream.wait_stream(get_accelerator().current_stream())
|
| 498 |
+
with get_accelerator().stream(cuda_stream):
|
| 499 |
+
for i in range(3):
|
| 500 |
+
ret = self.module(*inputs, **kwargs)
|
| 501 |
+
get_accelerator().current_stream().wait_stream(cuda_stream)
|
| 502 |
+
|
| 503 |
+
# create cuda_graph and assign static_inputs and static_outputs
|
| 504 |
+
self._cuda_graphs = get_accelerator().create_graph()
|
| 505 |
+
self.static_inputs = inputs
|
| 506 |
+
self.static_kwargs = kwargs
|
| 507 |
+
|
| 508 |
+
with get_accelerator().capture_to_graph(self._cuda_graphs):
|
| 509 |
+
self.static_output = self.module(*self.static_inputs, **self.static_kwargs)
|
| 510 |
+
|
| 511 |
+
self.cuda_graph_created = True
|
| 512 |
+
|
| 513 |
+
def _graph_replay(self, *inputs, **kwargs):
|
| 514 |
+
for i in range(len(inputs)):
|
| 515 |
+
if torch.is_tensor(inputs[i]):
|
| 516 |
+
self.static_inputs[i].copy_(inputs[i])
|
| 517 |
+
for k in kwargs:
|
| 518 |
+
if torch.is_tensor(kwargs[k]):
|
| 519 |
+
self.static_kwargs[k].copy_(kwargs[k])
|
| 520 |
+
get_accelerator().replay_graph(self._cuda_graphs)
|
| 521 |
+
return self.static_output
|
| 522 |
+
|
| 523 |
+
def model_times(self):
|
| 524 |
+
assert self.model_profile_enabled, "model profiling is not enabled"
|
| 525 |
+
model_times = self._model_times
|
| 526 |
+
if self._config.enable_cuda_graph and len(self._model_times) == 0:
|
| 527 |
+
raise ValueError("Model times are empty and cuda graph is enabled. If "
|
| 528 |
+
"this is a GPT-style model this combo is not supported. If this is a "
|
| 529 |
+
"BERT-style model this is a bug, please report it. "
|
| 530 |
+
f"Model type is: {type(self.module)}")
|
| 531 |
+
self._model_times = []
|
| 532 |
+
return model_times
|
| 533 |
+
|
| 534 |
+
def _module_match(self, module):
|
| 535 |
+
for policy in generic_policies:
|
| 536 |
+
policy = policy()
|
| 537 |
+
if policy.match_replaced(module):
|
| 538 |
+
return True
|
| 539 |
+
return False
|
| 540 |
+
|
| 541 |
+
def _local_cuda_graph_used(self, module):
|
| 542 |
+
if isinstance(module, torch.nn.Module):
|
| 543 |
+
return False
|
| 544 |
+
else:
|
| 545 |
+
sub_module_cuda_graph = False
|
| 546 |
+
for name in module.__dict__.keys():
|
| 547 |
+
sub_module = getattr(module, name)
|
| 548 |
+
|
| 549 |
+
if self._module_match(sub_module) and hasattr(sub_module, "enable_cuda_graph"):
|
| 550 |
+
sub_module_cuda_graph = True
|
| 551 |
+
|
| 552 |
+
return sub_module_cuda_graph
|
| 553 |
+
|
| 554 |
+
def forward(self, *inputs, **kwargs):
|
| 555 |
+
"""Execute forward propagation
|
| 556 |
+
|
| 557 |
+
Arguments:
|
| 558 |
+
*inputs: Variable length input list
|
| 559 |
+
**kwargs: variable length keyword arguments
|
| 560 |
+
"""
|
| 561 |
+
start = None
|
| 562 |
+
if self.model_profile_enabled and get_accelerator().device_name() == 'cuda' and self._config.enable_cuda_graph:
|
| 563 |
+
get_accelerator().synchronize()
|
| 564 |
+
start = time.time()
|
| 565 |
+
|
| 566 |
+
if get_accelerator().device_name() == 'cuda' and self._config.enable_cuda_graph and not self.local_cuda_graph:
|
| 567 |
+
if self.cuda_graph_created:
|
| 568 |
+
outputs = self._graph_replay(*inputs, **kwargs)
|
| 569 |
+
else:
|
| 570 |
+
self._create_cuda_graph(*inputs, **kwargs)
|
| 571 |
+
outputs = self._graph_replay(*inputs, **kwargs)
|
| 572 |
+
|
| 573 |
+
else:
|
| 574 |
+
outputs = self.module(*inputs, **kwargs)
|
| 575 |
+
|
| 576 |
+
if self.model_profile_enabled and self._config.enable_cuda_graph:
|
| 577 |
+
get_accelerator().synchronize()
|
| 578 |
+
duration = (time.time() - start) * 1e3 # convert seconds to ms
|
| 579 |
+
self._model_times.append(duration)
|
| 580 |
+
|
| 581 |
+
return outputs
|
| 582 |
+
|
| 583 |
+
def _generate(self, *inputs, **kwargs):
|
| 584 |
+
# Reset KV-cache at the beginning of generate
|
| 585 |
+
if hasattr(self.module, 'reset_cache'):
|
| 586 |
+
self.module.reset_cache()
|
| 587 |
+
num_beams = 1
|
| 588 |
+
if "generation_config" in kwargs:
|
| 589 |
+
gen_config = kwargs["generation_config"]
|
| 590 |
+
num_beams = getattr(gen_config, "num_beams", 1)
|
| 591 |
+
if "num_beams" in kwargs:
|
| 592 |
+
num_beams = kwargs["num_beams"]
|
| 593 |
+
|
| 594 |
+
if num_beams > 1:
|
| 595 |
+
raise NotImplementedError("DeepSpeed does not support `num_beams` > 1, if this is important to you please "
|
| 596 |
+
"add your request to: https://github.com/deepspeedai/DeepSpeed/issues/2506")
|
| 597 |
+
|
| 598 |
+
if ("input_ids" in kwargs) and (kwargs["input_ids"].dim() == 2):
|
| 599 |
+
for input_tensor in kwargs["input_ids"]:
|
| 600 |
+
tensor_length = input_tensor.shape[-1]
|
| 601 |
+
if tensor_length > self._config.max_out_tokens:
|
| 602 |
+
raise RuntimeError(
|
| 603 |
+
f"Input with size {tensor_length} exceeds maximum length of {self._config.max_out_tokens}. Please increase max_tokens in the DeepSpeed Inference Config."
|
| 604 |
+
)
|
| 605 |
+
|
| 606 |
+
return self.module.generate(*inputs, **kwargs)
|
| 607 |
+
|
| 608 |
+
def compile(self, backend=get_accelerator().get_compile_backend(), compile_kwargs={}) -> None:
|
| 609 |
+
"""
|
| 610 |
+
Compile the module using the specified backend and kwargs.
|
| 611 |
+
"""
|
| 612 |
+
if not is_compile_supported():
|
| 613 |
+
raise RuntimeError("compile is not supported in your version of PyTorch.")
|
| 614 |
+
|
| 615 |
+
if self._is_compiled:
|
| 616 |
+
return
|
| 617 |
+
|
| 618 |
+
# Avoid graph breaks
|
| 619 |
+
deepspeed.utils.nvtx.enable_nvtx = False
|
| 620 |
+
self.module.compile(backend=backend, **compile_kwargs)
|
| 621 |
+
self._is_compiled = True
|
| 622 |
+
|
| 623 |
+
@property
|
| 624 |
+
def is_compiled(self) -> bool:
|
| 625 |
+
return self._is_compiled
|
lib/python3.12/site-packages/deepspeed/inference/quantization/__init__.py
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (211 Bytes). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/layers.cpython-312.pyc
ADDED
|
Binary file (6.9 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/quantization.cpython-312.pyc
ADDED
|
Binary file (4.93 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/quantization_context.cpython-312.pyc
ADDED
|
Binary file (974 Bytes). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/quantization/__pycache__/utils.cpython-312.pyc
ADDED
|
Binary file (17.6 kB). View file
|
|
|
lib/python3.12/site-packages/deepspeed/inference/quantization/layers.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Microsoft Corporation.
|
| 2 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 3 |
+
|
| 4 |
+
# DeepSpeed Team
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
|
| 8 |
+
from torch import nn
|
| 9 |
+
from torch import Tensor
|
| 10 |
+
from torch.nn import functional as F
|
| 11 |
+
from .utils import Quantizer, DeQuantizer, concat_to_compat_param
|
| 12 |
+
from typing import Tuple, Callable, Dict
|
| 13 |
+
from deepspeed.runtime.zero import register_external_parameter
|
| 14 |
+
|
| 15 |
+
quantized_weight_registry = {}
|
| 16 |
+
is_zero3_enabled = False
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
# deal with weight sharing
|
| 20 |
+
def get_quantized_weight_wrapper(model, pre_quant_weight: nn.Parameter, quantize_weight_fn: Callable) -> nn.Parameter:
|
| 21 |
+
if id(pre_quant_weight) in quantized_weight_registry:
|
| 22 |
+
compat_tensor = quantized_weight_registry[id(pre_quant_weight)]
|
| 23 |
+
if is_zero3_enabled:
|
| 24 |
+
register_external_parameter(model, compat_tensor)
|
| 25 |
+
|
| 26 |
+
return quantized_weight_registry[id(pre_quant_weight)]
|
| 27 |
+
else:
|
| 28 |
+
quantized_weights, quant_scale, quant_min = quantize_weight_fn()
|
| 29 |
+
quantized_weight_registry[id(pre_quant_weight)] = concat_to_compat_param(quantized_weights, quant_scale,
|
| 30 |
+
quant_min)
|
| 31 |
+
return quantized_weight_registry[id(pre_quant_weight)]
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def get_quantize_weight_fn(quantizer: Quantizer, pre_quant_weight: nn.Parameter) -> Callable:
|
| 35 |
+
|
| 36 |
+
def func() -> Tuple[nn.Parameter, Tensor, Tensor]:
|
| 37 |
+
quantized_weights, quant_scale, quant_min = quantizer.quantize(pre_quant_weight.data)
|
| 38 |
+
# A temporary hack as zero Zero3 assume all model weights has the same type. in all_gather_coalesced.get_only_unique_item
|
| 39 |
+
quantized_weights = quantized_weights.view(pre_quant_weight.dtype)
|
| 40 |
+
quant_scale = quant_scale.type(pre_quant_weight.dtype)
|
| 41 |
+
quant_min = quant_min.type(pre_quant_weight.dtype)
|
| 42 |
+
return quantized_weights, quant_scale, quant_min
|
| 43 |
+
|
| 44 |
+
return func
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class QuantizedLinear(nn.Linear):
|
| 48 |
+
|
| 49 |
+
def __init__(self, config: Dict, pre_quant_layer: nn.Linear) -> None:
|
| 50 |
+
super(QuantizedLinear, self).__init__(in_features=pre_quant_layer.in_features,
|
| 51 |
+
out_features=pre_quant_layer.out_features,
|
| 52 |
+
bias=pre_quant_layer.bias is not None,
|
| 53 |
+
device=pre_quant_layer.weight.device,
|
| 54 |
+
dtype=pre_quant_layer.weight.dtype)
|
| 55 |
+
self.config = config
|
| 56 |
+
|
| 57 |
+
self.quantizer = Quantizer(config=config)
|
| 58 |
+
self.bias = pre_quant_layer.bias
|
| 59 |
+
self.weight = get_quantized_weight_wrapper(self, pre_quant_layer.weight,
|
| 60 |
+
get_quantize_weight_fn(self.quantizer, pre_quant_layer.weight))
|
| 61 |
+
|
| 62 |
+
self.weight.dequantizer = DeQuantizer(config, pre_quant_layer.weight.dtype)
|
| 63 |
+
|
| 64 |
+
def forward(self, input: Tensor) -> Tensor:
|
| 65 |
+
quantized_weight, quant_scale, quant_min = self.weight.deconcat(self.weight)
|
| 66 |
+
temp_dequantized_weight = self.weight.dequantizer.dequantize(quantized_weight.view(torch.uint8), quant_scale,
|
| 67 |
+
quant_min)
|
| 68 |
+
|
| 69 |
+
# !!! Do not use torch.functional.linear(input, temp_dequantized_weight, self.bias) here as in zero3 torch.functional.linear is
|
| 70 |
+
# replaced by LinearFunctionForZeroStage3. Which assume weight is non-temporary.
|
| 71 |
+
# If weight is temp buffer there will be memory leak.
|
| 72 |
+
return torch._C._nn.linear(input, temp_dequantized_weight, self.bias)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
class QuantizedEmbedding(nn.Embedding):
|
| 76 |
+
|
| 77 |
+
def __init__(self, config: Dict, pre_quant_layer: nn.Embedding) -> None:
|
| 78 |
+
super(QuantizedEmbedding, self).__init__(num_embeddings=pre_quant_layer.num_embeddings,
|
| 79 |
+
embedding_dim=pre_quant_layer.embedding_dim,
|
| 80 |
+
padding_idx=pre_quant_layer.padding_idx,
|
| 81 |
+
max_norm=pre_quant_layer.max_norm,
|
| 82 |
+
norm_type=pre_quant_layer.norm_type,
|
| 83 |
+
scale_grad_by_freq=pre_quant_layer.scale_grad_by_freq,
|
| 84 |
+
sparse=pre_quant_layer.sparse,
|
| 85 |
+
_weight=pre_quant_layer.weight,
|
| 86 |
+
device=pre_quant_layer.weight.device,
|
| 87 |
+
dtype=pre_quant_layer.weight.dtype)
|
| 88 |
+
|
| 89 |
+
assert pre_quant_layer.max_norm is None, 'Not supported'
|
| 90 |
+
assert pre_quant_layer.norm_type == 2, 'Not supported'
|
| 91 |
+
assert pre_quant_layer.scale_grad_by_freq == False, 'Not supported'
|
| 92 |
+
assert pre_quant_layer.sparse == False, 'Not supported'
|
| 93 |
+
|
| 94 |
+
self.config = config
|
| 95 |
+
quantizer = Quantizer(config=config)
|
| 96 |
+
|
| 97 |
+
self.weight = get_quantized_weight_wrapper(self, pre_quant_layer.weight,
|
| 98 |
+
get_quantize_weight_fn(quantizer, pre_quant_layer.weight))
|
| 99 |
+
|
| 100 |
+
self.weight.dequantizer = DeQuantizer(config, pre_quant_layer.weight.dtype)
|
| 101 |
+
|
| 102 |
+
def forward(self, input: Tensor) -> Tensor:
|
| 103 |
+
quantized_weight, quant_scale, quant_min = self.weight.deconcat(self.weight)
|
| 104 |
+
temp_dequantized_weight = self.weight.dequantizer.dequantize(quantized_weight.view(torch.uint8), quant_scale,
|
| 105 |
+
quant_min)
|
| 106 |
+
|
| 107 |
+
return F.embedding(input, temp_dequantized_weight, self.padding_idx, self.max_norm, self.norm_type,
|
| 108 |
+
self.scale_grad_by_freq, self.sparse)
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
QUANTIZATION_LAYER_MAPPINGS = {
|
| 112 |
+
nn.Linear: QuantizedLinear,
|
| 113 |
+
nn.Embedding: QuantizedEmbedding,
|
| 114 |
+
}
|