Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 2277ce9

Browse files
authored
Deepsparse framework and sparsification implementation for phase 2 (#169)
* Deepsparse framework and sparsification implementation for phase 2 * add nightly as alternative name for deepsparse
1 parent 0c8b1d4 commit 2277ce9

File tree

14 files changed

+572
-1
lines changed

14 files changed

+572
-1
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ MDCHECKFILES := CODE_OF_CONDUCT.md CONTRIBUTING.md DEVELOPING.md README.md
99
SPARSEZOO_TEST_MODE := "true"
1010

1111
BUILD_ARGS := # set nightly to build nightly release
12-
TARGETS := "" # targets for running pytests: keras,onnx,pytorch,pytorch_models,pytorch_datasets,tensorflow_v1,tensorflow_v1_models,tensorflow_v1_datasets
12+
TARGETS := "" # targets for running pytests: deepsparse,keras,onnx,pytorch,pytorch_models,pytorch_datasets,tensorflow_v1,tensorflow_v1_models,tensorflow_v1_datasets
1313
PYTEST_ARGS := ""
14+
ifneq ($(findstring deepsparse,$(TARGETS)),deepsparse)
15+
PYTEST_ARGS := $(PYTEST_ARGS) --ignore tests/sparseml/deepsparse
16+
endif
1417
ifneq ($(findstring keras,$(TARGETS)),keras)
1518
PYTEST_ARGS := $(PYTEST_ARGS) --ignore tests/sparseml/keras
1619
endif
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing,
10+
# software distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Functionality for working with and sparsifying Models in the DeepSparse framework
17+
"""
18+
19+
# flake8: noqa
20+
21+
from .base import *
22+
from .framework import detect_framework, framework_info, is_supported
23+
from .sparsification import sparsification_info

src/sparseml/deepsparse/base.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing,
10+
# software distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
import functools
17+
from typing import Optional
18+
19+
from sparseml.base import check_version
20+
21+
22+
try:
23+
import deepsparse
24+
25+
deepsparse_err = None
26+
except Exception as err:
27+
deepsparse = object() # TODO: populate with fake object for necessary imports
28+
deepsparse_err = err
29+
30+
31+
__all__ = [
32+
"deepsparse",
33+
"deepsparse_err",
34+
"check_deepsparse_install",
35+
"require_deepsparse",
36+
]
37+
38+
39+
def check_deepsparse_install(
40+
min_version: Optional[str] = None,
41+
max_version: Optional[str] = None,
42+
raise_on_error: bool = True,
43+
) -> bool:
44+
"""
45+
Check that the deepsparse package is installed.
46+
If raise_on_error, will raise an ImportError if it is not installed or
47+
the required version range, if set, is not installed.
48+
If not raise_on_error, will return True if installed with required version
49+
and False otherwise.
50+
51+
:param min_version: The minimum version for deepsparse that it must be greater than
52+
or equal to, if unset will require no minimum version
53+
:type min_version: str
54+
:param max_version: The maximum version for deepsparse that it must be less than
55+
or equal to, if unset will require no maximum version.
56+
:type max_version: str
57+
:param raise_on_error: True to raise any issues such as not installed,
58+
minimum version, or maximum version as ImportError. False to return the result.
59+
:type raise_on_error: bool
60+
:return: If raise_on_error, will return False if deepsparse is not installed
61+
or the version is outside the accepted bounds and True if everything is correct.
62+
:rtype: bool
63+
"""
64+
if deepsparse_err is not None:
65+
if raise_on_error:
66+
raise deepsparse_err
67+
return False
68+
69+
return check_version(
70+
"deepsparse",
71+
min_version,
72+
max_version,
73+
raise_on_error,
74+
alternate_package_names=["deepsparse-nightly"],
75+
)
76+
77+
78+
def require_deepsparse(
79+
min_version: Optional[str] = None, max_version: Optional[str] = None
80+
):
81+
"""
82+
Decorator function to require use of deepsparse.
83+
Will check that deepsparse package is installed and within the bounding
84+
ranges of min_version and max_version if they are set before calling
85+
the wrapped function.
86+
See :func:`check_deepsparse_install` for more info.
87+
88+
param min_version: The minimum version for deepsparse that it must be greater than
89+
or equal to, if unset will require no minimum version
90+
:type min_version: str
91+
:param max_version: The maximum version for deepsparse that it must be less than
92+
or equal to, if unset will require no maximum version.
93+
:type max_version: str
94+
"""
95+
96+
def _decorator(func):
97+
@functools.wraps(func)
98+
def _wrapper(*args, **kwargs):
99+
check_deepsparse_install(min_version, max_version)
100+
101+
return func(*args, **kwargs)
102+
103+
return _wrapper
104+
105+
return _decorator
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing,
10+
# software distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Functionality related to integrating with, detecting, and getting information for
17+
support and sparsification in the DeepSparse framework.
18+
"""
19+
20+
# flake8: noqa
21+
22+
from .info import *
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing,
10+
# software distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Functionality related to detecting and getting information for
17+
support and sparsification in the DeepSparse framework.
18+
"""
19+
20+
import logging
21+
from typing import Any
22+
23+
from sparseml.base import Framework, get_version
24+
from sparseml.deepsparse.base import check_deepsparse_install
25+
from sparseml.deepsparse.sparsification import sparsification_info
26+
from sparseml.framework import FrameworkInferenceProviderInfo, FrameworkInfo
27+
from sparseml.sparsification import SparsificationInfo
28+
from sparsezoo import File, Model
29+
30+
31+
__all__ = ["is_supported", "detect_framework", "framework_info"]
32+
33+
34+
_LOGGER = logging.getLogger(__name__)
35+
36+
37+
def is_supported(item: Any) -> bool:
38+
"""
39+
:param item: The item to detect the support for
40+
:type item: Any
41+
:return: True if the item is supported by deepsparse, False otherwise
42+
:rtype: bool
43+
"""
44+
framework = detect_framework(item)
45+
46+
return framework == Framework.deepsparse
47+
48+
49+
def detect_framework(item: Any) -> Framework:
50+
"""
51+
Detect the supported ML framework for a given item specifically for the
52+
deepsparse package.
53+
Supported input types are the following:
54+
- A Framework enum
55+
- A string of any case representing the name of the framework
56+
(deepsparse, onnx, keras, pytorch, tensorflow_v1)
57+
- A supported file type within the framework such as model files:
58+
(onnx, pth, h5, pb)
59+
- An object from a supported ML framework such as a model instance
60+
If the framework cannot be determined, will return Framework.unknown
61+
62+
:param item: The item to detect the ML framework for
63+
:type item: Any
64+
:return: The detected framework from the given item
65+
:rtype: Framework
66+
"""
67+
framework = Framework.unknown
68+
69+
if isinstance(item, Framework):
70+
_LOGGER.debug("framework detected from Framework instance")
71+
framework = item
72+
elif isinstance(item, str) and item.lower().strip() in Framework.__members__:
73+
_LOGGER.debug("framework detected from Framework string instance")
74+
framework = Framework[item.lower().strip()]
75+
elif isinstance(item, str) and (
76+
"deepsparse" in item.lower().strip() or "deep sparse" in item.lower().strip()
77+
):
78+
_LOGGER.debug("framework detected from deepsparse text")
79+
# string, check if it's a string saying deepsparse first
80+
framework = Framework.deepsparse
81+
elif isinstance(item, str) and ".onnx" in item.lower().strip():
82+
_LOGGER.debug("framework detected from .onnx")
83+
# string, check if it's a file url or path that ends with onnx extension
84+
framework = Framework.deepsparse
85+
elif isinstance(item, Model) or isinstance(item, File):
86+
_LOGGER.debug("framework detected from SparseZoo instance")
87+
# sparsezoo model/file, deepsparse supports these natively
88+
framework = Framework.deepsparse
89+
90+
return framework
91+
92+
93+
def framework_info() -> FrameworkInfo:
94+
"""
95+
Detect the information for the deepsparse framework such as package versions,
96+
availability for core actions such as training and inference,
97+
sparsification support, and inference provider support.
98+
99+
:return: The framework info for deepsparse
100+
:rtype: FrameworkInfo
101+
"""
102+
arch = {}
103+
104+
if check_deepsparse_install(raise_on_error=False):
105+
from deepsparse.cpu import cpu_architecture
106+
107+
arch = cpu_architecture()
108+
109+
cpu_warnings = []
110+
if arch and arch.isa != "avx512":
111+
cpu_warnings.append(
112+
"AVX512 instruction set not detected, inference performance will be limited"
113+
)
114+
if arch and arch.isa != "avx512" and arch.isa != "avx2":
115+
cpu_warnings.append(
116+
"AVX2 and AVX512 instruction sets not detected, "
117+
"inference performance will be severely limited"
118+
)
119+
if arch and not arch.vni:
120+
cpu_warnings.append(
121+
"VNNI instruction set not detected, "
122+
"quantized inference performance will be limited"
123+
)
124+
125+
cpu_provider = FrameworkInferenceProviderInfo(
126+
name="cpu",
127+
description=(
128+
"Performant CPU provider within DeepSparse specializing in speedup of "
129+
"sparsified models using AVX and VNNI instruction sets"
130+
),
131+
device="cpu",
132+
supported_sparsification=SparsificationInfo(), # TODO: fill in when available
133+
available=check_deepsparse_install(raise_on_error=False),
134+
properties={
135+
"cpu_architecture": arch,
136+
},
137+
warnings=cpu_warnings,
138+
)
139+
140+
return FrameworkInfo(
141+
framework=Framework.deepsparse,
142+
package_versions={
143+
"deepsparse": get_version(package_name="deepsparse", raise_on_error=False),
144+
"sparsezoo": get_version(package_name="sparsezoo", raise_on_error=False),
145+
"sparseml": get_version(package_name="sparseml", raise_on_error=False),
146+
},
147+
sparsification=sparsification_info(),
148+
inference_providers=[cpu_provider],
149+
training_available=False,
150+
sparsification_available=False,
151+
exporting_onnx_available=False,
152+
inference_available=True,
153+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# flake8: noqa
2+
3+
# Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""
18+
Functionality related to applying, describing, and supporting sparsification
19+
algorithms to models within in the DeepSparse framework.
20+
"""
21+
22+
# flake8: noqa
23+
24+
from .info import *
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) 2021 - present / Neuralmagic, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing,
10+
# software distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Functionality related to describing availability and information of sparsification
17+
algorithms to models within in the DeepSparse framework.
18+
"""
19+
20+
import logging
21+
22+
from sparseml.sparsification import SparsificationInfo
23+
24+
25+
__all__ = ["sparsification_info"]
26+
27+
28+
_LOGGER = logging.getLogger(__name__)
29+
30+
31+
def sparsification_info() -> SparsificationInfo:
32+
"""
33+
Load the available setup for sparsifying model within deepsparse.
34+
:return: The sparsification info for the deepsparse framework
35+
:rtype: SparsificationInfo
36+
"""
37+
_LOGGER.debug("getting sparsification info for deepsparse")
38+
info = SparsificationInfo(modifiers=[])
39+
_LOGGER.info("retrieved sparsification info for deepsparse: %s", info)
40+
41+
return info

0 commit comments

Comments
 (0)